Changing multiple elements (from known coordinates) of a matrix without a for loop

I have a matrix

Z = [1 2 3; 4 5 6; 7 8 9] 

I need to change its values, for example, in positions (2,2) and (3,1), to some given value. I have two matrices rowNos and colNos that contain these positions:

 rowNos = [2, 3] colNos = [2, 1] 

Let's say I want to change the value of the elements in these positions to 0.

How to do this without using a loop?

+2
source share
3 answers

Use sub2ind , it converts your subindexes to linear indexes, which is a number pointing to one exact place in ( more ).

 Z = [ 1 2 3 ; 4 5 6 ; 7 8 9]; rowNos = [2, 3]; colNos = [2, 1]; lin_idcs = sub2ind(size(Z), rowNos, colNos) 

If you want to work with all the elements in a specific row and column (elements in higher dimensions), you can also access them using linear indexing. It gets a little harder to figure them out:

 Z = reshape(1:4*4*3,[4 4 3]); rowNos = [2, 3]; colNos = [2, 1]; siz = size(Z); lin_idcs = sub2ind(siz, rowNos, colNos,ones(size(rowNos))); % just the first element of the remaining dimensions lin_idcs_all = bsxfun(@plus,lin_idcs',prod(siz(1:2))*(0:prod(siz(3:end))-1)); % all of them lin_idcs_all = lin_idcs_all(:); Z(lin_idcs_all) = 0; 

experiment a bit with sub2ind and go through my code to understand it.

It would be simpler if this were the first dimension that you wanted to take from all elements, then you could use the colon operator :

 Z = reshape(1:3*4*4,[3 4 4]); rowNos = [2, 3]; colNos = [2, 1]; siz = size(Z); lin_idcs = sub2ind(siz(2:end),rowNos,colNos); Z(:,lin_idcs) = 0; 
+5
source

Use sub2ind with multiple entries for rows and columns

 Z(sub2ind(size(Z), rowNos, colNos))=0 

An example :

 Z = [1 2 3; 4 5 6; 7 8 9]; rowNos = [2, 3]; colNos = [2, 1]; Z(sub2ind(size(Z), rowNos, colNos))=0 Z = 1 2 3 4 0 6 0 8 9 
+2
source

Would you like to do it

 z(rowNos, colNos) 

but you cannot - MATLAB does the Cartesian product of indices. You can do this trick

 idx=(colNos-1)*size(z, 1)+rowNos; z(idx)=0 

Smooth the z-matrix and access it through a linear index, which is a combination of rowNos and colNos. Remember that MATLAB aligns the matrix in columns (column-based matrix repository).

+1
source

Source: https://habr.com/ru/post/1441452/


All Articles