NxNマトリックスA、数値1:Nのサブセットで構成されるインデックスベクトルV、および値Kがあり、これを実行するとします。
_ for i = V
A(i,i) = K
end
_
ベクトル化のある1つのステートメントでこれを行う方法はありますか?
例えばA(何か)= K
ステートメントA(V,V) = K
は機能せず、非対角要素を割り当てますが、これは私が望むものではありません。例えば。:
_>> A = zeros(5);
>> V = [1 3 4];
>> A(V,V) = 1
A =
1 0 1 1 0
0 0 0 0 0
1 0 1 1 0
1 0 1 1 0
0 0 0 0 0
_
私は通常 [〜#〜] eye [〜#〜] を使用します:
A = magic(4)
A(logical(eye(size(A)))) = 99
A =
99 2 3 13
5 99 10 8
9 7 99 12
4 14 15 99
または、1つの対角要素から次の要素までnRows+1
ステップ:
[nRows,nCols] = size(A);
A(1:(nRows+1):nRows*nCols) = 101
A =
101 2 3 13
5 101 10 8
9 7 101 12
4 14 15 101
対角要素のサブセットにのみアクセスする場合は、対角インデックスのリストを作成する必要があります。
subsetIdx = [1 3];
diagonalIdx = (subsetIdx-1) * (nRows + 1) + 1;
A(diagonalIdx) = 203
A =
203 2 3 13
5 101 10 8
9 7 203 12
4 14 15 101
または、diag
を使用して論理インデックス配列を作成できます(正方配列でのみ機能します)
diagonalIdx = false(nRows,1);
diagonalIdx(subsetIdx) = true;
A(diag(diagonalIdx)) = -1
A =
-1 2 3 13
5 101 10 8
9 7 -1 12
4 14 15 101
>> tt = zeros(5,5)
tt =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
>> tt(1:6:end) = 3
tt =
3 0 0 0 0
0 3 0 0 0
0 0 3 0 0
0 0 0 3 0
0 0 0 0 3
より一般的な:
>> V=[1 2 5]; N=5;
>> tt = zeros(N,N);
>> tt((N+1)*(V-1)+1) = 3
tt =
3 0 0 0 0
0 3 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 3
これは、2つのインデックス(m、n)が線形マッピングm * N + nに置き換えられる1次元配列(ベクトル)として行列にアクセスできるという事実に基づいています。
Kが値だとします。コマンド
A=A-diag(K-diag(A))
少し速いかもしれません
>> A=randn(10000,10000);
>> tic;A(logical(eye(size(A))))=12;toc
経過時間は0.517575秒です。
>> tic;A=A+diag((99-diag(A)));toc
経過時間は0.353408秒です。
しかし、それはより多くのメモリを消費します。
sub2ind
を使用して、xとyの両方のパラメーターとして対角インデックスを渡します。
A = zeros(4)
V=[2 4]
idx = sub2ind(size(A), V,V)
% idx = [6, 16]
A(idx) = 1
% A =
% 0 0 0 0
% 0 1 0 0
% 0 0 0 0
% 0 0 0 1
>> B=[0,4,4;4,0,4;4,4,0]
B =
0 4 4
4 0 4
4 4 0
>> v=[1,2,3]
v =
1 2 3
>> B(eye(size(B))==1)=v
%insert values from v to eye positions in B
B =
1 4 4
4 2 4
4 4 3
A = zeros(7,6);
V = [1 3 5];
[n m] = size(A);
diagIdx = 1:n+1:n*m;
A( diagIdx(V) ) = 1
A =
1 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 1 0
0 0 0 0 0 0
0 0 0 0 0 0