45

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
4

7 に答える 7

62

私は通常、そのために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

If you only want to access a subset of diagonal elements, you need to create a list of diagonal indices:

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

Alternatively, you can create a logical index array using diag (works only for square arrays)

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
于 2010-10-18T21:32:40.680 に答える
24
>> 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

これは、行列が 1 次元配列 (ベクトル) としてアクセスできるという事実に基づいています。ここで、2 つのインデックス (m,n) は線形マッピング m*N+n に置き換えられます。

于 2010-10-18T21:33:21.363 に答える
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
于 2010-10-18T21:39:10.337 に答える
2

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

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

于 2011-03-26T02:57:23.623 に答える
2

sub2indx と 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
于 2014-02-20T21:51:15.167 に答える