1- *! boottest 2.1.8 3 August 2018
1+ *! boottest 2.1.9 4 August 2018
22*! Copyright (C) 2015-18 David Roodman
33
44* This program is free software: you can redistribute it and/or modify
@@ -20,7 +20,7 @@ mata set mataoptimize on
2020mata set matalnum off
2121
2222string scalar boottestStataVersion() return(" `c(stata_version)'" )
23- string scalar boottestVersion() return(" 02.01.00 " )
23+ string scalar boottestVersion() return(" 02.01.09 " )
2424
2525struct smatrix {
2626 real matrix M
@@ -68,7 +68,7 @@ class boottestModel {
6868 pointer (class AnalyticalModel scalar ) scalar pM_Repl, pM
6969 struct smatrix matrix denom
7070 struct smatrix colvector Kcd, XEndstar, XExXEndstar, ZExclXEndstar, XZi, eZi, euZVR0
71- pointer ( struct structFE scalar ) scalar FEs
71+ struct structFE rowvector FEs
7272 pointer (real matrix ) matrix pQ
7373 pointer (struct boottest_clust scalar ) scalar pBootClust
7474
@@ -386,8 +386,8 @@ void boottestModel::setID (real matrix ID, | real scalar NBootClustVar, rea
386386 this.pID = & ID; this.NBootClustVar = editmissing(NBootClustVar, 1); this.NErrClust= editmissing(NErrClust, 1); setdirty(1)
387387 if (cols(ID)) this.robust = 1
388388}
389- void boottestModel:: setFEID (real matrix ID) {
390- this.pFEID = & ID; setdirty(1)
389+ void boottestModel:: setFEID(real matrix ID, real scalar NFE ) {
390+ this.pFEID = & ID; this.NFE = NFE; setdirty(1)
391391}
392392void boottestModel:: setlevel (real scalar level )
393393 this.level = level
@@ -602,7 +602,7 @@ void boottestModel::boottest() {
602602 real colvector rAll, sortID, o, _FEID
603603 real rowvector val, ClustCols
604604 real matrix RAll, L, LAll, vec, Combs, t, IDErr
605- real scalar i, j, c, minN, sumN, _reps, g
605+ real scalar i, j, c, minN, sumN, _reps, g, i_FE
606606 pointer (real matrix ) scalar _pR0, pIDAll
607607 class AnalyticalModel scalar M_WRE
608608 pragma unset vec; pragma unset val; pragma unused M_WRE
@@ -713,37 +713,36 @@ void boottestModel::boottest() {
713713 J_ClustN_NBootClust = J(Clust.N, NBootClust, 0)
714714 }
715715
716- if (cols( * pFEID)) { // fixed effect prep
716+ if (NFE) {
717717 sortID = (* pFEID)[o = order(* pFEID, 1)]
718- NFE = 1; FEboot = reps> 0; j = Nobs; _FEID = wtFE = J(Nobs, 1, 1)
718+ i_FE = 1; FEboot = reps> 0; j = Nobs; _FEID = wtFE = J(Nobs, 1, 1)
719+ FEs = structFE(NFE)
719720 for (i= Nobs- 1;i;i-- ) {
720721 if (sortID[i] != sortID[i+ 1]) {
721- NFE++
722- next = FEs; (FEs = & (structFE()))-> next = next // add new FE to linked list
723- FEs-> is = o[| i+ 1\ j| ]
722+ FEs[i_FE].is = o[| i+ 1\ j| ]
724723 if (weights) {
725- FEs -> wt = (* pwt)[FEs-> is]
726- FEs-> wt = FEs -> wt / colsum(FEs -> wt )
724+ t = (* pwt)[FEs[i_FE]. is]
725+ FEs[i_FE]. wt = t / colsum(t )
727726 } else
728- FEs-> wt = J(j- i, 1, 1/ (j- i))
729- wtFE[FEs-> is] = FEs-> wt
727+ FEs[i_FE]. wt = J(j- i, 1, 1/ (j- i))
728+ wtFE[FEs[i_FE]. is] = FEs[i_FE]. wt
730729 j = i
731730
732731 if (FEboot & NClustVar) { // are all of this FE's obs in same bootstrapping cluster?
733- t = (* pID)[FEs-> is, 1.. NBootClustVar]
732+ t = (* pID)[FEs[i_FE]. is, 1.. NBootClustVar]
734733 FEboot = all (t :== t[1, ])
735734 }
735+ ++ i_FE
736736 }
737- _FEID[o[i]] = NFE
737+ _FEID[o[i]] = i_FE
738738 }
739- next = FEs; (FEs = & (structFE()))-> next = next
740- FEs-> is = FEs-> is = o[| .\ j| ]
739+ FEs[NFE].is = FEs[NFE].is = o[| .\ j| ]
741740 if (weights) {
742- FEs -> wt = (* pwt)[FEs-> is]
743- FEs-> wt = FEs -> wt / colsum(FEs -> wt )
741+ t = (* pwt)[FEs[NFE]. is]
742+ FEs[NFE]. wt = t / colsum(t )
744743 } else
745- FEs-> wt = J(j- i, 1, 1/ (j- i))
746- wtFE[FEs-> is] = FEs-> wt
744+ FEs[NFE]. wt = J(j- i, 1, 1/ (j- i))
745+ wtFE[FEs[NFE]. is] = FEs[NFE]. wt
747746 pFEID = & _FEID // ordinal fixed effect ID
748747 if (robust & ! (scoreBS | FEboot) & granular < NErrClustCombs)
749748 infoBootAll = _panelsetup(* pIDAll, 1.. NBootClustVar) // info for bootstrapping clusters wrt data collapsed to intersections of all bootstrapping & error clusters
@@ -1094,9 +1093,12 @@ real scalar boottestModel::MakeNonWRENumers(real scalar thisWeightGrpStart, real
10941093
10951094
10961095
1096+
1097+
1098+
1099+
10971100void boottestModel:: MakeNonWREStats(real scalar thisWeightGrpStart, real scalar thisWeightGrpStop) {
1098- real scalar d, i, c, j, l; real matrix eu, eueu, t; real colvector numer_l
1099- pointer (real matrix ) scalar peZVR0, pVR0
1101+ real scalar d, i, c, j, l; real matrix eu, eueu, t; real colvector numer_l; pointer (real matrix ) scalar peZVR0, pVR0
11001102
11011103 if (robust) {
11021104 if (granular < NErrClustCombs & thisWeightGrpStart== 1) { // if pure robust and no multi-way clustering, initialized stuff that depends on r0 but not u
@@ -1169,7 +1171,7 @@ void boottestModel::MakeNonWREStats(real scalar thisWeightGrpStart, real scalar
11691171 denom[i, j].M = colsum(u :* QQ * u)
11701172 }
11711173 else { // alternative core computational loop, avoiding computing Q'Q which has cubic time cost in numbers of bootstrapping clusters
1172- if (granular) // prep optimized treatment when bootstrapping by small groups
1174+ if (granular) // prep optimized treatment when bootstrapping by many/ small groups
11731175 if (purerobust) {
11741176 eu = * M_DGP.partialFE(& (pM-> e :* u)) - * pX * betadev
11751177 eueu = eu:* eu
@@ -1332,13 +1334,12 @@ real matrix boottestModel::count_binary(real scalar N, real scalar lo, real scal
13321334
13331335// partial fixed effects out of a data matrix
13341336pointer(real matrix) scalar AnalyticalModel:: partialFE(pointer(real matrix) scalar pIn) {
1337+ real matrix Out, t; real scalar i
13351338 if (parent-> NFE & pIn!= NULL) {
1336- real matrix Out, t; pointer (struct structFE scalar ) scalar thisFE
1337- thisFE = parent-> FEs; Out = J(rows(* pIn), cols(* pIn), .)
1338- while (thisFE != NULL) {
1339- t = (* pIn)[thisFE-> is, ]
1340- Out[thisFE-> is, ] = t :- cross(thisFE-> wt, t)
1341- thisFE = thisFE-> next
1339+ Out = * pIn
1340+ for (i= parent-> NFE;i;i-- ) {
1341+ t = Out[parent-> FEs[i].is, ]
1342+ Out[parent-> FEs[i].is, ] = t :- cross(parent-> FEs[i].wt, t)
13421343 }
13431344 return(& Out)
13441345 }
@@ -1516,7 +1517,7 @@ void boottest_stata(string scalar statname, string scalar dfname, string scalar
15161517 real scalar K, real scalar AR, real scalar null, real scalar scoreBS, string scalar weighttype, string scalar ptype, string scalar madjtype, real scalar NumH0s,
15171518 string scalar XExnames, string scalar XEndnames, real scalar hascons, string scalar Ynames, string scalar bname, string scalar Vname, string scalar Wname,
15181519 string scalar ZExclnames, string scalar samplename, string scalar scnames, real scalar robust, string scalar IDnames, real scalar NBootClustVar, real scalar NErrClust,
1519- string scalar FEname, string scalar wtname, string scalar wttype, string scalar Cname, string scalar C0name, real scalar reps, string scalar repsname, string scalar repsFeasname,
1520+ string scalar FEname, real scalar NFE , string scalar wtname, string scalar wttype, string scalar Cname, string scalar C0name, real scalar reps, string scalar repsname, string scalar repsFeasname,
15201521 real scalar small, string scalar diststat, string scalar distname, real scalar gridmin, real scalar gridmax, real scalar gridpoints, real scalar MaxMatSize) {
15211522
15221523 real matrix C, R, C0, R0, ZExcl, ID, FEID, sc, XEnd, XEx
@@ -1548,7 +1549,7 @@ void boottest_stata(string scalar statname, string scalar dfname, string scalar
15481549 M.setZExcl(ZExcl)
15491550 M.setwt (wt)
15501551 M.setID(ID, NBootClustVar, NErrClust)
1551- M.setFEID(FEID)
1552+ M.setFEID(FEID, NFE )
15521553 M.setR (R , r )
15531554 M.setR0(R0, r0)
15541555 M.setnull(null)
0 commit comments