program define gmm_ivcloglog version 11 syntax varlist if [fweight iweight pweight], /// at(name) /// // This contains the parameter estimates y1(varname) /// y2(varlist) /// vhatname(string) /// order(integer) /// [ /// derivatives(varlist) /// // Must be optional because -gmm- presumably calls the moment evaluator program multiple times but does not request derivatives every time fakederivatives /// ] local num_endo : list sizeof y2 tokenize `varlist' // Get the names of the variables storing the residual functions * Reduced form equations ("first stage") forval i = 1/`num_endo' { local y2_`i' : word `i' of `y2' tempvar zp_`i' local mfeval_reduced`i' ``i'' matrix score double `zp_`i'' = `at' `if', eq(#`i') // Get projection qui replace `mfeval_reduced`i'' = `y2_`i'' - `zp_`i'' `if' // Gets returned as evaluated residual function } * Main equation ("second stage") moment functions except for CFs tempvar xb expxb local mfeval_main ``=`num_endo' + 1'' matrix score double `xb' = `at' `if', eq(#`=`num_endo' + 1') gen double `expxb' = exp(`xb') qui replace `mfeval_main' = cond(`y1', exp(`xb'-`expxb')/(-expm1(-`expxb')), -`expxb') `if' // These functions are "residual functions" (more specifically, the contribution of each observation). // Stata multiplies them with the instruments (specified for a given "residual equation") to get the moment functions. // Each residual function is used by Stata to create w moment functions, where w is the number of instruments for that residual function. // If no instruments are specified for a given residual function (like this section), then it directly becomes a moment function. * Calculate derivatives only if requested if "`derivatives'" == "" { exit } if ("`fakederivatives'" == "") { * Get the names of the variables storing the derivatives forval w = 1/`=(`num_endo' + 1)^2' { local d`w' : word `w' of `derivatives' } local c = 0 * First-stage residual function(s) forval eq = 1/`num_endo' { forval pg = 1/`=`eq' - 1' { // Note that loops do not run if the second number is less than the first local ++c replace `d`c'' = 0 `if' } local ++c replace `d`c'' = -1 `if' forval pg = 1/`=`num_endo' - `eq' + 1' { local ++c replace `d`c'' = 0 `if' } } * Second-stage residual function // Using expm1() rather than exp() - 1 is good practice to increase precision (though it won't matter much here) tempvar C_i gen double `C_i' = cond(`y1', /// `mfeval_main' * (expm1(`xb') + exp(-`expxb')) / expm1(-`expxb'), /// -`expxb') forval eq = 1/`num_endo' { // Get the needed rhos (coefficients on vhat powers) forval p = 1/`order' { scalar rho`eq'_`p' = `at'[1, colnumb(`at', "`y1': `vhatname'`eq'_`p'")] } } forval eq = 1/`num_endo' { forval p = 2/`order' { local temp`eq' "`temp`eq'' + rho`eq'_`p' * `vhatname'`eq'_`=`p' - 1'" } local resid`eq'_polyderiv "rho`eq'_1 `temp`eq''" local ++c replace `d`c'' = -`C_i' * (`resid`eq'_polyderiv') `if' } local ++c replace `d`c'' = `C_i' `if' // We must supply Stata with the derivatives of the residual functions, so there are // * // derivatives to supply, NOT // * } else { * Fake derivatives to hackily make -gmm- stop calculating the VCE local length : list sizeof derivatives forval w = 1/`length' { local d`w' : word `w' of `derivatives' replace `d`w'' = 0 } } end