why doesn't limitation this work?

14 views (last 30 days)
So I've got another loop which makes a new matrix called nn. The values in nn varies a lot. The only interesting interval is between 300 and 1300 so I made this loop to remove all values outside the interval.
for i=1:length(nn)
if nn(i) < 300 || nn(i) > 1300
nn(i) = [ ];
end
end
I get this message:
Index exceeds matrix dimensions.
Error in HRV (line 60)
if nn(i) < 300 || nn(i) > 1300
I don't know what the problem is. Please help
  2 Comments
Steven Lord
Steven Lord on 17 May 2018
When you use a function call like length(x) in the definition of the range over which the for loop iterates, it does not execute that function each time the for loop starts a new iteration. It executes once at the start. If the length of x changes inside the loop, the for loop doesn't change how many iterations it will run to adjust.
So the first time your for loop body deletes an element of nn, the last iteration of the for loop will try to access an element of the (now shorter) nn array that no longer exists.
Walter Roberson
Walter Roberson on 17 May 2018
Also, looping forward ends up skipping some elements. Suppose the arrangement is
1 2 -3 -4 5 6
where the negatives indicate elements to be deleted. Then you examine #1 and leave it, examine #2 and leave it, examine #3 and delete it. That laves 1 2 -4 5 6 in the matrix. Then you examine element #4 of that, which is the 5 and leave it, then examine element #5 and leave it, then you go to examine element #6 and find there is no element #6. If you had simply adjusted the end length to account for the array getting shorter, you would have missed that you never examined the content of what was originally the 4th element, because it "fell down" into #3 and you do not re-check #3 in case what "fell down" also needs to go.
This is not a problem if you loop backwards like I suggest: when you loop backwards, the things that "fall down" are things you have already examined and left in place.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 17 May 2018
for i=length(nn):-1:1

More Answers (1)

Andrei Bobrov
Andrei Bobrov on 17 May 2018
Edited: Andrei Bobrov on 17 May 2018
out = nn(nn >= 300 & nn <= 1300);
  2 Comments
Mathias Katballe
Mathias Katballe on 17 May 2018
Edited: Mathias Katballe on 17 May 2018
Like this?
out = nn(nn >= 300 & nn <= 1300);
for i=1:length(nn)
if out
nn(i) = [ ];
end
end
Because then there is a new problem
Matrix index is out of range for deletion.
Error in HRV (line 61)
nn(i) = [ ];
Walter Roberson
Walter Roberson on 17 May 2018
No loops..
nn = nn(nn >= 300 & nn <= 1300);

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!