*! version 1.1.0 10apr2022 /* by Pascal Erhardt & Martin Biewen, University of Tuebingen */ program define arhomme, eclass byable(recall) version 16 syntax varlist(min=2 numeric) [if] [in] [pweight/], SELect(string) [RHOpoints(integer 19) /// TAUpoints(integer 3) /// REPetitions(integer 100) /// SUBsample(string) /// INSTRument(varname numeric) /// COPulaparameter(varname numeric) /// MESHsize(real 1) /// CENTergrid(real 0) /// Quantiles(numlist >0 <1 ascending max=100) /// GAUssian FRAnk PLACKett JOEma GRAph NOSTDerrors /// OUTput(string) FAILfraction(real 0.3)] if ("`copulaparameter'" != "") { qui sum `copulaparameter' local copmax = `r(max)' local copmin = `r(min)' } cmd_in `0' /* call the optional input interpreter */ /* define copula */ if (`r(fra)' + `r(gau)' + `r(plack)' + `r(joe)' == 0) { local copula "frank" // frank is default } else if (`r(fra)' + `r(gau)' + `r(plack)' + `r(joe)' > 1) { display as error "options {bf:frank}, {bf:gaussian}, {bf:plackett}, and {bf:joema} are mutually exclusive" exit 198 } else { local copula `frank'`gaussian'`plackett'`joema' } /* restrict RHOpoints & TAUpoints >0 & REPetitions >= 0 & MESHsize >0 */ if (`rhopoints' < 1) { display as error "{p}{bf:rhopoints(`rhopoints')} must be a positive " /// "integer{p_end}" exit 198 } if (`taupoints' < 1) { display as error "{p}{bf:taupoints(`taupoints')} must be a positive " /// "integer{p_end}" exit 198 } if (`meshsize' <= 0) { display as error "{p}{bf:meshsize(`meshsize')} must be strictly positive{p_end}" exit 198 } else if ("`copula'"=="gaussian" & `meshsize'>1) { display as error "{p}{bf:meshsize(`meshsize')} must not exceed 1 when " /// "option {bf:gaussian} is chosen{p_end}" exit 198 } if ("`copula'" == "gaussian" & (`centergrid' <= -1 | `centergrid' >= 1) ) { display as error "{p}{bf:centergrid(`centergrid')} is restricted " /// " to ]-1,1[ with option {bf:gaussian}{p_end}" exit 198 } else if (`r(plack)' + `r(joe)' > 0 & `centergrid' < 0) { display as error "{p}{bf:centergrid(`centergrid')} must be a positive" /// " real number when choosing option {bf:plackett} or {bf:joema}{p_end}" exit 198 } if (`r(plack)' + `r(joe)' > 0 & `r(cent)' == 0) { /* set new default for plackett & joe copulae */ local centergrid = 1 } if (`r(nostd)' + `r(rep)' > 1) { //("`nostderrors'" != "" & "`repetitions'" != "") { display as error "options {bf:nostderrors} and {bf:repetitions} are mutually exclusive" exit 198 } else if (`r(nostd)' + `r(sub)' > 1) { //( "`nostderrors'" != "" & "`subsample'" != "") { display as error "options {bf:nostderrors} and {bf:subsample} are mutually exclusive" exit 198 } else if (`r(nostd)' + `r(fail)' > 1) { display as error "options {bf:nostderrors} and {bf:failfraction} are mutually exclusive" exit 198 } if (`repetitions' < 2) { display as error "{bf:repetitions(`repetitions')} must be an integer greater than 1" exit 198 } if ((`failfraction' < 0) | (`failfraction' > 1)) { display as error "{bf:failfraction(`failfraction')} must not be outside the unit interval" exit 198 } if (`r(sub)' == 1) { /* default defined later */ local n_substr: word count `subsample' if (`n_substr' != 1) { display as error "too many input arguments for option {bf:subsample(`subsample')}" exit 198 } capture confirm integer number `subsample' if (_rc != 0){ display as error "{bf:subsample(`subsample')} must be a positive integer" exit 198 } } if (`r(cop)' == 1) { if (`r(nostd)' == 0) { di as error "option {bf:copulaparameter} must be chosen with option {bf:nostderrors}" exit 198 } else if (`r(mesh)' + `r(cent)' + `r(rho)' + `r(tau)' + `r(gra)' + `r(instr)' > 0) { di as error "{p}options {bf:meshsize}, {bf:centergird}, {bf:rhopoints}," /// " {bf:taupoints}, {bf:graph}, and {bf:instrument} are not allowed when " /// " {bf:copulaparameter(`copulaparameter')} is defined{p_end}" exit 198 } else if (`r(gau)' == 1 & (`copmax' >= 1 | `copmin' <= -1) ) { di as error "{p}{bf:copulaparameter(`copulaparameter')} is restricted to ]-1,1[" /// " when {bf:gaussian} copula is chosen{p_end}" exit 198 } else if (`r(plack)' + `r(joe)' > 0 & `copmin' <= 0) { di as error "{p}{bf:copulaparameter(`copulaparameter')} is restricted to the postive" /// " real line when {bf:plackett} or {bf:joema} copula is chosen{p_end}" exit 198 } } if (`r(out)' + `r(nostd)' > 1) { di as error "options {bf:nostderrors} and {bf:output} are mutually exclusive" exit 198 } if (`r(out)' > 0) { local num_outp: word count `output' if (`num_outp' > 2) { di as error "too many input arguments for option {bf:output(`output')}" exit 198 } else { tokenize `output' local out_normal = ("`1'" == "normal") + ("`2'" == "normal") local out_bootstrap = ("`1'" == "bootstrap") + ("`2'" == "bootstrap") local out_check = `out_normal' + `out_bootstrap' + ("`1'" == "`2'") local 1 "" local 2 "" if (`out_check' != `num_outp') { di as error "no valid input argument for option {bf:output(`output')}" exit 198 } } } else { /* define output default */ local out_normal = 1 } local num_vlist: word count `varlist' gettoken depvar indepvar : varlist tempvar seldep /* allow = after depvar in selection equation */ tokenize `select', parse("=") if ("`1'" == "=") { /* allow binary response to be missing */ qui gen byte `seldep' = 0 qui replace `seldep' = 1 if `depvar' !=. /* build the binary response */ gettoken eq_sign selreg : select } else if ("`2'" == "=") { /* case where binary response and selection regressors are seperated by '=' */ local biname `1' qui gen byte `seldep' = . qui replace `seldep' = 0 if `1' == 0 qui replace `seldep' = 1 if `1' != 0 local selreg `3' } else { /* case where no '=' was typed */ qui gen byte `seldep' = 0 qui replace `seldep' = 1 if `depvar' !=. /* build the binary response */ local selreg `select' } tempvar touse probuse tempname sN N /* marker for conditional quantile regression */ mark `touse' `if' `in' markout `touse' `seldep' `selreg' `varlist' qui replace `touse' = 0 if `seldep' == 0 /* markout selected individuals */ /* marker for selection equation */ mark `probuse' `if' `in' markout `probuse' `seldep' `selreg' `indepvar' qui replace `probuse' = 0 if `depvar'==. & `seldep'==1 /* remove all observations where dependent variable is missing despite no selection */ capture confirm variable `instrument' if (_rc == 0) { // remove missings in user-specified instrument (if existent) markout `touse' `instrument' markout `probuse' `instrument' } capture confirm variable `copulaparameter' if (_rc == 0) { // remove any missings in user-specified copula parameters (if existen) markout `touse' `copulaparameter' markout `probuse' `copulaparameter' } qui sum `touse' sca `sN' = `r(sum)' qui sum `probuse' sca `N' = `r(sum)' local nobs = `r(sum)' qui sum `seldep' if `probuse' if `r(N)' == `r(sum)' { di in red "Dependent variable never censored because of selection: " di in red "model reduces to conditional quantile regression" exit 498 } local num_sel: word count `selreg' if ("`subsample'" == "" & "`nostderrors'" == "") { /* now define default */ local subsample = `nobs' /* if subsample size is left unspecified bootstrap is applied */ display _newline(1) as text "{p}option {bf:subsample} left unspecified: " /// "{bf:subsample} automatically set to `subsample' (bootstrap){p_end}" display as text "use option {bf:nostderrors} to disable estimation of covariance matrix" } else if ("`subsample'" != "") { if (`subsample' <= `num_sel' | `subsample' < `num_vlist') { display as error "{p}{bf:subsample(`subsample')} must contain at least " /// "as many observations as regressors{p_end}" exit 198 } else if (`subsample' > `nobs') { display _newline(1) as text "{bf:subsample(`subsample')} exceeds effective size of dataset: " display as text "{bf:subsample} automatically set to `nobs'" local subsample = `nobs' } } /* remove collinear quantile regressors */ _rmcoll `indepvar' if `touse', forcedrop local indepvar "`r(varlist)'" /* remove collinearity in selection regressors _rmcoll `selreg' if `probuse' //, forcedrop local selreg "`r(varlist)'" */ tempvar wght if ("`weight'" != "") { qui sum `exp' if `probuse' qui gen `wght'=`exp'/`r(mean)' /* rescale weights */ } else { qui gen `wght' = 1 } /* perform first stage of Arellano Bonhomme estimation*/ tempvar zgamma tempname gammaCov gamma objvec rhovec minFval rho bvec COVmat subsize kendall spearman blomqvist actreps Vrho pvals b_betas s_betas cbands quietly { probit `seldep' `selreg' if `probuse' [pw=`wght'] predict double `zgamma' if `probuse', xb mat `gamma' = get(_b) mat `gammaCov' = get(VCE) local probnames: colnames `gamma' // local probeq: coleq `gamma' } if (`e(converged)' == 1) { /* inform user about probit estimation */ di _newline(1) as text "First step estimation (probit model) successfully completed." } else { di as error "probit model did not converge" exit 430 } if ("`instrument'" == "") { /* if option instrument is left unspecified */ tempname instrument qui gen `instrument' = normal(`zgamma') } tempname quant /* process quantile input */ if ("`quantiles'" == "") { // set default quantiles local nq = 9 mat `quant' = (.\.1\.2\.3\.4\.5\.6\.7\.8\.9) local quantiles = ".1 .2 .3 .4 .5 .6 .7 .8 .9" forvalues i = 1/`nq' { local temp_q = abbrev("`i'_quantile",11) local coef_eq = "`coef_eq'" + `num_vlist'*".`temp_q' " } } else { // user specific quantiles local nq : word count `quantiles' mat `quant' =. forvalues i = 1/`nq' { local temp_q: word `i' of `quantiles' mat `quant' = (`quant'\ `temp_q') local temp_q = abbrev("`temp_q'_quantile",11) local coef_eq = "`coef_eq' " + `num_vlist'*".`temp_q' " } } if ("`biname'" == "") { /* binary response equation names */ local biname "select" local probeq = (`num_sel' + 1)*"`biname' " } else { local probeq = (`num_sel' + 1)*"`biname' " } if ("`copulaparameter'" == "") { mata: heavylift_7355("`varlist'", /// "`gamma'", /// "`zgamma'", /// "`copula'", /// `taupoints', /// `rhopoints', /// `nq', /// "`quant'", /// "`touse'", /// "`objvec'", /// "`rhovec'", /// "`minFval'", /// "`rho'", /// "`bvec'", /// "`wght'", /// "`spearman'", /// "`kendall'", /// "`blomqvist'", /// `meshsize', /// `centergrid', /// "`instrument'") local clist = `nq'*"_cons `indepvar' " + "rho" local coef_list = "`probnames' " + "`clist'" local ceq = "`coef_eq' " + "_anc" local coef_eq = "`probeq' " + "`coef_eq' " + "_anc" matrix colnames `bvec' = `coef_list' matrix coleq `bvec' = `coef_eq' } else { di _newline(1) as txt "{p}note: second step estimation redundant because copula parameter" /// " already defined as {bf:copulaparameter(`copulaparameter')}{p_end}" mata: main_fct2("`varlist'", /// "`gamma'", /// "`zgamma'", /// "`copula'", /// `nq', /// "`quant'", /// "`touse'", /// "`bvec'", /// "`wght'", /// "`copulaparameter'") local coef_list = "`probnames' " + `nq'*"_cons `indepvar' " local coef_eq = "`probeq' " + "`coef_eq' " matrix colnames `bvec' = `coef_list' matrix coleq `bvec' = `coef_eq' } if ("`nostderrors'" == "") { mata: std_erf("`varlist'", /// "`gamma'", /// "`copula'", /// `taupoints', /// `rhopoints', /// `nq', /// "`quant'", /// "`touse'", /// "`probuse'", /// "`seldep'", /// "`selreg'", /// "`COVmat'", /// `subsample', /// `repetitions', /// "`gammaCov'", /// "`subsize'", /// "`wght'", /// `meshsize', /// `centergrid', /// "`bvec'", /// "`instrument'", /// "`actreps'", /// "`Vrho'", /// "`pvals'", /// "`b_betas'", /// "`s_betas'", /// "`cbands'", /// `failfraction') } di _newline(3) as text "{hline 78}" di as text "{bf:Arellano & Bonhomme (2017)} selection model" di as text "(conditional quantile regression with sample selection)" di as text "{hline 78}" if ("`nostderrors'" != "") { ereturn post `bvec', depname("`depvar'") esample(`probuse') } else { matrix rownames `COVmat' = `coef_list' matrix colnames `COVmat' = `coef_list' matrix roweq `COVmat' = `coef_eq' matrix coleq `COVmat' = `coef_eq' matrix colnames `cbands' = "2.5%" "97.5%" matrix rownames `cbands' = `clist' matrix rownames `b_betas' = `clist' matrix rownames `s_betas' = `clist' matrix rownames `pvals' = `clist' matrix roweq `cbands' = `ceq' matrix roweq `b_betas' = `ceq' matrix roweq `s_betas' = `ceq' matrix roweq `pvals' = `ceq' matrix colnames `pvals' = "P>|z-H_0|" ereturn post `bvec' `COVmat', depname("`depvar'") esample(`probuse') } ereturn scalar sN = `sN' ereturn scalar N = `N' if ("`copulaparameter'" == "") { ereturn scalar rho = `rho' ereturn scalar minFval = `minFval' ereturn scalar rhopts = `rhopoints' ereturn scalar taupts = `taupoints' ereturn scalar meshsize = `meshsize' ereturn scalar spearman = `spearman' ereturn scalar kendall = `kendall' ereturn scalar blomqvist = `blomqvist' } di as text _col(50) "Number of obs. = " as result %10.0gc e(N) di as text _col(50) "Num. of selected = " as result %10.0gc e(sN) if ("`copulaparameter'" == "") { di as text _col(50) "Rho points = " as result %10.0gc e(rhopts) di as text _col(50) "Tau points = " as result %10.0gc e(taupts) di as text _col(50) "Meshsize = " as result %10.4fc e(meshsize) di as text _col(50) "Spearman's rho = " as result %10.4fc e(spearman) di as text _col(50) "Kendall's tau = " as result %10.4fc e(kendall) di as text _col(50) "Blomqvist's beta = " as result %10.4fc e(blomqvist) di as text _col(50) "Minimum Fval = " %10.7e as result e(minFval) if ("`nostderrors'" == "") { ereturn scalar subsample = `subsample' ereturn scalar repetitions = `actreps' ereturn scalar Vrho = `Vrho' ereturn scalar failfrac = `failfraction' ereturn matrix pvals = `pvals' ereturn matrix bbetas = `b_betas' ereturn matrix sbetas = `s_betas' ereturn matrix confivals = `cbands' di as text _col(50) "Replications = " %10.0gc as result e(repetitions) di as text _col(50) "Subsample Size = " %10.0gc as result e(subsample) } } if ("`out_normal'" == "1") { if (("`copula'" == "plackett" | "`copula'" == "joema") & ("`nostderrors'" == "")){ local neq = `nq' + 1 ereturn display, neq(`neq') nolstretch plus /* placket and joema copula parameters not normally distributed under H0 rho=0 */ qui test [_anc]rho = 1 local stdrho = sqrt(`e(Vrho)') local trho = (`e(rho)'-1)/`stdrho' local ub = `e(rho)' + invnormal(.975)*`stdrho' local lb = `e(rho)' - invnormal(.975)*`stdrho' di as text _col(14) "{c |}" _col(21) "Coef. Std. Err. rho=1 p_val [95% Conf. Interval]" di as text "{hline 13}{c +}{hline 64}" di as text "{bf:_anc}" _col(14) "{c |}" di as text _col(10) "rho" _col(14) "{c |} " as result %9.8g e(rho) _col(28) %9.8g `stdrho' _col(40) %6.2f `trho' _col(49) %4.3f `r(p)' _col(58) %9.8g `lb' " " %9.8g `ub' di as text "{hline 13}{c BT}{hline 64}" } else { ereturn display, nolstretch } } if ("`out_bootstrap'" == "1") { qui ereturn display cmd_out ,dep("`depvar'") regs("`indepvar'") seldep("`biname'") selreg("`selreg'") nsel(`num_sel') beta("e(b)") cov("e(V)") nq(`nq') nvar(`num_vlist') quant("`quant'") pvals("e(pvals)") conf("e(confivals)") cop("`copula'") } di as text "note: parameter estimates based on `copula' copula model" if ("`nostderrors'" == "") { if (`actreps' != `repetitions') { local fsubs = `repetitions' - `actreps' local plu = plural(`fsubs',"subsample") local failp = 100*`failfraction' di _newline in red "`fsubs' `plu' had to be discarded because of failed convergence" di as text "remember: a maximum of `failp'% of subsamples are replaced" di as text "you may wish to increase {bf:subsample(`subsample')} or {bf:failfraction(`failfraction')}" } } /* check whether graph was requested */ if ("`graph'" != "") { _matplot (`objvec', `rhovec'), nonames ytitle("Objective function") xtitle("rho") } ereturn local cmdline `"`0'"' ereturn local cmd "arhomme" ereturn local instrument `"`instrument'"' ereturn local cparameter `"`copulaparameter'"' end mata: /* =============================================================================== *** This section replicates rq.m by D. Morillo, R. Koenker & P. Eilers. Note that the subroutines below are in opposite order compared to rq.m To perform a quantile regression call rq_fnm('Regressors X as (n x k) matrix', 'Dependent Variable y as (n x 1) vector', 'Quantile p as scalar or (n x 1) vector') from your main code. --IMPORTANT-- p must not contain any elements that are (numerically) zero[one] for Stata. Thus, set all elements of p smaller[larger] than 5*epsilon(1)[1-5*epsilon(1)] to 5*epsilon(1)[1-5*epsilon(1)] beforehand. Otherwise this algorithm may break down. The tolerance level and maximum amount of iterations are set to 1e-5 and 100, respectively. Both may be altered manually in lp_fnm. *** =============================================================================== */ real matrix bound(numeric matrix x, numeric matrix dx) { /* =============================================================================== *** Fill vector with allowed step lengths Support function for lp_fnm *** =============================================================================== */ real vector b, f b = 1e20 :+ 0* x // define b either as column or row vector (depending on what x itself is) f = selectindex(dx:<0) // now get the index of all negative elements b[f] = -x[f] :/ dx[f] // then alter all negative elements return(b) // end of bound routine } real rowvector lp_fnm(numeric matrix A, real rowvector c, real colvector b, real colvector u, real colvector x) { /* =============================================================================== *** Solve a linear program by the interior point method: min(c * u), s.t. A * x = b and 0 < x < u An initial feasible solution has to be provided as x Function lp_fnm of Daniel Morillo & Roger Koenker Found at: http://www.econ.uiuc.edu/~roger/rqn/rq.ox Translated from Ox to Matlab by Paul Eilers 1999 Modified slightly by Roger Koenker, April, 2001. Translated from Matlab to Stata by Pascal Erhardt, October, 2019 *** for the remainder n denotes the sample size, k the number of regressors A is k x n c is 1 x n b is k x 1 u is n x 1 x is n x 1 =============================================================================== */ real vector s, y, r, z, w, q, rhs, dy, dx, dz, dw, fx, fs, fw, fz, dxdz, dsdw, xinv, sinv, xi real matrix AQA //, AQ real scalar beta, small, max_it, n, gap, mu, g //, k // Set some constants beta = 0.9995 small = 1e-5 max_it = 100 n = cols(A) //k = rows(A) // Generate initial feasible point s = u - x // n x 1 y = (qrsolve(A',c'))' // 1 x k -->> approximate a system of linear equations where n > k r = c - y*A // 1 x n -->> r = -1* regression error z = r :* (r:>0) // 1 x n w = z - r // 1 x n //Tau = s // weight of absolut sum //check = colsum( (Tau - (-r':<=0)):*(-r') ) // calculates the value of the check function, i.e. sum of abs. weighted deviations gap = c*x - y*b + w*u // 1 x 1 // Start iterations it = 0 while (gap > small & it < max_it) { it = it +1 // Compute affine step q = 1 :/ ((z' :/ x) + (w' :/ s)) // n x 1 r = z - w // 1 x n //Q = diag(q) // no sparse option available /* AQ = J(k,n,0) for (i=1;i<=n;i++) { for (j=1;j<=k;j++) { AQ[j,i] = q[i,1]*A[j,i] } } AQA = AQ * A' // k x k */ AQA = cross(A',q,A') /* a (faster) alternative for A*(q:*A') */ rhs = cross((q':*A)',r') //A*(q:*r') // k x 1 dy = (qrsolve(AQA,rhs))' // (invsym(AQA) * rhs)' // 1 x k dx = q :* (dy * A - r)' // n x 1 ds = -dx // n x 1 dz = -z :* (1 :+ (dx :/ x))' // 1 x n dw = -w :* (1 :+ (ds :/ s))' // 1 x n // Compute maximum allowable step lengths fx = bound(x, dx) // n x 1 fs = bound(s, ds) // n x 1 fw = bound(w, dw) // 1 x n fz = bound(z, dz) // 1 x n fp = rowmin((fx,fs)) // n x 1 fd = colmin((fw \ fz)) // 1 x n fp = min((min(beta * fp), 1)) // 1 x 1 fd = min((min(beta * fd), 1)) // 1 x 1 // If full step is feasible, take it. Otherwise modify it if (min((fp, fd)) < 1) { // Update mu mu = z * x + w * s // 1 x 1 g = (z + fd*dz) * (x + fp * dx) + (w + fd * dw) * (s + fp * ds) // 1 x 1 mu = mu * ((g / mu)^3) / ( 2 * n) // Compute modified step dxdz = dx :* dz' // n x 1 dsdw = ds :* dw' // n x 1 xinv = 1 :/ x // n x 1 sinv = 1 :/ s // n x 1 xi = mu * (xinv - sinv) // n x 1 rhs = rhs + A * ( q :* (dxdz - dsdw - xi)) // k x 1 dy = (qrsolve(AQA,rhs))' // (invsym(AQA)* rhs)' // 1 x k dx = q :* (A' * dy' + xi - r' - dxdz + dsdw) // n x 1 ds = -dx // n x 1 dz = mu * xinv' - z - (xinv' :* z :* dx') - dxdz' // 1 x n dw = mu * sinv' - w - (sinv' :* w :* ds') - dsdw' // 1 x n // Compute maximum allowable step lengths fx = bound(x, dx) // n x 1 fs = bound(s, ds) // n x 1 fw = bound(w, dw) // 1 x n fz = bound(z, dz) // 1 x n fp = rowmin((fx,fs)) // n x 1 fd = colmin((fw\ fz)) // 1 x n fp = min((min(beta * fp), 1)) // 1 x 1 fd = min((min(beta * fd), 1)) // 1 x 1 } // Take the step x = x + fp * dx // n x 1 s = s + fp * ds // n x 1 y = y + fd * dy // 1 x k w = w + fd * dw // 1 x n z = z + fd * dz // 1 x n gap = c * x - y * b + w * u // 1 x 1 } return(y) // end of lp_fnm routine } real colvector rq_fnm(numeric matrix X, real colvector y, real colvector p) { /* ================================================================================ *** Construct the dual problem of quantile regression Solve it with lp_fnm Function rq_fnm of Daniel Morillo & Roger Koenker Found at: http://www.econ.uiuc.edu/~roger/rqn/rq.ox Translated from Ox to Matlab by Paul Eilers 1999 Translated from Matlab to Stata by Pascal Erhardt, October, 2019 *** ================================================================================ */ real scalar m real vector u, a, b m = rows(X) u = J(m,1,1) a = (1 :- p):*u b = -lp_fnm(X', -y', X' * a, u, a)' return(b) // end of rq_fnm routine } end mata: real scalar Newton_Inter(real scalar u, real scalar opt) { real colvector c_rho, c_tau, x /* nodes and coefficients of polynomial roots; calculated in matlab file 'NewtonInter' */ real scalar v /* output: approximated point */ real rowvector V c_rho = (0 \ 0.0623226545583605\ 0.00367720639528224\ 0.000204476024281372\ 1.03437246404126e-05\ 4.15585381991934e-07\ 3.48909067719662e-09\ -1.98263806304224e-09\ -3.23883618501762e-10\ -3.34511912644218e-11\ -1.74556024907062e-12\ 2.11960643792196e-13\ 6.06149744183511e-14\ 6.66330930515645e-16\ -1.29555629687939e-15\ 6.39754640572107e-17\ 1.39285864150616e-17\ -2.55385247457695e-18\ 1.97566196797646e-19\ -5.30453701296442e-21\ -6.42712550471012e-22\ 1.09183691525891e-22\ -9.78501480707626e-24\ 6.42130274358149e-25\ -3.22318578611179e-26\ 1.09281841663308e-27\ -1.13739641406728e-38) c_tau = (0\0.0510894916414473\0.00252120904203062\0.000117738370513448\4.87666340933214e-06\1.35916840733332e-07\-4.21027733773708e-09\-1.28045048336379e-09\-1.57284516072431e-10\-1.35771845429325e-11\-4.90746123562826e-13\1.11271766559380e-13\2.40530846253367e-14\-1.30696341745966e-16\-5.10195448652022e-16\3.03678711055533e-17\4.99892607168443e-18\-9.96986777421439e-19\8.01064607852310e-20\-2.39416931588077e-21\-2.30147399582405e-22\4.17106447699158e-23\-3.79389161698803e-24\2.50410109316078e-25\-1.25957705584903e-26\4.27058536216758e-28\-2.63735668609671e-39) x = (0\ -14.8985753661291\ -14.5956730586974\ -14.0953893117886\-13.4044896048512\ -12.5323171711940\-11.4906666467847\-10.2936245680310\-8.95737887554179\-7.50000000000000\-5.94119649058735\-4.30204849066636\-2.60472266500396\-0.872172433657139\0.872172433657136\2.60472266500396\4.30204849066635\5.94119649058735\7.50000000000000\8.95737887554179\10.2936245680310\11.4906666467847\12.5323171711940\13.4044896048512\14.0953893117886\14.5956730586974\14.8985753661291) V = J(1,27,1) for (j=2; j<=27; j++) { V[1,j] = V[1,j-1]*(u-x[j-1,1]) } if (opt==1) { /* option 1 approximates Spearman's rank coefficient */ v = V*c_rho } else { /* option 2 approximates Kendall's tau */ v = V*c_tau } return(v) /* end of function Newton_Inter */ } real scalar integral(real scalar t, real scalar k) { return(t:^k :/ (expm1(t))) /* end of function integral */ } real scalar debye(real scalar x, real scalar k) { /* determines the k-th order debye function at x by quadrature */ class Quadrature scalar q q = Quadrature() q.setEvaluator(&integral()) q.setLimits((0,x)) q.setArgument(1,k) integral = q.integrate() /* integrate the debye integral by quadrature */ return(k/(x^k) *integral) /* end of function deye */ } void heavylift_7355(string scalar vnames, /// string scalar gam, /// string scalar zgam, /// string scalar copula, /// real scalar taupoints, /// real scalar rhopoints, /// real scalar numq, /// string scalar quantiles, /// string scalar touse, /// string scalar object_fct, /// string scalar rho_vec, /// string scalar min_val, /// string scalar min_rho, /// string scalar est_bvec, /// string scalar weights, /// string scalar S_rho, /// string scalar K_tau, /// string scalar B_beta, /// real scalar mesh, /// real scalar cent, /// string scalar instr) { /* construct data matrices */ data = st_data(., vnames, touse) /* import quantile vars */ zgamma = st_data(., zgam, touse) /* get probit prediction */ wght = st_data(., weights, touse) /* import weights */ gamma = st_matrix(gam) /* get probit coefficients */ instrument = st_data(., instr, touse) /* load instrument variable*/ v = cols(data) n = rows(data) pscore = normal(zgamma) varphi = wght :*instrument X = wght :*(J(n,1,1), data[.,2::v]) y = wght :*data[.,1] /* define grid points for tau */ tauvec = (1::taupoints):/(taupoints + 1) /* define grid points for copula parameter */ equiUnit = (1::rhopoints):/(rhopoints + 1) /* initialize objective function vector */ object = J(rhopoints,1,1) /* 2nd step in Arellano Bonhomme estimation */ if (copula == "frank") { rhovec = tan( pi() :* (equiUnit :- .5)) :*mesh :+cent // generate grid points using a cauchy distribution /* minimization */ for (j=1; j<=rhopoints; j++) { // rho grid points rhoa = rhovec[j,1] obj = 0 for (k=1; k<=taupoints; k++) { // tau grid points tau = tauvec[k,1] /* frank copula */ if (abs(rhoa) > 5*epsilon(1) ) { G = -1/rhoa :* log( 1 :+ ((exp(-rhoa*tau) - 1):*(exp(-rhoa:*pscore) :- 1)) :/ expm1(-rhoa) ) :/pscore } else { // for rhoa == 0 frank copula becomes independent copula, i.e. plain vanilla conditional quantile regression is conducted G = J(n,1,tau) } if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } beta = rq_fnm(X,y,G) // call minimization routine to estimate beta yhat = X*beta // prediction indicator = (y:<=yhat) // define the indicator function in our object obj = obj + mean(varphi:*(indicator - G)) // sum_{k=1}^{K} sum_{n=1}^{N} varphi_i(Z)*( 1[y_i <= X_i*b] - G_i ) } object[j,1] = obj^2 // pseudo-euclidean norm } } else if (copula == "gaussian"){ rhovec = asin( 2:*(equiUnit :-.5)) :*(2/pi()):*mesh :*(1-abs(cent)) :+cent // generate grid points using sin() as density on [-1;1] /* minimization */ for (j=1; j<=rhopoints; j++) { // rho grid points rhoa = rhovec[j,1] obj = 0 for (k=1; k<=taupoints; k++) { // tau grid points tau = tauvec[k,1] /* gaussian copula */ G = binormal(invnormal(tau),zgamma,rhoa):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } beta = rq_fnm(X,y,G) // call minimization routine to estimate beta yhat = X*beta // prediction indicator = (y:<=yhat) // define the indicator function in our object obj = obj + mean(varphi:*(indicator - G)) // sum_{k=1}^{K} sum_{n=1}^{N} varphi_i(Z)*( 1[y_i <= X_i*b] - G_i ) } object[j,1] = obj^2 // pseudo-euclidean norm } } else if (copula == "plackett") { rhovec = sqrt(equiUnit:/(1:-equiUnit)) // plackett grid rhovec = rhovec:*(rhovec:<=1)*cent :+ (rhovec:+(cent-1)):*(rhovec:>1) rhovec = (rhovec:-cent)*(mesh<=1)*mesh :+ cent :+ (mesh>1)*(rhovec:1)*(rhovec:>cent):*(rhovec*mesh :-cent) /* minimization */ for (j=1; j<=rhopoints; j++) { // rho grid points rhoa = rhovec[j,1] obj = 0 for (k=1; k<=taupoints; k++) { // tau grid points tau = tauvec[k,1] /* plackett copula */ if (abs(rhoa - 1) > 5*epsilon(1) ) { G = (.5/(rhoa-1) *( 1 :+ (rhoa-1)*(pscore :+ tau) :- sqrt( (1 :+ (rhoa-1)*(pscore :+ tau)):^2 :- 4*rhoa*(rhoa-1)*pscore*tau ) ) ):/pscore } else { /* plackett for rhoa=1 => independent copula */ G = J(n,1,tau) } if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } beta = rq_fnm(X,y,G) // call minimization routine to estimate beta yhat = X*beta // prediction indicator = (y:<=yhat) // define the indicator function in our object obj = obj + mean(varphi:*(indicator - G)) // sum_{k=1}^{K} sum_{n=1}^{N} varphi_i(Z)*( 1[y_i <= X_i*b] - G_i ) } object[j,1] = obj^2 // pseudo-euclidean norm } } else { /* Joe and Ma (2000) copula */ rhovec = sqrt(equiUnit:/(1:-equiUnit)) // grid rhovec = rhovec:*(rhovec:<=1)*cent :+ (rhovec:+(cent-1)):*(rhovec:>1) rhovec = (rhovec:-cent)*(mesh<=1)*mesh :+ cent :+ (mesh>1)*(rhovec:1)*(rhovec:>cent):*(rhovec*mesh :-cent) /* minimization */ for (j=1; j<=rhopoints; j++) { // rho grid points rhoa = rhovec[j,1] obj = 0 for (k=1; k<=taupoints; k++) { // tau grid points tau = tauvec[k,1] /* cf. Joe, H. 2014. Dependence Modelling with Copulas. Chapter 4. pp. 177-180 */ G = (1 :- gammap( rhoa, ( (invgammap(rhoa,1-tau):^rhoa ) :+ (invgammap(rhoa,1:-pscore):^rhoa ) ):^(1/rhoa) ) ):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } beta = rq_fnm(X,y,G) // call minimization routine to estimate beta yhat = X*beta // prediction indicator = (y:<=yhat) // define the indicator function in our object obj = obj + mean(varphi:*(indicator - G)) // sum_{k=1}^{K} sum_{n=1}^{N} varphi_i(Z)*( 1[y_i <= X_i*b] - G_i ) } object[j,1] = obj^2 // pseudo-euclidean norm } } minObj = colmin(object) /* minimize euclidean norm */ minindex(object,1,row=.,nix=.) /* estimated copula parameter */ rho = rhovec[row,1] if (rows(rho)!=1) { // break if estimated copula parameter is not unique; in practice this only happens if rq_fnm did not converge printf("{error:unable to minimize objective function}\n") exit(error(430)) } else { printf("\n{txt}Second step (" + copula + "{txt} copula parameter estimation) successfully completed.\n") printf("{txt}Found objective function minimum " + strofreal(minObj,"%10.7e") + "{txt} for rho = " + strofreal(rho,"%10.4fc") + "\n") } /* 3rd step in Arellano Bonhomme estimation */ Qtiles = st_matrix(quantiles) Qtiles = Qtiles[2::(numq+1),1] est_betas = J(numq*v,1,0) if (copula == "frank") { for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles if (abs(rho) > 5*epsilon(1) ) { G = -1/rho :* log( 1 :+ ((exp(-rho*Qtiles[q,1]) - 1):*(exp(-rho:*pscore) :- 1)) :/ expm1(-rho) ) :/pscore } else { // for rho == 0 frank copula becomes independent copula, i.e. plain vanilla conditional quantile regression is conducted G = J(n,1,Qtiles[q,1]) } if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else if (copula == "gaussian"){ for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles G = binormal(invnormal(Qtiles[q,1]),zgamma,rho):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else if (copula == "plackett"){ for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles /* plackett copula */ if (abs(rho - 1) > 5*epsilon(1) ) { G = (.5/(rho-1) *( 1 :+ (rho-1)*(pscore :+ Qtiles[q,1]) :- sqrt( (1 :+ (rho-1)*(pscore :+ Qtiles[q,1])):^2 :- 4*rho*(rho-1)*pscore*Qtiles[q,1] ) ) ):/pscore } else { /* plackett for rhoa=1 => independent copula */ G = J(n,1,Qtiles[q,1]) } if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else { /* Joe and Ma (2000) copula */ for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles /* joema copula */ G = (1 :- gammap( rho, ( (invgammap(rho,1-Qtiles[q,1]):^rho ) :+ (invgammap(rho,1:-pscore):^rho ) ):^(1/rho) ) ):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } est_betas = (gamma' \est_betas \rho) // maybe check whether est_betas contains missings from failed minimizaton printf("\n{txt}Third step (minimization of rotated check function) successfully completed. \n") /* for the following cf. Joe, H. 2014. Dependence Modelling with Copulas. Chapter 4. */ if (copula == "frank") { if (abs(rho)>5*epsilon(1)) { /* Joe, 2014, p.166 */ spear = sign(rho)*(1 + (12/abs(rho)) *(debye(abs(rho),2) - debye(abs(rho),1) ) ) kend = sign(rho)*(1 + (4/abs(rho)) *(debye(abs(rho),1) - 1) ) blom = -4/rho * log( (2*exp(-rho/2) - 2*exp(-rho)) /(1-exp(-rho)) ) - 1 } else { spear = 0 kend = 0 blom = 0 } } else if (copula == "gaussian") { /* Joe, 2014, p.164 */ spear = (6/pi()) *asin(rho/2) kend = (2/pi()) *asin(rho) blom = kend } else if (copula == "plackett") { /* Joe, 2014, pp.164-165 */ if (abs(rho-1)<=5*epsilon(1)) { spear = 0 kend = . blom = 0 } else { spear = (rho+1)/(rho-1) - (2*rho*log(rho))/((rho-1)^2) kend = . blom = (sqrt(rho)-1)/(sqrt(rho)+1) } } else { /* Joe, 2014, pp.177-180 */ if (abs(rho-1)<=5*epsilon(1)) { spear = . kend = 0 blom = 0 } else { spear = . kend = 1 - 2*gamma(.5 + rho)/( sqrt(pi())*gamma(1+rho) ) blom = 3 - 4*gammap(rho, 2^(1/rho) * invgammap(rho,.5)) } } st_matrix(object_fct,object) st_matrix(rho_vec,rhovec) st_numscalar(min_rho,rho) st_numscalar(min_val,minObj) st_numscalar(S_rho,spear) st_numscalar(K_tau,kend) st_numscalar(B_beta,blom) st_matrix(est_bvec,est_betas') /* end of function heavylift_7355 */ } void main_fct2(string scalar vnames, /// string scalar gam, /// string scalar zgam, /// string scalar copula, /// real scalar numq, /// string scalar quantiles, /// string scalar touse, /// string scalar est_bvec, /// string scalar weights, /// string scalar cpara) { /* construct data matrices */ data = st_data(., vnames, touse) /* import quantile vars */ zgamma = st_data(., zgam, touse) /* get probit prediction */ wght = st_data(., weights, touse) /* import weights */ gamma = st_matrix(gam) /* get probit coefficients */ rhovar = st_data(., cpara, touse) /* load user-specified copula parameter */ v = cols(data) n = rows(data) pscore = normal(zgamma) X = wght :*(J(n,1,1), data[.,2::v]) y = wght :*data[.,1] /* 3rd step in Arellano Bonhomme estimation */ Qtiles = st_matrix(quantiles) Qtiles = Qtiles[2::(numq+1),1] est_betas = J(numq*v,1,0) if (copula == "frank") { aindep = selectindex(abs(rhovar) :>= 5*epsilon(1)) /* mark non-independent copulae */ for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles G = J(n,1,Qtiles[q,1]) /* frank copula */ G[aindep] = (-1:/rhovar[aindep]) :* log( 1 :+ ((exp(-rhovar[aindep]:*Qtiles[q,1]) :- 1):*(exp(-rhovar[aindep]:*pscore[aindep]) :- 1)) :/ expm1(-rhovar[aindep]) ) :/pscore[aindep] if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else if (copula == "gaussian") { for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles /* gaussian copula */ G = binormal(invnormal(Qtiles[q,1]),zgamma,rhovar):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else if (copula == "plackett"){ aindep = selectindex(abs(rhovar:-1) :> 5*epsilon(1)) /* mark non-independent copulae */ for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles /* plackett copula */ G = J(n,1,Qtiles[q,1]) G[aindep] = (.5:/(rhovar[aindep]:-1) :*( 1 :+ (rhovar[aindep]:-1):*(pscore[aindep] :+ Qtiles[q,1]) :- sqrt( (1 :+ (rhovar[aindep]:-1):*(pscore[aindep] :+ Qtiles[q,1])):^2 :- 4*rhovar[aindep]:*(rhovar[aindep]:-1):*pscore[aindep]:*Qtiles[q,1] ) ) ):/pscore[aindep] if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else { /* Joe and Ma (2000) copula */ for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles /* joema copula */ G = (1 :- gammap( rhovar, ( (invgammap(rhovar,1-Qtiles[q,1]):^rhovar ) :+ (invgammap(rhovar,1:-pscore):^rhovar ) ):^(1:/rhovar) ) ):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } est_betas = (gamma' \est_betas) fail = (est_betas :== .) if (colsum(fail) > 0) { printf("\n{error:estimation of rotated check function failed for some quantiles}\n") exit(error(430)) } else { printf("\n{txt:Third step (minimization of rotated check function) successfully completed.} \n") } st_matrix(est_bvec,est_betas') /* end of function main_fct2 */ } end mata: function probit_func(transmorphic M, /// real rowvector gamma, /// real colvector loglikeF) { real colvector para real colvector binary para = moptimize_util_xb(M, gamma, 1) binary = moptimize_util_depvar(M, 1) w = moptimize_util_userinfo(M, 1) loglikeF = w:*( binary:*log(normal(para)) :+ (1:-binary):*log(1:-normal(para)) ) } void std_erf(string scalar vnames, /// string scalar gam, /// string scalar copula, /// real scalar taupoints, /// real scalar rhopoints, /// real scalar numq, /// string scalar quantiles, /// string scalar touse, /// string scalar probuse, /// string scalar seldep, /// string scalar selreg, /// string scalar est_Vmat, /// real scalar subS, /// real scalar boots, /// string scalar gamCov, /// string scalar subsize, /// string scalar weights, /// real scalar mesh, /// real scalar cent, /// string scalar est_bvec, /// string scalar instr, /// string scalar actr, /// string scalar rhoVar, /// string scalar pvals, /// string scalar bbetas, /// string scalar sbetas, /// string scalar confb, /// real scalar failfrac) { /* construct data matrices */ data = st_data(., vnames, probuse) /* import quantile vars */ Z = st_data(., selreg, probuse) /* import selection regressors */ D = st_data(., touse, probuse) /* import binary response var */ wght = st_data(., weights, probuse) /* import weights */ init_gamma = st_matrix(gam) /* get probit coefficients */ gammaCov = st_matrix(gamCov) /* get probit covariance matrix */ Ebetas = st_matrix(est_bvec) instrument = st_data(., instr, probuse) v = cols(data) n = rows(data) Ebetas = Ebetas' nEbetas = rows(Ebetas) bmax = ceil((1+ failfrac)*boots) /* maximum of samples to be drawn */ rep = 0 b = 1 prob_fail=0 q_fail=0 Ebetas = Ebetas[(cols(gammaCov)+1)::nEbetas,1] /* define grid points for tau */ tauvec = (1::taupoints):/(taupoints + 1) /* define grid points for copula parameter */ equiUnit = (1::rhopoints):/(rhopoints + 1) /* subsample size */ subS = rowmin( (n, subS) ) Qtiles = st_matrix(quantiles) Qtiles = Qtiles[2::(numq+1),1] /* initialize bootstrap based beta matrix */ boots_betas = J(numq*v + 1,boots,0) displayas("text") printf("\n{txt:Initialising standard error estimation by }" + strofreal(subS) + "{txt: out of }" + strofreal(n) + "{txt: bootstrap method:}\n") printf("{hline 4}{c +}{hline 3} 1 {hline 3}{c +}{hline 3} 2 {hline 3}{c +}{hline 3} 3 {hline 3}{c +}{hline 3} 4 {hline 3}{c +}{hline 3} 5 \n") while (b<=boots & rep < bmax) { isel = subS conv=0 mck=0 rep++ /* start to count subsamping repetitioins */ while (isel==subS | isel==0) { /* rule out subsamples with[out] [perfect] selection */ inSample = ceil(n * runiform(subS,1)) Sub_data = data[inSample,.] Sub_Z = Z[inSample,.] Sub_D = D[inSample,1] Sub_wght = wght[inSample,1] Sub_instr = instrument[inSample,1] isel = colsum(Sub_D) } y = Sub_wght :* Sub_data[.,1] y = select(y,Sub_D) /* selected in subsample */ X = Sub_wght :* (J(subS,1,1), Sub_data[.,2::v]) X = select(X,Sub_D) /* selected regressors in subsample */ M = moptimize_init() moptimize_init_evaluator(M, &probit_func()) moptimize_init_depvar(M, 1, Sub_D ) moptimize_init_eq_indepvars(M, 1, Sub_Z ) moptimize_init_userinfo(M, 1, Sub_wght ) moptimize_init_trace_value(M, "off") moptimize_init_trace_ado(M, "on") moptimize_init_eq_coefs(M, 1, init_gamma) /* use full-sample probit estimates as starting values to boost convergence */ moptimize_init_search(M,"on") moptimize_init_search_rescale(M,"on") /* in rare cases probably better "on" */ moptimize_init_conv_maxiter(M,50) moptimize_init_conv_warning(M,"off") moptimize_init_verbose(M, "off") moptimize(M) //moptimize_result_display(M) conv = moptimize_result_converged(M) /* end loop if probit succesfully converged */ if (conv==0 & rep <= bmax) { if (mod(rep,50) != 0 & b!=boots) { displayas("text") printf("{txt}x") } else if (mod(rep,50)== 0 | b==boots) { displayas("text") printf("x %6.0g", rep) printf("\n") } //displayas("error") //printf("\n{red:note: probit failed to converge for subsample }" + strofreal(b) + "/" + strofreal(boots) + "{red:. Subsample dropped and replaced}\n") } gamma = moptimize_result_coefs(M) mck = rowsum( (gamma :== .) ) if (mck>=1 & rep < bmax) { if (mod(rep,50) != 0 & b!=boots) { displayas("text") printf("{txt}x") } else if (mod(rep,50)== 0 | b==boots) { displayas("text") printf("x %6.0g", rep) printf("\n") } //displayas("error") //printf("\n{red:note: probit estimation on subsample }" + strofreal(b) + "/" + strofreal(boots) + "{red: contains at least one missing. Subsample dropped and replaced}\n") } if (mck >=1 | conv==0) { prob_fail++ } if (conv==1 & mck==0) { zgamma = (Sub_Z,J(subS,1,1)) * gamma' pscore = normal(zgamma) Sub_wght = select(Sub_wght,Sub_D) zgamma = select(zgamma,Sub_D) /* selected probit prediction in subsample */ pscore = select(pscore,Sub_D) /* subsample pscore for selected individuals */ Sub_instr = select(Sub_instr,Sub_D) varphi = Sub_wght :* Sub_instr /* initialize objective function vector */ object = J(rhopoints,1,1) /* 2nd step in Arellano Bonhomme estimation */ if (copula == "frank") { rhovec = tan( pi() :* (equiUnit :- .5)):*mesh :+cent // generate grid points using a cauchy distribution; now symmetric about entire sample estimate /* minimization */ for (j=1; j<=rhopoints; j++) { // rho grid points rhoa = rhovec[j,1] obj = 0 for (k=1; k<=taupoints; k++) { // tau grid points tau = tauvec[k,1] /* frank copula */ if (abs(rhoa) > 5*epsilon(1) ) { G = -1/rhoa :* log( 1 :+ ((exp(-rhoa*tau) - 1):*(exp(-rhoa:*pscore) :- 1)) :/ expm1(-rhoa) ) :/pscore } else { // for rhoa == 0 frank copula becomes independent copula, i.e. plain vanilla conditional quantile regression is conducted G = J(isel,1,tau) } if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } beta = rq_fnm(X,y,G) // call minimization routine to estimate beta yhat = X*beta // prediction indicator = (y:<=yhat) // define the indicator function in our object obj = obj + mean(varphi :*(indicator - G)) // sum_{k=1}^{K} sum_{n=1}^{N} varphi_i(Z)*( 1[y_i <= X_i*b] - G_i ) } object[j,1] = obj^2 // pseudo-euclidean norm } } else if (copula == "gaussian") { rhovec = asin( 2:*(equiUnit :-.5)) :*(2/pi()):*mesh :*(1-abs(cent)) :+cent // generate grid points using sin() as density on [-1;1]; now symmetric about entire sample estimate of rho /* minimization */ for (j=1; j<=rhopoints; j++) { // rho grid points rhoa = rhovec[j,1] obj = 0 for (k=1; k<=taupoints; k++) { // tau grid points tau = tauvec[k,1] /* gaussian copula */ G = binormal(invnormal(tau),zgamma,rhoa):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } beta = rq_fnm(X,y,G) // call minimization routine to estimate beta yhat = X*beta // prediction indicator = (y:<=yhat) // define the indicator function in our object obj = obj + mean(varphi :*(indicator - G)) // sum_{k=1}^{K} sum_{n=1}^{N} varphi_i(Z)*( 1[y_i <= X_i*b] - G_i ) } object[j,1] = obj^2 // pseudo-euclidean norm } } else if (copula == "plackett") { rhovec = sqrt(equiUnit:/(1:-equiUnit)) // plackett grid rhovec = rhovec:*(rhovec:<=1)*cent :+ (rhovec:+(cent-1)):*(rhovec:>1) rhovec = (rhovec:-cent)*(mesh<=1)*mesh :+ cent :+ (mesh>1)*(rhovec:1)*(rhovec:>cent):*(rhovec*mesh :-cent) /* minimization */ for (j=1; j<=rhopoints; j++) { // rho grid points rhoa = rhovec[j,1] obj = 0 for (k=1; k<=taupoints; k++) { // tau grid points tau = tauvec[k,1] /* plackett copula */ if (abs(rhoa - 1) > 5*epsilon(1) ) { G = (.5/(rhoa-1) *( 1 :+ (rhoa-1)*(pscore :+ tau) :- sqrt( (1 :+ (rhoa-1)*(pscore :+ tau)):^2 :- 4*rhoa*(rhoa-1)*pscore*tau ) ) ):/pscore } else { /* plackett for rhoa=1 => independent copula */ G = J(isel,1,tau) } if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } beta = rq_fnm(X,y,G) // call minimization routine to estimate beta yhat = X*beta // prediction indicator = (y:<=yhat) // define the indicator function in our object obj = obj + mean(varphi:*(indicator - G)) // sum_{k=1}^{K} sum_{n=1}^{N} varphi_i(Z)*( 1[y_i <= X_i*b] - G_i ) } object[j,1] = obj^2 // pseudo-euclidean norm } } else { /* Joe and Ma (2000) copula */ rhovec = sqrt(equiUnit:/(1:-equiUnit)) // grid rhovec = rhovec:*(rhovec:<=1)*cent :+ (rhovec:+(cent-1)):*(rhovec:>1) rhovec = (rhovec:-cent)*(mesh<=1)*mesh :+ cent :+ (mesh>1)*(rhovec:1)*(rhovec:>cent):*(rhovec*mesh :-cent) /* minimization */ for (j=1; j<=rhopoints; j++) { // rho grid points rhoa = rhovec[j,1] obj = 0 for (k=1; k<=taupoints; k++) { // tau grid points tau = tauvec[k,1] /* cf. Joe, H. 2014. Dependence Modelling with Copulas. Chapter 4. pp. 177-180 */ G = (1 :- gammap( rhoa, ( (invgammap(rhoa,1-tau):^rhoa ) :+ (invgammap(rhoa,1:-pscore):^rhoa ) ):^(1/rhoa) ) ):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } beta = rq_fnm(X,y,G) // call minimization routine to estimate beta yhat = X*beta // prediction indicator = (y:<=yhat) // define the indicator function in our object obj = obj + mean(varphi:*(indicator - G)) // sum_{k=1}^{K} sum_{n=1}^{N} varphi_i(Z)*( 1[y_i <= X_i*b] - G_i ) } object[j,1] = obj^2 // pseudo-euclidean norm } } minObj = colmin(object) /* minimize euclidean norm */ minindex(object,1,row=.,nix=.) /* estimated copula parameter */ rho = rhovec[row[1,1],1] /* make sure that rho is a scalar */ /* 3rd step in Arellano Bonhomme estimation */ est_betas = J(numq*v,1,0) if (copula == "frank") { for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles if (abs(rho) > 5*epsilon(1) ) { G = -1/rho :* log( 1 :+ ((exp(-rho*Qtiles[q,1]) - 1):*(exp(-rho:*pscore) :- 1)) :/ expm1(-rho) ) :/pscore } else { // for rho == 0 frank copula becomes independent copula, i.e. plain vanilla conditional quantile regression is conducted G = J(isel,1,Qtiles[q,1]) } if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else if (copula == "gaussian") { for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles G = binormal(invnormal(Qtiles[q,1]),zgamma,rho):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else if (copula == "plackett"){ for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles /* plackett copula */ if (abs(rho - 1) > 5*epsilon(1) ) { G = (.5/(rho-1) *( 1 :+ (rho-1)*(pscore :+ Qtiles[q,1]) :- sqrt( (1 :+ (rho-1)*(pscore :+ Qtiles[q,1])):^2 :- 4*rho*(rho-1)*pscore*Qtiles[q,1] ) ) ):/pscore } else { /* plackett for rhoa=1 => independent copula */ G = J(isel,1,Qtiles[q,1]) } if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } else { /* Joe and Ma (2000) copula */ for (q=1; q<=numq; q++) { // estimate qunatile coefficients at user specified quantiles /* joema copula */ G = (1 :- gammap( rho, ( (invgammap(rho,1-Qtiles[q,1]):^rho ) :+ (invgammap(rho,1:-pscore):^rho ) ):^(1/rho) ) ):/pscore if (colmin(G)<=5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) zero z = selectindex(G:<5*epsilon(1)) NisZ = rows(z) G[z] = J(NisZ,1,5*epsilon(1)) } if (colmax(G)>=1-5*epsilon(1)) { // IMPORTANT!! check whether one or more elements of G are (practically) one o = selectindex(G:>=1-5*epsilon(1)) Nis1 = rows(o) G[o] = J(Nis1,1,1-5*epsilon(1)) } para = rq_fnm(X,y,G) // call minimization routine to estimate beta est_betas[((v*q)-(v-1))::(q*v),1] = para // fill in the estimated parameters } } bmiss = colsum(est_betas :==.) /* check whether a subsample beta vector contains a missing */ if (bmiss == 0) { boots_betas[.,b] = (est_betas\rho) if (mod(rep,50) != 0 & b!=boots) { displayas("text") printf("{txt}.") } else if (mod(rep,50) == 0 | b==boots) { displayas("text") printf(". %6.0g", rep) printf("\n") } b++ /* now consider such a sample properly estimated */ } else { q_fail++ /* count as failed estimation */ //displayas("error") //printf("\n{red:note: minimization of rotated check function on subsample }" + strofreal(b) + "{red: resulted in at least one missing. Subsample dropped and replaced}\n") if (mod(rep,50) != 0 & b!=boots) { displayas("text") printf("{txt}x") } else if (mod(rep,50)== 0 | b==boots) { displayas("text") printf("x %6.0g", rep) printf("\n") } } } } if (rep == bmax & b<=boots) { displayas("text") printf("%6.0g", rep) displayas("error") printf("\n{red:note: standard error computation by }" + strofreal(subS) + "{red: out of }" + strofreal(n) + "{red: bootstrap aborted because maximum of allowed repetitions (}" + strofreal(bmax) + "{red:) was reached}\n") } if (prob_fail > 0) { displayas("text") printf("\n{txt}Probit model failed to converge for " + strofreal(prob_fail) + plural(prob_fail," subsample")) } else if (q_fail >0) { displayas("text") printf("\n{txt}Selection corrected quantile regression failed to converge for " + strofreal(q_fail) + plural(q_fail," subsample")) } if (b>=3) { // Ebetas = (mean(boots_betas'))' /* average coefficient estimates */ colZ = cols(gammaCov) CMatrix =( ( boots_betas[.,1::(b-1)] :- Ebetas )* ( boots_betas[.,1::(b-1)] :- Ebetas )' ):/(b - 2) /* calculate covariance matrix */ CMatrix = ( J(colZ,numq*v + 1,0) \ CMatrix ) * (subS/n) gammaCov = (gammaCov\J(numq*v + 1,colZ,0)) CMatrix = (gammaCov, CMatrix) /* covariance matrix including first step standard errors */ if (copula == "plackett" | copula == "joema") { relF = rowsum(boots_betas[.,1::(b-1)]:<=(J(numq*v,1,0)\1)):/(b-1) /* test for significance with bootstrap distribution */ p_vals = 2*rowmin((relF,1:-relF)) } else { relF = rowsum(boots_betas[.,1::(b-1)]:<=0):/(b-1) /* test for significance with bootstrap distribution */ p_vals = 2*rowmin((relF,1:-relF)) } vrs = 1 sorted_betas = J(numq*v+1,b-1,0) while (vrs<=numq*v+1) { sorted_betas[vrs,.] = sort(boots_betas[vrs,1::(b-1)]',1)' vrs++ } lconfb = sorted_betas[.,ceil(.025*(b-1))] uconfb = sorted_betas[.,ceil(.975*(b-1))] st_matrix(est_Vmat,CMatrix) /* export entire covariance matrix */ st_numscalar(subsize,subS) st_numscalar(actr,b-1) st_numscalar(rhoVar,CMatrix[rows(CMatrix),cols(CMatrix)]) st_matrix(pvals,p_vals) st_matrix(bbetas,boots_betas) st_matrix(sbetas,sorted_betas) st_matrix(confb,(lconfb, uconfb)) } else { printf("\n{error:too few subsamples left to compute standard errors}\n") exit(error(430)) } /* end of function std_erf */ } end /* end of program arhomme */ program cmd_in, rclass tokenize `"`0'"', parse("(") mac shift 2 local options "`*'" gettoken sel options : options, parse(")") local options = subinstr("`options'","(","",.) local n_opt : word count `options' local idx = 1 while (`idx'<=`n_opt') { local temp_w : word `idx' of `options' local is_inp = strpos("`temp_w'",")") if (`is_inp' !=0) { local options : subinstr local options "`temp_w'" "" } local idx = `idx' + 1 } local options = stritrim("`options'") local options = strltrim("`options'") local rho = (strpos("`options'","rho") != 0) local tau = (strpos("`options'","tau") != 0) local rep = (strpos("`options'","rep") != 0) local sub = (strpos("`options'","sub") != 0) local instr = (strpos("`options'","instr") != 0) local cop = (strpos("`options'","cop") != 0) local mesh = (strpos("`options'","mesh") != 0) local cent = (strpos("`options'","cent") != 0) local q = (strpos("`options'","q") != 0) local gau = (strpos("`options'","gau") != 0) local fra = (strpos("`options'","fra") != 0) local plack = (strpos("`options'","plack") != 0) local joe = (strpos("`options'","joe") != 0) local gra = (strpos("`options'","gra") != 0) local nostd = (strpos("`options'","nostd") != 0) local out = (strpos("`options'","out") != 0) local fail = (strpos("`options'","fail") != 0) return local opt `"`options'"' return local rho `"`rho'"' return local tau `"`tau'"' return local rep `"`rep'"' return local sub `"`sub'"' return local instr `"`instr'"' return local cop `"`cop'"' return local mesh `"`mesh'"' return local cent `"`cent'"' return local q `"`q'"' return local gau `"`gau'"' return local fra `"`fra'"' return local plack `"`plack'"' return local joe `"`joe'"' return local gra `"`gra'"' return local nostd `"`nostd'"' return local out `"`out'"' return local fail `"`fail'"' /* end of sub-program cmd_in */ end program cmd_out syntax [anything], [dep(string) regs(string) nvar(string) seldep(string) selreg(string) nsel(string) beta(string) cov(string) nq(string) quant(string) conf(string) pvals(string) cop(string)] di as text "{hline 13}{c TT}{hline 64}" di as text %12s abbrev("`dep'",12) " {c |}" _col(21) "Coef. Std. Err. z P>|z| [95% Conf. Interval]" di as text "{hline 13}{c +}{hline 64}" local seldep = abbrev("`seldep'",12) di as text "{bf:`seldep'}" _col(14) "{c |}" local line=1 while(`line'<=`nsel') { local temp_name: word `line' of `selreg' local b = `beta'[1,`line'] local std = sqrt(`cov'[`line',`line']) local z = `b'/`std' local p = 2*(1-normal(abs(`z'))) local lb = `b'+invnormal(.025)*`std' local ub = `b'+invnormal(.975)*`std' di as text %12s abbrev("`temp_name'",12) " {c |} " as result %9.8g `b' _col(28) %9.8g `std' _col(40) %6.2f `z' _col(49) %4.3f `p' _col(58) %9.8g `lb' " " %9.8g `ub' local line = `line'+1 } local b = `beta'[1,`nsel'+1] local std = sqrt(`cov'[`nsel'+1,`nsel'+1]) local z = `b'/`std' local p = 2*(1-normal(abs(`z'))) local lb = `b'+invnormal(.025)*`std' local ub = `b'+invnormal(.975)*`std' di as text %12s "_cons" " {c |} " as result %9.8g `beta'[1,`nsel'+1] _col(28) %9.8g sqrt(`cov'[`nsel'+1,`nsel'+1]) _col(40) %6.2f `z' _col(49) %4.3f `p' _col(58) %9.8g `lb' " " %9.8g `ub' di as text "{hline 13}{c +}{hline 64}" local eqs = 0 while (`eqs'<`nq') { local temp_q = `quant'[`eqs'+2,1] local temp_q = abbrev("`temp_q'_quantile",11) di as text "{bf:.`temp_q'}" _col(14) "{c |}" local b = `beta'[1,`nsel'+2+`eqs'*`nvar'] local std = sqrt(`cov'[`nsel'+2+`eqs'*`nvar',`nsel'+2+`eqs'*`nvar']) local z = `b'/`std' local p = `pvals'[`eqs'*`nvar'+1,1] local lb = `conf'[`eqs'*`nvar'+1,1] local ub = `conf'[`eqs'*`nvar'+1,2] di as text %12s "_cons" " {c |} " as result %9.8g `b' _col(28) %9.8g `std' _col(40) %6.2f `z' _col(49) %4.3f `p' _col(58) %9.8g `lb' " " %9.8g `ub' local line=1 while(`line'<`nvar') { local temp_name: word `line' of `regs' local b = `beta'[1,`line'+`nsel'+2+`eqs'*`nvar'] local std = sqrt(`cov'[`line'+`nsel'+2+`eqs'*`nvar',`line'+`nsel'+2+`eqs'*`nvar']) local z = `b'/`std' local p = `pvals'[`eqs'*`nvar'+`line'+1,1] local lb = `conf'[`eqs'*`nvar'+`line'+1,1] local ub = `conf'[`eqs'*`nvar'+`line'+1,2] di as text %12s abbrev("`temp_name'",12) " {c |} " as result %9.8g `b' _col(28) %9.8g `std' _col(40) %6.2f `z' _col(49) %4.3f `p' _col(58) %9.8g `lb' " " %9.8g `ub' local line = `line'+1 } di as text "{hline 13}{c +}{hline 64}" local eqs = `eqs'+1 } local b = `beta'[1,`nsel'+2+`nq'*`nvar'] local std = sqrt(`cov'[`nsel'+2+`nq'*`nvar',`nsel'+2+`nq'*`nvar']) if ("`cop'" == "plackett" | "`cop'" == "joema") { local z = (`b'-1)/`std' di as text _col(14) "{c |}" _col(21) "Coef. Std. Err. rho=1 p_val [95% Conf. Interval]" di as text "{hline 13}{c +}{hline 64}" } else { local z = `b'/`std' } local p = `pvals'[`nq'*`nvar'+1,1] local lb = `conf'[`nq'*`nvar'+1,1] local ub = `conf'[`nq'*`nvar'+1,2] di as text "{bf:_anc}" _col(14) "{c |}" di as text %12s "rho" " {c |} " as result %9.8g `b' _col(28) %9.8g `std' _col(40) %6.2f `z' _col(49) %4.3f `p' _col(58) %9.8g `lb' " " %9.8g `ub' di as text "{hline 13}{c BT}{hline 64}" /* end of sub-program cmd_out */ end