Super Hornet
Super Hornet

Reputation: 2907

Range Selection in Matlab

I defined a matrix 6 by 6 and want to make a change in values in some ranges.

c = floor(rand(6,6) * 100)

the result:

22    26    10     2     9     3
38    82    90    42    59     6
58    98    87    31    47    31
25    73    81    16    69    53
29    34    26    17    69    65
61    58    59    42    63    40

then I run:

c(c(1:3,:)<17) = 0

22     0     0     2     9     3
38    82    90    42    59     6
58    98    87    31    47    31
25     0     0    16    69    53
29    34     0    17    69    65
61    58    59    42    63    40

I want to make elements in rows between 1 and 3 which are less than 17 zero, but the result seems wrong to me! any idea?

Upvotes: 1

Views: 128

Answers (3)

rahnema1
rahnema1

Reputation: 15837

Here is another approach that multiplies the matrix with a logical mask:

c(1:3,:) = c(1:3,:) .* c(1:3,:) >= 17;

Upvotes: 0

Yacine
Yacine

Reputation: 321

This does not work because you are getting linear indices from your condition and the size of the submatrix is different from that of the original one. You can first get the subscripts and then change your original matrix:

c = floor(rand(6,6) * 100)
c =

28    60    24    48    20    99
 0    78    34    80    38    70
49    11    54    37    66     8
98    57     6    51    75     4
73    87    41     9    17    49
31    68    23    90    51    44

[a,b]=find(c(1:3,:)<17);
c(sub2ind(size(c),a,b))=0
c =

28    60    24    48    20    99
 0    78    34    80    38    70
49     0    54    37    66     0
98    57     6    51    75     4
73    87    41     9    17    49
31    68    23    90    51    44

please note that if you dont start from the first row or the first column, you should consider the difference:

[a,b]=find(c(3:6,2:5)<17);
c(sub2ind(size(c),a+2,b+1))=0

Another solution is to create a mask matrix of indicies to use for the substitution. This would also work in the general case of not starting from the first row or column:

idx = zeros(size(c));
idx(1:3,:) = c(1:3,:)<17;
c(idx==1) = 0

Upvotes: 5

Luis Mendo
Luis Mendo

Reputation: 112679

Use a logical index built from two conditions: element is less than the threshold and row index is within the set of target rows.

th = 17;                                                  % threshold
rows = [1 2 3];                                           % target rows
ind = bsxfun(@and, c<th, ismember(1:size(c,1), rows).');  % logical index 
c(ind) = 0;                                               % set entries to 0

For your example input

c = [22    26    10     2     9     3
     38    82    90    42    59     6
     58    98    87    31    47    31
     25    73    81    16    69    53
     29    34    26    17    69    65
     61    58    59    42    63    40]

this gives

c =
    22    26     0     0     0     0
    38    82    90    42    59     0
    58    98    87    31    47    31
    25    73    81    16    69    53
    29    34    26    17    69    65
    61    58    59    42    63    40

Upvotes: 2

Related Questions