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

1 visualizzazione (ultimi 30 giorni)
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 Commenti
Michal Szkup
Michal Szkup il 18 Mar 2020
Modificato: Michal Szkup il 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 il 18 Mar 2020
Modificato: Michal Szkup il 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.

Accedi per commentare.

Risposte (0)

Categorie

Scopri di più su Loops and Conditional Statements in Help Center e File Exchange

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by