今回は、アイパターンの表示をやってみます。
まず、アイパターンって知っていますか?

ご参考。
http://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%A4%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

私の元々の仕事は光ディスクドライブの開発設計だったのですが、光ピックアップからの出力を観測するとき、アナログシンクロスコープを用いてアイパターンというものを表示させます。
このアイパターンの観測は光ディスクの信号のみならず、通信系の信号の観測にも使われます。
http://www.yobology.info/text/eye_pattern/eye_pattern.htm

理想のロジック信号は非常に信号の立ち上がりが早いと云うことで、矩形波の固まりとして表示されますが、実際には伝送系の問題により立ち上がり特性はなまったり、歪んだりします。そうすると本来のタイミングで論理判定ができず通信エラーになったりします。これを信号観測で直感的に評価するために使われます。

前に通信系の信号処理をやってみたので、その信号を表示させてみます。
伝送系での歪みとしては一般的なフィルタでもいいのですが、今回は光ディスクドライブで関係のある光学スポットによる波形歪みを加えてみました。

前に使った信号の再利用になりますが、信号の発生は以下のプログラムを実行します。
これで datasignal というデータを得ます。

//ランダムデジタルデータの発生

//初期値の設定
rand('seed',0)

//一様分布の乱数発生。数値範囲 0-1.0
randomdata=(rand(1,64,'uniform'))

//'0','1' 符号化するために、0.5を足して整数部分のみを抽出
data=int(0.5+randomdata)

//オーバサンプリングする
for i=1:64
    j=(i-1)*8
    if data(1,i)==0 then data8(1,j+1:j+8)=[0 1 0 1 1 0 0 0];
    else data8(1,j+1:j+8)=[1 0 1 0 0 1 1 1];
    end
end

//BPSK 変調を掛ける。
datasignal=[]

//データサイズを取得
datasize=size(data8,'c')

//1bit辺りの周期数を設定
f=4;

//1周期16サンプル
Fs=1/16/f

//データ数と刻みを設定
n=0:Fs:datasize-Fs

//元データ 1bit が 8 x 4 x 16 される。

for i=1:datasize
    for j=1:16*f
        if data8(1,i)==0 then datasignal(1,(i-1)*16*f+j)=0;
                      else datasignal(1,(i-1)*16*f+j)=1;
        end
    end
end

scf(3);
clf(3)
plot(datasignal)


波形は以下のようになります。

イメージ 1
拡大です。
イメージ 2

このデータ列はパルスで構成されていますので、仮想的にディスクの盤面上に矩形波の凸凹があったとして、これをガウス分布のエネルギー密度を持つ光スポットを当てて、その反射光を観測したとします。

// 正規分布ベクトル

clf(0)
scf(0)

vr=128
// 分布の片側幅を設定

strate=5
// 片側幅に対する標準偏差の割合の逆数: ※この場合、5σが±128ということ。

x1=[-vr:vr]
stndsigma=vr/strate
sqtsigma=stndsigma^2
ave=0

normal=1/((2*%pi*sqtsigma)^0.5)*exp(-((x1-ave)^2/2/sqtsigma))
// 正規分布の生成

plot(normal)
イメージ 3
そのスクリプトは以下のようです。


// vr×2+1 個のガウスカーブが出来た。
// datasignal(=data8.sce で生成される)を加工する。サイズ=(1,32768)

a0=zeros(0:vr)
datapro=[a0,datasignal,a0]
// 頭に 0 を vr 個、後ろに 0 を vr 個付ける

sdata=size(datasignal,'c')
outputdata=zeros(0:sdata+2*vr)
// 同じサイズのオールゼロベクトルを準備

for i=1:sdata

    outputdata(i+vr)=datapro(i:i+vr*2)*normal'
// ある一点におけるエネルギー量を前後±vrを含めて合計
       
end

clf(1)
scf(1)

result=outputdata(vr+1:sdata+vr)

plot(result)

結果は以下のようになります。

イメージ 4
拡大です。

イメージ 5
さてこうして得た伝送信号をアイパターンで表示してみます。
スクリプトは以下のようです。


clf(2)
scf(2)

i=1
j=1
while i<sdata do
    while result(i)<0.5 & i<sdata do i=i+1
    end
// 0.5 以上のレベルが出るまでカウントを進める。

    if result(i)>0.5 then plot(result(i:i+500))
        i=i+500
        j=j+1       
    end
 // 0.5 以上のレベルが出たところから、500カウント分表示しカウンタも500進める。
  
//    while i<32767 do
        while result(i)>0.5 do i=i+1
        end
// 次に 0.5 以下になるまでカウントを進める。
//    end

end

結果は以下のようになります。

イメージ 6
いかがでしょうか。
strate という変数を小さくしてみると、波形干渉の影響が見られます。

条件判断文が合理的に作れていないようで、下手くその極致だと思います。是非プログラミングの上手な方の教えを請いたいものです。

最後のスクリプトは result というベクトルを与えるとアイパターンを表示するようになっているので、ローパスフィルタなどの波形のなまりやノイズを与えた信号でやって見てみるのも面白いと思います。