IMLを使わずFCMPで行列計算⑦ コレスキー分解

proc fcmp;

   array mat1[3,3] 2 2 3 2 4 2 3 2 6;

   array mat2[3,3] / nosym;

   call chol(mat1, mat2, 0);

   rc = write_array("MAT1", mat1 ) ;

   rc = write_array("MAT2", mat2 ) ;

run;

proc print data=MAT1;

run;

proc print data=MAT2;

run;


mat2の転置行列を作って,mat2とmat2tの行列積をつくればmat1に戻ることが確認できる
つまり,コレスキー分解は 下三角行列とその転置の積に分解する操作


 

IMLを使わずFCMPで行列計算⑥ 行列式の算出

 proc fcmp;

   array mat1[2,2] (2 1 3 4);

   call det(mat1, result);

   put result=;

quit;

result = 5



2次正方行列なので
2 * 4  - 1 * 3 = 5










IMLを使わずFCMPで行列計算⑤ 単位行列の生成

proc fcmp;

  array mat1[3,3] /nosym;

   call identity(mat1);

   rc = write_array("RESULT", mat1 ) ;

quit;








 

IMLを使わずFCMPで行列計算④ 転置行列

 proc fcmp;

   array mat1[3,2] (3,5,0,9,1,2);

   array trans_mat1[2,3] /nosym;

  /*call transposeでmat1の転置行列をtrans_mat1に格納 */

   call transpose(mat1,trans_mat1);

   rc = write_array("MAT1", mat1 ) ;

   rc = write_array("TRANS_MAT1", trans_mat1 ) ;

quit;

proc print data=MAT1;

run;

proc print data=TRANS_MAT1;

run;




IMLを使わずFCMPで行列計算③ 逆行列

 proc fcmp;

   array mat1[3,3] (3,5,0,9,1,2,8,7,9);

   array inv_mat1[3,3] /nosym;

   array result[3,3] /nosym;

  /*call invでmat1の逆行列をinv_mat1に格納 */

   call inv(mat1,inv_mat1);

  /*mat1と逆行列の行列積をresultに格納*/

   call mult(mat1, inv_mat1, result);

   rc = write_array("MAT1", mat1 ) ;

   rc = write_array("INV_MAT1", inv_mat1 ) ;

   rc = write_array("RESULT", result ) ;

quit;

proc print data=MAT1;

run;

proc print data=INV_MAT1;

run;

proc print data=RESULT;

run;



















浮動小数点誤差で-0とかってなってますが,逆行列かけたら 単位行列になるのが確認できる

IMLを使わずFCMPで行列計算② SASデータセット⇔行列

 data wk1;

a=1;b=2;c=4;output;

a=5;b=8;c=9;output;

run;


data wk2;

var1=3;var2=6;dum=99;output;

var1=2;var2=1;dum=99;output;

var1=0;var2=10;dum=99;output;

run;



wk1から全変数を読み込んでFCMP配列mat1(そのまま行列計算に使える)へ
wk2からvar1,var2だけを読み込んでFCMP配列mat2(そのまま行列計算に使える)へ

proc fcmp;

   array mat1[2,3] /nosym;

   array mat2[3,2] /nosym;

   array result[2,2];

   rc = read_array("wk1", mat1) ;

   rc = read_array("wk2", mat2 ,"var1","var2") ;

   put mat1=;

   put mat2=;

   call mult(mat1, mat2, result);

   rc = write_array("RESULT", result ) ;

quit;


結果をFCMP配列resultからSASデータセットRESULTへ


最後の書き出し部分で第三引数以降に出力時の変数名を指定できる
rc = write_array("RESULT", result ,"COL1","COL2") ;




IMLを使わずFCMPで行列計算① 行列の積

以外と知られていなくて,IMLライセンスがないからSASで行列計算できないと思い込んでませんか.できます
IMLに比べれば機能は劣りますが,基本的な行列計算はFCMPでできます(DS2のmatrixパッケージもあるけど,あらかじめの備え付け機能の充実はFCMPが上)
 
proc fcmp;

   array mat1[2,3] (1,2,4,5,8,9);

   array mat2[3,2] (3,6,2,1,0,10);

   array result[2,2];

   call mult(mat1, mat2, result);

   rc = write_array("RESULT", result ) ;

quit;