Страницы

Поиск по вопросам

пятница, 15 марта 2019 г.

Удалить элементы из вектора в MATLAB

Пытаюсь удалять элементы из вектора в 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
Замечу, что переменная цикла не увеличивается в случае удаления элемента, поскольку при этом другие элементы сдвигаются.
(Но перебирать с конца в начало, как Вы сделали, на самом деле проще.)

Комментариев нет:

Отправить комментарий