Имам 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
Има ли нещо, което мога да направя, за да ускоря това? Може ли кодът да бъде векторизиран?