*! nehurdle_heckman v1.1.0 *! 29 June 2017 *! Alfonso Sanchez-Penalver *! Version history at the bottom. /******************************************************************************* * ML lf evaluator for linear and exponential Type II Tobit models, with * * homoskedastic selection errors. * *******************************************************************************/ capture program drop nehurdle_heckman program define nehurdle_heckman version 11 args todo b lnfj g1 g2 g3 g4 H quietly { // Evaluate the parameters for each equation tempvar zg xb lnsval athrho mleval `zg' = `b', eq(1) mleval `xb' = `b', eq(2) mleval `lnsval' = `b', eq(3) mleval `athrho' = `b', eq(4) // Transform parametrized values to make equations easier to read tempvar sval rho zval rtrho hge gen double `sval' = exp(`lnsval') gen double `rho' = tanh(`athrho') gen double `zval' = ($ML_y2 - `xb') / `sval' gen double `rtrho' = sqrt(1 - `rho'^2) gen double `hge' = (`zg' + `rho' * `zval') / `rtrho' // Log-Likelihood replace `lnfj' = lnnormal(-`zg') if $ML_y1 == 0 replace `lnfj' = lnnormal(`hge') + lnnormalden(`zval') - `lnsval' /// if $ML_y1 == 1 // The global macro neh_method is set in nehurdle.ado and tells us whether // we want a linear or exponential specification of the value function if "$neh_method" == "exponential" /// replace `lnfj' = `lnfj' - $ML_y2 if $ML_y1 == 1 if (`todo' == 0) exit // Variables to make programming gradient and hessian easier tempvar nlamzi lamhge gen double `nlamzi' = normalden(`zg') / normal(- `zg') gen double `lamhge' = normalden(`hge') / normal(`hge') // Gradient // g1 (zg) replace `g1' = - `nlamzi' if $ML_y1 == 0 replace `g1' = `lamhge' / `rtrho' if $ML_y1 == 1 // g2 (xb) replace `g2' = 0 if $ML_y1 == 0 replace `g2' = `sval'^(-1) * (`zval' - `rho' / `rtrho' * `lamhge') if /// $ML_y1 == 1 // g3 (lnsval) replace `g3' = 0 if $ML_y1 == 0 replace `g3' = `zval' * (`zval' - `rho' / `rtrho' * `lamhge') - 1 if /// $ML_y1 == 1 // g4 (athrho) replace `g4' = 0 if $ML_y1 == 0 replace `g4' = `lamhge' * `rtrho' * (`zval' + `rho' / `rtrho' * `hge') /// if $ML_y1 == 1 if (`todo' == 1) exit // Hessian // The Hessian is 4 x 4 tempvar d11 d12 d13 d14 d22 d23 d24 d33 d34 d44 tempname h11 h12 h13 h14 h22 h23 h24 h33 h34 h44 // h11 (zg zg) gen double `d11' = `nlamzi' * (`zg' - `nlamzi') if $ML_y1 == 0 replace `d11' = - `lamhge' / (1 - `rho'^2) * (`hge' + `lamhge') if /// $ML_y1 == 1 mlmatsum `lnfj' `h11' = `d11', eq(1) // h12 (zg xb) gen double `d12' = 0 if $ML_y1 == 0 replace `d12' = `rho' / `sval' * `lamhge' / (1 - `rho'^2) * (`hge' + /// `lamhge') if $ML_y1 == 1 mlmatsum `lnfj' `h12' = `d12', eq(1,2) // h13 (zg lnsval) gen double `d13' = 0 if $ML_y1 == 0 replace `d13' = `rho' / (1 - `rho'^2) * `lamhge' * `zval' * (`hge' + /// `lamhge') if $ML_y1 == 1 mlmatsum `lnfj' `h13' = `d13', eq(1,3) // h14 (zg athrho) gen double `d14' = 0 if $ML_y1 == 0 replace `d14' = `lamhge' * (`rho' / `rtrho' - (`hge' + `lamhge') * /// (`zval' + `rho' / `rtrho' * `hge')) if $ML_y1 == 1 mlmatsum `lnfj' `h14' = `d14', eq(1,4) // h22 (xb xb) gen double `d22' = 0 if $ML_y1 == 0 replace `d22' = - `sval'^(-2) * (1 + (`rho' / `rtrho')^2 * `lamhge' * /// (`hge' + `lamhge')) if $ML_y1 == 1 mlmatsum `lnfj' `h22' = `d22', eq(2) // h23 (xb lnsval) gen double `d23' = 0 if $ML_y1 == 0 replace `d23' = `sval'^(-1) * (`rho' / `rtrho' * `lamhge' * (1 - `rho' /// / `rtrho' * `zval' * (`hge' + `lamhge')) - 2 * `zval') if $ML_y1 == 1 mlmatsum `lnfj' `h23' = `d23', eq(2,3) // h24 (xb athrho) gen double `d24' = 0 if $ML_y1 == 0 replace `d24' = `lamhge' / `sval' * `rtrho' * (`rho' / `rtrho' * /// ((`hge' + `lamhge') * (`zval' + `rho' / `rtrho' * `hge') - `rho' / /// `rtrho') - 1) if $ML_y1 == 1 mlmatsum `lnfj' `h24' = `d24', eq(2,4) // h33 (lnsval lnsval) gen double `d33' = 0 if $ML_y1 == 0 replace `d33' = `zval' * (`rho' / `rtrho' * `lamhge' * (1 - `rho' / /// `rtrho' * `zval' * (`hge' + `lamhge')) - 2 * `zval') if $ML_y1 == 1 mlmatsum `lnfj' `h33' = `d33', eq(3) // h34 (lnsval athrho) gen double `d34' = 0 if $ML_y1 == 0 replace `d34' = `zval' * `lamhge' * `rtrho'* (`rho' / `rtrho' * /// ((`hge' + `lamhge') * (`zval' + `rho' / `rtrho' * `hge') - `rho' / /// `rtrho') - 1) if $ML_y1 == 1 mlmatsum `lnfj' `h34' = `d34', eq(3,4) // h44 (athrho athrho) gen double `d44' = 0 if $ML_y1 == 0 replace `d44' = `lamhge' * (1 - `rho'^2) * ((1 + `rho'^2 / (1 - /// `rho'^2)) * `hge' - (`hge' + `lamhge') * (`zval' + `rho' / /// `rtrho' * `hge')^2) if $ML_y1 == 1 mlmatsum `lnfj' `h44' = `d44', eq(4) // Compose the Hessian mat `H' = (`h11',`h12',`h13',`h14') mat `H' = `H' \ ((`h12')',`h22',`h23',`h24') mat `H' = `H' \ ((`h13')',(`h23')',`h33',`h34') mat `H' = `H' \ ((`h14')',(`h24')',(`h34')',`h44') } end // Version 1.0.0 is an lf evaluator for the linear model with homoskedastic // selection errors // Version 1.1.0 is an lf2 evaluator (adding analytical gradient and hessian) // for both linear and exponential models with homoskedastic selection // errors