我有一个函数可以执行以下循环很多次:
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()
的精简版本,我想知道是否有办法在标有(*)的行,完全避免了repmat。
关于如何从这件事中挤出表现的任何其他想法也会受到欢迎。
答案 0 :(得分:1)
在MATLAB中加速计算的一个显而易见的方法是制作MEX文件。您可以编译C代码并执行所需的任何操作。如果您正在寻找最快的性能,那么将操作转换为自定义MEX文件可能就是您的选择。
答案 1 :(得分:1)
使用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,:);
答案 2 :(得分:1)
首先:正确格式化代码,用空格包围任何运算符或赋值。我发现你的代码很难理解,因为它看起来像一大块字符。
接下来,您可以按照其他响应将代码自动或手动转换为C(mex)或Java,但我认为这是最后的选择。只有当你的表现不存在时,你才应该做这些事情。另一方面,您的算法没有显示出明显的缺陷。
但是在尝试提高性能时应该做的第一件事:个人资料。使用MATLAB探查器确定代码的哪个部分导致您的问题。您需要多少才能改善这一点以满足您的期望?如果您不知道:首先确定这个边界,否则您将在干草堆中寻找一个甚至可能不在那里的针。对于运行时,MATLAB永远不会是块上最快的孩子,但对于某些类型的操作,它可能是最快的开发时间。在这方面,牺牲MATLAB在其他语言(C甚至Java)的执行速度上的清晰度可能是有用的。但是在同样的方面,你可以用汇编程序中的所有内容编码来挤出代码中的所有性能。
答案 3 :(得分:1)
以下是避免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,:);
答案 4 :(得分:0)
在MATLAB中加速计算的另一个显而易见的方法是创建一个Java库(类似于@ aardvarkk的答案),因为MATLAB是基于Java构建的,并且与用户Java库有很好的集成。
Java比C更容易进行接口和编译。在某些情况下,它可能比C慢,但Java虚拟机中的实时(JIT)编译器通常可以很好地加速。