チュートリアル 17:
データ構造と確率

イントロダクション

このチュートリアルでは、itable オブジェクトを使用したデータ保存、データ変換、ヒストグラム追跡について見ていきます。itable オブジェクトは描画によって値を入力したり、様々な方法でデータをセットすることができます。また、uzi オブジェクトを使用し、短い時間で、多量のbang メッセージを生成したり、増加していく数値のストリームを生成したりする方法についても見ていきます。どちらも、アルゴリズム的に生成されるデータを、短時間で大量に作るために使用することができます。

2次元データ構造(itable のようなもの)を使うと、データ変換システムを簡単に構築することができます。このような伝達関数(訳注:システムへの入力を出力に変換する関数)によって、不規則な曲線、入力に基づいて出力を決定する確率テーブル、簡単に視覚化を行なうことができるランダムなパターンを作ることができます。さらに、短時間で手続き的メッセージの生成を行なう uzi オブジェクトを導入することによって、これらの itable オブジェクトに興味深い方法で重みをかける関数を作る方法が見つけやすくなります。

このチュートリアルで使用されているitableオブジェクトは、実質的にtable オブジェクトと同じものです。table オブジェクトは独自のウィンドウを持ち、通常のオブジェクトボックスで名前をタイプすることができます。ここで itable を使用した理由は、単に、これが別のエディタウィンドウにではなく、パッチャーの中に埋め込まれた形で表示されるものだからです。

itable による基本的なデータ構造

チュートリアルを開いて下さい。

このチュートリアルパッチには、描画と表示を行なうパッチが2つ(数字が表示されています)と、いくつかの小さな計算を行なう部分(アルファベットが表示されています)があることがわかるでしょう。まず、パッチの中の1 と表示された部分から見ていきましょう。このパッチではitable オブジェクトの機能を紹介しています。2次元データ構造の視覚的なインターフェイスを提供するオブジェクトを table と呼びます。table/itable システムは、X-Y というデータの組み合わせと、このデータに対するシンプルなインターフェイスを提供します。入力された数値はX軸のインデックスと解釈され、対応するY軸のデータが出力されます。

最初にパッチを開いたとき、itable には値がランダムに分布しています。パッチの上部にあるslider を動かすと、itable はsliderからの値をXと解釈して値をスキャンし、Xの位置にある Y の値をアウトレットから出力します。アウトレットにはナンバーボックスとslider が接続してあり、itable によって描かれる伝達関数の出力結果を見ることができます。入力用 slider の隣には、2つのメッセージボックスがあり、それぞれ2つの整数によるリストが書かれています。このメッセージを送信すると、最初の整数で表される位置(X) に2番目の整数の値(Y)がセットされます。したがって、最初のメッセージボックスでは、50 という位置に値 80 がセットされます。このメッセージボックスをクリックし、slider(またはナンバーボックス)を 50まで動かすと、itable の出力が 80 であることがわかります。
同様に、2つめのメッセージボックス(100 20)をクリックすると、値100 を入力したときに 値20 が出力されます。

clear メッセージは、itable の画面を「消去」します。しかしitableの値がなくなってしまうわけではありません。clear メッセージが送信されると、すべての可能なデータポイント(すべてのXの値)に対して 0 が割り当てられるだけです。itable の値を変更するには、もう1つ、itable 自身の画面の中に描画するという方法があります。マウスを itable の内部に置き、マウスボタンを押してドラッグすると、望み通りにitable の関数を描くことができます。直線を描きたい場合には、[Shift] キーを押しながらマウスを動かし、端点でマウスをクリックすると新しい直線が得られます。このような描画コマンドを使用すると、簡単に、手作業で面白い伝達関数を作ることができます。

このパッチの下には、3つの小さなパッチがあります。ここでは、uzi オブジェクトを利用してitable のすべての点の値を生成します。A というbutton をクリックすると、入力と出力が同じ値になるような関数が生成されます。B というbutton をクリックすると、これと逆の関数が生成されます。この関数は 0 から 127 の範囲の入力を 127 から 0 の範囲に変換します。C という button は、最初の itable に描かれていたようなランダムな分布を生成します。

uzi を使った数式の作成

これらの関数生成ルーチンをもう少し詳しく見てみましょう。特に uzi オブジェクトに注目して下さい。uzi オブジェクトは、その名前が示すように、短い時間でbang メッセージを出力するために作られたものです。uzi オブジェクトに1つのbang を入力すると、uzi オブジェクトのアーギュメントで指定された数の bang メッセージを生成します。したがって、uzi 128 では128個のbang メッセージが左アウトレットから送信されます。出力された bang が何番目かという経過を追跡するために、右端のアウトレットではこれをカウントして出力します(カウントは 1 から始まります)。この出力をitable のインデックスとして使用しています。パッチの A という部分では、このカウントの値から1を減じて(itable の範囲が 0から始まるためです)、これを X と Y 両方の値として使用しています。この結果、関数として直線が出力されます。

B という部分も同様ですが、Y の値は !- オブジェクトを使って、入力された値を 127 から引いています。この結果は同じような傾斜を作りますが、方向が逆になります。X の最小値には Y の最大値が対応します。C の部分では、ランダムな値を持ったリストを出力するために、乱数ジェネレータを使用しています。ここでは、swap オブジェクト(これは、受信した左と右のインレットの値を単純に「スワップ(入れ替え)」するものです)を使って、リストの順番を入れ替えています。これにより、random オブジェクトの出力を X ではなく Y の値として使用できるようになります。

B の部分を少し変更して、生成される関数がどのように変化するかを見てみましょう。!- オブジェクトを 除算(/)オブジェクトに変更し、アーギュメントを 4 にすると、Y の値の範囲は 縦方向の1/4 に抑えられます。同じように、乗算(*)オブジェクトを使って、アーギュメントを 2 にすると、X の値が半分進んだ所で Y 範囲の最大値に達してしまうでしょう。uzi とわずかな数の演算オブジェクトを使い、ちょっとした操作を行なうだけで、多くの複雑な関数を生成できることがよくわかると思います。

table によるヒストグラム

パッチの右側の部分(2 と表示されています)では、itable システムの面白い使い方を示していて、いくつかの数式パッチとhisto という新しいオブジェクトがあります。histo オブジェクトはヒストグラム関数の処理を行ないます。この処理は、ある数値が何回入力されたかをカウントしていくものです。histo オブジェクトは、値を入力されると、その値を今まで何回受信したかという回数を右アウトレットから出力し、その直後に、その値自身を左アウトレットから出力します。この結果は直接 itable オブジェクトに入力することができます。itable オブジェクトでは、左インレットで受信した値は X に、右インレットで受信した値は Y になります。パッチの上部にあるslider を使って、数多くの値を「スクラッチ」すると、itable オブジェクトが送信された値の相対的な分布を示すことがわかるでしょう。itableオブジェクトとhisto オブジェクトをクリアしたい場合には、キーボードの [Return] キー(ASCII コード 13)を押します。

パッチの上部にある toggle をクリックして、metro オブジェクトをオンにして下さい。これによってitable に bang メッセージが送信され、itable からランダムな「分位」出力が行なわれます。このitable オブジェクトからの出力は、ランダムですが、頻度に重み付けが行なわれています。この結果、itable の下の lcd の中では小さな円の描画がスタートし、この円の密度はitable ルーチンで表示されている分布曲線とほぼ等しいものになります。lcd をクリアしたい場合には、スペースバー(ASCII 値32)を押して下さい。これにより、描画が再スタートします。

最初の描画パッチでは、いくつかの小さなパッチの部分があり、これらはitable オブジェクトに入力する数値を生成する関数として使用されていました。しかし、ここでは、個別の描画関数の代わりに、ランダムな値やセミランダムな値を使った「ファジー」な分布をhisto オブジェクトの中に生成しています。このヒストグラムが itable に送られて確率マップがつくられます。D と E の部分では、そそれぞれ random と drunk を使って値を生成しています。接続された button オブジェクトを繰り返しクリックすると、それぞれのオブジェクトが分布曲線に与えている影響がどのようなものかがわかるでしょう。random ではすべての値がかなり均等に出力されるのに対し、drunk では分布がより「凹凸のある」ものになります。ここでも、[Return] キーを使って、ヒストグラムを随時クリアすることができます。

パッチのFとG の部分では、少し異なったアプローチを行なっています。F では2つの乱数を生成し、minimum オブジェクトを使って2つの数値のうちの小さい方を選んでいます。そのため、範囲の中の小さい値を強調する傾向があります。接続された button を繰り返しクリックすると、たいていの場合、小さい値が大きい値より多く生成されていることがわかります。G では、この反対のことを行なっています。ここでは、maximum オブジェクトを使って2つの乱数のうちの大きい方を選んでいます。そのため、接続された button を繰り返しクリックすると、大きい値用のがより多く生成される傾向があります。

最後に H では、乱数を3つ発生させ、それを加算した合計を3で割っています。これによって、3つの乱数の平均値が生成されます。itable をクリアして、この H の button を繰り返しクリックすると、「ベル型」の曲線が生成されます。これは、3つの乱数の平均値が、範囲の中央付近の値を取る傾向を持つためです。これはシンプルなガウス分布(あるいは正規分布)になります。この分布は、ほとんどの標本値が可能な範囲の中央付近に存在するような統計調査でよく見られる分布です。

どの場合でも、関数によって値を生成して metro を動作させると、itable オブジェクトの分布曲線をシミューレートした描画が実行されます。itable の中に鋭角的な線を描き、そのカーブを出力させて、より急激なカーブによる描画を試してみることができます。また、slider を使って出力の一部に「陰影」をつけ、新しい分布曲線の一部を変化させた描画出力を行なわせることもできます。

結び

入力範囲を出力範囲に変換するような関数を作ることができる能力によって、多くの様々な処理が可能になります。前のチュートリアルでは、scale オブジェクトがこれをどのように行なうかを見てきました。しかし、値の分布を手動で変更したい場合や、データ変換のための式を用いたい場合には、より複雑なシステムを使用する必要があります。このチュートリアルで見てきたように、tabe/itable オブジェクトはこの目的を十分に果たしてくれます。このオブジェクトは変換関数を描く機能を提供してくれるもので、その操作は手動で行なうことも、アルゴリズムを使って行なうことも可能です。

histo オブジェクトを使うことによって、ある種の分布曲線のようなものを生成する方法を見ることができます。これは、ジェネレーティブ・アートやストカスティック・ミュージック(確率音楽)の中で、乱数を扱う一般的なテクニックとして役立つものです。完全な乱数が生成する曖昧さを用いる場合でも、あるいは、他の数学的な方法によってある種の傾向を持たせる場合でも、望ましい結果を生成したり、望ましい結果に導いたりするためにこれらの曲線を利用することができます。

参照

table 数値の配列を格納し、そのグラフィカルな編集ができます。
itable パッチャーウィンドウの中に配置できる table
uzi n個のbang を送信します。
swap 左右のインレットの値を入れ替えて出力します。
histo シンプルなヒストグラム処理を行ないます。
minimum 2つの数値、または数値のリストの最小値を出力します。
maximun 2つの数値、または数値のリストの最大値を出力します。