Замена для repmat в MATLAB - PullRequest
       2

Замена для repmat в MATLAB

4 голосов
/ 08 июля 2011

У меня есть функция, которая выполняет следующий цикл много-много раз:

for cluster=1:max(bins), % bins is a list in the same format as kmeans() IDX output
    select=bins==cluster; % find group of values
    means(select,:)=repmat_fast_spec(meanOneIn(x(select,:)),sum(select),1); 
    % (*, above) for each point, write the mean of all points in x that 
    % share its label in bins to the equivalent row of means
    delta_x(select,:)=x(select,:)-(means(select,:)); 
    %subtract out the mean from each point
end

Отмечая, что repmat_fast_spec и meanOneIn являются урезанными версиями repmat() и mean() соответственно, мне интересно, есть ли способ выполнить присвоение в строке, помеченной (*), которая позволяет избежать повторения полностью.

Любые другие мысли о том, как выжать производительность из этой вещи, также приветствуются.

Ответы [ 5 ]

1 голос
/ 09 июля 2011

Вот возможное улучшение, чтобы избежать REPMAT:

x = rand(20,4);
bins = randi(3,[20 1]);

d = zeros(size(x));
for i=1:max(bins)
    idx = (bins==i);
    d(idx,:) = bsxfun(@minus, x(idx,:), mean(x(idx,:)));
end

Другая возможность:

x = rand(20,4);
bins = randi(3,[20 1]);

m = zeros(max(bins),size(x,2));
for i=1:max(bins)
    m(i,:) = mean( x(bins==i,:) );
end
dd = x - m(bins,:);
1 голос
/ 09 июля 2011

Прежде всего: правильно отформатируйте код, окружите любой оператор или присвоение пробелом. Я нахожу ваш код очень сложным для понимания, так как он выглядит как большой набор символов.

Далее, вы можете следить за другими ответами и автоматически или вручную преобразовывать код в C (mex) или Java, но, по моему скромному мнению, это последнее средство. Вы должны делать такие вещи только тогда, когда ваша производительность еще не достигнута с небольшим отрывом. С другой стороны, ваш алгоритм не имеет явных недостатков.

Но первое, что вы должны сделать при попытке улучшить производительность: профиль. Используйте профилировщик MATLAB, чтобы определить, какая часть вашего кода вызывает ваши проблемы. Насколько вам нужно улучшить это, чтобы оправдать ваши ожидания? Если вы не знаете: сначала определите эту границу, в противном случае вы будете искать иголку в стоге сена, которой вообще не может быть. MATLAB никогда не будет самым быстрым игроком в блоке в отношении времени выполнения, но он может быть самым быстрым в отношении времени разработки для определенных видов операций. В этом отношении может оказаться полезным пожертвовать ясностью MATLAB ради скорости выполнения других языков (C или даже Java). Но в том же отношении вы могли бы также написать все на ассемблере, чтобы выжать всю производительность из кода.

1 голос
/ 09 июля 2011

Вы можете получить некоторое улучшение, используя ACCUMARRAY .

%# gather array sizes
[nPts,nDims] = size(x);
nBins = max(bins);

%# calculate means. Not sure whether it might be faster to loop over nDims
meansCell = accumarray(bins,1:nPts,[nBins,1],@(idx){mean(x(idx,:),1)},{NaN(1,nDims)});
means = cell2mat(meansCell);

%# subtract cluster means from x - this is how you can avoid repmat in your code, btw.
%# all you need is the array with cluster means. 
delta_x = x - means(bins,:);
1 голос
/ 08 июля 2011

Одним из очевидных способов ускорить вычисления в MATLAB является создание MEX-файла.Вы можете скомпилировать код C и выполнять любые операции, которые вы хотите.Если вы ищете максимально быструю производительность, вам, вероятно, следует превратить операцию в пользовательский MEX-файл.

0 голосов
/ 09 июля 2011

Другой очевидный способ ускорить вычисления в MATLAB - создать библиотеку Java (аналогично ответу @ aardvarkk), поскольку MATLAB построен на Java и имеет очень хорошую интеграцию с пользовательскими библиотеками Java.интерфейс и компиляция, чем C. В некоторых случаях он может быть медленнее, чем C, но компилятор JIT в виртуальной машине в целом обычно очень быстро ускоряет процесс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...