speed-up the given code

7 views (last 30 days)
Abhinav
Abhinav on 22 Jun 2018
Edited: Abhinav on 22 Jun 2018
The following code is taking a most of the time in my script and I have to run the script many times Is there a way to reduce the time for its execution.
t=0:200000;
lambda=[1,2,3;4,5,6;7,8,9;10,11,12];
for trans=1:size(lambda,1)
uh_fun{trans}=expconv(lambda(trans,:));
end
uh=zeros(length(t),1);
for i=1:length(uh_fun)
temp_uh_fun=uh_fun{i};
f_gamma=zeros(length(t),1);
for j=1:length(temp_uh_fun)
f_gamma=f_gamma+temp_uh_fun{j}(t)'; % this line take a lot of time
end
uh=uh+p(i)*f_gamma; % p is an array of scalars
end
I have added expconv function for reference. I need some suggestions to improve the performance. I have also attached a pdf which contains profiler analysis of anonymous function in expconv.
  13 Comments
Geoff Hayes
Geoff Hayes on 22 Jun 2018
have you posted the actual function that you are using or just an example? We need to see the actual code so that we can provide some hints on how to improve the performance.
Abhinav
Abhinav on 22 Jun 2018
Edited: Abhinav on 22 Jun 2018
This is the actual function. Just the lambda values are arbitrary. I think that you are right about calls to exp taking a lot of time.

Sign in to comment.

Accepted Answer

OCDER
OCDER on 22 Jun 2018
Edited: OCDER on 22 Jun 2018
This might be a variant of the xy-problem that @Stephen points out. http://xyproblem.info/
Solve X: you want to add the values for a function for all P, C, lambda values. Attempt with using function handles, called Solution Y.
Solve Y: you make a lot of function handles for all P, C, lambda sets. But this is too slow. You want a solution to make Solution Y faster, not seeing a faster solution for X.
%This is just an EXAMPLE. Check to make sure you get the right results
C = rand(1000, 1);
P = rand(1000, 1);
lambda = rand(1000, 1);
t = 1:10000;
%Solution Y approach : use handles
Ysum = zeros(1, length(t));
for i = 1:length(C)
fh = @(t) P(i)*exp(-lambda(i)*t) + C(i);
Ysum = Ysum + fh(t);
end
t2 = toc
%Solution X approach : use vectorized math
tic
Ysum = sum(bsxfun(@times, exp(-lambda*t), P) + C, 1);
t1 = toc % ~5 times faster
I notice you like using repmat and find. Note that use of repmat is slower than bsxfun. Also, if possible, avoid using find if dealing with logical indexing. For instance:
function uh_fun=expconv(lambda)
k=length(lambda);
% Lambda=repmat(lambda,k,1);
% temp_den=Lambda'-Lambda;
temp_den = lambda' - lambda; %faster
% ind=find(temp_den==0);
ind = temp_den == 0; %stick with logical indexing
if sum(ind(:)) > k % length(ind)>k %corrected this
error('atleast two of the pdfs to be convolved are identical')
else
% temp_den(temp_den==0)=1;
temp_den(ind) = 1; %no need to re-find temp_den == 0;
den=prod(temp_den);
nume=prod(lambda);
C=nume./den;
for i=1:k
uh_fun{i}=@(t)exp(-lambda(i)*t)*C(i); %Do you reallly have to make all these handles?
end
end
end
If this is still too slow, then you could try using parfor or mex functions.
  4 Comments
OCDER
OCDER on 22 Jun 2018
If you look at the example, you could get away by calling exp once, but on a 2D matrix.
exp(-lambda*t), where lambda is a Mx1 matrix, and t is 1xN matrix.
so lambda * t is a MxN matrix.
This could save some time instead of trying to do a for loop and multip exp calls for each column of data.
The other question is what other function is calling your slow code "2,016,028" times? That's a lot... Do you often have the same input and output values? If so, you can cache your function outputs via memoize to prevent matlab from having to recalculate the output values.
This is what it does, assuming it's applied to a function myFun:
B = myFun(1, 2, 3, 2, 3) --> computing value B... --> B = 3;
B = myFun(1, 2, 1, 2, 1) --> computing value B... --> B = 1;
B = myFun(1, 2, 3, 2, 3) --> B = 3; %Same input/output as before
Abhinav
Abhinav on 22 Jun 2018
Edited: Abhinav on 22 Jun 2018
I have another 'unitHydrograph' in which the slow code is written. unitHydrograph has changing inputs. I have declared other useful variables which are calculated by unitHydrograph and remain fixed as 'persistent' so that I am not recomputing all those. Using matrix computation in lambda has not helped though.
Thanks a lot for your help and suggestions for improving my code!!

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!