我正在研究一种网格搜索程序,它解决了z1 z2 z3对许多e和phi对的解决方案。经过多次尝试,我想出了如何解决任何特定对e和phi的问题,但无法弄清楚如何编写循环使其适用于所有对。以下是整个代码。非常感谢你的帮助!
第一部分设定e和phi的值,没有问题。
obs 20000
gen id=_n
gen e=.
gen phi=.
gen N_e=100 // number of values for e
gen N_phi=200 // number of values for phi
gen step_e=0.01 // step of grids for e
gen step_phi=1 // step of grids for phi
gen error_code=.
gen z1=.
gen z2=.
gen z3=.
gen b1=.
gen b2=.
gen b3=.
foreach seq_e of numlist 1(1)100 {
foreach seq_phi of numlist 1(1)200 {
qui replace e=0.01*`seq_e' if id==(`seq_e'-1)*(N_phi)+`seq_phi'
qui replace phi=`seq_phi' if id==(`seq_e'-1)*(N_phi)+`seq_phi'
}
}
第二部分是我遇到问题的地方。以下代码适用于任何一对e和phi。通过将temp_e = st_data(1,“e”)和temp_phi = st_data(1,“phi”)更改为temp_e = st_data(n,“e”)和temp_phi = st_data(n,“phi”),我可以将第n对e和phi程序。
clear mata
mata:
temp_e=st_data(1, "e")
temp_phi=st_data(1, "phi")
st_local("e", strofreal(temp_e))
st_local("phi", strofreal(temp_phi))
void function solvez(real colvector z, real colvector y)
{
y[1] = ((20000+z[1])*(1-0.2)/(1+1/`e'))*(1-(20000/(20000+z[1]))^(1+1/`e'))-`phi'-z[1]*(1-0.25)
y[2] = ((9000+z[2])*(1-0.2)/(1+1/`e'))*(1-(9000/(9000+z[2]))^(1+1/`e'))-`phi'-z[2]*(1-0.25)
y[3] = ((35000+z[3])*(1-0.25)/(1+1/`e'))*(1-(35000/(35000+z[3]))^(1+1/`e'))-`phi'-z[3]*(1-0.3)
}
S = solvenl_init()
solvenl_init_evaluator(S, &solvez())
solvenl_init_type(S, "zero")
solvenl_init_technique(S, "newton")
solvenl_init_startingvals(S, J(3,1,10))
solvenl_init_conv_maxiter(S, 100)
solvenl_init_iter_log(S, "off")
_solvenl_solve(S)
ERR=solvenl_result_error_code(S)
M=solvenl_result_values(S)
st_matrix("M", M)
st_matrix("ERR", ERR)
end
matrix list M
matrix list ERR
replace z1=M[1,1] if id==`num'
replace z2=M[2,1] if id==`num'
replace z3=M[3,1] if id==`num'
replace b1=(e*0.05/(1-0.2)*20000-z1)/50 if id==`num'
replace b2=(e*0.05/(1-0.2)*9000-z2)/50 if id==`num'
replace b3=(e*0.05/(1-0.25)*35000-z3)/500 if id==`num'
replace error_code=ERR[1,1] if id==`num'
我的问题是如何编写一个循环来实现所有e和phi对的上述代码。我已尽力编写如下循环。但我很确定它有多个问题。谁能帮助我让循环工作?我知道这个问题可能不是很具体。但我已经尽力找到以前线程的可能解决方案,似乎没有足够的信息让我自己解决问题。如果你能给我任何暗示,我将非常感激。
以下是我尝试的循环代码。
capture program drop solveprogram
program define solveprogram
args num var_e var_phi
mata: mywork("`num'", "`var_e'", "`var_phi'")
replace z1=M[1,1] if id==`num'
replace z2=M[2,1] if id==`num'
replace z3=M[3,1] if id==`num'
replace b1=(e*0.05/(1-0.2)*20000-z1)/50 if id==`num'
replace b2=(e*0.05/(1-0.2)*9000-z2)/50 if id==`num'
replace b3=(e*0.05/(1-0.25)*35000-z3)/500 if id==`num'
replace error_code=ERR[1,1] if id==`num'
end
clear mata
mata:
void mywork(string scalar num_value, string scalar e_name, string scalar phi_name)
{
real scalar e_temp, phi_temp
e_temp = st_data(num_value, e_name)
phi_temp = st_data(num_value, phi_name)
S = solvenl_init()
solvenl_init_argument(S, 1, e_temp)
solvenl_init_argument(S, 2, phi_temp)
solvenl_init_evaluator(S, &solvez())
solvenl_init_type(S, "zero")
solvenl_init_technique(S, "newton")
solvenl_init_startingvals(S, J(3,1,10))
solvenl_init_conv_maxiter(S, 100)
solvenl_init_iter_log(S, "off")
_solvenl_solve(S)
ERR=solvenl_result_error_code(S)
M=solvenl_result_values(S)
st_matrix("M", M)
st_matrix("ERR", ERR)
}
void function solvez(real colvector z, real scalar e, real scalar phi, real colvector y)
{
y[1] = ((20000+z[1])*(1-0.2)/(1+1/e))*(1-(20000/(20000+z[1]))^(1+1/e))-phi-z[1]*(1-0.25)
y[2] = ((9000+z[2])*(1-0.2)/(1+1/e))*(1-(9000/(9000+z[2]))^(1+1/e))-phi-z[2]*(1-0.25)
y[3] = ((35000+z[3])*(1-0.25)/(1+1/e))*(1-(35000/(35000+z[3]))^(1+1/e))-phi-z[3]*(1-0.3)
}
end
forvalues i= 1/20000 {
solveprogram `i' e phi
}