如何编写一个引用stata Mata solvenl()函数的循环?

时间:2016-04-18 20:44:01

标签: loops stata

我正在研究一种网格搜索程序,它解决了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
}

0 个答案:

没有答案