Chapter Seventy seven

第77話


32個のランプしかないなら複雑なパターンといっても大したことはないだろう、と侮ってはいけない。ナイジェルコーナーに添付した32bitSpace.viを動かしてみると、稀に一つの周期が250を越えるパターンが現れる。また、初期値が違っていても、いつの間にか同じパターンにたどり場合も多い。ランダムネットワークとパターンの関係を調べていくためには、簡単にパターンを抽出するVIが必要だ。

現実世界のパターンは決まってノイズを含むのだが、今回のパターンは純粋だ。1ビットでも違えば異なる数値であり、あるランプが点いているべきときにランプが消えているのである。現実世界でパターンを正確に把握するのは大変だが、ランダムネットワークのパターンではノイズがないので簡単である。

繰り返しのパターンなのかどうかを調べるには、データをずらして重ねてみるのがローテクではあっても確実な方法だろう。幼稚園の子供に四角い厚紙を持たせて、これと同じ形を探させるようなもので、子供は床に散らばっているいろんな形をした厚紙と重ね合わせて同じ形を見つけるだろう。数回やって飽きてしまう子もいれば、親が飽きても続けている子もいるのだが、、。コンピュータは飽きないから面倒な仕事を黙々と正確にやってくれる。

前回の最後に見たグラフをもう一度見てみよう。

ネットワークを動かし始めた直後は規則性が見られないが、何かのきっかけからかパターンが始まって、後はそのパターンの繰り返しになる。多分この後は永遠に繰り返すことになるのだろう。パターンが始まっている部分から1周期以上のデータをコピーしておいて基準のデータとする。開始位置を一つずつずらして同じ幅でコピーして、基準データと比べていくと完全に一致するデータが現れたところが1周期分進んだところになる。

これを自動的に行うには、どうすればよいか。パターンがどこから始まるかは分かっていないし、パターンの長さも分かっていない。そこで、次のような方法で抽出することにした。1)データを4分割して、3番目の部分を基準とする。2)基準の開始から1個ずつずらして4番目の領域が無くなるまで比較していく。3)一致するものが見つからない場合はデータを追加して、1)からの手順を繰り返す。データ数の上限を決めて異常に長いサイクル(カオス)は打ち切る。

下のダイアグラムはfindPitch.viというVIだ。4分割をQuotient & Remainderを使っているのでデータ数を4の倍数以外で入力しても変なことは起こらない。数値の比較ということで、差分の自乗和で行こうと短絡的に決めた。下のダイアグラムでは自乗でなくて絶対値でもいいやと、トーンダウンをしたが、U32は負数を含まないので拡張精度に変換している。考えてみると、equal?関数で全ての配列がTrueになっているかどうか確認すれば拡張精度に変換しなくてもすんだのだった。後で直しておこう。

最後まで一致しないときにはブール表示器のperiodicがFalseで出力される。Falseの場合は呼び出し側でデータを増やして再び(何度でも)findPitch.viを呼び出せばよい。下の方にあるケース構造の中には、regular patter.viが入っている。これは、スタート地点が異なるだけで何種類ものパターンができてしまうのを防ぐために、パターンを(ある程度)正規化するVIだ。transition.viは初期状態からパターンに入り込むまでの動作数と、パターンの何個目からパターンに入り込んできたかを調べるVIだ。

regular patter.viは何らかの規則でパターンの開始点を定めて、位相が異なるだけのパターンを排除しようとするVIだ。思いついた規則は、

1)パターンは最小値からスタートする。2)最大値より後ろに最小値がない。

これで、最大値が一つしかない場合には、(最小値がいくつあっても)パターンの位相が一意に決まる。しかし、最大値と最小値が複数ある場合には一意に決まらないのだ。しょうがないので、チェックサムを作って、チェックサムが一致する場合は回転して一致するかどうかチェックすることにした。

下のダイアグラムは配列の要素を回転して、規則にしたがったパターンになるようにした工夫したものだ。要素の順番を逆にして最大値の要素の指標を調べて最大値が配列の最後になるように回転する。次に最小値の要素の指標を調べて最小値が先頭になるように配列を逆回転(最先頭が最後尾に移動するように)する。下のフォーループではU32に次々加算してチェックサムを作っている。

何回実行した後に、正規化パターンの何番目の要素からパターンに入り込んだのか調べると面白いことがあるかもしれない。(もちろん、ないかもしれない。)transition.viはパターンに入り込んだデータ配列の指標(Pattern start)とパターン配列の指標(Pattrn Pos)を出力する。

transition.viでは、データ配列の先頭から一致するかどうか調べて、一致しなければ、それに続くパターンサイズ毎にチェックを続ける。ここでのチェックはequal?で行っている。配列でequal?を使うと個々の要素を比較してブール配列で出力する。Falseでサーチをかけて1個も見つからなければ全てtrueなので、完全に一致していることになる。途中から一致している場合はTrueでサーチをかけた結果でTrueとなった指標が出力される。このVIではシフトレジスタを駆使してなんとか狙いの動作を実現しているのだが、複雑なダイアグラムになってしまっている。たぶん、これは悪い実例なのであって、データサイズ分のパターンを作りだして実際のデータと突き合わせた方が良いのではないかと思えてくる。勝負は動作速度で、動作速度に大きな差が出なければ、分かりやすいシンプルなダイアグラムが勝ち。

次回は、初期状態を変えながらパターンについて記録するVIを作ってみよう。

 

See you!

Nigel Yamaguchi


戻る