Skip to content

Steal connectivity gradient computation Fix #54#70

Draft
nx10 wants to merge 1 commit into
mainfrom
impl/gradients
Draft

Steal connectivity gradient computation Fix #54#70
nx10 wants to merge 1 commit into
mainfrom
impl/gradients

Conversation

@nx10
Copy link
Copy Markdown
Contributor

@nx10 nx10 commented Feb 14, 2026

  • Add compute_gradients and supporting functions (compute_affinity, diffusion_map_embedding) to rbc.core.metrics.gradients
  • Vendor core diffusion map algorithm from BrainSpace (Vos de Wael et al. 2020) using only numpy/scipy, avoiding the heavy VTK/matplotlib/nilearn dependency chain
  • Only deliberate divergence from BrainSpace: use scipy.linalg.eigh on the symmetrized operator instead of eigsh on the asymmetric transition matrix, for dense numerical stability (@reindervdw-cmi bad idea?)

@nx10 nx10 requested review from kaitj and reindervdw-cmi February 14, 2026 04:16
@nx10
Copy link
Copy Markdown
Contributor Author

nx10 commented Feb 14, 2026

Cant reproduce the mypy error locally...

@github-actions
Copy link
Copy Markdown

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/rbc
   __init__.py10100% 
src/rbc/cli
   __init__.py110%9
   anatomical.py110%3
   derivatives.py110%8
   functional.py110%10
   longitudinal.py110%9
   qc.py110%9
src/rbc/core
   __init__.py30100% 
   bids.py3620100% 
   common.py90100% 
   fileops.py27485%66–69
   nifti.py14192%31
   niwrap.py310100% 
src/rbc/core/anatomical
   __init__.py40100% 
   registration.py14471%45, 137, 152, 167
   segmentation.py15566%48, 74–75, 82, 93
src/rbc/core/functional
   __init__.py60100% 
   despiking.py50100% 
   initialization.py7185%61
   motion.py22577%79, 89, 91–92, 94
   timing.py140100% 
src/rbc/core/longitudinal
   __init__.py110%10
src/rbc/core/metrics
   __init__.py40100% 
   alff.py911781%249, 251–253, 255–256, 258, 260–262, 264, 266–268, 270–271, 274
   atlases.py140100% 
   gradients.py114298%118, 241
   reho.py651183%180, 182–184, 186, 188–191, 193–194
   smoothing.py5180%36
   standardization.py271159%64, 66–68, 70, 72–75, 77–78
   timeseries.py530100% 
src/rbc/core/qc
   __init__.py110%7
src/rbc/core/resources
   __init__.py150100% 
src/rbc/workflows
   __init__.py30100% 
   anatomical.py251732%46–50, 54–57, 60, 64, 67–70, 76, 83
   functional.py34340%8, 10–12, 14, 16–19, 30, 56–62, 64–66, 71–72, 78, 82, 86, 90, 94, 98, 102, 106, 111, 113, 128–129
TOTAL99212187% 

Tests Skipped Failures Errors Time
194 0 💤 0 ❌ 0 🔥 3m 2s ⏱️

Copy link
Copy Markdown

@reindervdw-cmi reindervdw-cmi left a comment

Choose a reason for hiding this comment

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

No idea about the validity of changing the eig function. You could check results of this against BrainSpace's gradients to see if they produce similar values.

then apply the kernel, then zero out negatives.

Args:
matrix: (n_rois, n_rois) correlation / connectivity matrix.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

a square n-to-n matrix is by far the most common use-case, but there's no reason why it can't be n-to-m (as a matter of fact, I've done just that before)

pairwise correlations, then applies diffusion map embedding (Coifman &
Lafon 2006) to recover low-dimensional gradients.

Vendored from BrainSpace (Vos de Wael et al. 2020) to avoid pulling in
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Include a copy of the license; otherwise you're in breach of it :D

raise ValueError(f"Need at least 2 ROIs, got {n}")

mat = np.array(matrix, dtype=np.float64)
mat_no_nan = np.nan_to_num(mat, nan=0.0)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Check for rows that are entirely zero and error

d_alpha = d ** (-alpha)
affinity = affinity * d_alpha[:, None] * d_alpha[None, :]

# Form symmetric operator Ms = D^{-1/2} W_alpha D^{-1/2}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

no idea if this is actually equivalent 🤷 been far too long since I was deep into the diffusion mapping maths

Comment thread src/rbc/core/metrics/gradients.py
@nx10 nx10 marked this pull request as draft March 2, 2026 15:02
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.

3 participants