Matlab:需要一些帮助以使操作看似简单的向量化 [英] Matlab: need some help for a seemingly simple vectorization of an operation

查看:68
本文介绍了Matlab:需要一些帮助以使操作看似简单的向量化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想优化这段Matlab代码,但到目前为止,我失败了.我已经尝试过将repmat以及总和与总和进行不同的组合,但是我的所有尝试似乎都无法给出正确的结果.对于这个棘手的问题,我将提供一些专家指导.

I would like to optimize this piece of Matlab code but so far I have failed. I have tried different combinations of repmat and sums and cumsums, but all my attempts seem to not give the correct result. I would appreciate some expert guidance on this tough problem.

S=1000; T=10;
X=rand(T,S),
X=sort(X,1,'ascend');
Result=zeros(S,1);
for c=1:T-1
    for cc=c+1:T
        d=(X(cc,:)-X(c,:))-(cc-c)/T;
        Result=Result+abs(d');
    end
end

基本上,我创建1000个包含10个随机数的向量,并为每个向量计算每对值(例如 m th和 n th)的差它们之间的差减去( nm ).我对所有可能的对进行求和,然后为每个向量返回结果.

Basically I create 1000 vectors of 10 random numbers, and for each vector I calculate for each pair of values (say the mth and the nth) the difference between them, minus the difference (n-m). I sum over of possible pairs and I return the result for every vector.

我希望这个解释很清楚

非常感谢.

推荐答案

向量化内循环至少很容易:

It is at least easy to vectorize your inner loop:

Result=zeros(S,1);
for c=1:T-1
   d=(X(c+1:T,:)-X(c,:))-((c+1:T)'-c)./T;
   Result=Result+sum(abs(d),1)';
end

在这里,我正在使用新的自动单例扩展.如果您使用的是旧版本的MATLAB,则需要对两个减法操作使用bsxfun.例如,X(c+1:T,:)-X(c,:)bsxfun(@minus,X(c+1:T,:),X(c,:))相同.

Here, I'm using the new automatic singleton expansion. If you have an older version of MATLAB you'll need to use bsxfun for two of the subtraction operations. For example, X(c+1:T,:)-X(c,:) is the same as bsxfun(@minus,X(c+1:T,:),X(c,:)).

在代码中所发生的是,我们没有循环cc=c+1:T,而是一次获取了所有这些索引.因此,我只是将cc替换为c+1:T. d然后是一个具有多行的矩阵(第一次迭代中为9行,而在随后的每次迭代中为更少行).

What is happening in the bit of code is that instead of looping cc=c+1:T, we take all of those indices at once. So I simply replaced cc for c+1:T. d is then a matrix with multiple rows (9 in the first iteration, and one fewer in each subsequent iteration).

令人惊讶的是,这比双循环慢,并且速度类似于乔达格的答案.

Surprisingly, this is slower than the double loop, and similar in speed to Jodag's answer.

接下来,我们可以尝试改善索引编制.请注意,上面的代码从矩阵中按行提取数据. MATLAB按列存储数据.因此,从矩阵中提取列比行更有效.让我们转置X:

Next, we can try to improve indexing. Note that the code above extracts data row-wise from the matrix. MATLAB stores data column-wise. So it's more efficient to extract a column than a row from a matrix. Let's transpose X:

X=X';
Result=zeros(S,1);
for c=1:T-1
   d=(X(:,c+1:T)-X(:,c))-((c+1:T)-c)./T;
   Result=Result+sum(abs(d),2);
end

这比按行索引的代码快两倍.

This is more than twice as fast as the code that indexes row-wise.

但是当然可以将相同的技巧应用到问题代码中,将其速度提高约50%:

But of course the same trick can be applied to the code in the question, speeding it up by about 50%:

X=X';
Result=zeros(S,1);
for c=1:T-1
   for cc=c+1:T
      d=(X(:,cc)-X(:,c))-(cc-c)/T;
      Result=Result+abs(d);
   end
end


我从本练习中获得的主要信息是,MATLAB的JIT编译器已大大改善了性能.在过去,任何形式的循环都会使代码停顿下来.今天,它不一定是最糟糕的方法,尤其是如果您只使用内置函数.


My takeaway message from this exercise is that MATLAB's JIT compiler has improved things a lot. Back in the day any sort of loop would halt code to a grind. Today it's not necessarily the worst approach, especially if all you do is use built-in functions.

这篇关于Matlab:需要一些帮助以使操作看似简单的向量化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆