Пытаюсь удалять элементы из вектора в Matlab по какому-либо условию. Например хочу удалить все четные числа.
a = [1 2 3 4 5 6];
for i = 1:numel(a)
if (mod(a(i), 2)) == 0
a(i) = [];
end
end
При этом получаю "Index exceeds matrix dimensions.". Похоже цикл продолжает крутиться до первоначальной длины вектора, не смотря на то, что она уменьшилась. Как с этим бороться?
Но если быть до конца точным, я хочу написать такой цикл:
function [centers, rads, metrics] = ...
DeleteOverlapCircles(centers, rads, metrics)
for i = 1:(length(metrics) - 1)
for j = (i + 1):length(metrics)
minRad = min([rads(i), rads(j)]);
maxRad = max([rads(i), rads(j)]);
if pdist2(centers(i), centers(j)) < maxRad + 1 / 2 * minRad
metrics(j) = [];
centers(j) = [];
rads(j) = [];
end
end
end
end
Вопрос решился следующим образом:
function [centers, rads, metrics] = ...
DeleteOverlapCircles(centers, rads, metrics)
for i = (length(metrics) - 1):-1:1
for j = (i - 1):-1:1
minRad = min([rads(i), rads(j)]);
maxRad = max([rads(i), rads(j)]);
if pdist2(centers(i, :), centers(j, :)) ...
< maxRad + 1 / 2 * minRad
centers(i, :) = [];
rads(i) = [];
metrics(i, :) = [];
break;
end
end
end
end
Но я не готов поверить, что нет более очевидного и красивого решения.
Ответ
Цикл for не предназначен для условий, которые изменяются внутри цикла. То есть, при наличии условия
for i = 1:numel(a)
значение numel(a) будет вычислено только однажды, при входе в цикл.
Если же конечное значение будет менятся, нужен цикл while:
a = [1 2 3 4 4 5 6];
i = 1;
while i <= numel(a)
if (mod(a(i), 2)) == 0
a(i) = [];
else
i = i+1;
end
end
Замечу, что переменная цикла не увеличивается в случае удаления элемента, поскольку при этом другие элементы сдвигаются.
(Но перебирать с конца в начало, как Вы сделали, на самом деле проще.)
Комментариев нет:
Отправить комментарий