Hi all,
I am trying to define a function and optimize it. My aim is to find parameter values (para_a and para_b) returning minium value of objective function. My code is as follows:
--Break-- r(1) error message pops up at the end of the code. Right before the last restore command. I am new to Stata and don't understand what's wrong with my code. Until the very last line, it seems everything works.
I am trying to define a function and optimize it. My aim is to find parameter values (para_a and para_b) returning minium value of objective function. My code is as follows:
Code:
mata: mata drop myobjfunc()
mata
void myobjfunc(real scalar lnf, real scalar para_a, real scalar para_b, real scalar assigned_value_lower, real scalar assigned_value_upper)
{
real scalar observed_cdf, diff, sum_diff, temp_cdf, current_sum_diff
real scalar xl, xr, lower_bound, upper_bound, total_sum_obsCDF, total_sum_diff, pred_cdf
real scalar i
xl = .
xr = .
lower_bound = round(assigned_value_lower, 0.01) // assigned_value_lower and assigned_value_upper are data on the original dataset (.dta).
upper_bound = round(assigned_value_upper, 0.01)
total_sum_obsCDF = 0
total_sum_diff = 0
pred_cdf = 0
for (i=1; i<=10; i++) {
// Replace with actual value
real scalar qsp7dens_i_new
qsp7dens_i_new= 0.0 * initial value
total_sum_obsCDF = total_sum_obsCDF + qsp7dens_i_new
if (i == 10) {
xl = -0.16
xr = -0.12
}
else if (i == 9) {
xl = -0.12
xr = -0.08
}
else if (i == 8) {
xl = -0.08
xr = -0.04
}
else if (i == 7) {
xl = -0.04
xr = -0.02
}
else if (i == 6) {
xl = -0.02
xr = 0.00
}
else if (i == 5) {
xl = 0.00
xr = 0.02
}
else if (i == 4) {
xl = 0.02
xr = 0.04
}
else if (i == 3) {
xl = 0.04
xr = 0.08
}
else if (i ==2){
xl = 0.08
xr = 0.12
}
else if(i == 1){
xl = 0.12
xr = 0.16
}
printf("xl is %f, xr is %f\n", xl, xr)
if (xr > upper_bound) {
temp_cdf = 1
}
else if (lower_bound <= xl & xl < upper_bound & lower_bound < xr & xr <= upper_bound) {
temp_cdf = ibeta(para_a, para_b, (xr - lower_bound) / (upper_bound - lower_bound))
}
else if (xl < lower_bound) {
temp_cdf = 0
}
pred_cdf = temp_cdf
diff = (total_sum_obsCDF - pred_cdf)^2
total_sum_diff = total_sum_diff + diff
}
lnf = -total_sum_diff // objective function: This is what I want to minimize.
}
end
gen opt_a = .
gen opt_b = .
// define a new function (my_mata_function) to call position of specific id.
mata:
real matrix my_mata_function(real scalar id) {
real matrix idx
idx = select(rownum(1::rows(st_data(., "uniqueid"))), st_data(., "uniqueid") :== id)
display(idx); // 반환값 출력
return(idx);
}
end
levelsof uniqueid, local(userids)
foreach id of local userids {
preserve
// select a current id
keep if uniqueid == `id'
mata:
// call my_mata_function.
real id_scalar=`id'
real matrix idx = my_mata_function(id_scalar)
display(idx)
// constraints
real rowvector lb
lb = (1, 1) // Lower bounds for para_a and para_b
real rowvector ub
ub = (3000 , 3000) // Upper bounds for para_a and para_b (no upper bounds in this case)
printf("lb: %f, ub: %f\n", lb, ub)
// moptimize
M = moptimize_init()
moptimize_init_search(M, "on")
moptimize_init_evaluator(M, "myobjfunc")
moptimize_init_evaluatortype(M, "d0")
moptimize_init_eq_indepvars(M, 1, ("para_a", "para_b"))
moptimize_init_constraints(M, lb, ub)
moptimize(M)
// call optimized para_a and para_b
real rowvector theta_hat()
theta_hat = moptimize_result_coefs(M)
// replace opt_a and opt_b variables on the original dataset with optimized para_a and para_b.
opt_a_col = st_varindex("opt_a")
opt_b_col = st_varindex("opt_b")
st_store(idx, opt_a_col, theta_hat[1, 1])
st_store(idx, opt_b_col, theta_hat[1, 2])
display(idx)
end
restore
}

Comment