@@ -39,11 +39,11 @@ struct structFE {
3939
4040class AnalyticalModel { // class for analyitcal OLS, 2SLS, LIML, GMM estimation--everything but iterative ML
4141 real scalar LIML, YY, ee, eec, Fuller, AR, K, k
42- real matrix ZX, ZXEnd, ZZ, H_2SLS, invH, A, VR0, ZVR0, e2, numer, Splus, pi, XXEnd, dbetads, Ze2
42+ real matrix ZX, ZXEnd, ZZ, H_2SLS, invH, A, VR0, ZVR0, e2, numer, Splus, pi, XXEnd, dbetads, Ze2, ZExclXEnd , XExXEnd
4343 real colvector sAll, e, beta, beta0, Ze, ZY
4444 real rowvector YXEnd
4545 pointer(real colvector) scalar pY
46- pointer(real matrix) scalar pXEnd, pXX, pXY, pZExclY, pXExY, pZExclXEnd , pV, pW, pinvZZ, pXExXEx, pZXEx, pXExXEnd , pH, pR0, pS
46+ pointer(real matrix) scalar pXEnd, pXX, pXY, pZExclY, pXExY, pV, pW, pinvZZ, pXExXEx, pZXEx, pH, pR0, pS
4747 pointer (class boottestModel scalar ) scalar parent
4848 pointer (class AnalyticalModel scalar ) scalar DGP
4949 struct smatrix matrix CT_ZVR0
@@ -57,7 +57,7 @@ class boottestModel {
5757 real scalar scoreBS, reps, small, weighttype, null, dirty, initialized, Neq, ML, Nobs, _Nobs, k, kEx, el, sumwt, NClustVar, robust, weights, REst, multiplier, quietly, FEboot, NErrClustCombs, ///
5858 sqrt, hascons, LIML, Fuller, K, IV, WRE, WREnonAR, ptype, twotailed, df, df_r, AR, D, cuepoint, willplot, plotted, NumH0s, p, NBootClustVar, NErrClust, ///
5959 NFE, doQQ, granular, purerobust, subcluster, NBootClust, repsFeas, u_sd, level, MaxMatSize, NWeightGrps, enumerate
60- real matrix QQ, eZVR0, SewtXV, VR0, betadev, numer, u, U , S, SAR, SAll, LAll_invRAllLAll, plot, CI, CT_WE, infoBootAll, infoErrAll, infoAllData, J_ClustN_NBootClust, denom0
60+ real matrix QQ, eZVR0, SewtXV, VR0, betadev, numer, u, S, SAR, SAll, LAll_invRAllLAll, plot, CI, CT_WE, infoBootAll, infoErrAll, infoAllData, J_ClustN_NBootClust, denom0
6161 pointer (real matrix ) scalar pZExcl, pR, pR0, pID, pFEID, pXEnd, pXEx, pG, pX, pinfoBootData, pinfoErrData
6262 pointer (real colvector ) scalar pr, pr0, pY, pSc, pwt, pW, pV
6363 string scalar wttype, madjtype, seed
@@ -67,7 +67,7 @@ class boottestModel {
6767 class AnalyticalModel scalar M_DGP
6868 pointer (class AnalyticalModel scalar ) scalar pM_Repl, pM
6969 struct smatrix matrix denom
70- struct smatrix colvector Kcd, XEndstar , XExXEndstar , ZExclXEndstar , XZi, eZi, euZVR0
70+ struct smatrix colvector Kcd, XZi, eZi, euZVR0
7171 struct structFE rowvector FEs
7272 pointer (real matrix ) matrix pQ
7373 pointer (struct boottest_clust scalar ) scalar pBootClust
@@ -121,25 +121,25 @@ void AnalyticalModel::SetS(real matrix S) {
121121
122122// stuff that can be done before S & r0 set, but depend on endogenous variables, which are bootstrapped in WRE
123123void AnalyticalModel:: InitEndog(pointer (real colvector ) scalar _pY, pointer (real matrix ) scalar _pXEnd, | ///
124- pointer (real colvector ) scalar _pZExclY, pointer (real rowvector ) scalar _pXExY, real scalar _YY , pointer ( real matrix ) scalar _pZExclXEnd , pointer ( real matrix ) scalar _pXExXEnd ) {
124+ pointer (real colvector ) scalar _pZExclY, pointer (real rowvector ) scalar _pXExY) {
125125
126126 pY = partialFE(_pY); pXEnd = partialFE(_pXEnd)
127-
128- pXExY = _pXExY== NULL? & cross(* parent-> pXEx, * parent-> pwt, * parent -> pY) : _pXExY
127+
128+ pXExY = _pXExY== NULL? & cross(* parent-> pXEx, * parent-> pwt, * pY) : _pXExY
129129 if (K | AR)
130130 pZExclY = _pZExclY== NULL? & cross(* parent-> pZExcl, * parent-> pwt, * pY) : _pZExclY
131131 if (K) {
132- pXExXEnd = _pXExXEnd == NULL ? & cross(* parent-> pXEx , * parent-> pwt, * pXEnd) : _pXExXEnd
133- pZExclXEnd = _pZExclXEnd == NULL ? & cross(* parent-> pZExcl, * parent-> pwt, * pXEnd) : _pZExclXEnd
134- ZXEnd = * pXExXEnd \ * pZExclXEnd
132+ XExXEnd = cross(* parent-> pXEx , * parent-> pwt, * pXEnd)
133+ ZExclXEnd = cross(* parent-> pZExcl, * parent-> pwt, * pXEnd)
134+ ZXEnd = XExXEnd \ ZExclXEnd
135135 ZX = * pZXEx, ZXEnd
136- XXEnd = * pXExXEnd \ cross(* pXEnd, * parent-> pwt, * pXEnd)
137- pXX = & (* pXExXEx, * pXExXEnd \ XXEnd' )
136+ XXEnd = XExXEnd \ cross(* pXEnd, * parent-> pwt, * pXEnd)
137+ pXX = & (* pXExXEx, XExXEnd \ XXEnd' )
138138 YXEnd = cross(* pY, * parent-> pwt, * pXEnd)
139139 ZY = * pXExY \ * pZExclY
140140 pXY = & (* pXExY \ YXEnd' )
141141 if (LIML | ! (parent-> robust | parent-> scoreBS))
142- YY = _YY == . ? cross(* pY, * parent-> pwt, * pY) : _YY
142+ YY = cross(* pY, * parent-> pwt, * pY)
143143
144144 if (parent-> IV) // if GMM weight matrix not provided, prepare 2SLS one
145145 A = (I(parent-> kEx) \ J(parent-> el- parent-> kEx, parent-> kEx, 0)), * pinvZZ * ZXEnd // 2SLS is (A' ZX)^-1 * (A'ZY). Also apparently used in k-class and LIML robust VCV by Stata convention
@@ -845,7 +845,6 @@ void boottestModel::boottest() {
845845
846846 denom = smatrix(df, df)
847847 if (WREnonAR) {
848- XEndstar = XExXEndstar = ZExclXEndstar = smatrix(D- 1)
849848 if (NClustVar)
850849 XZi = eZi = smatrix(NBootClust)
851850 } else if (robust) {
@@ -890,7 +889,7 @@ void boottestModel::boottest() {
890889
891890 if (! ML) // GMM, 2SLS, analytical LIML
892891 if (AR) {
893- pM_Repl-> InitEndog(& (* pY - * pXEnd * * pr0), NULL, & (* M_DGP.pZExclY - * M_DGP.pZExclXEnd * * pr0), & (* M_DGP.pXExY - * M_DGP.pXExXEnd * * pr0))
892+ pM_Repl-> InitEndog(& (* pY - * pXEnd * * pr0), NULL, & (* M_DGP.pZExclY - M_DGP.ZExclXEnd * * pr0), & (* M_DGP.pXExY - M_DGP.XExXEnd * * pr0))
894893 pM_Repl-> InitEstimate()
895894 pM_Repl-> Estimate(sAR)
896895 pM_Repl-> InitTestDenoms(SAR)
@@ -954,21 +953,18 @@ void boottestModel::MakeWildWeights(real scalar _reps, real scalar first) {
954953 u = runiform(NBootClust, _reps+ first) :>= .5; u = u :- .5 // Rademacher weights, divided by 2
955954 u_sd = .5
956955 }
956+
957957 if (first)
958958 u[, 1] = J(NBootClust, 1, WREnonAR? 0 : u_sd) // keep original residuals in first entry to compute base model stat
959-
960- U = WREnonAR? u[IDBootData, ] : J(0, 0, 0)
961959}
962960
963-
964961real scalar boottestModel:: MakeWREStats(real scalar thisWeightGrpStart, real scalar thisWeightGrpStop) {
965- real scalar c, j, i
966- real colvector _e, Ystar, _beta, betaEnd
967- real rowvector YstarYstar
968- real matrix ZExclYstar, XExYstar, Subscripts, Zi, AVR0, t, XExi
969- pointer (real matrix ) scalar peZVR0, pu, pXEndstar, pXExXEndstar, pZExclXEndstar
970962 pragma unused thisWeightGrpStop
971-
963+ real scalar c, j, i
964+ real colvector _e, _beta, betaEnd, _u
965+ real matrix Subscripts, Zi, AVR0, t, XExi
966+ pointer (real matrix ) scalar peZVR0
967+
972968 if (initialized & ! null) { // if not imposing null and we have returned, then df=1; and distribution doesn't change with r0, only test stat
973969 numer[1] = * pR0 * pM_Repl-> beta - * pr0
974970 Dist[1] = numer[1] / sqrt(denom.M[1]) * multiplier
@@ -977,52 +973,27 @@ real scalar boottestModel::MakeWREStats(real scalar thisWeightGrpStart, real sca
977973
978974 if (thisWeightGrpStart == 1) { // first/only weight group? initialize a couple of things
979975 _e = M_DGP.e + M_DGP.e2 * M_DGP.beta[| kEx+ 1\ .| ]
980- pu = NClustVar? & U : & u
981- }
982-
983- Ystar = * M_DGP.pY :+ _e :* * pu
984- XExYstar = cross(* pXEx , * pwt, Ystar)
985- ZExclYstar = cross(* pZExcl, * pwt, Ystar)
986-
987- if ((LIML | ! robust) & ! NFE)
988- YstarYstar = weights? cross(* pwt, Ystar:* Ystar) : colsum(Ystar:* Ystar)
989976
990- if (D== 2) {
991- XEndstar.M = * pXEnd :+ M_DGP.e2 :* * pu
992- XExXEndstar.M = cross(* pXEx , * pwt, XEndstar.M)
993- ZExclXEndstar.M = cross(* pZExcl, * pwt, XEndstar.M)
994- } else
995- for (j= D- 1; j; j-- ) {
996- XEndstar[j].M = (* pXEnd)[, j] :+ M_DGP.e2[, j] :* * pu
997- XExXEndstar [j].M = cross(* pXEx , * pwt, XEndstar[j].M)
998- ZExclXEndstar[j].M = cross(* pZExcl, * pwt, XEndstar[j].M)
999- }
1000-
1001- if (NClustVar & ! NFE) // prep for optimized computation for bootstrapping cluster when no FE
1002- for (i= NBootClust; i; i-- ) {
1003- Subscripts = (* pinfoBootData)[i, ]', (.\ .)
1004- XExi = kEx? (* pXEx)[| Subscripts| ] : J((* pinfoBootData)[i, 2]- (* pinfoBootData)[i, 1]+ 1, 0, 0)
1005- Zi = XExi , (* pZExcl)[| Subscripts| ] // inefficient?
1006- if (weights) Zi = Zi :* (* pwt)[| Subscripts| ]
1007- XZi[i].M = cross(XExi, Zi) \ cross((* pXEnd)[| Subscripts| ], Zi) \ cross((* pY)[| Subscripts| ], Zi)
1008- eZi[i].M = cross(M_DGP.e2[| Subscripts| ], Zi) \ cross( _e[| Subscripts| ], Zi)
1009- }
977+ if (NClustVar & ! NFE) // prep for optimized computation for bootstrapping cluster when no FE
978+ for (i= NBootClust; i; i-- ) {
979+ Subscripts = (* pinfoBootData)[i, ]', (.\ .)
980+ XExi = kEx? (* pXEx)[| Subscripts| ] : J(Subscripts[2, 1]- Subscripts[1, 1]+ 1, 0, 0)
981+ Zi = XExi , (* pZExcl)[| Subscripts| ] // inefficient?
982+ if (weights) Zi = Zi :* (* pwt)[| Subscripts| ]
983+ XZi[i].M = cross(XExi, Zi) \ cross((* pXEnd)[| Subscripts| ], Zi) \ cross((* pY)[| Subscripts| ], Zi)
984+ eZi[i].M = cross(M_DGP.e2[| Subscripts| ], Zi) \ cross( _e[| Subscripts| ], Zi)
985+ }
986+ }
1010987
1011988 for (j= cols(u); j; j-- ) { // WRE bootstrap
1012- pXEndstar = & ( XEndstar.M [, j])
1013- pXExXEndstar = & (XExXEndstar.M [, j])
1014- pZExclXEndstar = & (ZExclXEndstar.M[, j])
1015- for (i= 2; i< D; i++ ) {
1016- pXEndstar = & (* pXEndstar , XEndstar [i].M[, j])
1017- pXExXEndstar = & (* pXExXEndstar , XExXEndstar [i].M[, j])
1018- pZExclXEndstar = & (* pZExclXEndstar, ZExclXEndstar[i].M[, j])
1019- }
1020-
1021- pM_Repl-> InitEndog(& (Ystar[, j]), pXEndstar, & (ZExclYstar[, j]), & (XExYstar[, j]), (cols(YstarYstar)? YstarYstar[j] : .), pZExclXEndstar, pXExXEndstar)
989+ _u = u[IDBootData, j]
990+
991+ pM_Repl-> InitEndog(& (* M_DGP.pY:+ _e:* _u) , & (* pXEnd:+ M_DGP.e2:* _u))
1022992 pM_Repl-> InitEstimate()
1023993 pM_Repl-> InitTestDenoms(S) // prepare for replication regressions, null not imposed
1024994 pM_Repl-> Estimate(s)
1025- numer = null | j== 1? * pR0 * pM_Repl-> beta - * pr0 : * pR0 * (pM_Repl-> beta - M_DGP.beta0)
995+
996+ numer = null | thisWeightGrpStart== 1 & j== 1? * pR0 * pM_Repl-> beta - * pr0 : * pR0 * (pM_Repl-> beta - M_DGP.beta0)
1026997
1027998 if (robust) { // Compute denominator for this WRE test stat
1028999 denom = smatrix()
@@ -1048,7 +1019,6 @@ real scalar boottestModel::MakeWREStats(real scalar thisWeightGrpStart, real sca
10481019 denom.M = (* pR0 * pM_Repl-> VR0) * pM_Repl-> eec
10491020
10501021 Dist[j+ thisWeightGrpStart- 1] = sqrt? numer/ sqrt(denom.M) : cross(numer, invsym(denom.M) * numer)
1051-
10521022 }
10531023 if (thisWeightGrpStart== 1 & df== 2) denom0 = denom.M // original-sample denominator
10541024
@@ -1093,14 +1063,6 @@ real scalar boottestModel::MakeNonWRENumers(real scalar thisWeightGrpStart, real
10931063 return(0)
10941064}
10951065
1096-
1097-
1098-
1099-
1100-
1101-
1102-
1103-
11041066void boottestModel:: MakeNonWREStats(real scalar thisWeightGrpStart, real scalar thisWeightGrpStop) {
11051067 real scalar d, i, c, j, l; real matrix eu, eueu, t; real colvector numer_l; pointer (real matrix ) scalar peZVR0, pVR0
11061068
0 commit comments