*! Author: Alfonso Miranda (alfonso.miranda@cide.edu) *! Center for Economic and Teaching Research (CIDE) *! This version 7/03/2013 program define lcmc_ll version 10.1 args todo b lnf g NegH tempvar xb1 xb2 xb3 xb4 last group vartype edv mcvar yvar selvar #delimit ; tempname lambda_1 lambda_2 lambda_3 /* 6 + ncuts equations */ sigma_y thetaM kappaM lambdaM Vf lf bmv hvec; #delimit cr local Vs `Vf' local xb `xb1' `xb2' `xb3' local xbplus `xb1' `xb2' `xb3' `xb4' local ncuts=$S_ncuts local ncats=$S_ncats local nex1 =$S_snex1 local nex2 =$S_snex2 local nex3 =$S_snex3 local nscores = 6 + `ncats' + `ncuts' local scale =$S_scale local theta "" forval x = 1/`ncats' { tempname theta`x' local theta "`theta' `theta`x''" } local kappa "" forval x = 1/`ncuts' { tempname kappa`x' local kappa "`kappa' `kappa`x''" } local lambda `lambda_1' `lambda_2' `lambda_3' local sigma_y `sigma_y' local id "$S_id" local rep "$S_rep" local endogvs "$S_endogvs" local method "$S_method" local samp "$ML_samp" local vartype "$S_vartype" local resp "$S_resp" local Nyvar = $S_sNyvar local k = 0 scalar `lf' = . foreach v in `xb' { mleval `v' = `b', eq(`++k') } foreach v in `theta' { mleval `v' = `b', scalar eq(`++k') } foreach v in `kappa' { mleval `v' = `b', scalar eq(`++k') } foreach v in `lambda' { mleval `v' = `b', scalar eq(`++k') } foreach v in `sigma_y' { scalar `v' = `scale' } qui sort $S_id $S_vartype qui gen `selvar'=cond(`vartype'==1,1,0) qui gen `yvar'=cond(`vartype'==2,1,0) qui gen `mcvar'=cond(`vartype'==3,1,0) qui sort $S_id qui by $S_id : gen `last' = cond(_n==_N,1,0) qui by $S_id: gen `group' = (_n==2) qui by $S_id: replace `group' = 1 if _n==3 qui { by $S_id: replace `xb1'=. if `selvar'==0 & `samp' by $S_id: replace `xb2'=. if `yvar'==0 & `samp' by $S_id: replace `xb3'=. if `mcvar'==0 & `samp' } /* ensure thetas are acceptable */ if ($S_threstr == 1) { local flag = 0 forval x = 2/`ncats' { local j = `x' - 1 local flag = cond(`theta`x'' > `theta`j'',0,1) } if (`flag'==1) { scalar `lnf'=. matrix `g' = J(1,colsof(`b'),.) matrix `NegH' = J(colsof(`b'),colsof(`b'),.) exit } } /* generate prediction for missing covariate in whole data using current values of coeff. */ mat `bmv' = `b'[1,(`nex1'+`nex2'+1)..(`nex1'+`nex2'+`nex3')] mat score double `xb4' = `bmv' /* prepare input matrices */ mat `lambdaM' =(`lambda_1',`lambda_2', `lambda_3') mat `Vf' = (`sigma_y') *mat Vf=. mat `thetaM' = (`theta1') forval x = 2/`ncats' { mat `thetaM' = (`thetaM', `theta`x'') } mat `kappaM' = (`kappa1') forval x = 2/`ncuts' { mat `kappaM' = (`kappaM', `kappa`x'') } /* prepare variables for scores */ local D "" forval i=1/`nscores' { tempvar d`i' local D "`D' `d`i''" qui gen double `d`i'' = . } /* matrix hvec */ mat `hvec' = ($S_hv_1, $S_hv_2, $S_hv_3, $S_hv_4) /* calculate log-likelihood */ tempvar pr qui gen double `pr' = . #delimit ; mata: mcvop_32_v2d1("xbplus","resp","endogvs","vartype","`lambdaM'","`thetaM'","`kappaM'","id", "Vs",`Nyvar',`method',`rep',"`hvec'","`pr'","`D'",`scale',"`samp'"); #delimit cr qui replace `pr' = log(`pr') if `samp' mlsum `lnf' = `pr' if `last' & `samp' if (`todo'==0 | `lnf'>=.) { matrix `g' = J(1,colsof(`b'),.) matrix `NegH' = J(colsof(`b'),colsof(`b'),.) exit } /* Calculate the scores at equation level and feed them to Stata */ tempvar g1 g2 g3 mlvecsum `lnf' `g1' = `d1' if `selvar'==1, eq(1) /* equations */ mlvecsum `lnf' `g2' = `d2' if `yvar'==1, eq(2) mlvecsum `lnf' `g3' = `d3' if `last'==1, eq(3) local j = 3 + `ncats' forval i = 4/`j' { tempvar g`i' mlvecsum `lnf' `g`i'' = `d`i'' if `yvar'==1, eq(`i') /* theta */ } local k = `j' + 1 local j = `j' + `ncuts' forval i = `k'/`j' { tempvar g`i' mlvecsum `lnf' `g`i'' = `d`i'' if `last'==1, eq(`i') /* kappa */ } local k_1 = `j' + 1 local k_2 = `j' + 2 local h = `j' + 3 tempvar g`k_1' g`k_2' g`h' mlvecsum `lnf' `g`k_1'' = `d`k_1'' if `yvar'==1, eq(`k_1') /* lambdas */ mlvecsum `lnf' `g`k_2'' = `d`k_2'' if `selvar'==1, eq(`k_2') mlvecsum `lnf' `g`h'' = `d`h'' if `selvar'==1, eq(`h') /* deliver matrix of first derivatives */ matrix `g' = (`g1',`g2',`g3') forval i = 4/`h' { matrix `g' = (`g',`g`i'') } /* Obtain the scores at variable level to calculate OPG approx to Variance */ local scores "" /* calculate scores eqn 1 */ local scores_x_1 "" local i = 1 foreach var of global S_x_1 { tempvar scores_x_1_`i' by $S_id: gen double `scores_x_1_`i'' = sum(`d1'*`var') if `samp' local scores_x_1 "`scores_x_1' `scores_x_1_`i''" local i = `i' + 1 } if $S_sncselvar == 1 { local i = `i' + 1 tempvar scores_x_1_`i' by $S_id: gen double `scores_x_1_`i'' = sum(`d1') if `samp' local scores_x_1 "`scores_x_1' `scores_x_1_`i''" } local scores "`scores' `scores_x_1'" /* calculate scores eqn 2 */ local scores_x_2 "" local i = 1 foreach var of global S_x_2 { tempvar scores_x_2_`i' by $S_id: gen double `scores_x_2_`i'' = sum(`d2'*`var') if `samp' local scores_x_2 "`scores_x_2' `scores_x_2_`i''" local i = `i' + 1 } local scores "`scores' `scores_x_2'" /* calculate scores eqn 3 */ local scores_x_3 "" local i = 1 foreach var of global S_x_3 { tempvar scores_x_3_`i' by $S_id: gen double `scores_x_3_`i'' = sum(`d3'*`var') if `samp' local scores_x_3 "`scores_x_3' `scores_x_3_`i''" local i = `i' + 1 } local scores "`scores' `scores_x_3'" /* calculate scores theta */ local scores_theta "" local j = 3 + `ncats' local bb = 1 forval i = 4/`j' { tempvar score_theta_`bb' by $S_id: gen double `score_theta_`bb'' = sum(`d`i'') if `samp' local scores_theta "`scores_theta' `score_theta_`bb''" local bb = `bb' + 1 } local scores "`scores' `scores_theta'" /* calculate scores kappas */ local scores_kappa "" local bb = 1 local k = `j' + 1 local j = `j' + `ncuts' forval i = `k'/`j' { tempvar score_kappa_`bb' by $S_id: gen double `score_kappa_`bb'' = sum(`d`i'') if `samp' local scores_kappa "`scores_kappa' `score_kappa_`bb''" local bb = `bb' + 1 } local scores "`scores' `scores_kappa'" /* lambdas */ tempvar score_lambda_1 score_lambda_2 score_lambda_3 by $S_id: gen double `score_lambda_1' = sum(`d`k_1'') if `samp' by $S_id: gen double `score_lambda_2' = sum(`d`k_2'') if `samp' by $S_id: gen double `score_lambda_3' = sum(`d`h'') if `samp' local scores "`scores' `score_lambda_1' `score_lambda_2' `score_lambda_3' " /* Keep the scores for future use */ local i = 1 tokenize $S_snames foreach var of local scores { qui replace `1' = `var' if `samp' mac shift } if (`todo'==1 | `lnf'>=.) exit /* Calculate OPG covariance matrix */ tempvar tus gen `tus' = (`last'==1 & `samp'==1) mata: OPG("scores","tus","`NegH'") end