2012,11,02, Friday
以前の記事で、「集約演算部分は、レコード毎に投入されるデータをソートして配列に格納し保持する処理のみで良い」と書きました。 そのような処理を行う集約関数を定義します。
レコード毎に投入される numeric データを昇順にソートし、配列として格納・保持する集約関数 arraySorted() を、以下のように定義します。 -- arraySorted() : 集約対象フィールドを昇順ソートにて格納した配列を得るBASETYPE とは、この集約関数に投入される(引数として渡される)フィールドデータの型を定義するもので、型変換にてあらゆる数値データを扱えるよう float8(倍精度浮動小数点実数)とします。 STYPE は、この集約関数のなかで内部的に保持される(状態)データの型であり、投入されるデータ(float8)がソートされて保持される配列ですから、float8[] とします。 この配列は、新たなフィールデータが投入される都度、SFUNC により更新されます。 SFUNC は、新たな投入データにより内部状態データがどのように更新されるのかを定義した状態遷移関数であり、ここでは insArraySorted() と命名しました。 この関数は、実際にはこの集約関数定義の前に、定義しておかなくてはなりません。 なお、最終関数 FINALFUNC を宣言していませんので、この集約関数自体の型は STYPE で宣言した float8[] となります。 次に、状態遷移関数 SFUNC として宣言した insArraySorted() を、以下のように定義します。 SFUNC は原則として2つの引数を取ることとされています。 第1引数は状態遷移前の状態データであり、その型は STYPE、また第2引数は投入されたフィールドデータであり、その型は BASETYPE です。 第2引数は省略可能であり、その場合引数の数は1となります。 どちらの場合も、この関数が返す値の型は、STYPE となります。 状態遷移関数の機能は、第1引数として与えられた状態遷移前の状態データを、何がしか処理して状態遷移後の状態データへと更新し、呼出し側に返すことです。 多くの場合には第2引数のフィールドデータが与えられ、それを使って更新処理をします。 ここでは、第1引数で与えられたソート配列が状態データであり、第2引数で与えられた新たなエレメントをソート配列の適当な位置に挿入して更新します。 なお、前述したとおり、この状態遷移関数は集約関数 arraySorted() の定義より先に定義しておかなくてはなりません。 -- insArraySorted() : 新規エレメントを昇順ソート配列中の適正な位置に挿入する単純な処理です。 第2引数で与えられたフィールドデータ(新エレメント)が NULL ならば、第1引数で与えれた元のソート配列を何もしないで返します。 フィールドデータが NULL でない(有意な)データであるならば、ソート配列中の挿入すべき位置を求めてそこに挿入しますが、ソート配列がまだ空である場合には、新エレメントのみを要素として持つ新しい配列を生成します。 こうして更新あるいは新規生成されたソート配列を、返します。 さらに、この insArraySorted() から呼ばれる、新エレメントの挿入位置を求める関数 srchPosIns() を定義します。 この関数は、新たなエレメントがすでにソートされている配列のどこに挿入されるべきかを二分検索にて求め、その位置を返します。 その位置に実際に新エレメントを挿入する処理は、呼出した側で行います。 二分検索というと再帰的呼出しによるのが定番であり、わきたのルーチンでもそうしていますが、再帰呼出しの際に教科書的に引渡す部分配列のため新たな記憶域を確保してしまうと、エレメント数によっては記憶域確保のオーバーヘッドが大きくなり過ぎることが危惧されます。 そこでわきたのルーチンでは、再帰呼出しで引渡す部分配列用の記憶域を新たに確保することはせず、元の配列の先頭と末尾を示す添え字を引渡すことで、部分配列の引渡しとしました。 -- srchPosIns() : 新規エレメントが挿入されるべき昇順ソート配列中の適正な位置を、二分検索により求める再帰呼出しからの脱出条件は2つ。
以上で、集約関数 arraySorted() が定義できました。 あとはこれを使って、第xN分位数を求める関数を定義すれば良い。 ついでにジニ係数を求める関数も作りました。 これらのソースリスト
| http://blog.wakita.cc/index.php?e=87 |
| サーバ・Linux::PostgreSQL | 05:35 PM | comments (0) | trackback (0) | |
コメント
コメントする
|
この記事のトラックバックURL
http://blog.wakita.cc/tb.php/87
トラックバック
|