真正愚蠢的是我所要做的就是拥有一个7列矩阵,同时包含所有mod 7号码,使用以下代码生成这样的矩阵需要花费大量时间
to = 7^k;
msgValue = zeros(to,k);
for l=0:to
for kCounter=0:(k-1)
msgValue(l+1,kCounter+1)=mod((l/7^kCounter),7);
end
end
msgValue = floor(msgValue);
我怎样才能更快地完成这项工作?
答案 0 :(得分:3)
您可以vectorized approach
使用bsxfun
-
msgValue = floor(mod(bsxfun(@rdivide,[0:to]',7.^(0:(k-1))),7));
k = 7
的快速运行时测试:
-------------------- With Original Approach
Elapsed time is 1.519023 seconds.
-------------------- With Proposed Approach
Elapsed time is 0.279547 seconds.
答案 1 :(得分:3)
或另一种矢量化方法(直接矩阵乘法):
msgValue = floor( mod( (0:7^k).' * (1./(7.^(0:k-1))),7 ) ) ;
比着名的bsxfun
; - )
%// For 10000 iterations, k=3
Elapsed time is 2.280774 seconds. %// double loop
Elapsed time is 1.329179 seconds. %// bsxfun
Elapsed time is 0.958945 seconds. %// matrix multiplication
答案 2 :(得分:0)
我使用了来自matlab中心的一个名为rude的submssion,我倾向于不时使用它,并且能够消除一个for循环并在某种程度上对代码进行矢量化。
tic
k=7;
modval = 7;
to=modval^k;
mods = mod(0:(modval-1),modval);
msgValue=zeros(to,k);
for kCounter=1:k
aux = rude(modval^(kCounter-1)*ones(1,modval),mods)';
msgValue(:,kCounter) = repmat(aux,to/(7^kCounter),1);
end
toc
代码背后的想法是使用粗鲁函数在每次迭代开始时使用列向量的构建块。反过来,粗鲁使用mods = [0 1 2 3 4 5 6]作为操纵的起点。真正的工作是通过矢量化完成的。
您没有提到代码运行的时间。所以我只想一次给你一个粗略的想法。它在我的机器上运行0.43秒,Windows 7旗舰版,2.4 GHz,4GB Ram,双CPU。
此外,您定义循环的方式会在msgValue矩阵中添加重复。第一行包含所有列中的零值,因此最后一行,我也修复了。对于k = 3的玩具示例,您的代码返回344x1矩阵,而您明确地将其初始化为7³x1(343x1)矩阵。