В проблеме, над которой я сейчас работаю, я вычисляю некоторые значения в матрице x
, а затем для каждого элемента в x
необходимо найти индекс ближайшего элемента ниже в монотонно возрастающем векторе X
а также относительная близость элементов x
к первым элементам с обеих сторон. (По сути, это линейная интерполяция без фактической интерполяции.) Я делаю это по-разному, так что я действительно очень заинтересован в том, чтобы это было как можно быстрее.
Я написал функцию locate
, которую я Можно вызвать с некоторыми примерами данных:
X = linspace(5, 300, 40)';
x = randi(310, 5, 6, 7);
[ii, weights] = locate(x, X);
Я написал две версии locate
. Первый - для экспозиции, а второй - моя лучшая попытка ускорить вычисления. Есть ли у вас какие-либо предложения или альтернативные подходы для дальнейшего повышения производительности?
1. Экспозиция
function [ii, weights] = locate(x, X)
% LOCATE Locate first node on grid below a given value.
%
% [ii, weights] = locate(x, X) returns the first node in X that is below
% each element in x and the relative proximities to the two closest nodes.
%
% X must be a monotonically increasing vector. x is a matrix (of any
% order).
% Preallocate
ii = ones(size(x)); % Indices of first node below (or 1 if no nodes below)
weights = zeros([2, size(x)]); % Relative proximity of the two closest nodes
% Find indices and compute weights
for ix = 1:numel(x)
if x(ix) <= X(1)
ii(ix) = 1;
weights(:, ix) = [1; 0];
elseif x(ix) >= X(end)
ii(ix) = length(X) - 1;
weights(:, ix) = [0; 1];
else
ii(ix) = find(X <= x(ix), 1, 'last');
weights(:, ix) = ...
[X(ii(ix) + 1) - x(ix); x(ix) - X(ii(ix))] / (X(ii(ix) + 1) - X(ii(ix)));
end
end
end
2. Лучшая попытка
function [ii, weights] = locate(x, X)
% LOCATE Locate first node on grid below a given value.
%
% [ii, weights] = locate(x, X) returns the first node in X that is below
% each element in x and the relative proximities to the two closest nodes.
%
% X must be a monotonically increasing vector. x is a matrix (of any
% order).
% Preallocate
ii = ones(size(x)); % Indices of first node below (or 1 if no nodes below)
weights = zeros([2, size(x)]); % Relative proximity of the two closest nodes
% Find indices
for iX = 1:length(X) - 1
ii(X(iX) <= x) = iX;
end
% Find weights
below = x <= X(1);
weights(1, below) = 1; % All mass on the first node
weights(2, below) = 0;
above = x >= X(end);
weights(1, above) = 0;
weights(2, above) = 1; % All mass on the last node
interior = ~below & ~above;
xInterior = x(interior)';
iiInterior = ii(interior);
XBelow = X(iiInterior)';
XAbove = X(iiInterior + 1)';
weights(:, interior) = ...
[XAbove - xInterior; xInterior - XBelow] ./ (XAbove - XBelow);
end