2007年3月16日金曜日

matlab: 対角行列を効率的に生成

Matlab で対角行列の類を生成する場合がよくある.これを,メモリ・速度・コード量とも効率よく行うにはどうすればいいかという話.
普通の対角行列の場合.対角成分を並べたベクトルを w とすると,
W = diag(sparse(w));

が多分最良.
ブロック対角行列の場合はどうか.m by n の行列が k 個対角に並ぶ場合を考える.ブロック対角成分を並べた行列を B (m by n*k) とすると,
C1 = sparse(B);
C1(m*k,n*k) = 0;
C2 = reshape(C1,[m*k*n,k]);
C2(m*(k*n+1),k) = 0;
C = reshape(C2, [m*k,n*k+1]);
C(:,end) = [];

くらいでどうだろう.
blkdiag は引数の形式が馴染まないことが多いと思う.セル配列から展開するのか?あとは,単に自分が sparse や spdiags を使いこなせていないという噂もある.
※最後の行 20070424 に訂正した.bad->C(:,end-(n-1):end) = [];

行列からのブロック対角成分の抽出や,抽出した成分を用いてブロック対角行列を再構成する方法について,「matlab: ブロック対角成分の抽出」という記事も書きました.


0 件のコメント:

コメントを投稿