8 views (last 30 days)

Show older comments

My Matlab code has a subroutine that repeatedly executes a double for loop. While testing large simulations, this subroutine is called over 10^6 times. I am curious if I can change/reuse part of the subroutine so that I can improve performance.

My original Matlab code (with test data) is shown below.

% Test Data

clc; clear all;

M = 30;

N = 30;

Nx = 32;

f_n_m = rand(Nx,N+1,M+1);

epsilon = 0.3;

delta = 0.4;

SumType = randi(3,1);

f = zeros(Nx,1);

coeff = zeros(N+1,M+1);

% Original Implementation

for j=1:Nx

% Can this double for loop be performed once instead of Nx times?

for r=0:N

for s=0:M

coeff(r+1,s+1) = f_n_m(j,r+1,s+1);

end

end

if(SumType==1)

% My code calls seperate subroutines which need the value of coeff.

% For testing purposes I have put f(j) = test data. These three if

% statements call external functions in my code.

f(j) = coeff(j)*epsilon*delta*N*M;

elseif(SumType==2)

f(j) = 2*coeff(j)*epsilon*delta*N*M;

elseif(SumType==3)

f(j) = 3*coeff(j)*epsilon*delta*N*M;

end

end

My first (bad) idea was to change the above code to the code below.

f2 = zeros(Nx,1);

coeff2 = zeros(N+1,M+1);

% Move the double for loop here

for j=1:Nx

for r=0:N

for s=0:M

coeff2(r+1,s+1) = f_n_m(j,r+1,s+1);

end

end

end

% Then run the original for loop

for j=1:Nx

if(SumType==1)

f2(j) = coeff2(j)*epsilon*delta*N*M;

elseif(SumType==2)

f2(j) = 2*coeff2(j)*epsilon*delta*N*M;

elseif(SumType==3)

f2(j) = 3*coeff2(j)*epsilon*delta*N*M;

end

end

% However, this gives different answers since f(j) runs against a single

% value of j while f2(j) computes all the values of j.

diff = norm(f-f2,inf) % large

I'm curious if there is a more efficient way of writing

for j=1:Nx

% start inner double for loop

for r=0:N

for s=0:M

coeff(r+1,s+1) = f_n_m(j,r+1,s+1);

end

end

% end inner double for loop

if(SumType==1)

f(j) = % An external function involving coeff, epsilon, delta, N, M

elseif(SumType==2)

f2(j) = % A different external function involving coeff, epsilon, delta, N, M

elseif(SumType==3)

f2(j) = % A third external function involving coeff, epsilon, delta, N, M

end

end

so that the inner double for loop is only calculated once instead of Nx times. Is this a limitation of the way the function is written?

per isakson
on 23 Jul 2021

Caveat: I don't fully understand your code and what I say might not be relevant to your real project.

"% Can this double for loop be performed once instead of Nx times?" The short answer is no, because coeff is 2D and f_n_m is 3D. Maybe, you can make coeff 3D. Depends on how you will use coeff.

"f(jj) = coeff(jj)*epsilon*delta*N*M;" What is coeff(jj) supposed to return? This is linear indexing, which returns a scalar.

Proposal: Replace the double for-loop by alt_coeff = f_n_m( :, :, jj );. Notice that I have modified the indexing of f_n_m so that jj is the third index. Run the function cssm1() with profile(). alt_coeff improves speed significantly.

cssm1

function out = cssm1

% Test Data

% clc; clear all;

M = 30;

N = 30;

Nx = 32;

f_n_m = rand(N+1,M+1,Nx);

epsilon = 0.3;

delta = 0.4;

SumType = randi(3,1);

f = zeros(Nx,1);

coeff = zeros(N+1,M+1);

% Original Implementation

for jj=1:Nx

% Can this double for loop be performed once instead of Nx times?

for r=0:N

for s=0:M

coeff(r+1,s+1) = f_n_m(r+1,s+1,jj);

end

end

alt_coeff = f_n_m( :, :, jj );

if(SumType==1)

% My code calls seperate subroutines which need the value of coeff.

% For testing purposes I have put f(j) = test data. These three if

% statements call external functions in my code.

f(jj) = coeff(jj)*epsilon*delta*N*M;

elseif(SumType==2)

f(jj) = 2*coeff(jj)*epsilon*delta*N*M;

elseif(SumType==3)

f(jj) = 3*coeff(jj)*epsilon*delta*N*M;

end

end

out = "Happy end";

end

Simon Chan
on 23 Jul 2021

Edited: Simon Chan
on 23 Jul 2021

The loop of finding the coefficient can be entirely replaced by:

new_coeff = permute(f_n_m,[2 3 1]);

Noticed that size of new_coeff is 31x31x32 and new_coeff(:,:,1) is equivalent to your coeff when j = 1.

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

Start Hunting!