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

前端 未结 3 1804
南笙
南笙 2020-12-20 00:59

I have a matrix say

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

I have to change its values, say at positions (2,2) and (3,1), to some specified v

相关标签:
3条回答
  • 2020-12-20 01:30

    Use sub2ind with multiple entries for rows and columns

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

    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
    
    0 讨论(0)
  • 2020-12-20 01:48

    Use sub2ind, it'll convert your sub-indices to linear indices, which is a number pointing at one exact spot in the matrix (more info).

    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 operate on all elements on a specific row and column (elements in higher dimensions that is), you can also address them using linear indexing. It only becomes a bit trickier of calculating them:

    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 step-by-step to understand it.

    It would've been easier if it was the first dimension you wanted to take all elements off, then you could have used 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;
    
    0 讨论(0)
  • 2020-12-20 01:55

    You would like to do this

    z(rowNos, colNos)
    

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

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

    Flatten the z-matrix and access it through a linear index, which is a combination of rowNos and colNos. Remember that MATLAB flattens the matrix by columns (column-based matrix storage).

    0 讨论(0)
提交回复
热议问题