A doubt regarding a simple For loop indexing for certain rows only.

1 view (last 30 days)
abhisrisai
abhisrisai on 2 Aug 2019
Commented: abhisrisai on 2 Aug 2019
Hi,
I have a matrix 'a' and I want to index only certain rows and delete them. Refer to code below.
Logic : when I reach the row starting point A or starting point B, I want to delete the following rows which contain the value [1 2 4 5]. I need to delete only those which come below either starting point A or B, also, the number of times [1 2 4 5] repeat is not fixed. If you observe, even after the 11th row [1 2 3 7] there are values [1 2 4 5] present but I want to retain them.
Any suggestions would be of great help, thank you. :)
a = 1 2 3 4 % start point A
1 2 4 5 % delete
1 2 4 5 % delete
1 2 4 5 % delete
1 2 4 5 % delete
1 2 3 5 % don't delete
1 2 3 6 % start point B
1 2 4 5 % delete
1 2 4 5 % delete
1 2 3 5 % don't delete
1 2 3 7 % don't delete anything from below here.
1 2 4 5
1 2 4 5
1 2 4 5
1 2 4 5
1 2 3 5
b = size(a,1);
for c = 1:b
if a(c, [1:4]) == [1, 2, 3, 4] | [1, 2, 3, 6]
for d = c+1:b
if (a(d, [1:4]) == [1, 2, 4, 5])
a(d, 5) = 1;
end
end
end
end
% displaying the numbers except for the ones that have 1 in their last column, basically deleting the rows with 1 in their last column
z = a(:, end);
y = a(~(z == 2), :);
y(:, end) = []
%% The result I'm obtaining from the above code :
y = 1 2 3 4
1 2 3 5
1 2 3 6
1 2 3 5
1 2 3 7
1 2 3 5
%% My expected output :
y = 1 2 3 4
1 2 3 5
1 2 3 6
1 2 3 5
1 2 3 7
1 2 4 5
1 2 4 5
1 2 4 5
1 2 4 5
1 2 3 5

Accepted Answer

Guillaume
Guillaume on 2 Aug 2019
Edited: Guillaume on 2 Aug 2019
Since nobody has explained why your code doesn't work:
There are several problems with your
if a(c, [1:4]) == [1, 2, 3, 4] | [1, 2, 3, 6]
First one is that your condition is a row vector and in all likelyhood you don't know how if behaves when the condition is a vector and not a scalar. That is the result of
a(c, [1:4]) == [1, 2, 3, 4] | [1, 2, 3, 6]
is a logical vector of true and false values that you pass to if. In the examples below, do you know which of the if will consider the condition true?
if [true, true, true, true] %case 1
if [true, true, true, false] %case 2
if [false, true, true, true] %case 3
if [false, false, false, false] %case 4
It's only the first one. Thankfully for you, that's what you actually meant but it's better to be explicit and pass a scalar to if with:
if all(some_logical_vector)
Or even better, if you want to check that two vectors are identical use isequal which returns a vector, so
if isequal(a(c, 1:4), [1, 2, 3, 4])
The second and bigger problem is your made up syntax a == b | c. This is never going to mean if a is equal to b or a is equal to c (even if you use brackets). It means if (a is equal to b) or (c is true). And don't think you can use brackets to make it work, a == (b | c) means if a is equal to the result of (b or c is true). The proper way to write the expression is explicitly:
if a == b | a == c
So, for your test:
if isequal(a(c, 1:4), [1, 2, 3, 4]) || isequal(a(c, 1:4), [1,2 ,3 ,6])
However, the above can be expressed more simply with ismember, with the 'rows' option:
if ismember(a(c, :), [1, 2, 3, 4; 1, 2, 3, 6], 'rows')
  1 Comment
abhisrisai
abhisrisai on 2 Aug 2019
Hi,
Thank you for the explanation. I now realize the mistakes I've made. This gives me better clarity. :)

Sign in to comment.

More Answers (2)

Andrei Bobrov
Andrei Bobrov on 2 Aug 2019
lo = a(:,3) == 4;
ii = cumsum([0;diff(lo) == 1]).*lo;
m = max(ii);
ii(ii == 0) = m + 1;
out = a(ii >= m,:);

Mariano
Mariano on 2 Aug 2019
a = [1 2 3 4 % start point A
1 2 4 5 % delete
1 2 4 5 % delete
1 2 4 5 % delete
1 2 4 5 % delete
1 2 3 5 % don't delete
1 2 3 6 % start point B
1 2 4 5 % delete
1 2 4 5 % delete
1 2 3 5 % don't delete
1 2 3 7 % don't delete anything from below here.
1 2 4 5
1 2 4 5
1 2 4 5
1 2 4 5
1 2 3 5];
sp = find(ismember(a(:,4),[4,6])); % Find starting points
ep = find(ismember(a(:,4),[6,7])); % Find end points
n = length(ep); % How many? (assume number staring points = number
% end points)
dp = find(a(:,4)==5); % Candidates to be deleted
dr=[]; % DOES SOMEONE KNOW HOW TO VECTORIZE NEXT LOOP?
for j = 1:n
dr = [dr(:);dp(dp>sp(j)&dp<ep(j)-1)]; % Only delete rows between
% starting and end points
% Do not delete immediately
% before end point
end
a(dr,:)=[]

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!