Skip to content

Commit

Permalink
Fixed crash in AR test after over-ID'd regression; added mention of j…
Browse files Browse the repository at this point in the history
…ackknifing to output
  • Loading branch information
droodman committed Dec 29, 2022
1 parent 911d995 commit 2b81ba5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 58 deletions.
9 changes: 7 additions & 2 deletions boottest.ado
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*! boottest 4.4.0 23 December 2022
*! boottest 4.4.1 28 December 2022
*! Copyright (C) 2015-22 David Roodman

* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -1001,7 +1001,11 @@ program define _boottest, rclass sortpreserve
}

di
if `reps' di as txt strproper("`boottype'") " bootstrap-`statistic', null " cond(0`null', "", "not ") "imposed, " as txt `reps' as txt " replications, " _c
if `reps' {
di as txt strproper("`boottype'") " bootstrap-`statistic', null " cond(0`null', "", "not ") "imposed, " _c
if `jk' di "jackknifed residuals, " _c
di as txt `reps' as txt " replications, " _c
}
di as txt cond(`ar', "Anderson-Rubin ", "") cond(!`reps' & `null' & "`boottype'"=="score", "Rao score (Lagrange multiplier)", "Wald") " test" _c
if "`cluster'"!="" di ", clustering by " as res "`cluster'" _c
if ("`bootcluster'"!="" | `NErrClustVar' > 1) & `reps' di as txt ", bootstrap clustering by " as res "`bootcluster'" _c
Expand Down Expand Up @@ -1169,6 +1173,7 @@ end


* Version history
* 4.4.1 Fixed crash in AR test after over-ID'd regression; added mention of jackknifing to output
* 4.4.0 Minimized O(N) operations in non-jk WRE when clustering is coarse. Skip FE code in WRE if FE = cluster grouping. Bumped Julia version to 0.8.5.
* 4.3.1 Bumped Julia version to 0.8.3. Check for Python 2. Restored code path of memory-intensive granular WRE computation of denominator.
* 4.3.0 Added jackknife for WRE; fixed failure to detect constant term after ivreg; fixed incorrect computation in "WUE"
Expand Down
84 changes: 36 additions & 48 deletions boottest.mata
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*! boottest 4.4.0 23 December 2022
*! boottest 4.4.1 28 December 2022
*! Copyright (C) 2015-22 David Roodman

* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -527,7 +527,7 @@ void boottestIVGMM::InitVars(|pointer(real matrix) scalar pRperp) {
if (parent->robust & parent->bootstrapt & (parent->granular | parent->jk /*| parent->NFE*/)) { // for WRE replication regression, prepare for CRVE
XinvXX = *pX12B(*pX1, X2, invXX)
if (((parent->granular & parent->Nw==1) | parent->jk) & parent->WREnonARubin)
if ((parent->granular | parent->jk) & parent->WREnonARubin)
PXZ = *pX12B(*pX1, X2, invXXXZ)
}
}
Expand Down Expand Up @@ -1409,7 +1409,7 @@ void boottest::boottest() {
rseed(seed)
MakeWildWeights(WeightGrpStop[1] - 1, 1)
}
if (WREnonARubin)
PrepWRE()
else
Expand Down Expand Up @@ -1501,6 +1501,7 @@ void boottest::MakeWildWeights(real scalar _B, real scalar first) {
// (only really the Hessian when we narrow Y to Z)
real matrix boottest::HessianFixedkappa(real rowvector ind1, real scalar ind2, real scalar kappa, real scalar _jk) {
real matrix retval; real scalar i
if (cols(ind1) > 1) {
retval = J(cols(ind1),cols(v),0)
for (i=cols(ind1);i;i--)
Expand Down Expand Up @@ -1559,52 +1560,39 @@ pointer(real matrix) scalar boottest::Filling(real scalar ind1, real matrix beta
pragma unset retval
if (granular) { // create pieces of each N x B matrix one at a time rather than whole thing at once
if (Nw == 1) { // create or avoid NxB matrix?
pPXYstar = pcol(PXZbar, ind1)
if (Repl.Yendog[ind1+1])
pPXYstar = &(*pPXYstar :+ SstarUPX[ind1+1].M * v)
retval = *_panelsum(*pPXYstar :* (DGP.y1bar :- SstarUMZperp.M * v), *pinfoCapData)
for (ind2=Repl.kZ;ind2;ind2--) {
retval = J(Clust.N, cols(v), 0)
SstarUXv = SstarUX[ind1+1].M * v
for (ind2=0; ind2<=Repl.kZ; ind2++) {
if (ind2) {
_beta = betas[ind2,]
retval = retval - *_panelsum(*pPXYstar :* (Repl.Yendog[ind2+1]? *pcol(Zbar,ind2) * _beta :- SstarUMZperp[ind2+1].M * (v :* _beta) :
*pcol(Zbar,ind2) * _beta ), *pinfoCapData)
}
} else { // create pieces of each N x B matrix one at a time rather than whole thing at once--slower, but less memory-intensive
retval = J(Clust.N, cols(v), 0)
SstarUXv = SstarUX[ind1+1].M * v
for (ind2=0; ind2<=Repl.kZ; ind2++) {
if (ind2) {
_beta = betas[ind2,]
pbetav = &(v :* _beta)
} else
pbetav = &v
pbetav = &(v :* _beta)
} else
pbetav = &v
if (Repl.Yendog[ind2+1])
SstarUZperpinvZperpZperp_v = SstarinvZperpZperpZperpU[ind2+1].M * *pbetav
if (Repl.Yendog[ind2+1])
SstarUZperpinvZperpZperp_v = SstarinvZperpZperpZperpU[ind2+1].M * *pbetav
if (NFE & FEboot==0)
CTstarFEUv = invFEwt :* (CTstarFEU[ind2+1].M * *pbetav)
if (NFE & FEboot==0)
CTstarFEUv = invFEwt :* (CTstarFEU[ind2+1].M * *pbetav)
for (i=Clust.N;i;i--) {
S = (*pinfoCapData)[i,]'
pPXYstar = &PXZbar[|S,(ind1\ind1)|]
if (Repl.Yendog[ind1+1])
pPXYstar = &(*pPXYstar :+ *pXS(Repl.XinvXX,S) * SstarUXv)
if (Repl.Yendog[ind2+1]) {
SstarUMZperp_ind2_i = *pXS(*Repl.pZperp,S) * SstarUZperpinvZperpZperp_v - (ind2? (*pU2parddot)[|S, (ind2\ind2)|] :* (*pbetav)[*pXS(*pIDBootData,S),] :
DGP.u1dddot.M[|S |] :* v [*pXS(*pIDBootData,S),])
if (NFE & FEboot==0)
SstarUMZperp_ind2_i = SstarUMZperp_ind2_i + CTstarFEUv[(*pFEID)[|S|],] // CT_(*,FE) (U ̈_(∥j) ) (S_FE S_FE^' )^(-1) S_FE
if (ind2)
retval[i,] = retval[i,] - colsum(*pPXYstar :* (Zbar[|S,(ind2\ind2)|] * _beta :- SstarUMZperp_ind2_i))
else
retval[i,] = colsum(*pPXYstar :* (DGP.y1bar[|S|] :- SstarUMZperp_ind2_i))
} else
retval[i,] = retval[i,] - colsum(*pPXYstar :* (Zbar[|S,(ind2\ind2)|] * _beta))
}
for (i=Clust.N;i;i--) {
S = (*pinfoCapData)[i,]'
pPXYstar = &PXZbar[|S,(ind1\ind1)|]
if (Repl.Yendog[ind1+1])
pPXYstar = &(*pPXYstar :+ *pXS(Repl.XinvXX,S) * SstarUXv)
if (Repl.Yendog[ind2+1]) {
SstarUMZperp_ind2_i = *pXS(*Repl.pZperp,S) * SstarUZperpinvZperpZperp_v - (ind2? (*pU2parddot)[|S, (ind2\ind2)|] :* (*pbetav)[*pXS(*pIDBootData,S),] :
DGP.u1dddot.M[|S |] :* v [*pXS(*pIDBootData,S),])
if (NFE & FEboot==0)
SstarUMZperp_ind2_i = SstarUMZperp_ind2_i + CTstarFEUv[(*pFEID)[|S|],] // CT_(*,FE) (U ̈_(∥j) ) (S_FE S_FE^' )^(-1) S_FE
if (ind2)
retval[i,] = retval[i,] - colsum(*pPXYstar :* (Zbar[|S,(ind2\ind2)|] * _beta :- SstarUMZperp_ind2_i))
else
retval[i,] = colsum(*pPXYstar :* (DGP.y1bar[|S|] :- SstarUMZperp_ind2_i))
} else
retval[i,] = retval[i,] - colsum(*pPXYstar :* (Zbar[|S,(ind2\ind2)|] * _beta))
}
}
} else if (jk) // coarse error clustering with O(N) operations
Expand Down Expand Up @@ -1879,7 +1867,7 @@ void boottest::InitWRE() { // stuff done only once that knits together results
}
}
if (NFE & FEboot==0) {
if (jk==0 & robust & bootstrapt & NFE & FEboot==0) {
CTstarFEY2 = smatrix(kY2); for (i=kY2;i;i--) CTstarFEY2[i].M = crosstabFE(*pcol(DGP.Y2,i), infoBootData)
CTstarFEX = smatrix(DGP.kX); for (i=DGP.kX1;i ;i--) CTstarFEX[i].M = crosstabFE(*pcol(*DGP.pX1,i ), infoBootData)
for (i=DGP.kX;i>DGP.kX1;i--) CTstarFEX[i].M = crosstabFE(*pcol(DGP.X2 ,i-DGP.kX1), infoBootData)
Expand Down Expand Up @@ -1973,7 +1961,7 @@ void boottest::PrepWRE() {
SstarUU[i+1,j+1].M = *_panelsum(j? *pcol(*pU2parddot,j) : DGP.u1dddot.M, *pu, infoBootData)
}
if (robust & bootstrapt & (granular==0 | Nw==1) & Repl.Yendog[i+1]) {
if (robust & bootstrapt & granular==0 & Repl.Yendog[i+1]) {
SstarUPX[i+1].M = Repl.XinvXX * SstarUX[i+1].M
SstarUMZperp[i+1].M = *Repl.pZperp * SstarinvZperpZperpZperpU[i+1].M
if (Nobs == Nstar) // subtract "crosstab" of observation by cap-group of u
Expand Down Expand Up @@ -2711,7 +2699,7 @@ void boottest::plot() {
if (q==2) { // 2D plot
lo = hi = J(2, 1, .)
for(d=df;d;d--) {
for(d=q;d;d--) {
lo[d] = editmissing(gridmin[d], confpeak[d] - halfwidth[d])
hi[d] = editmissing(gridmax[d], confpeak[d] + halfwidth[d])
Expand Down
Binary file modified lboottest.mlib
Binary file not shown.
16 changes: 8 additions & 8 deletions unit tests.log
Original file line number Diff line number Diff line change
Expand Up @@ -246,15 +246,15 @@ Wild bootstrap-t, null imposed, 999 replications, Wald test, bootstrap clusterin
t(7) = 2.0194
Prob>|t| = 0.0921

Wild bootstrap-t, null imposed, 999 replications, Wald test, bootstrap clustering by year, Webb weights:
Wild bootstrap-t, null imposed, jackknifed residuals, 999 replications, Wald test, bootstrap clustering by year, Webb weights:
post_self=.04

t(7) = 2.0194
Prob>|t| = 0.0991

95% confidence set for null hypothesis expression: [.03593, .07168]

Wild bootstrap-t, null not imposed, 999 replications, Wald test, bootstrap clustering by year, Webb weights:
Wild bootstrap-t, null not imposed, jackknifed residuals, 999 replications, Wald test, bootstrap clustering by year, Webb weights:
post_self=.04

t(7) = 2.0194
Expand Down Expand Up @@ -471,7 +471,7 @@ Wild bootstrap-t, null imposed, 999 replications, Wald test, bootstrap clusterin
z = 7.5847
Prob>|z| = 0.0070

Wild bootstrap-t, null imposed, 999 replications, Wald test, bootstrap clustering by industry, Rademacher weights:
Wild bootstrap-t, null imposed, jackknifed residuals, 999 replications, Wald test, bootstrap clustering by industry, Rademacher weights:
tenure

z = 7.5847
Expand Down Expand Up @@ -524,7 +524,7 @@ Wild bootstrap-t, null imposed, 999 replications, Wald test, bootstrap clusterin

95% confidence set for null hypothesis expression: [−.8324, −.602] ∪ [.2065, 1.205]

Wild bootstrap-t, null imposed, 999 replications, Wald test, bootstrap clustering by industry, Rademacher weights:
Wild bootstrap-t, null imposed, jackknifed residuals, 999 replications, Wald test, bootstrap clustering by industry, Rademacher weights:
tenure

z = 4.0267
Expand All @@ -546,7 +546,7 @@ Wild bootstrap-t, null imposed, 999 replications, Anderson-Rubin Wald test, boot
chi2(2) = 477.2687
Prob > chi2 = 0.0000

Wild bootstrap-t, null imposed, 999 replications, Anderson-Rubin Wald test, bootstrap clustering by industry, Rademacher weights:
Wild bootstrap-t, null imposed, jackknifed residuals, 999 replications, Anderson-Rubin Wald test, bootstrap clustering by industry, Rademacher weights:
collgrad tenure

chi2(2) = 477.2687
Expand All @@ -566,7 +566,7 @@ Wild bootstrap-t, null imposed, 999 replications, Wald test, Rademacher weights:

95% confidence set for null hypothesis expression: [−.0196, .0829]

Wild bootstrap-t, null imposed, 999 replications, Wald test, Rademacher weights:
Wild bootstrap-t, null imposed, jackknifed residuals, 999 replications, Wald test, Rademacher weights:
tenure

t(2227) = 1.2925
Expand Down Expand Up @@ -616,7 +616,7 @@ Wild bootstrap-t, null imposed, 999 replications, Wald test, clustering by age o

Overriding estimator's cluster/robust settings with cluster(age occupation)

Wild bootstrap-t, null imposed, 999 replications, Wald test, clustering by age occupation, bootstrap clustering by occupation, Rademacher weights:
Wild bootstrap-t, null imposed, jackknifed residuals, 999 replications, Wald test, clustering by age occupation, bootstrap clustering by occupation, Rademacher weights:
tenure

t(12) = 0.4874
Expand All @@ -636,7 +636,7 @@ Wild bootstrap-t, null imposed, 999 replications, Wald test, clustering by age o

Overriding estimator's cluster/robust settings with cluster(age occupation)

Wild bootstrap-t, null imposed, 999 replications, Wald test, clustering by age occupation, bootstrap clustering by occupation, Rademacher weights:
Wild bootstrap-t, null imposed, jackknifed residuals, 999 replications, Wald test, clustering by age occupation, bootstrap clustering by occupation, Rademacher weights:
tenure

t(12) = 0.4874
Expand Down

0 comments on commit 2b81ba5

Please sign in to comment.