我正在尝试优化经济模型的蒙特卡罗模拟,涉及三个 MATLAB 文件:StartMonCarFinal.m、SDsysFinal.m 和 SDMasterFinal.m。以下是每个文件功能的简要概述:
为了提高仿真的运行速度,我尝试将StartMonCarFinal.m中的常规for循环替换为parfor来实现并行处理。然而,在这次尝试中我遇到了几个问题:
如果有任何关于如何有效并行处理此类蒙特卡罗模拟的建议,尤其是如何处理 parfor 循环中的保存问题和全局变量问题,我将不胜感激。任何有关如何提高此类脚本的并行效率的建议都会非常有帮助。
感谢您的时间和帮助!
niter = 100; %number of random realizations for montecarlo
for mcar = 1:niter
save mcar mcar niter
mcar
SDMasterFinal
load mcar
if mcar > 1
load OutputFinal
end
wMC(mcar,:,:) = w;
Z_MMC(mcar,:,:) = Z_M;
Z_SMC(mcar,:,:) = Z_S;
Z_M_MorMC(mcar,:,:) = Z_M_Mor;
Z_S_MorMC(mcar,:,:) = Z_S_Mor;
c_MMC(mcar,:,:) = c_M;
c_SMC(mcar,:,:) = c_S;
p_MMC(mcar,:,:) = p_M;
p_SMC(mcar,:,:) = p_S;
MMC(mcar,:,:) = M;
SMC(mcar,:,:) = S;
L_MMC(mcar,:,:) = L_M;
L_SMC(mcar,:,:) = L_S;
L_MNANMC(mcar,:,:) = L_MNAN;
L_SNANMC(mcar,:,:) = L_SNAN;
LMC(mcar,:,:) = L;
R_MMC(mcar,:,:) = R_M;
R_SMC(mcar,:,:) = R_S;
phi_MMC(mcar,:,:) = phi_M;
phi_SMC(mcar,:,:) = phi_S;
thetaMC(mcar,:,:) = theta;
Po_MMC(mcar,:,:) = Po_M;
Po_SMC(mcar,:,:) = Po_S;
taoMC(mcar,:,:) = tao;
tao_SMC(mcar,:,:) = tao_S;
tao_MMC(mcar,:,:) = tao_M;
ES_MMC(mcar,:,:) = ES_M;
UbarMC(mcar,:,:) = Ubar;
RIMC(mcar,:,:) = RI;
Z_MvecMC(mcar,:,:) = Z_Mvec;
Z_SvecMC(mcar,:,:) = Z_Svec;
save OutputFinal *MC niter
end
save OutputFinal
clear all
global t h_M h_S alfa gamma mu sigma l a ksi1 ksi2 Lbar kappa
global w Z_M Z_S Z_M_Mor Z_S_Mor c_M c_S p_M p_S M S L_M L_S L R_M R_S phi_M phi_S theta Po_M Po_S tao ES_M Ubar RI
%Parameter Values
beta = .9747;
h_M = 0.9;
h_S = 1.4;
alfa = -1.5;
mu = .6;
gamma = 1-mu; %(needs to be 1-mu);
sigma =.6;
l = 1:500;
a = 45; %Pareto coefficient
ksi1 = 1.142793;
ksi2 = 0.0082433;
delta = 7.5;
Lbar = 100;
kappa = 0.08;
T = 240;
%Allocate variables
w = zeros(length(l),T);
Z_M = zeros(length(l),T);
Z_S = zeros(length(l),T);
Z_M_Mor = zeros(length(l),T);
Z_S_Mor = zeros(length(l),T);
c_M = zeros(length(l),T);
c_S = zeros(length(l),T);
p_M = zeros(length(l),T);
p_S = zeros(length(l),T);
M = zeros(length(l),T);
S = zeros(length(l),T);
L_M = zeros(length(l),T);
L_S = zeros(length(l),T);
L_MNAN = zeros(length(l),T);
L_SNAN = zeros(length(l),T);
L = zeros(length(l),T);
R_M = zeros(length(l),T);
R_S = zeros(length(l),T);
phi_M = zeros(length(l),T);
phi_S = zeros(length(l),T);
theta = zeros(length(l),T);
Po_M = zeros(length(l),T);
Po_S = zeros(length(l),T);
tao = zeros(length(l),T);
tao_S = zeros(length(l),T);
tao_M = zeros(length(l),T);
ES_M = zeros(length(l),T);
Ubar = zeros(1,T);
RI = zeros(1,T);
Z_Mvec = zeros(length(l),length(l));
Z_Svec = zeros(length(l),length(l));
X0(1) = 0.0492; %Ubar(1) initial value for solver
X0(2) = 1.035; %p_M(1,1) initial value for solver
X0(3) = 0.054; %RI(1) initial value for solver
for t = 1:T
%t
%Initial Productivity
if t == 1
Z_M_Mor(:,1) = .8 + .4*l/length(l);
Z_S_Mor(:,1) = 1*ones(length(l),1);
end
F=@(R)SDsysFinal(R);
options=optimset('MaxFunEvals',10000000000,'TolFun',0.0001,'MaxIter',1000000,'Display','off');
[X,Eval] = fsolve(F,X0,options);
X0(1) = Ubar(t);
X0(2) = p_M(1,t);
X0(3) = RI(t);
%Eval
%Diffusion
for i = 1:length(l)
for j = 1:length(l)
Z_Mvec(i,j) = exp(-delta*abs(i-j)/length(l))*Z_M(j,t);
Z_Svec(i,j) = exp(-delta*abs(i-j)/length(l))*Z_S(j,t);
end
Z_M(i,t+1) = max(Z_Mvec(i,:));
Z_S(i,t+1) = max(Z_Svec(i,:));
%Save Morning Productivity
Z_M_Mor(:,t+1) = Z_M(:,t+1);
Z_S_Mor(:,t+1) = Z_S(:,t+1);
end
end
function D = SDsysFinal(X)
global t h_M h_S alfa gamma mu sigma l a ksi1 ksi2 Lbar kappa
global w Z_M Z_S Z_M_Mor Z_S_Mor c_M c_S p_M p_S M S L_M L_S L R_M R_S phi_M phi_S theta Po_M Po_S ES_M Ubar RI
p_S(:,t) = ones(length(l),1);
Ubar(t) = X(1);
p_M(1,t) = X(2);
RI(t) = X(3);
Z_M(:,t) = Z_M_Mor(:,t);
Z_S(:,t) = Z_S_Mor(:,t);
for i = 1:length(l)
%Wages and consumption
w(i,t) = Ubar(t)*((((p_M(i,t)./h_M)/(p_S(i,t)./h_S))^(1/(alfa-1)))*p_M(i,t) + p_S(i,t))...
./(h_M*(((p_M(i,t)./h_M)/(p_S(i,t)./h_S))^(alfa/(alfa-1))) + h_S).^(1/alfa) - RI(t);
c_S(i,t) = (w(i,t) + RI(t))./(p_M(i,t).*(((p_M(i,t)./h_M)/(p_S(i,t)./h_S))^(1/(alfa-1)))+p_S(i,t));
c_M(i,t) = c_S(i,t).*(((p_M(i,t)./h_M)/(p_S(i,t)./h_S))^(1/(alfa-1)));
%Choose phi
phi_M(i,t) = 1-((Z_M(i,t)*p_M(i,t)*gamma)/(ksi2*(a-1)*((w(i,t)/(mu*p_M(i,t)))^((1-gamma)/gamma))))^(-1/2);
phi_S(i,t) = 1-((Z_S(i,t)*p_S(i,t)*gamma)/(ksi2*(a-1)*((w(i,t)/(sigma*p_S(i,t)))^((1-gamma)/gamma))))^(-1/2);
if phi_M(i,t) < 0
phi_M(i,t) = 0;
end
if phi_M(i,t) > 1;
phi_M(i,t) = 1;
end
if phi_S(i,t) < 0
phi_S(i,t) = 0;
end
if phi_S(i,t) > 1;
phi_S(i,t) = 1;
end
%Production and labor choices
L_M(i,t) = (w(i,t)./(mu*p_M(i,t).*((Z_M(i,t)*(phi_M(i,t)/(a-1)+1)).^gamma))).^(1/(mu-1));
L_S(i,t) = (w(i,t)./(sigma*p_S(i,t).*((Z_S(i,t)*(phi_S(i,t)/(a-1)+1)).^gamma))).^(1/(sigma-1));
if (ksi1 + ksi2*(1/(1-phi_M(i,t))))*w(i,t) > (((Z_M(i,t)).^gamma)*p_M(i,t).*(L_M(i,t).^mu)/((a-1)^gamma))...
*(((phi_M(i,t)+a-1)^gamma - (a-1)^gamma));
phi_M(i,t) = 0;
L_M(i,t) = (w(i,t)./(mu*p_M(i,t).*(Z_M(i,t).^gamma))).^(1/(mu-1));
end
if (ksi1 + ksi2*(1/(1-phi_S(i,t))))*w(i,t) > (((Z_S(i,t)).^gamma)*p_S(i,t).*(L_S(i,t).^sigma)/((a-1)^gamma))...
*(((phi_S(i,t)+a-1)^gamma - (a-1)^gamma));
phi_S(i,t) = 0;
L_S(i,t) = (w(i,t)./(sigma*p_S(i,t).*(Z_S(i,t).^gamma))).^(1/(sigma-1));
end
%Land Use and Land Rents
R_M(i,t) = p_M(i,t)*((Z_M(i,t)*(phi_M(i,t)/(a-1)+1)).^gamma).*(L_M(i,t).^mu)-w(i,t).*L_M(i,t)- w(i,t)*(ksi1+ksi2*(1/(1-phi_M(i,t))));
R_S(i,t) = p_S(i,t)*((Z_S(i,t)*(phi_S(i,t)/(a-1)+1)).^gamma).*(L_S(i,t).^sigma)-w(i,t).*L_S(i,t)- w(i,t)*(ksi1+ksi2*(1/(1-phi_S(i,t))));
if R_M(i,t) > R_S(i,t)
theta(i,t) = 1;
phi_S(i,t) = 0;
else
theta(i,t) = 0;
phi_M(i,t) = 0;
end
%Expected Outputs
M(i,t) = ((Z_M(i,t)*(phi_M(i,t)/(a-1)+1)).^gamma).*L_M(i,t).^mu;
S(i,t) = ((Z_S(i,t)*(phi_S(i,t)/(a-1)+1)).^gamma).*L_S(i,t).^sigma;
%Aggregate Labor
L(i,t) = theta(i,t).*L_M(i,t)+(1-theta(i,t)).*L_S(i,t);
%Construct Excess Supply
if i > 1
if phi_M(i,t) > 0
ES_M(i,t) = ES_M(i-1,t) + (theta(i,t)*(M(i,t)- (w(i,t)/p_M(i,t))*(ksi1+ksi2*(1/(1-phi_M(i,t))))) - c_M(i,t).*L(i,t) - kappa*(abs(ES_M(i-1,t))))/length(l);
else
ES_M(i,t) = ES_M(i-1,t) + (theta(i,t)*M(i,t) - c_M(i,t).*L(i,t) - kappa*(abs(ES_M(i-1,t))))/length(l);
end
else
if phi_M(i,t) > 0
ES_M(i,t) = (theta(i,t)*(M(i,t)- (w(i,t)/p_M(i,t))*(ksi1+ksi2*(1/(1-phi_M(i,t))))) - c_M(i,t).*L(i,t))/length(l);
else
ES_M(i,t) = (theta(i,t)*M(i,t) - c_M(i,t).*L(i,t))/length(l);
end
end
%Construct prices for i+1
if ES_M(i,t) > 0
if i < length(l)
p_M(i+1,t) = p_M(i,t)*exp(kappa/length(l));
end
else
if i < length(l)
p_M(i+1,t) = p_M(i,t)*exp(-kappa/length(l));
end
end
%Generate Poisson draws
Po_M(i,t) = rand;
Po_S(i,t) = rand;
%Generate Pareto and update productivity after innovation
if Po_M(i,t) > phi_M(i,t);
Z_M(i,t) = Z_M(i,t);
else
z = gprnd(1/a,1/a,1);
Z_M(i,t) = z*Z_M(i,t);
end
if Po_S(i,t) > phi_S(i,t);
Z_S(i,t) = Z_S(i,t);
else
z = gprnd(1/a,1/a,1);
Z_S(i,t) = z*Z_S(i,t);
end
%Actual Outputs
M(i,t) = theta(i,t).*(Z_M(i,t).^gamma).*L_M(i,t).^mu;
S(i,t) = (1-theta(i,t)).*(Z_S(i,t).^gamma).*L_S(i,t).^sigma;
end
%Equilibrium in the goods market
if (Ubar(t) > 0) %&& sum((1-theta(:,t)).*L_S(:,t))/length(l) < 100);
d1 = ES_M(length(l),t);
else
d1 = 1000000;
end
%Equilibrium condition in labor market
if (p_M(1,t)> 0)% && p_M(1,t) < pp)
d2 = sum(L(:,t))/length(l) - Lbar;
else
d2 = 1000000;
end
%Calculate Rental Income (RI)
if (RI(t) > 0 && min(w(:,t)) > 0)
d3 = RI(t) - (sum(theta(:,t).*R_M(:,t)) + sum((1-theta(:,t)).*R_S(:,t)))/(Lbar*length(l));
else
d3 = 1000000;
end
D = [d1,d2,d3];
MATLAB 指示 save 命令不能在 parfor 循环内使用。我不知道如何克服这个限制。
您可以创建一个函数来在 forloop 内进行保存,如下所示:
function parsave(fname, x,y)
save(fname, 'x', 'y')
end
我还担心SDMasterFinal.m中大量使用全局变量,这可能会与parfor的并行性发生冲突。
我建议根本不要使用全局,因为它很难调试,我建议尽可能编辑代码以使用函数,以便更容易实现 MC。
您可以创建一个名为
states
的结构,其中包含所有所需的变量并将其包含在函数中。我建议使用较小的结构,以便您确切地知道函数内部和外部的内容