Announcement

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

  • Solving non-linear equations within a loop in Stata

    Cross posted on Stack Overflow.

    Hi I am trying to solve 3 non-linear equations using nl command in Stata within a loop. The working program to solve equations for one set of values is as follows;
    Code:
    capture program drop nlcostsolver
    program nlcostsolver    
    syntax varlist(min=1 max=1) [if], at(name)      
    
    tempname    G S K    
    scalar      `G' = `at'[1,1]    
    scalar      `S' = `at'[1,2]    
    scalar      `K' = `at'[1,3]      
    
    tempvar     yh    
    
    gen         double `yh' = `G'*log(1531.560) - log(`S'+0) + log(`K') + 1 in 1    
    replace     `yh' = `G'*log(2015.896) - log(`S'+0.01) + log(`K') in 2    
    replace     `yh' = `G'*log(2152.582) - log(`S'+0.10) + log(`K') in 3      
    
    replace     `varlist' = `yh'    
    end  
    
    clear  
    
    set         obs 3
    generate    y = 0
    replace     y = 1 in 1  
    
    scalar      k = exp((log(0.10) - ((log(0.01)*log(2152.582))/log(2015.896))) / (1 - (log(2152.582)/log(2015.896))))
    scalar      gamma = exp(log((log(0.01) - log(k))/log(2015.896)))
    scalar      s = exp(exp(log(gamma))*log(1531.560) + log(k))  
    
    nl costsolver@ y, parameters(G S K) initial(G gamma S s K k)
    The above code gives me the value of parameters (G, S and K) for particular values (1531.560, 2015.896, 2152.582) in the program. However, I have 3 variables (Points0, Points3 and Points0) with 1000 observations each for which I need to calculate values of these parameters. So I need to calculate 1000 set of parameters. I tried looping the program as follows;

    Code:
    gen     G = .
    gen     S = .
    gen     K = .  
    
    forvalues i = 1/1000 {    
    
    capture program drop nlcostsolver    
    program nlcostsolver        
    syntax      varlist(min=1 max=1) [if], at(name)          
    
    tempname    G S K        
    
    scalar      `G' = `at'[1,1]        
    scalar      `S' = `at'[1,2]        
    scalar      `K' = `at'[1,3]          
    
    tempvar     yh        
    
    gen         double `yh' = `G'*log(`Points0[`i']') - log(`S'+0) + log(`K') + 1 in 1        
    replace     `yh' = `G'*log(`Points3[`i']') - log(`S'+0.03) + log(`K') in 2        
    replace     `yh' = `G'*log(`Points9[`i']') - log(`S'+0.09) + log(`K') in 3          
    
    replace     `varlist' = `yh'              
    
    scalar      k = exp((log(0.09) - ((log(0.03)*log(`Points9[`i']'))/log(`Points3[`i']'))) / (1 - (log(`Points9[`i']')/log(`Points3[`i']'))))        
    scalar      gamma = exp(log((log(`p3') - log(k))/log(`Points3[`i']')))        
    scalar      s = exp(exp(log(gamma))*log(`Points0[`i']') + log(k))      
    end      
    preserve        
    clear          
    set         obs 3        
    generate    y = 0        
    replace     y = 1 in 1          
    
    nl costsolver @ y, parameters(G S K) initial(G gamma S s K k)    
    restore      
    
    replace G = [G]_b[_cons] in `i'    
    replace S = [S]_b[_cons] in `i'    
    replace K = [K]_b[_cons] in `i' }
    However, since I am using program within a loop, the moment I get to end statement in the program the loop breaks. Appreciate your help.
    Last edited by Sher Afghan Asad; 25 Oct 2018, 11:14.

  • #2
    You can't define a program inside a loop. Define the program before the loop. If you need to use an extra parmeter that you can't pass with the nl command, you could use a global macro.

    Comment


    • #3
      Hi Jean,

      Thanks for your comment. I have realized that programs can't be used inside a loop. However I remain unable to come up with a program that can use values from the variable to generate parameters for each combination of variables value. Sorry I can't see straight away how could using global macros achieve what I want in this case.

      It seems to me Stata is not an ideal software for non-linear optimization, maybe I should do this in R then.

      Comment


      • #4
        The trick with using globals worked. Thanks for the suggestion Jean!

        Comment

        Working...
        X