Assign instead of compare when marking explicit zeros in spatio_temporal_dist_adjacency - #14124
Conversation
In `spatio_temporal_dist_adjacency` the sparse branch wrote `block.data[block.data == 0] == -1`, a comparison whose result is discarded, so the explicit zeros the comment above it promises to keep were never marked. The dense branch one line up does the assignment. Introduced together with the guard itself in 3545c3f (mne-tools#8050).
|
Hello! 👋 Thanks for opening your first pull request here! ❤️ We will try to get back to you soon. 🚴 |
|
Oof... could you add a tiny test that would have caught this? And also a |
|
Thanks for looking. The changelog entry and the CircleCI login I can sort out, but I owe you an honest answer on the test first: I could not write one, because I cannot find an input where the two versions differ. I went looking for one. Both values end up on the same side of the comparison two lines down: edges.data[:] = np.less_equal(edges.data, dist)
edges.eliminate_zeros()
def run(val, dist):
m = sparse.csr_matrix(([val, 2., 2., val], ([0, 0, 1, 1], [0, 1, 0, 1])), shape=(3, 3))
e = sparse.block_diag([sparse.csr_array(m)])
e.data[:] = np.less_equal(e.data, dist)
e = e.tocsr(); e.eliminate_zeros(); e = e.tocoo()
return sorted(zip(e.row.tolist(), e.col.tolist()))
for dist in (0.0, 1.0, 2.0, 5.0):
assert run(0.0, dist) == run(-1.0, dist) # passes for all of themSo as far as I can tell the line is a no-op today, and this is a correctness cleanup rather than a bug fix: the statement does not do what it plainly reads as doing, and Three ways forward, your call:
I would rather say this than hand you a test that passes either way and call it a regression test. |
|
Okay I think we can live without a test here then. I'll start CircleCI and mark for merge-when-green, thanks in advance @karpovantonme ! |
|
🎉 Congrats on merging your first pull request! 🥳 Looking forward to seeing more from you in the future! 💪 |
* upstream/main: (35 commits) Fix bug with coreg scaling (mne-tools#14132) MAINT: Update code credit (mne-tools#14131) Fix bugs with dark mode panels (mne-tools#14109) Improve code credit workflow (mne-tools#14120) Align _AbstractRenderer.tube with the PyVista implementation (mne-tools#14125) Assign instead of compare when marking explicit zeros in spatio_temporal_dist_adjacency (mne-tools#14124) MAINT: Update pre-commit hook versions (mne-tools#14122) MAINT: Update dependency specifiers (mne-tools#14121) fix: correct typo in comment (mne-tools#14117) [dependabot]: Bump the actions group with 2 updates (mne-tools#14123) Fix` read_raw_eyelink()` failure when recording blocks are empty or starting with empty values (mne-tools#13571) ENH: Add `event_key` parameter to `read_raw_egi` for MFF event metadata (mne-tools#14086) fix for scipy sparse deprecations (mne-tools#14118) Fix notch spectrum fit (mne-tools#14116) Speed up notch filter spectrum fit (mne-tools#14114) fix MNE-RT links and update roadmap (mne-tools#14096) Clarify `docdict["filter_length_notch"]` (mne-tools#14113) Refactor test_plot_alignment_basic() (mne-tools#13472) BUG: Cleanup cHPI filtering using smooth interpolation (mne-tools#14112) Use redirector app (mne-tools#14111) ... # Conflicts: # mne/tests/test_filter.py
Reference issue (if any)
None.
What does this implement/fix?
In
spatio_temporal_dist_adjacencythe sparse branch of the "keep explicit zeros" loop is a comparison, not an assignment:The dense branch one line up does assign. The sparse one has read
==since the guard was added in 3545c3f (#8050, Jul 2020), so for sparsesrc['dist']the explicit zeros have never actually been marked.Additional information
I could not find a case where this changes the returned adjacency, and I do not want to claim more than I checked. With SciPy 1.13 the explicit zeros survive both the
csr_arrayconversion andblock_diag, andnp.less_equalmaps a stored0and a stored-1to the sameTrue, so the two branches agree today:So this is not a behaviour fix on current SciPy. It is the line doing what the comment next to it says it does, and what the dense branch already does — the comment's "deal with changes in SciPy" is exactly the case the marking is meant to survive, and right now it would not.
Slicing does preserve the explicit zeros (
src['dist'][vertno, :][:, vertno]keepsnnzincluding the stored0s on SciPy 1.13), so there is something for the assignment to act on.No changelog entry, since there is no user-facing change; happy to add one if you would rather have it recorded.
AI assistance, per the policy: the line was surfaced by a static-analysis sweep (ruff
B015) run with Claude Opus in Claude Code, which also wrote the one-character patch and the SciPy check above. I reviewed the diff, the blame and the reasoning about whether it changes results before submitting.