*! Bollen-Stine bootstrap, v.1.3, Stas Kolenikov program define bollenstine, eclass syntax, [Reps(int 200) SAVing(str) notable noheader nolegend /// SAFER CONFAOPTions(str) *] * this is a post-estimation command following confa1 if "`e(cmd)'" ~= "confa1" & "`e(cmd)'" ~= "confa" error 301 * the low level preserve preserve tempfile pres tempname confares est store `confares' qui save `pres' qui keep if e(sample) local T = e(lr_u) local safer cap noi if "`saving'" == "" { tempfile bsres local saving `bsres' } if "`e(cmd)'" == "confa1" { local varlist = "`e(depvar)'" local p : word count `varlist' tempname Sigma bb mat `Sigma' = e(Model) mat `bb' = e(b) mata: CONFA1_BSrotate("`Sigma'","`varlist'") `safer' bootstrap _b (T: T = e(lr_u)) (reject: reject = (e(lr_u) > `T') ) , /// reps(`reps') saving(`saving') notable noheader nolegend /// reject( e(converged) == 0) `options' /// : confa1 `varlist' , from(`bb', skip) `confaoptions' * may need some other options, too! nobreak if "`safer'"~="" & _rc { * for whatever reason, the bootstrap broke down qui use `pres' , clear qui est restore `confares' qui est drop `confares' error _rc } * just to display the results * the covariance matrix should have been reposted by the -bootstrap-! * we still need to trick Stata back into confa1! ereturn local cmd confa1 } else if "`e(cmd)'" == "confa" { local varlist = "`e(observed)'" local p : word count `varlist' tempname Sigma bb mat `Sigma' = e(Sigma) mat `bb' = e(b) mata: CONFA1_BSrotate("`Sigma'","`varlist'") * set up the call local k = 1 while "`e(factor`k')'" ~= "" { local call `call' (`e(factor`k')') local ++k } * the first call and resetting the from vector cap confa `call' , from(`bb') `confaoptions' if _rc { di as err "cannot execute confa with rotated data only" restore qui est restore `confares' cap est drop `confares' exit 309 } mat `bb' = e(b) if ~strpos("`confaoptions'", "from") local from from(`bb') * correlated errors? * unit variance identification? `safer' bootstrap _b (T: T = e(lr_u)) (reject: reject = (e(lr_u) > `T') ) , /// reps(`reps') saving(`saving') notable noheader nolegend /// reject( e(converged) == 0) `options' /// : confa `call' , `from' `confaoptions' * may need some other options, too! nobreak if "`safer'"~="" & _rc { * for whatever reason, the bootstrap broke down qui use `pres' , clear qui est restore `confares' cap est drop `confares' error _rc } * the covariance matrix should have been reposted by the -bootstrap-! * we still need to trick Stata back into confa! ereturn local cmd confa } else { * what on earth was that? error 301 } * the bootstrap test on T gettoken bsres blah : saving , parse(",") * to strip off replace option, if there is any qui use `bsres', clear sum reject_reject, mean local pBS = r(mean) local BBS = r(N) qui sum T_T, det local q05 = r(p5) local q95 = r(p95) qui use `pres', clear qui est restore `confares' qui est drop `confares' ereturn scalar p_u_BS = `pBS' ereturn scalar B_BS = `BBS' * ereturn scalar lr_u = `T' * ereturn scalar p_u = chi2tail(e(df_u),e(lr_u)) ereturn scalar T_BS_05 = `q05' ereturn scalar T_BS_95 = `q95' ereturn local vce BollenStine ereturn local vcetype Bollen-Stine `e(cmd)' end cap mata: mata drop CONFA1_BSrotate() mata: void CONFA1_BSrotate( string SigmaName, // the parameter matrix name string varnames // the variable names ) { // declarations real matrix data // views of the data real matrix Sigma, SS, S2, SS2 // the covariance matrices and temp matrices real matrix means // the means -- need modifications for weighted data!!! real scalar p, n // dimension, no. obs // get the data in st_view(data=., ., tokens(varnames) ) n=rows(data) p=cols(data) Sigma = st_matrix(SigmaName) // probability weights!!! means = colsum(data)/n SS = (cross(data,data)-n*means'*means)/(n-1) S2 = cholesky(Sigma) SS2 = cholesky(SS) SS2 = solveupper(SS2',I(rows(SS))) data[,] = data*SS2*S2' } end exit History: v.1.1 -- Jan 9, 2007 v.1.2 -- Mar 26, 2008: confa1 options added; reject() added v.1.3 -- July 12, 2008: upgraded to confa