【发布时间】:2021-04-04 04:00:57
【问题描述】:
我在 Julia 中非常有效地实现了一个运算符 T_,我想使用 while 循环进行迭代。我的操作员由以下人员给出:
% parameters
β = 0.987
δ = 0.012;
% grids
Kss = 48.1905148382166
kgrid = range(0.75*Kss, stop=1.25*Kss, length=500);
zgrid = [-0.06725382459813659, -0.044835883065424395, -0.0224179415327122, 0 , 0.022417941532712187, 0.04483588306542438, 0.06725382459813657]
% auxiliary functions to build my operator
F_(z,k) = exp(z) * (k^(1/3));
u_(c) = (c^(1-2) - 1)/(1-2)
% T_operator
function T_(V, P, kgrid, zgrid, β, δ)
E = V * P'
T1 = similar(V)
for i in axes(T1, 2)
for j in axes(T1, 1)
temp = F_(zgrid[i], kgrid[j]) + (1-δ)*kgrid[j]
aux = -Inf
for l in eachindex(kgrid)
c = max(0.0, temp - kgrid[l])
aux = max(aux, u_(c) + β * E[l, i])
end
T1[j,i] = aux
end
end
return T1
end
简要说明。该运算符作为输入
- V 是一个 500x7 矩阵,P 是一个 7x7 转换矩阵(即每一行加一个)
- kgrid 是长度为 500 的网格,zgrid 是长度为 7 的网格
- β 和 δ 特定参数
T_ 返回一个 T1 (500x7) 矩阵。有关此运算符的更多详细信息以及运行此运算符的正确方法可以在我提出的另一个问题中找到:Tricks to improve the performance of a cunstom function in Julia
只运行一次这个操作符,它花费的时间很短,几乎是瞬间的。但是,我需要迭代此运算符,直到获得可接受的容差错误,但我的实现导致效率低下的过程需要很长时间:
max_it = 1000
it = 1
tol = 1e-3
dist = tol +1
V0 = repeat(sqrt.(a_grid), outer = [1,7]);
while it < max_it && dist > tol
TV= T_(V0,P,kgrid, zgrid, β, δ)
dist = maximum(abs.(TV - V0)) % Computing distance or error
V0 = TV % update
it = it + 1 % Updating iterations
% Some information about the state of the iteration
if rem(it, 100) == 0
println("Current iteration:")
println(it)
println("Current norm:")
println(dist)
end
end
我认为更有效的解决方案是将while循环直接合并到T_运算符的实现中,但是我花了一整天的时间尝试这个并无法做到。帮助。
更新
这是 MATLAB 版本。效率更高
V0 = repmat(sqrt(kgrid), 1, 7); % Concave and increasing guess
max_it = 1000;
tol = 1e-3;
%% Iteration
tic
norm = tol + 1;
it = 1;
tic;
[K, Z, new_K] = meshgrid(kgrid, zgrid, kgrid);
K = permute(K, [2, 1, 3]);
Z = permute(Z, [2, 1, 3]);
new_K = permute(new_K, [2, 1, 3]);
% Computing consumption on each possible state and choice
C = max(f(Z,K) + (1-delta)*K - new_K,0);
% All possible utilities
U = u(C);
disp('Starting value function iteration through the good and old brute force...')
while it < max_it & norm > tol
EV = V0 * P';
EV = permute(repmat(EV, 1, 1, nk), [3, 2, 1]);
H = U + beta*EV;
[TV, index] = max(H, [], 3);
it = it + 1; % Updating iterations
norm = max(max(abs(TV - V0))); % Computing error
V0 = TV;
if rem(it, 100) == 0
disp('Current iteration:')
disp(it)
disp('Current norm:')
disp(norm)
end
end
V = TV;
toc;
【问题讨论】:
-
你是否将整个 while 循环包装在一个函数中?
-
比
T_慢多少。它明显比1000x慢吗?如果没有,将不会有太多可用的加速。 -
是的,您应该将
F_(zgrid[i], kgrid[j]) + (1-δ)*kgrid[j]拉到函数T_之外,以避免在每次迭代时重做。 -
当前 Julia 代码在我尝试运行时抛出(例如,
a_grid和P未定义)。 -
是的,我想通了,可以参考另一个问题...但是您应该通过确保代码可复制粘贴并按原样运行来使这个问题自成一体!
标签: performance iterator julia