У меня есть программа MATLAB с одним довольно очевидным узким местом. Я профилировал функцию, в результате чего 2/3 вычислительного времени используется в функции levels
:
Функция levels
принимает матрицу float и разбивает каждый столбец на nLevels
ведер, возвращая матрицу того же размера, что и входная, с каждой записью, замененной на номер ведра, в которое она попадает.
Для этого я использую функцию quantile
, чтобы получить границы ведер, и цикл для распределения записей по ведрам. Вот моя реализация:
function [Y q] = levels(X,nLevels)
% "Assign each of the elements of X to an integer-valued level"
p = linspace(0, 1.0, nLevels+1);
q = quantile(X,p);
if isvector(q)
q=transpose(q);
end
Y = zeros(size(X));
for i = 1:nLevels
% "The variables g and l indicate the entries that are respectively greater than
% or less than the relevant bucket limits. The line Y(g & l) = i is assigning the
% value i to any element that falls in this bucket."
if i ~= nLevels % "The default; doesnt include upper bound"
g = bsxfun(@ge,X,q(i,:));
l = bsxfun(@lt,X,q(i+1,:));
else % "For the final level we include the upper bound"
g = bsxfun(@ge,X,q(i,:));
l = bsxfun(@le,X,q(i+1,:));
end
Y(g & l) = i;
end
Могу ли я что-нибудь сделать, чтобы ускорить процесс? Можно ли векторизовать код?