@@ -703,7 +703,7 @@ void boottestModel::boottest() {
703703 NBootClust = rows(* pinfoBootData)
704704
705705 purerobust = NBootClust== Nobs & ! ML & ! subcluster // do we ever error-cluster *and* bootstrap-cluster by individual?
706- granular = purerobust | 5* Nobs* k+ 1/ 25* 2* Clust.N * k^ 2+ 1/ 25* 2* Clust.N ^ 2* k+ Clust.N + 1/ 25* 2* Clust.N ^ 2* reps+ 2* Clust.N * reps > 3* Nobs* reps+ Nobs* k+ 1/ 25* (2* Clust.N * k* reps+ 2* k* reps- 2* k* Clust.N - 2* Clust.N * reps+ 2* Clust.N * k* reps)+ 2* Clust.N * reps
706+ granular = ! scoreBS & ( purerobust | 5* Nobs* k+ 1/ 25* 2* NBootClust * k^ 2+ 1/ 25* 2* NBootClust ^ 2* k+ NBootClust + 1/ 25* 2* NBootClust ^ 2* reps+ 2* NBootClust * reps > 3* Nobs* reps+ Nobs* k+ 1/ 25* (2* NBootClust * k* reps+ 2* k* reps- 2* k* NBootClust - 2* NBootClust * reps+ 2* NBootClust * k* reps)+ 2* NBootClust * reps)
707707 doQQ = ! granular & NBootClust * (sumN + NBootClust* reps + .5* (NErrClustCombs)) < 2* reps* (2* sumN + NErrClustCombs) // estimate compute time for U :* (sum_c QQ) * U vs. sum_c(colsum((Q_c*U):*(Q_c*U)))
708708
709709 if (granular & rows(IDBootData)== 0 & NClustVar)
@@ -809,8 +809,7 @@ void boottestModel::boottest() {
809809
810810 if (granular) {
811811 euZVR0 = smatrix(df)
812- if (! scoreBS)
813- pX = AR? & (* pXEx, * pZExcl) : pXEx
812+ pX = AR? & (* pXEx, * pZExcl) : pXEx
814813 }
815814
816815 M_DGP.SetS(SAll) // (potentially) constrained model in DGP; SAll imposes constraints, pR0 tests hypotheses on results
@@ -899,6 +898,7 @@ void boottestModel::boottest() {
899898
900899 if (NWeightGrps > 1)
901900 rseed(seed)
901+
902902 for (g= 1; g<= NWeightGrps; g++ ) { // do group 1 first because it includes col 1, which is all that might need updating in constructing CI in WCU
903903 if (NWeightGrps > 1)
904904 MakeWildWeights(WeightGrpStop[g] - WeightGrpStart[g] + (g> 1), g== 1)
@@ -1173,29 +1173,14 @@ void boottestModel::MakeNonWREStats(real scalar thisWeightGrpStart, real scalar
11731173 denom[i, j].M = colsum(u :* QQ * u)
11741174 }
11751175 else { // alternative core computational loop, avoiding computing Q'Q which has cubic time cost in numbers of bootstrapping clusters
1176- if (granular) // prep optimized treatment when clustering and bootstrapping by observation
1177- if (ML)
1178- for (d= df;d;d-- ) {
1179- pQ[1, d] = & _panelsum(u, eZVR0[, d], Clust.info)
1180- pQ[1, d] = & (* pQ[1, d] :- (weights? cross(ClustShare, * pQ[1, d]) : colsum(* pQ[1, d]) * ClustShare)) // recenter
1181- if (weights) pQ[1, d] = & (* pQ[1, d] :* * pwt)
1182- }
1183- else if (purerobust) {
1184- eu = * M_DGP.partialFE(& (pM-> e :* u))
1185- if (scoreBS)
1186- eu = eu :- (weights? cross(ClustShare, eu) : colsum(eu) * ClustShare) // recenter
1187- else
1188- eu = eu - * pX * betadev
1176+ if (granular) // prep optimized treatment when bootstrapping by small groups
1177+ if (purerobust) {
1178+ eu = * M_DGP.partialFE(& (pM-> e :* u)) - * pX * betadev
11891179 eueu = eu:* eu
11901180 } else { // clusters small but not all singletons
1191- eu = * M_DGP.partialFE(& (pM-> e :* (purerobust? u : u[IDBootData, ])))
1192- for (d= df;d;d-- ) {
1193- pQ[1, d] = & _panelsum(eu, pM-> WZVR0[d].M, * pinfoErrData)
1194- if (scoreBS)
1195- pQ[1, d] = & (* pQ[1, d] :- (weights? cross(ClustShare, * pQ[1, d]) : colsum(* pQ[1, d]) * ClustShare)) // recenter
1196- else
1197- pQ[1, d] = & (* pQ[1, d] - _panelsum(* pX, pM-> WZVR0[d].M, * pinfoErrData) * betadev)
1198- }
1181+ eu = * M_DGP.partialFE(& (pM-> e :* u[IDBootData, ]))
1182+ for (d= df;d;d-- )
1183+ pQ[1, d] = & (_panelsum(eu, pM-> WZVR0[d].M, * pinfoErrData) - _panelsum(* pX, pM-> WZVR0[d].M, * pinfoErrData) * betadev)
11991184 }
12001185
12011186 for (c= NErrClustCombs; c> granular; c-- )
0 commit comments