Matlab: ускорение "find () для каждого элемента в массиве ND" - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть массив ND, и для каждого элемента в массиве мне нужно найти индекс самого большого элемента в векторе, который находится ниже него. Я делаю это раз за раз, так что я действительно очень заинтересован в том, чтобы это было как можно быстрее.

Я написал функцию locate, которую я вызываю с некоторыми типичными примерами данных. (Я использую arrayfun, чтобы увеличить число раз, когда timeit запускает функцию, чтобы минимизировать случайные колебания.)

Xmin = 5;
Xmax = 300;
Xn = 40;
X = linspace(Xmin, Xmax, Xn)';
% iters = 1000;
% timeit(@() arrayfun(@(iter) locate(randi(Xmax + 10, 5, 6, 6), X), 1:iters, 'UniformOutput', false))
timeit(@() locate(randi(Xmax + 10, 5, 6, 6), X))

Моя оригинальная версия locate выглядела так:

function indices = locate(x, X)
    % Preallocate
    indices = ones(size(x));

    % Find indices
    for ix = 1:numel(x)
        if x(ix) <= X(1)
            indices(ix) = 1;
        elseif x(ix) >= X(end)
            indices(ix) = length(X) - 1;
        else
            indices(ix) = find(X <= x(ix), 1, 'last');
        end
    end
end

И самая быстрая версия, которую я могу собрать, выглядит следующим образом:

function indices = locate(x, X)
    % Preallocate
    indices = ones(size(x));

    % Find indices
    % indices(X(1) > x) = 1;  % No need as indices are initialized to 1
    for iX = 1:length(X) - 1
        indices(X(iX) <= x & X(iX + 1) > x) = iX;
    end
    indices(X(iX) <= x) = length(X) - 1;
end

Можете ли вы придумать какой-нибудь другой способ, который был бы быстрее?

1 Ответ

1 голос
/ 04 апреля 2020

что вам нужно, это в основном 2-й вывод histc

[pos,bin]=histc(magic(5),X);
bin(bin==0)=1;
...