Страницы

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

пятница, 27 декабря 2019 г.

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

#массивы #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


Но я не готов поверить, что нет более очевидного и красивого решения.
    


Ответы

Ответ 1



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

Ответ 2



Можно наоборот сохранять в отдельный массив нужные элементы. a = [1 2 3 4 5 6]; b = []; for i = 1:numel(a) if (mod(a(i), 2)) ~= 0 b(end + 1) = a[i]; end end a = b; Или коротко: b = find (~mod (a, 2))

Ответ 3



Удалить заданные номера элементов из массива: aaa = 1:1:10; % Исходные индексы bbb = 1:2:10; % Индексы, которые следует удалить ccc = aaa; ccc(bbb) = 0; ccc = (ccc > 0); % Исключенные индексы

Ответ 4



Лаконичнее всего a = [1 2 3 4 4 5 6]; a=a(mod(a, 2)==0);

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

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