*! 2.1.0 Stephen P. Jenkins and Fernando Rios-Avila, March 2026 ******************************************************************************** * Bivariate Mixed-Poisson Regression using Simulated Maximum Likelihood * Implementation of Munkin & Trivedi (1999). Simulated maximum likelihood * estimation of multivariate mixed-Poisson regression * models, with application. The Econometrics Journal 2, 29-48. * https://doi.org/10.1111/1368-423X.00019 * * evaluator function for MSL using sampling function ******************************************************************************** program define bimpoisson_lf version 15 args lnf xb_1 xb_2 /// Covariates ln_sig_1 ln_sig_2 /// sigma1 and sigma2 arho_s /// correlation qui: { local nsim = $nsim___ local antithetic = $antithetic___ local bias = $bias___ local rho_sf = $rho_sf___ // Rho in sampling function (default = 0) set rngstate $rngstate___ // For replication (if uniform draws) local sig_1 exp(`ln_sig_1' ) // Transformation of sigma and rho local sig_2 exp(`ln_sig_2' ) local rho tanh(`arho_s') tempvar p1 p2 tempvar f12 g12 tempvar e1 e2 v1 v2 tempvar local_lnf mu_1 mu_2 agg_lnf v1 v2 gen double `local_lnf' = 0 gen double `mu_1' = 0 gen double `mu_2' = 0 gen double `agg_lnf' = 0 gen double `f12' = . gen double `g12' = . // Other needed variables tempvar r1 r2 gen double `r1' = . gen double `r2' = . gen double `e1' = . gen double `e2' = . gen double `v1' = . gen double `v2' = . *gen double `v1' = . *gen double `v2' = . gen double `p1' = . gen double `p2' = . local S = `nsim' local h = 0 if `antithetic' == 0 local SS = `S' if `antithetic' == 1 local SS = `S'*2 tempvar px1 gen double `px1' = . forvalues s = 1/`S' { // First get random draws for two normals via Halton/uniform draws // They have same varnames (but different values) // so don't need to distinguish below in defining `r1', `r2' if `antithetic' == 0 { local h = `h' + 1 replace `v1' = invnormal(${dr1_`s'__}) replace `v2' = (`rho_sf')*`v1' /// + sqrt(1-(`rho_sf')^2)*invnormal(${dr2_`s'__}) replace `e1' = `sig_1'*`v1' replace `e2' = `sig_2'*`v2' // Obtained standardized versions *replace `v1' = `e1'/`sig_1' *replace `v2' = `e2'/`sig_2' // get the density g(e1,e2) replace `g12'= -ln(2*_pi*`sig_1'*`sig_2'*sqrt(1-(`rho_sf')^2)) + /// -(1/(2*(1-(`rho_sf')^2))) * ( `v1'^2 - 2*(`rho_sf')*`v1'*`v2'+`v2'^2 ) // get other components replace `mu_1' = exp(`xb_1'+`e1') replace `mu_2' = exp(`xb_2'+`e2') // Individual Proabilities replace `p1' = $ML_y1 * ln(`mu_1') - `mu_1' - lngamma($ML_y1+1) replace `p2' = $ML_y2 * ln(`mu_2') - `mu_2' - lngamma($ML_y2+1) // Joint density replace `f12'= -ln(2*_pi*`sig_1'*`sig_2'*sqrt(1-(`rho')^2)) + /// -(1/(2*(1-(`rho')^2))) * ( `v1'^2 - 2*(`rho')*`v1'*`v2'+`v2'^2 ) // Putting it all together replace `local_lnf' = exp(`p1')*exp(`p2')*exp(`f12'-`g12') if `bias' == 1 { tempvar f12_`h' gen double `f12_`h'' = exp(`p1')*exp(`p2')*exp(`f12'-`g12') } replace `agg_lnf' = `agg_lnf' + `local_lnf' } if `antithetic' == 1 { forvalues j = 1/2 { local h = `h' + 1 if `j' == 1 { replace `v1' = invnormal(${dr1_`s'__}) replace `v2' = (`rho_sf')*`v1' /// + sqrt(1-(`rho_sf')^2)*invnormal(${dr2_`s'__}) replace `e1'=`sig_1'*`v1' replace `e2'=`sig_2'*`v2' } else if `j' == 2 { replace `v1' = invnormal(1 - ${dr1_`s'__}) replace `v2' = (`rho_sf')*`v1' /// + sqrt(1-(`rho_sf')^2)*invnormal(1 - ${dr2_`s'__}) replace `e1'=`sig_1'*`v1' replace `e2'=`sig_2'*`v2' } // Obtained standardized versions // get the density replace `g12'= -ln(2*_pi*`sig_1'*`sig_2'*sqrt(1-(`rho_sf')^2)) + /// -(1/(2*(1-(`rho_sf')^2))) * ( `v1'^2 - 2*(`rho_sf')*`v1'*`v2'+`v2'^2 ) // get other components replace `mu_1' = exp(`xb_1'+`e1') replace `mu_2' = exp(`xb_2'+`e2') // Individual probabilities replace `p1' = $ML_y1 * ln(`mu_1') - `mu_1' - lngamma($ML_y1+1) replace `p2' = $ML_y2 * ln(`mu_2') - `mu_2' - lngamma($ML_y2+1) // Joint density replace `f12'= -ln(2*_pi*`sig_1'*`sig_2'*sqrt(1-(`rho')^2)) + /// -(1/(2*(1-(`rho')^2))) * (`v1'^2 - 2*(`rho')*`v1'*`v2'+`v2'^2 ) // Putting it all together replace `local_lnf' = exp(`p1')*exp(`p2')*exp(`f12'-`g12') if `bias' == 1 { tempvar f12_`h' gen double `f12_`h''= exp(`p1')*exp(`p2')*exp(`f12'-`g12') } replace `agg_lnf' = `agg_lnf' + `local_lnf' } } local SS = `S'* (2^`antithetic') } if `bias' == 1 { tempvar lnf2 gen double `lnf2' = 0 forvalues s = 1/`SS' { replace `lnf2' = `lnf2' + (`f12_`s'' - `agg_lnf'/`SS')^2 } replace `lnf2' = `lnf2'/(`agg_lnf')^2 replace `lnf' = log(`agg_lnf'/`SS') + 0.5*`lnf2' } else replace `lnf' = log(`agg_lnf'/`SS') } end