matrix index is out of range for deletion

2 views (last 30 days)
Hello, I am trying to delete certain rows of an 1D array if a conditional statement is true.
My code is:
for i = 1:length(TF)
if TF(i) == 1
pitch(i) = [];
end
end
for the length of TF (a logical array) i evaluate TF as true or false and if it is true i want to delete the value in the array called pitch at that corrasponding index.
I am getting an error message that says "Matrix index is out of range for deletion."
I cannot seem to fix this probem and would appreciuate any help or suggestions.
Thank you,
Adam

Accepted Answer

madhan ravi
madhan ravi on 15 Jul 2020
Edited: madhan ravi on 15 Jul 2020
pitch(TF == 1) = []
  1 Comment
Adam Levschuk
Adam Levschuk on 15 Jul 2020
thank you for the help.
Could you pelase tell me what exactly i was doing wwrong so an how your solution is different?
Adam

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 15 Jul 2020
Edited: Walter Roberson on 15 Jul 2020
for i = length(TF) :-1 : 1
if TF(i) == 1
pitch(i) = [];
end
end
Or much more simply:
pitch(TF==1) = [];
  3 Comments
Walter Roberson
Walter Roberson on 15 Jul 2020
Suppose you have 3 items in your array, [A, B, C], and you are incrementing forward in your array. Suppose you have marked to delete item #2. You start with [A,B,C] and index 1 and test and find no change to be made, so you move on to i=2. You have [A,B,C] with index 2, and you see that you have to delete it, so you do pitch(i)=[] which would be pitch(2)=[] which would remove B, leaving you with pitch=[A,C]. You then move on to i=3. Remember that for does not re-test the bounds each time, so when you asked to increment up to length(pitch), it recorded that 3 and will continue to use that 3 even as you change the array (besides, the length of your TF has not changed.). So you are now at i=3. But pitch(3) does not exist at this point.
Furthermore, what was in pitch(3), C, is now located at pitch(2) so if your loop were something like
for i = 1 : length(pitch)
if pitch(i) < 0; pitch(i) = []; end
end
then when you reached i=3, besides pitch(3) not existing anymore, you have not examined C. Like Tetris, C "fell down" to occupy the hole created by deleting pitch(2).
So... if you are going to increment forward in deletions, you need to use a while instead of a for (so that the termination conditions will be re-tested), and when you do a deletion, you need to not increment the counter, so that you can examine the element that just "fell down".
Now, on the other hand if you loop from 3 down to 1, then the things that "fall down" to occupy the hole are things you have already examined, and although the array gets shorter, you are not removing items before the one you are working with, so they will always still be there when you decrement the counter to look at them.
Thus, if you must delete items in a loop, loop backwards to do it.... but more efficient is to just keep a record of which items to delete and do a vectorized deletion afterwards.
Adam Levschuk
Adam Levschuk on 15 Jul 2020
Thank you so much for the explanation Walter. It makes perfect sense how you explained that.
Best,
Adam

Sign in to comment.

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!