逆行列の組立方針 (1) ?getrf, ?getri の組合せで逆行列を求める。 (2a) csiを求める必要がなければ、素直に以下を解けば良い。(ZF) y = H*x; xhat = Hest \ y % _GESV % A*x = b % (Hest)*(xhat) = y (2b) csiを求める必要がなければ、素直に以下を解けば良い。(MMSE) HHH=(H'*H+sigma*I) % _HERK % C = A'*B+ beta*C % エルミート(正定値?) HY = H'*y % _GEMV % C = A'*B HHH*(xhat) = H'*y % _POSV % A*x = b (3a) csiを求めるなら、以下。(ZF/MMSE) : MATLAB方式 HHH=(H'*H+sigma*I) % _HERK % C = A'*A+ beta*C % エルミート(正定値?) HY = H'*y % _GEMV % C = A'*B INV = inv(HHH) % _POSV % A*x = b % (HHH)*(INV) = (I) csi = 1./real(diag(INV)); xhat = INV*HY % BLAS % C = A * B (3b) csiを求めるなら、以下。(ZF/MMSE) : 提案手法 HHH=(H'*H+sigma*I); % CHERK % C = A'*A+ beta*C % エルミート(正定値?) %G=HHH\H'; % CHESV % A*X = B % (HHH)*(G) = (H') %csi3c = 1./sum((conj(G).*G),2); %xhat3c = G * y ; % CGEMV % C = A*B GH=H/HHH; % CHESV % X*A = B % (GH)*(HHH) = (H) %csi3c = 1./diag(GH'*GH); % CGEMV % C = A' * B csi3c = 1./sum(conj(GH).*GH,2); % CGEMV % C = A' * B xhat3c = GH' * y ; % CGEMV % C = A'*B -- BLASの簡単な使い方 http://azalea.s35.xrea.com/blas/ --- In-place Transpose: dge_trans 対角成分を直接SWAPする。入力された行列を直接操作。 --- BLAS level 1: single-loop set to zero (bzero), set to a constant (memset), copy vectors (dcopy), inner-product (ddot), ax+y (daxpy), ax+by (daxpby) BLAS level 2: double-loop matrix copy (dge_copy), matrix transpose (deg_trans), outerproduct (dger), matrix-vector product (dgemv) BLAS level 3: triple-loop matrix-matrix product (dgemm): optimized in-cache matrix solver. For use with dge_copy to create a blocked matrix-matrix multiply. --- LAPACK simple/divede and conqure/RRR(relatively robust representation)/Expert 配列添え字は、FORTRAN:1-base, C/C++:0-base C/C++では普通row major FORTRANや、Matlab, octaveはcolumn major orderingが異なる場合、以下の様な行列転置が発生しオーバーヘッドとなる。 C=( (A).' * (B).' ).' ---- Call LAPACK and BLAS Functions https://www.mathworks.com/help/matlab/matlab_external/calling-lapack-and-blas-functions-from-mex-files.html MATLAB2017b以前は、re/im別管理型。 MATLAB2018a以降は、re/imインタリーブ型。Fortrunもこの形式。 ''' mex -v -R2017b matrixMultiply.c -lmwblas mex -v -R2017b matrixDivide.c -lmwlapack ''' ----- ドライバルーチンには,通常の単純ドライバに加えて, 幾つかの機能を追加したエキスパート・ドライバがあります. エキスパート・ドライバは,条件数の算定,行列の特異性のチェック, 解の反復改良,誤差解析などの機能をサポートします. ただしエキスパート・ドライバを実行するためには,単純ドライバの約2倍の記憶容量が必要 ----- https://ja.wikipedia.org/wiki/行列の定値性 -- S: 単精度実数 D: 倍精度実数 C: 単精度複素数 Z: 倍精度複素数 --- SY: 対称行列 HE: エルミート行列 GT: 三重対角行列 ST: 対称三重対角行列 GE: 一般行列 -- SV: 線形方程式問題 EV: 固有値問題 ----- LAPACK 3.9.0 http://www.netlib.org/lapack/explore-html [LAPACK]->[Files]->[File List]->[LAPACKE]->[example]-> example_DGELS_colmajor.c ----- A * X = B % A[ LDA x N ] * X[ N x NRHS ] = B[ LDB x NRHS ] DGESV ( N, NRHS, A,LDA, IPIV, B,LDB, INFO ) 通常、N=LDA=LDB, IPIV[ N ] このサブルーチンの出力変数は • 2次元配列 A には行列 A を代入した状態でサブルーチンに値を渡しますが、実行後には値が書き換え られ、行列 A を LU 分解した結果が代入されます。L 行列と U 行列はそれぞれ下三角行列、上三角行 列で、対角要素を除いて一つの N × N 行列に値を入れることができますが、L の対角要素は 1 である ため、U の対角要素が A として返されます。 • 2次元配列 B には行列 B の値を入力しましたが、出力では方程式の解の X の値が返されます。 • INFO にはプログラムの実行結果が保存されます。正常終了した場合は 0 が入っています。負の数-i が 返された場合は、i 行目で不正な値があったことを示します。また正の数 i が返された場合、LU 分解の U 行列の Uii がゼロとなり (つまり det A = 0 となり) 連立一次方程式の解が求まらなかったことを示 します。 -----