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
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.12.0] - 2026-08-05

Scale-and-honesty release on the 0.11 stack: Kronecker-sum exact spectrum
for eligible networked graph operators, and docs-only topology-criticality
honesty. Homogeneous scientific defaults and the linear latent operator
contract are unchanged.

### Added

- Exact Kronecker-sum spectrum path for eligible discrete and continuous
graph operators (`koopman_graph.operators.kronecker_spectrum`;
`GraphKoopmanOperator.spectrum` /
`ContinuousGraphKoopmanOperator.spectrum`). Eligibility requires a
shared self factor, `diffusion` in `{"symmetric", "random_walk"}`, and
`sparsity` in `{"dense", "block_diagonal"}`. Eigenvalues and ambient
eigenvectors match the dense assembly oracle within float tolerance on
path/ring fixtures.
- Three-path spectrum contract: distributed leading-modulus Arnoldi
(discrete / multiplex hetero), Kronecker-sum exact reduction when
eligible, otherwise dense assembly. Continuous `distributed` has no
Arnoldi spectrum path and uses dense `L_eff`.
- Sphinx Scale / architecture / FAQ prose distinguishing the three
spectrum paths and residual dense ceilings for exact inverse, Jacobi /
Richardson, and eig-regularization hinges. Tutorial
`examples/29_large_graph_block_diagonal.ipynb` records a dense vs
Kronecker spectrum timing probe at the existing probe \(N\).
- Topology-criticality honesty in limitations (cross-linked from
architecture / capabilities), with `paper.bib` entry `Ghosh2025`.
Tutorial `examples/18_networked_koopman_dynamic_topology.ipynb` notes
that dynamic topology remains mechanical (no spectral-degeneracy /
early-warning diagnostic API).

### Notes

- Kronecker reduction applies to **spectrum only**. Exact inverse /
Jacobi / Richardson and eig-regularization hinges remain dense
\((N\cdot d)\) ceilings.
- No Kronecker-style spectrum for hetero / hypergraph ambient operators
in this release.
- Homogeneous training defaults are unchanged relative to 0.11.0.

## [0.11.0] - 2026-08-02

Domain-and-structure release on the 0.10 stack: measured topology transfer,
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ authors:
repository-code: "https://github.com/tjkessler/KoopmanGraph"
url: "https://koopmangraph.readthedocs.io/"
license: Apache-2.0
version: 0.11.0
date-released: 2026-08-02
version: 0.12.0
date-released: 2026-08-05
doi: 10.5281/zenodo.21763908
identifiers:
- type: doi
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ Featured tutorials: [01 synthetic](https://github.com/tjkessler/KoopmanGraph/blo
- [Architecture](https://koopmangraph.readthedocs.io/en/latest/architecture.html) — public vs power-user API layers
- [FAQ / troubleshooting](https://koopmangraph.readthedocs.io/en/latest/faq.html) — install, imports, checkpoints
- [Installation](https://koopmangraph.readthedocs.io/en/latest/installation.html) — dependencies and install paths
- What’s new in 0.11.0: measured topology transfer, directed hypergraph
incidence, Ray Train model DDP, presence-mask churn, teaching traffic /
GraphCast ports, sheaf / cell-complex MVPs, GraphVAMP + synthetic molecular
path, and isotypic self-block ties — see [CHANGELOG.md](CHANGELOG.md).
- What’s new in 0.12.0: Kronecker-sum exact spectrum for eligible discrete
and continuous graph operators (three-path spectrum contract), Scale /
architecture honesty for residual dense inverse and eig-reg ceilings, and
docs-only topology-criticality honesty — see [CHANGELOG.md](CHANGELOG.md).

## Related software

Expand All @@ -164,7 +164,7 @@ If you use KoopmanGraph in research, please cite:
publisher = {Zenodo},
doi = {10.5281/zenodo.21763908},
url = {https://github.com/tjkessler/KoopmanGraph},
version = {0.11.0},
version = {0.12.0},
}
```

Expand Down
53 changes: 45 additions & 8 deletions docs/source/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -401,13 +401,17 @@ power-user losses stay package imports outside root ``__all__``.
* ``graph_inverse`` — block-diagonal / Jacobi approximate inverse helpers for
``GraphKoopmanOperator`` / ``HypergraphKoopmanOperator`` with
``sparsity="block_diagonal"`` (no ``operators/graph/`` subtree)
* ``kronecker_spectrum`` — exact Kronecker-sum spectrum helpers for eligible
discrete / continuous graph operators (power-user; not in package
``__all__``; auto-routed from ``.spectrum`` — see spectrum routing below)
* ``continuous_graph`` —
:class:`~koopman_graph.operators.continuous_graph.ContinuousGraphKoopmanOperator`
(continuous networked generator ``I⊗L_self + Â⊗L_nbr``; select via
``koopman="graph"`` + ``dynamics_mode="continuous"`` or
``koopman="continuous_graph"``). Dense advance uses an ``N·d`` matrix
exponential; ``sparsity="block_diagonal"`` is the self-dominated
approximate path
approximate path. ``.spectrum`` may Kronecker-route when eligible (see
spectrum routing below); that does not shrink the matrix-exp ceiling
* ``hypergraph`` —
:class:`~koopman_graph.operators.hypergraph.HypergraphKoopmanOperator`
(discrete hyperedge-coupled advance; select via ``koopman="hypergraph"``;
Expand Down Expand Up @@ -1140,7 +1144,10 @@ Topology capability matrix

Dynamic topology is first-class in the data container and neural model path,
but not every consumer supports it. Callers must not assume silent freeze/flatten
behavior. Optional static hyperedge incidence (``hyperedge_index`` /
behavior. Mid-horizon rewiring is **mechanical** support for changing
``edge_index`` schedules; it is not criticality-aware forecasting or
spectral-degeneracy analysis (see :ref:`limitations-topology-criticality`).
Optional static hyperedge incidence (``hyperedge_index`` /
``hyperedge_weight`` on each ``Data`` snapshot; PyG bipartite format) is
accepted by :class:`~koopman_graph.data.GraphSnapshotSequence`. Hypergraph
encoder/decoder peers and ``koopman="hypergraph"`` consume the incidence;
Expand Down Expand Up @@ -1300,8 +1307,9 @@ spectral analysis uses the explicit helpers ``effective_matrix`` /
``dual_random_walk``); advance applies ``exp(L_eff Δt)``. Dense realization
forms an ``N·d`` matrix exponential (prefer modest ``N`` or
``sparsity="block_diagonal"`` for the self-dominated approximation, which
ignores neighbor coupling). Checkpoint kind is always ``continuous_graph``
(including when selected via ``koopman="graph"`` +
ignores neighbor coupling). ``.spectrum`` follows the graph /
continuous-graph spectrum routing below. Checkpoint kind is always
``continuous_graph`` (including when selected via ``koopman="graph"`` +
``dynamics_mode="continuous"``).
* Hypergraph — assemble ``I_N ⊗ K_self + Ĥ ⊗ K_hedge`` on a supplied
``hyperedge_index`` / ``hyperedge_weight`` (Zhou ``Ĥ`` semantics as advance).
Expand Down Expand Up @@ -1342,8 +1350,9 @@ always the sparse message-passing matvec (pairwise ``Â`` or Zhou ``Ĥ``).
- Notes
* - ``"dense"`` (default)
- Exact dense ``N·d`` inverse (pseudoinverse fallback)
- Suitable for modest ``N``; ``effective_matrix`` / ``spectrum`` still
assemble the dense map
- Suitable for modest ``N``; ``effective_matrix`` still assembles the
dense map. Graph / continuous-graph ``.spectrum`` may Kronecker-route
when eligible (see below)
* - ``"block_diagonal"``
- Approximate per-node ``d×d`` Jacobi inverse
(exact when the coupling factor is zero or the topology is empty —
Expand All @@ -1352,18 +1361,46 @@ always the sparse message-passing matvec (pairwise ``Â`` or Zhou ``Ĥ``).
- For backward-consistency / imputation at scale; **not** an exact
whole-network inverse. ``inverse_matrix=`` is rejected. Shared by
:class:`~koopman_graph.operators.GraphKoopmanOperator` and
:class:`~koopman_graph.operators.HypergraphKoopmanOperator`
:class:`~koopman_graph.operators.HypergraphKoopmanOperator`.
Eligible graph / continuous-graph ``.spectrum`` may still use
Kronecker reduction of the full coupled factors
* - ``"distributed"``
- Matrix-free Richardson inverse and Arnoldi leading-modulus
spectrum (discrete graph / multiplex hetero); forward stays the
sparse matvec. Hypergraph / continuous peers may still assemble
for inverse; continuous spectrum has no Arnoldi path
- Operator math only — **not** trainer DDP /
``[distributed]`` extras
``[distributed]`` extras and **not** Kronecker exact spectrum

The stored checkpoint field is ``config.sparsity`` (format 1). Continuous-graph
``block_diagonal`` remains the self-dominated advance / inverse shortcut
documented under that peer (not the Jacobi path above).

**Graph / continuous-graph spectrum routing.** Discrete
:meth:`~koopman_graph.operators.graph.GraphKoopmanOperator.spectrum` and
continuous
:meth:`~koopman_graph.operators.continuous_graph.ContinuousGraphKoopmanOperator.spectrum`
auto-route (no path-selection kwarg):

1. ``sparsity="distributed"`` — discrete graph / multiplex hetero use
matrix-free Arnoldi leading-modulus Ritz values; continuous graph falls
through to dense :math:`L_{\mathrm{eff}}` eigendecomposition (no Arnoldi
spectrum path).
2. Else if Kronecker-sum eligible — shared self factor,
``adjacency`` in ``{"symmetric", "random_walk"}``,
``sparsity`` in ``{"dense", "block_diagonal"}`` — exact reduction via
:mod:`koopman_graph.operators.kronecker_spectrum`
(:math:`I\otimes M_{\mathrm{self}} + \widehat{A}\otimes M_{\mathrm{nbr}}`
for discrete :math:`K` or continuous generator :math:`L`).
3. Else — dense assembled eigendecomposition
(``dual_random_walk``, discrete orbit / isotypic self banks, helper
fall-back, hetero / hypergraph as applicable).

This routing covers **spectrum only**. Exact inverse, continuous
:math:`\Phi=\exp(\Delta t\, L_{\mathrm{eff}})`, and eigenvalue-regularization
hinges keep their dense :math:`(N\cdot d)` ceilings where documented.
Ceilings and eligibility details: :doc:`limitations` (Scale).

**Graph / continuous-graph adjacency (``adjacency``).** Neighbor-coupling
normalization for pairwise networked operators:

Expand Down
20 changes: 16 additions & 4 deletions docs/source/capabilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ Topology-aware learning
* ``DelayEmbeddingEncoder`` / ``n_delays`` for Hankel-style partial
observability
* Per-snapshot ``edge_index`` (dynamic topology) and end-to-end
``edge_weight`` support
``edge_weight`` support — mechanical rewiring only; not
criticality / spectral-degeneracy analysis (see
:ref:`limitations-topology-criticality`)
* Opt-in fixed-union node churn: ``allow_node_churn=True`` with
:math:`N_{\max}` capacity and ``presence_masks`` ``(T, N_{\max})``
(losses ignore inactive nodes; matvecs stay at capacity — see
Expand All @@ -91,7 +93,10 @@ Dynamics
:math:`I_N \otimes K_{\mathrm{self}} + \widehat{A} \otimes K_{\mathrm{nbr}}`
(factorized blocks inspired by compositional / networked Koopman
constructions; cross-topology transfer is measured, not assumed — see
:doc:`limitations` and ``examples/37_cross_topology_transfer.ipynb``)
:doc:`limitations` and ``examples/37_cross_topology_transfer.ipynb``).
``.spectrum`` auto-routes Kronecker-sum reduction when eligible (shared
self; ``symmetric`` / ``random_walk``); see :doc:`limitations` (Scale)
for distributed Arnoldi, dense fall-backs, and inverse ceilings
* Pairwise ``adjacency`` modes on graph / continuous-graph operators:
``"symmetric"`` (default), ``"random_walk"``
(:math:`D_{\mathrm{out}}^{-1}A`), and ``"dual_random_walk"`` (forward plus
Expand All @@ -117,8 +122,11 @@ Dynamics
* Continuous networked generator ``ContinuousGraphKoopmanOperator``
(``koopman="graph"`` + ``dynamics_mode="continuous"`` or
``koopman="continuous_graph"``; ``adjacency`` modes match discrete
``GraphKoopmanOperator``; dense ``N·d`` matrix-exp cost caveat —
prefer modest ``N`` or ``sparsity="block_diagonal"`` self-only shortcut)
``GraphKoopmanOperator``). ``.spectrum`` uses the same Kronecker
eligibility as discrete graph when applicable; dense ``N·d``
matrix-exp (:math:`\Phi=\exp(\Delta t\, L_{\mathrm{eff}})`) remains a
separate ceiling — prefer modest ``N`` or ``sparsity="block_diagonal"``
self-only shortcut for advances (see :doc:`limitations`)
* Continuous hetero generators on ``koopman="hetero_graph"`` +
``dynamics_mode="continuous"`` (dense stacked :math:`\Phi` cost; see
:doc:`limitations`)
Expand Down Expand Up @@ -248,6 +256,10 @@ Analysis
~~~~~~~~

* ``KoopmanSpectrum`` / ``compute_spectrum`` with mode decoding helpers
* Networked graph / continuous-graph ``.spectrum`` paths: distributed
Arnoldi (discrete / multiplex hetero), Kronecker-sum exact reduction
when eligible, or dense assembled eigendecomposition — see
:doc:`limitations` (Scale); continuous graph has no Arnoldi spectrum path
* ``attribute_mode_energy`` / ``ModeEnergyAttribution`` — interpretive
type / relation energy fractions on assembled ``K_eff`` (not causal;
not a ResDMD residual on relation-attributed modes)
Expand Down
36 changes: 32 additions & 4 deletions docs/source/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,28 +170,56 @@ Several training paths still assemble or multiply dense structures whose
size grows with :math:`N` (or :math:`N\cdot d`), even when latents and
supports are cached within an evaluation:

* Exact spectrum / inverse and continuous dense
* Exact **inverse** and continuous dense
:math:`\Phi=\exp(\Delta t\, L_{\mathrm{eff}})` on
:math:`(N\cdot d)\times(N\cdot d)` matrices
* Exact **spectrum** when the Kronecker path does not apply (dense
:math:`(N\cdot d)` eigendecomposition, or discrete distributed Arnoldi
surrogate); eligible graph / continuous-graph spectrum uses Kronecker-sum
reduction instead — see below and :doc:`limitations` (Scale)
* DiffConv diffusion supports and hypergraph Zhou :math:`\hat{H}` as dense
:math:`N\times N` tensors
* Eigenvalue hinge on dense / ODO networked operators
(:math:`O((N\cdot d)^3)` eigendecomposition)
(:math:`O((N\cdot d)^3)` eigendecomposition of the assembled map)
* Self-adaptive topology materializing full :math:`N^2` COO

Shared pair latents, inverse / support / :math:`\hat{H}` / :math:`\Phi`
reuse, and PDE/worst-case prediction sharing reduce repeated work; they
do not change those representation sizes. See :doc:`limitations` (Scale)
and :doc:`capabilities` (Training performance).

Does spectrum still assemble :math:`N\cdot d`?
----------------------------------------------

Not always for discrete ``GraphKoopmanOperator`` /
``ContinuousGraphKoopmanOperator``. ``.spectrum`` auto-routes:

* ``sparsity="distributed"`` — Arnoldi leading-modulus surrogate on discrete
graph / multiplex hetero; continuous graph has no Arnoldi spectrum path
and uses dense :math:`L_{\mathrm{eff}}`
* Else if eligible (shared self; ``adjacency`` in
``{"symmetric", "random_walk"}``; ``sparsity`` in
``{"dense", "block_diagonal"}``) — Kronecker-sum exact spectrum
(order :math:`O(N^3 + N d^3)` via dense :math:`N\times N`
:math:`\widehat{A}` plus :math:`N` blocks of size :math:`d\times d`)
* Else — dense :math:`(N\cdot d)` eigendecomposition
(``dual_random_walk``, discrete orbit / isotypic self banks, hetero /
hypergraph, helper fall-back)

Exact inverse and eigenvalue-regularization hinges are unchanged (still
dense assembled ceilings where documented). Details:
:doc:`limitations` (Scale) and :doc:`architecture` (spectrum routing).

When should I use ``sparsity="block_diagonal"``?
------------------------------------------------

Use ``sparsity="block_diagonal"`` on graph / hypergraph / continuous-graph
operators when the dense :math:`N\cdot d` path dominates wall time and a
self-dominated (Jacobi-style) approximation is acceptable for your
advance / inverse / spectrum use case. Prefer ``sparsity="dense"`` when you
need the full coupled effective map. Tutorial:
advance / inverse use case. Prefer ``sparsity="dense"`` when you need the
full coupled effective map for advance / inverse. Eligible graph /
continuous-graph ``.spectrum`` may still Kronecker-route the full coupled
factors under ``block_diagonal``. Tutorial:
``examples/29_large_graph_block_diagonal.ipynb``.

How do I enable automatic mixed precision (AMP)?
Expand Down
4 changes: 2 additions & 2 deletions docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ version with the tag you intend; see PyPI and ``CHANGELOG.md``):

.. code-block:: bash

pip install koopman-graph==0.11.0
# or: uv pip install koopman-graph==0.11.0
pip install koopman-graph==0.12.0
# or: uv pip install koopman-graph==0.12.0

Releases are published automatically when a maintainer creates a GitHub Release
(see ``CONTRIBUTING.md`` in the repository). For the latest in-tree development
Expand Down
Loading