How can i speed up the following?

3 次查看(过去 30 天)
Can anyone help me speed up what is written below? I have a large code and this routine, while seemingly fast, gets called a great deal.
a = rand(31,31);
TmTn = rand(301,301,31,31);
f = zeros(size(TmTn,1),size(TmTn,2));
[qe pe] = size(a);
for p = 1:pe
for q = 1:qe;
f = f + a(q,p).*TmTn(:,:,p,q);
end
end
Note: I have tried various sequences of permute, repmat, direct multiplication, moving the sum, parfor and reshape.
Thanks in advance, Bill
  2 个评论
Adam
Adam 2016-4-28
Have you run the profile on your full "large code" to determine how much of the total time is actually spent on this routine?
Bill Hannon
Bill Hannon 2016-4-28
Yes. Several times. The script above gets called ~2000 times. It is the slowest (~0.5sec/call) portion of the large (~30min) code.

请先登录,再进行评论。

采纳的回答

Roger Stafford
Roger Stafford 2016-4-29
You can turn this into ordinary matrix multiplication. Since matlab is specially optimized for matrix multiplication, it might be faster.
a = rand(31,31);
TmTn = rand(301,301,31,31);
a2 = reshape(a.',[],1); % Transpose 'a' and make it a column vector
TmTn2 = reshape(TmTn,[],31^2); % Change TmTn to a 2D matrix
f = reshape(TmTn2*a2,301,301); % Use ordinary matrix multiplication and then reshape back
  1 个评论
Bill Hannon
Bill Hannon 2016-4-29
Superb & thank you. Thank you all. That was the reduction I needed.

请先登录,再进行评论。

更多回答(2 个)

Arnab Sen
Arnab Sen 2016-4-28
Hi Bill, You can try to replace the loop by vectorization. Something like below:
a = rand(31,31); TmTn = rand(301,301,31,31);
f = zeros(size(TmTn,1),size(TmTn,2));
[qe pe] = size(a);
TmTn2=reshape(TmTn,301*31,301*31);
TmTn1=mat2cell(TmTn2,size(TmTn,1)*ones(1,p),size(TmTn,2)*ones(1,q));
b=a';
C= cellfun(@(x,y) x.*y, mat2cell(b,ones(1,pe),ones(1,qe)),TmTn1, 'UniformOutput',false);
f=sum(cat(3,C{:,:}),3);
Using 'perfor' is another option where we can multiple for loops in parallel. For more detail refer to the following link:
  2 个评论
Adam
Adam 2016-4-28
编辑:Adam 2016-4-28
Be careful using cellfun if speed is your aim, it is almost always slower than a for loop, but in either case the profiler or a timeit wrapped around the two options should help to check that.
Working with cell arrays in general is a lot less performant than numeric arrays if you are able to use numeric arrays instead.
Bill Hannon
Bill Hannon 2016-4-28
Thank you for the (any) suggestion(s). I tic/toced the current and suggest cellfun approach while in debug mode. The cellfun approach is 3 times slower than the for loop.

请先登录,再进行评论。


Jan
Jan 2016-4-28
This seems to be a problem for FEX: MMX or FEX: MTIMESX .
  1 个评论
Bill Hannon
Bill Hannon 2016-4-28
The MMX & MTIMESX documentation leads me to believe they focus on matrix products and not element by element multiplication. Am i mistaken?

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by