Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • --Break-- r(1); error (while running moptimize)

    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:

    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
    }
    --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.

  • #2
    Multi-line Mata blocks
    Code:
    mata:
    ...
    end
    do not work withing Stata's foreach or forvalues loops. You would need to write a separate program or Mata function that you can call within a single line, or use the Mata prefix mata: separately for each line.
    Last edited by Sebastian Kripfganz; 25 Sep 2023, 02:54.
    https://twitter.com/Kripfganz

    Comment

    Working...
    X