How do I speed up a loop where I need to check whether elements are less than 0

1 view (last 30 days)
I am trying to speed-up the following loop. This loop updates a value function v_d given a guess v_ini_exp. All variables are pre-allocated. From running a profiler it seems that the major bottleneck is the line where I need to discard elements of a matrix which are less than 0. In my model, these values are not feasible. But it seems that this is taking almost 65% of the execution time. I was wondering if there is a way to speed up the loop (provided below)
I can think of two ways to try to speed it up:
(1) Speed-up the line that takes over 65% of the execution time (I tried different formulation but the current one is the fastest I could think of)
(2) Try to vectorize at least one the the loop, but this is unclear to me since the variable d in the inner loop is a matrix.
Is there any way to speed up this loop? I can use parfor to decrease the runtime by around 50% but is there another way to speed up this loop before jumping to use parallel toolbox?
% Variables defined up to this loop:
% (1) q_ini is an array (z_grid_num-by-k_grid_num-by-b_grid_num)
% (2) v_ini_exp is an array (z_grid_num-by-k_grid_num-by-b_grid_num)
% (3) wealth is an array (z_grid_num-by-k_grid_num-by-b_grid_num)
% (4) choice a matrix (k_grid_num-by-b_grid_num)
% continuation value function
for ii = 1:z_grid_num
q_ini_ii = squeeze(q_ini(ii,:,:));
v_ini_exp_ii = squeeze(v_ini_exp(ii,:,:));
choice = q_ini_ii.*b_grid_choice - k_grid_choice;
for jj = 1:k_grid_num
for kk = 1:b_grid_num
% dividends at time t
d = wealth(ii,jj,kk) + choice;
% choosing optimal consumption
vec_d = (d + v_ini_exp_ii).*(d>0) + (-1e30).*(d<=0); % <- THIS LINE TAKES 65% OF THE EXECUTION TIME
[v_d(ii,jj,kk)] = max(vec_d,[],'all'); % <- THIS LINE TAKES 25% OF THE EXECUTION TIME
end
end
end
  10 Comments
Michal Szkup
Michal Szkup on 18 Mar 2020
Edited: Michal Szkup on 18 Mar 2020
@Walter I am afraid of the first possibility. I will have to solve the problem for different parameter values so I would like to have a check against that. I cannot imagine that the second option would happen.
Apparently, writing the problematic line as
vec_d = d + v_ini_exp_ii.*(d>0)
provides an additional very small but positive gain. This formulation is valid for my problem since the lowest value v_ini_exp_ii takes is 0.
Michal Szkup
Michal Szkup on 18 Mar 2020
Edited: Michal Szkup on 18 Mar 2020
I tested the code a little bit more and it seems that if I could be sure that I can execute the line
vec_d = d + v_ini_exp_ii
rather than
vec_d = d + v_ini_exp_ii.*(d>0)
then, as @Walter suggested, this yields additional gains of up to 25% which is probably as fast as this can get without restructuring the whole code.
For the current parameters, the code returns the same solutions in both cases, but I will need to test that this holds true for a wide range of parameters.

Sign in to comment.

Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!