How to make MATLAB code run faster

How do I speed this script up?
nuke;
h = 16; %hours available
K = 15; %Capital
z = 1; %Total factor productivity
t = 0; %Taxes
G = 0; %Government Spending?
iteration = 0; % run counter
precision = 1e-3;
distance = 2; % random value greater than precision
w = 1; %wage rate
pi_max = 1e-3; %profit?
% declare lgrid
lmin = 1e-5;
lmax = h - 1e-5;
lnum = 100000;
lgrid = linspace(lmin,lmax,lnum);
while distance > precision
c = zeros(size(lgrid)); %init array
u = zeros(size(lgrid));
for i = 1:lnum
c(i) = w*(h - lgrid(i)) + pi_max - t;
u(i) = log(c(i)) + log(lgrid(i));
end
[u_max, position] = max(u);
l_max = lgrid(position);
N_max_supply = h - l_max;
N = h - lgrid;
pi = zeros(size(lgrid));
for i = 1:lnum
pi(i) = z*K^0.3*N(i)^0.7 - w*N(i);
end
[pi_max, location] = max(pi);
N_max_demand = N(location);
distance = abs(N_max_demand - N_max_supply);
w = 0.99999*w + 0.00001*(N_max_demand - N_max_supply);
if w < 0
stop
end
iteration = iteration + 1; % this is the number of times while loop has been executed befores topping
s = sprintf ( ' w = %6.3f iteration %4d ||labor demand - labor supply|| = %8.6f labor demand = %8.6f labor supply = %8.6f ', ...
w, iteration, distance, N_max_demand, N_max_supply);
disp(s)
end
% now we have found the general equilibrium point, we can play with it and
% see what other values we have:
% output:
y = z*K^0.3*N_max_demand^0.7;
C = w*(N_max_supply) + pi_max - t;
Utility = log(C) + log(h-N_max_supply);

7 comentarios

James Tursa
James Tursa el 2 de Dic. de 2018
Have you run the profiler? Which line(s) are the bottleneck?
Kai Jensen
Kai Jensen el 2 de Dic. de 2018
No, im trying to parallelize the while loop I have setup.
Rik
Rik el 2 de Dic. de 2018
It might not be possible to remove the while loop. At least I don't see an easy way to do it. If you really want to, you should try finding the direct formula. In my experience that's usually easier with pen and paper than with Matlab.
If you can't find the direct formula, you should run the profiler and look what your code spends most of the time on.
I notice the two for loops can probably be vectorized, so if that's the bottleneck, just post a comment.
Kai Jensen
Kai Jensen el 2 de Dic. de 2018
yeah I ran the profiler, it seems like the two for loops are the bottleneck.
Kai Jensen
Kai Jensen el 3 de Dic. de 2018
Even after vectorizing it still takes a bit of time. Any way to speed up the exponental function?
Jan
Jan el 3 de Dic. de 2018
Editada: Jan el 3 de Dic. de 2018
Of cousre you should not compute the expensive K^0.3 in each iteration, but once before the loop. Or replace the 2nd loop:
pi = z * K ^ 0.3 * N .^ 0.7 - w * N;
But do I see correctly that z * K ^0.3 * N .^ 0.7 is a constant and does not change in the while loop? Then compute this once before the loop.
By the way "pi" is a bad choice for the name of a variable, because this shadows the builtin function pi.
You calculate u and c in the first loop only to find the maximum value. Why not calcuklating the first derivative are find the formula to determine the maximum? This avoids a lot of expansive log() commands.
Kai Jensen
Kai Jensen el 3 de Dic. de 2018
what would that look like?

Iniciar sesión para comentar.

 Respuesta aceptada

Jan
Jan el 3 de Dic. de 2018
Editada: Jan el 4 de Dic. de 2018
I just moved some repeted calculations out of the loop:
h = 16; %hours available
K = 15; %Capital
z = 1; %Total factor productivity
t = 0; %Taxes
G = 0; %Government Spending?
iteration = 0; % run counter
precision = 1e-3;
distance = 2; % random value greater than precision
w = 1; %wage rate
pi_max = 1e-3; %profit?
% declare lgrid
lmin = 1e-5;
lmax = h - 1e-5;
lnum = 100000;
lgrid = linspace(lmin,lmax,lnum);
logLgrid = log(lgrid);
N = h - lgrid;
c1 = z * K ^ 0.3 * N .^ 0.7;
while distance > precision
c = w * N + pi_max - t;
u = log(c) + logLgrid;
[u_max, position] = max(u);
l_max = lgrid(position);
N_max_supply = h - l_max;
pi = c1 - w * N;
[pi_max, location] = max(pi);
N_max_demand = N(location);
distance = abs(N_max_demand - N_max_supply);
w = 0.99999*w + 0.00001*(N_max_demand - N_max_supply);
if w < 0
stop % ??? What is "stop"? Do you mean: break
end
iteration = iteration + 1; % this is the number of times while loop has been executed befores topping
s = fprintf(' w = %6.3f iteration %4d ||labor demand - labor supply|| = %8.6f labor demand = %8.6f labor supply = %8.6f\n', ...
w, iteration, distance, N_max_demand, N_max_supply);
end
% now we have found the general equilibrium point, we can play with it and
% see what other values we have:
% output:
y = z*K^0.3*N_max_demand^0.7;
C = w*(N_max_supply) + pi_max - t;
Utility = log(C) + log(h-N_max_supply);
This version needs 7 seconds in Matlab R2016b, and 5 if the slow output to the command window is omitted, while the original took 202 seconds. All I've done was moving the repeated expensive |log and power operations out of the loop.

Más respuestas (0)

Productos

Versión

R2018b

Etiquetas

Preguntada:

el 2 de Dic. de 2018

Comentada:

el 24 de En. de 2019

Community Treasure Hunt

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

Start Hunting!

Translated by