*! nehurdle_tobit v1.1.0 *! 29 June 2018 *! Alfonso Sanchez-Penalver *! Version history at the bottom. /******************************************************************************* * ML lf2 evaluator for homoskedastic and heteroskedastic Tobit, both linear * * and exponential. * *******************************************************************************/ capture program drop nehurdle_tobit program nehurdle_tobit version 11 args todo b lnfj g1 g2 H quietly { // Setting the censoring point and conditions, depending on whether it // is linear or exponential. The macro $neh_method should be set in // nehurdle.ado. tempname gamma if "$neh_method" == "linear" { scalar `gamma' = 0 local lcond "$ML_y1 <= 0" local rcond "$ML_y1 > 0" } else { sum $ML_y1, mean scalar `gamma' = r(min) - 1e-7 local lcond "missing($ML_y1)" local rcond "!missing($ML_y1)" } // Get the values of the parameters tempvar xb z lnsigma sigma mleval `xb' = `b', eq(1) mleval `lnsigma' = `b', eq(2) gen double `sigma' = exp(`lnsigma') gen double `z' = (`xb' - `gamma') / `sigma' // Log-Likelihood replace `lnfj' = lnnormal(- `z') if `lcond' replace `lnfj' = lnnormalden(($ML_y1 - `xb') / `sigma') - `lnsigma' /// if `rcond' if "$neh_method" == "exponential" /// replace `lnfj' = `lnfj' - $ML_y1 if `rcond' if (`todo' == 0) exit tempvar lambda gen double `lambda' = normalden(`z') / normal(- `z') // Gradient // g1 (xb) replace `g1' = - `lambda' * `sigma'^(-1) if `lcond' replace `g1' = ($ML_y1 - `xb') / (`sigma'^2) if `rcond' // g2 (lnsigma) replace `g2' = `lambda' * `z' if `lcond' replace `g2' = (($ML_y1 - `xb') / `sigma')^2 - 1 if `rcond' if (`todo' == 1) exit // Hessian // There are 2 equations so we need to compute 3 elements for the Hessian tempvar d11 d12 d22 tempname h11 h12 h22 // h11 (xb xb) gen double `d11' = `sigma'^(-2) * `lambda' * (`z' - `lambda') if `lcond' replace `d11' = - `sigma'^(-2) if `rcond' mlmatsum `lnfj' `h11' = `d11', eq(1) // h12 (xb lnsigma) gen double `d12' = `sigma'^(-1) * `lambda' * (1 - `z' * (`z' - /// `lambda')) if `lcond' replace `d12' = - 2 * ($ML_y1 - `xb') / (`sigma'^2) if `rcond' mlmatsum `lnfj' `h12' = `d12', eq(1,2) // h22 (lnsigma lnsigma) gen double `d22' = `z' * `lambda' * (`z' * (`z' - `lambda') - 1) /// if `lcond' replace `d22' = - 2 * (($ML_y1 - `xb') / `sigma')^2 if `rcond' mlmatsum `lnfj' `h22' = `d22', eq(2) mat `H' = (`h11',`h12') mat `H' = `H' \ ((`h12')', `h22') } end // Version 1.0.0 is an lf evaluator for only linear models // Version 1.1.0 is an lf2 evaluator (adding analytical gradient and hessian) // for both linear and exponential models