Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ under congruence transformations.
airm_geodesic
exp_map_airm
log_map_airm
spd_egrad2rgrad


Log-Euclidean Metric
Expand Down Expand Up @@ -194,6 +195,28 @@ manifold, essential for operations like domain adaptation.
transport_tangent_vector


Fréchet Derivatives
-------------------
Directional (Fréchet) derivatives of the matrix logarithm and exponential,
used for parallel transport under the Log-Euclidean metric.

.. autosummary::
:toctree: generated/frechet_functional

frechet_derivative_log
frechet_derivative_exp


Adversarial Robustness
----------------------
Riemannian projected gradient descent (PGD) attack for SPD-matrix inputs.

.. autosummary::
:toctree: generated/attacks_functional

spd_rpgd_attack


Vectorization Utilities
-----------------------
Vectorization helpers for batching, (un)vectorizing matrices, and symmetric matrix
Expand Down Expand Up @@ -237,10 +260,13 @@ Functions for Riemannian batch normalization computations on SPD manifolds.
.. autosummary::
:toctree: generated/batchnorm_functional

frechet_mean
karcher_mean_iteration
spd_centering
spd_rebiasing
spd_cholesky_congruence
tangent_space_variance
lie_group_variance


Bilinear Operations
Expand Down Expand Up @@ -285,6 +311,146 @@ for detailed guidance.
recommend_dtype_for_spd


pyRiemann Geometry (re-exported)
--------------------------------
Since pyRiemann (>= 0.12) is a core dependency and runs on PyTorch tensors via
the Python Array API, its broader geometry toolkit is re-exported from
:py:mod:`spd_learn.functional`, so the full SPD/Riemannian API is reachable from
a single namespace. These run on torch tensors (with autograd) like the native
functions above.

.. note::

The low-level matrix-function primitives (``logm``/``expm``/``sqrtm``/
``invsqrtm``/``powm``/``ddlogm``/``ddexpm``) are intentionally **not**
re-exported. Use spd_learn's numerically-stable :func:`matrix_log`,
:func:`matrix_exp`, :func:`matrix_sqrt`, ... and :func:`frechet_derivative_log` /
:func:`frechet_derivative_exp`, which keep gradients stable near degenerate
eigenvalues. The re-exported distances/means/maps inherit pyRiemann's generic
``eigh`` backward (see :doc:`/numerical_stability`).

Additional distances:

.. autosummary::
:toctree: generated/pyriemann_distance

distance
distance_chol
distance_euclid
distance_harmonic
distance_kullback
distance_kullback_right
distance_kullback_sym
distance_logchol
distance_logdet
distance_logeuclid
distance_mahalanobis
distance_poweuclid
distance_riemann
distance_thompson
distance_wasserstein
pairwise_distance

Additional geodesics:

.. autosummary::
:toctree: generated/pyriemann_geodesic

geodesic
geodesic_chol
geodesic_euclid
geodesic_logchol
geodesic_logeuclid
geodesic_riemann
geodesic_thompson
geodesic_wasserstein

Additional means and barycenters:

.. autosummary::
:toctree: generated/pyriemann_mean

gmean
maskedmean_riemann
mean_ale
mean_alm
mean_bmp
mean_cheap
mean_chol
mean_euclid
mean_harmonic
mean_kullback_sym
mean_logchol
mean_logdet
mean_logeuclid
mean_power
mean_poweuclid
mean_riemann
mean_thompson
mean_wasserstein
nanmean_riemann

Tangent space, inner products, and transport:

.. autosummary::
:toctree: generated/pyriemann_tangent

exp_map
exp_map_euclid
exp_map_logchol
exp_map_logeuclid
exp_map_riemann
exp_map_wasserstein
innerproduct
innerproduct_euclid
innerproduct_logchol
innerproduct_logeuclid
innerproduct_riemann
log_map
log_map_euclid
log_map_logchol
log_map_logeuclid
log_map_riemann
log_map_wasserstein
norm
tangent_space
transport
transport_euclid
transport_logchol
transport_logeuclid
transport_riemann
untangent_space
unupper
upper

Kernels:

.. autosummary::
:toctree: generated/pyriemann_kernel

kernel
kernel_euclid
kernel_logeuclid
kernel_riemann

Approximate joint diagonalization:

.. autosummary::
:toctree: generated/pyriemann_ajd

ajd
ajd_pham
rjd
uwedge

Matrix utilities:

.. autosummary::
:toctree: generated/pyriemann_base

nearest_sym_pos_def


Modules
=======

Expand Down Expand Up @@ -449,6 +615,17 @@ building blocks from :py:mod:`spd_learn.modules`.
TSMNet


Model Building Blocks
---------------------
Sub-modules used inside the models above, exposed for reuse and customization.

.. autosummary::
:toctree: generated/

AttentionManifold
PhaseDelay


Model Selection Guide
---------------------

Expand Down
20 changes: 18 additions & 2 deletions docs/source/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,24 @@ How is SPD Learn different from pyRiemann?
- GPU acceleration via PyTorch
- Integration with modern DL frameworks (Braindecode, skorch)

They are **complementary**: you can use pyRiemann for preprocessing and
SPD Learn for deep learning.
Since pyRiemann (>= 0.12) adopted the Python Array API, the two are no longer
merely complementary — **SPD Learn builds on pyRiemann**. pyRiemann is a core
dependency that runs natively on PyTorch tensors with autograd; SPD Learn
delegates the geometry it does not need to keep numerically special — geodesics,
parallel transport, and Fréchet derivatives — to it, and also re-exports
pyRiemann's broader geometry toolkit from :py:mod:`spd_learn.functional`. On top
of that shared backend SPD Learn adds:

- ``nn.Module`` layers (BiMap, ReEig, LogEig, SPD batch norm, LieBN, ...)
- Numerically-stable, custom-autograd matrix-function primitives, distances, and
means that keep gradients well-behaved (and forwards finite) near clustered or
near-singular eigenvalues — where the generic ``eigh`` backward and unclamped
``log`` are unstable — essential for training SPDNets.

So pyRiemann remains the place to look for the broader classical toolkit
(MDM/FgMDM classifiers, tangent-space pipelines, ``pyriemann.datasets``,
estimators, and many more metrics) — all of which interoperate with SPD Learn
on the same PyTorch tensors.


Technical Questions
Expand Down
21 changes: 20 additions & 1 deletion docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ Dependencies
- `PyTorch <https://pytorch.org/>`_ - Deep learning framework
- `einops <https://einops.rocks/>`_ - Flexible tensor operations
- `NumPy <https://numpy.org/>`_ - Numerical computing
- `pyRiemann <https://pyriemann.readthedocs.io/>`_ (>= 0.12) - SPD/Riemannian
geometry. SPD Learn delegates geodesics, parallel transport, and Fréchet
derivatives to pyRiemann's Array API backend (which runs natively on PyTorch
tensors) and re-exports pyRiemann's broader toolkit. It keeps its own
numerically-stable, custom-autograd matrix-function primitives
(``matrix_log``/``matrix_exp``/``matrix_sqrt``/...), distances, and means,
which stay finite/stable on ill-conditioned inputs — important for training.

.. note::

The Array API (PyTorch) backend lives in pyRiemann **0.12+**, which is not
yet on PyPI. SPD Learn therefore pins pyRiemann to its git ``master``::

pyriemann @ git+https://github.com/pyRiemann/pyRiemann.git

Because this is a direct-URL dependency, ``pip install spd_learn`` from PyPI
is unavailable until pyRiemann 0.12 is released — install from source (see
below) meanwhile. The pin becomes ``pyriemann>=0.12`` once 0.12 ships.

Installing from Source
----------------------
Expand Down Expand Up @@ -55,7 +73,8 @@ This installs:

- `Braindecode <https://braindecode.org/>`_ - Deep learning for EEG
- `Nilearn <https://nilearn.github.io/>`_ - Machine learning for neuroimaging
- `pyRiemann <https://pyriemann.readthedocs.io/>`_ - Riemannian geometry for BCI

(pyRiemann is now a **core** dependency — see above — so it is always installed.)

Documentation
^^^^^^^^^^^^^
Expand Down
12 changes: 9 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,25 @@ dependencies = [
"torch",
"einops",
"numpy",
# Array API support (torch backend) lives on pyriemann master / 0.12.
# Hard-pinned to git until 0.12 is released on PyPI. NOTE: a direct-URL
# dependency blocks uploading spd_learn to PyPI; swap to "pyriemann>=0.12"
# once 0.12 ships.
"pyriemann @ git+https://github.com/pyRiemann/pyRiemann.git",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pin pyriemann to an immutable ref

This comment says the dependency is hard-pinned, but the direct URL omits a tag or commit, so every install resolves whatever pyRiemann's default branch points to at that moment. Since core geometry is now imported from pyriemann at module import time, upstream master changes can silently change numerical results or break installs, making experiments unreproducible. Please pin a commit/tag until this can be replaced with pyriemann>=0.12.

Useful? React with 👍 / 👎.

]

[project.optional-dependencies]
tests = [
'pytest',
# pytest 9.1 changed IdMaker's signature, which pytest_cases (<= 3.10.1)
# still calls the old way -> TypeError at collection time. Cap pytest until
# pytest_cases ships 9.1 support.
'pytest<9.1',
'pytest-cov',
'pytest-codeblocks',
'sybil',
'codecov',
'pytest_cases',
'mypy',
'pyriemann',
]
docs = [
'sphinx',
Expand All @@ -75,7 +82,6 @@ brain = [
'moabb',
'braindecode',
'nilearn',
'pyriemann',
'skada',
]
dev = [
Expand Down
Loading
Loading