n 行 m 列の行列を mn 行 m 列の行列に変換したいのですが、結果の各 m 行 m 列のブロックには各行の対角線が含まれています。
たとえば、入力が次の場合:
[1 2; 3 4; 5 6]
出力は次のようになります。
[1 0; 0 2; 3 0; 0 4; 5 0; 0 6]
もちろん、for
ループを使用して自分で行列を段階的に組み立てたくはありません。
これを達成するためのベクトル化された簡単な方法はありますか?
n 行 m 列の行列を mn 行 m 列の行列に変換したいのですが、結果の各 m 行 m 列のブロックには各行の対角線が含まれています。
たとえば、入力が次の場合:
[1 2; 3 4; 5 6]
出力は次のようになります。
[1 0; 0 2; 3 0; 0 4; 5 0; 0 6]
もちろん、for
ループを使用して自分で行列を段階的に組み立てたくはありません。
これを達成するためのベクトル化された簡単な方法はありますか?
これをベクトル化して行うには、対角要素の線形インデックスを結果の行列に作成し、直接割り当てます。
%# create some input data
inArray = [10 11;12 13;14 15];
%# make the index array
[nr,nc]=size(inArray);
idxArray = reshape(1:nr*nc,nc,nr)';
idxArray = bsxfun(@plus,idxArray,0:nr*nc:nr*nc^2-1);
%# create output
out = zeros(nr*nc,nc);
out(idxArray) = inArray(:);
out =
10 0
0 11
12 0
0 13
14 0
0 15
X
が入力行列であると仮定して、単純なベクトル化されたソリューションを次に示します。
Y = repmat(eye(size(X, 2)), size(X, 1), 1);
Y(find(Y)) = X;
もう 1 つの方法は、 を使用sparse
することです。これは、すっきりとしたワンライナーとして記述できます。
Y = full(sparse(1:numel(X), repmat(1:size(X, 2), 1, size(X, 1)), X'));
これを行う最も簡単な方法は、実際には非常に単純で、単純なインデックス参照と reshape 関数を使用することです。
I = [1 2; 3 4; 5 6];
J(:,[1,4]) = I;
K = reshape(J',2,6)';
を調べるJ
と、次のようになります。
J =
1 0 0 2
3 0 0 4
5 0 0 6
マトリックスK
はまさに望んでいたものです:
K =
1 0
0 2
3 0
0 4
5 0
0 6
Eitan T がコメントで指摘したように、上記は例に固有のものであり、一般的な解決策はカバーしていません。したがって、以下は、質問で説明されているように m と n を使用した一般的な解決策です。
J(:,1:(m+1):m^2) = I;
K=reshape(J',m,m*n)';
テストして動作を確認したい場合は、
I=reshape(1:(m*n),m,n)';
注: J が既に存在する場合、これにより問題が発生する可能性があります。この場合、あなたも使用する必要があります
J=zeros(n,m^2);