在MATLAB中替换repmat

时间:2011-07-08 19:35:33

标签: matlab

我有一个函数可以执行以下循环很多次:

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_specmeanOneIn分别是repmat()mean()的精简版本,我想知道是否有办法在标有(*)的行,完全避免了repmat。

关于如何从这件事中挤出表现的任何其他想法也会受到欢迎。

5 个答案:

答案 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)编译器通常可以很好地加速。