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
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);
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 .
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.
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
>> 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With