How to assign values to a MATLAB matrix on the diagonal?

Jason S picture Jason S · Oct 18, 2010 · Viewed 73k times · Source

Suppose I have an NxN matrix A, an index vector V consisting of a subset of the numbers 1:N, and a value K, and I want to do this:

 for i = V
     A(i,i) = K
 end

Is there a way to do this in one statement w/ vectorization?

e.g. A(something) = K

The statement A(V,V) = K will not work, it assigns off-diagonal elements, and this is not what I want. e.g.:

>> 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

Answer

Jonas picture Jonas · Oct 18, 2010

I usually use EYE for that:

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

Alternatively, you can just create the list of linear indices, since from one diagonal element to the next, it takes nRows+1 steps:

[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