У меня есть процедура MATLAB с одним довольно очевидным узким местом. Я профилировал функцию, в результате чего 2/3 вычислительного времени используется в функции levels
:
Функция levels
берет матрицу чисел с плавающей запятой и разбивает каждый столбец на 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
Могу ли я что-нибудь сделать, чтобы ускорить это? Можно ли векторизовать код?