Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 
like image 661
Jason S Avatar asked Oct 18 '10 21:10

Jason S


People also ask

How do you index a diagonal matrix in Matlab?

indices = (1+ii*n):(n+1):(n*n); (Note that the parenthesis are not necessary, as the colon operator has the lowest precedence.) The lower diagonal elements are given by: indices = (1+ii):(n+1):((n-ii)*n);

How do you assign a matrix element in Matlab?

The most common way is to explicitly specify the indices of the elements. For example, to access a single element of a matrix, specify the row number followed by the column number of the element. e is the element in the 3,2 position (third row, second column) of A .

How do you extract the values above the main diagonal?

Extracting the above values of the main diagonal in a matrixAn outer loop is used to iterate over the row elements and an inner loop is used to iterate over the column elements. And if the condition is used to check if the column number is greater than the row number. The element is then extracted from the matrix.


2 Answers

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 
like image 71
Jonas Avatar answered Sep 19 '22 03:09

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 

and more general:

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

This is based on the fact that matrices can be accessed as one-dimensional arrays (vectors), where the 2 indices (m,n) are replaced by a linear mapping m*N+n.

like image 44
ysap Avatar answered Sep 20 '22 03:09

ysap