web-dev-qa-db-ja.com

対角線に値を割り当てる方法は?

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
_
42
Jason S

私は通常 [〜#〜] 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
61
Jonas
>> 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次元配列(ベクトル)として行列にアクセスできるという事実に基づいています。

24
ysap

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秒です。

しかし、それはより多くのメモリを消費します。

2
user677656

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
2
Eran W
>> 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
2
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
2
Amro