FCMPプロシジャはユーザー定義関数を作成するだけでなく、簡単な行列計算をしたい場合にも便利です。
ちなみに行列で解を求める式はこんな感じでしょうか。
data DT1; input A B C D; cards; 1 1 1 6 2 4 3 19 5 3 2 17 ; run;
|
FCMPプロシジャで行列により解を求めます。
proc fcmp; *** ① 計算用の配列を定義 ; array _ABC [3, 3] / nosym; array _D [3, 1] / nosym; array _INV [3, 3] / nosym; array _OUT [3] / nosym; *** ② 計算するデータセットを配列に格納 ; rc = read_array("DT1", _ABC, "A","B","C"); rc = read_array("DT1", _D , "D"); *** ③ 行列計算して解を出す ; call inv(_ABC, _INV); * 逆行列 ; call mult(_INV, _D, _OUT); * 行列の積 ; *** ④ 結果をデータセットに書き出す ; rc = write_array("OUT1", _OUT, "RESULT") ; run; データセットOUT1
x=1, y=2, z=3 という結果が得られました。 |
解説
処理のおおまかな流れは、計算用のデータセットを配列に格納 → その配列を使って行列計算 → 出た解をデータセットに吐き出す。。といった感じです。
①まず行列計算で必要になる配列を定義しておきます。
NOSYMをつけると配列に変数を割り当てる必要がなくなります。
(DATAステップのARRAYでいうところの一時配列_TEMPORARY_みたいなもの)
②READ_ARRAY関数でデータセットDT1を配列に格納します。
READ_ARRAY("読み込むデータセット", "読み込んだデータを格納する配列", "読み込む変数1", "読み込む変数2"…) |
③読み込んだ配列に対して、行列計算して解を出します。
逆行列 … CALL INV( 配列, 結果を格納する配列 )
行列の積 … CALL MULT( 配列1, 配列2, 結果を格納する配列 )
|
④WRITE_ARRAY'関数で解をデータセットOUT1に格納します。
WRITE_ARRAY("出力後データセット名", "出力する配列", "出力時の変数名1", "出力時の変数名2"…) |
0 件のコメント:
コメントを投稿