Skip to content

Conversation

@JaimeRZP
Copy link
Contributor

@JaimeRZP JaimeRZP commented Jul 4, 2025

Ensures that the delete2 covariance remains positive definite even when using a few jackknife regions.

Closes: #293

@codecov
Copy link

codecov bot commented Jul 4, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Flag Coverage Δ
py3.10 82.00% <100.00%> (-0.02%) ⬇️
py3.11 82.00% <100.00%> (-0.02%) ⬇️
py3.12 81.97% <100.00%> (-0.02%) ⬇️
py3.13 81.97% <100.00%> (-0.02%) ⬇️
py3.9 82.04% <100.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
heracles/dices/jackknife.py 97.19% <100.00%> (-0.04%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ntessore ntessore changed the title Delete 2 bug 2 gh-293: ensure delete-2 JK remains posdef Jul 7, 2025
Comment on lines -330 to -338
# Diagonalise the correction
for key in Q:
q = Q[key]
*_, length = q.shape
q_diag = np.diagonal(q, axis1=-2, axis2=-1)
q_diag_exp = np.zeros_like(q)
diag_indices = np.arange(length) # Indices for the diagonal
q_diag_exp[..., diag_indices, diag_indices] = q_diag
Q[key] = Result(q_diag_exp, axis=q.axis, ell=q.ell)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this no longer necessary here? Doesn't the change also change the result of this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it does but I think this way it is better. Rather than diagonalizing the correction and then simply adding it to the cov_jk, we can save the fully correction (in case somebody wishes to have a look) and then substract its diagonal to the diagonal of the cov_jk.

ell=cov_jk[key].ell,
axis=cov_jk[key].axis,
)
debiased_cov = deepcopy(cov_jk)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the deepcopy is useful here, if you set all entries to a new Result down below anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think otherwise the entries of cov_jk get accidentally overwritten in the process.

Comment on lines +362 to +363
# abs is only needed when too few Jackknife regions are used
c[..., diag_indices, diag_indices] = abs(c_diag - q_diag)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this materially changing the output of the debiasing step? In the sense that the absolute value is something we are making up on the spot to fix a "problem" that is really intrinsic to the process?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for large enough jk regions, q_diag should always be smaller than c_diag. The goal here is to cover for when only a few regions are used. We could something more kosher such as enfocing pos-def for each entry in the matrix stack but this would require more involved coding.

Comment on lines -318 to +328
_debiased_cov[key] = cov_jk[key].array - Q[key]
q = Q[key].array
c = _debiased_cov[key].array
*_, length = q.shape
q_diag = np.diagonal(q, axis1=-2, axis2=-1)
c_diag = np.diagonal(c, axis1=-2, axis2=-1)
# Indices for the diagonal
diag_indices = np.arange(length)
# abs is only needed when too few Jackknife regions are used
c[..., diag_indices, diag_indices] = abs(c_diag - q_diag)
_debiased_cov[key] = c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this test the exact same code used in the function? If so, can we have a test where you construct a known output for a known input by hand? Otherwise, we might just end up with the same bug in 2 places...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So was before to be honest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Delete-2 jackknife should remain pos def

3 participants