Skip to content

space: preserve tree structure in Jordan spectral results#58

Merged
Pavlo3P merged 1 commit into
0.4.2from
57-tree-spectral-results-preserve-tree-structure
Jul 1, 2026
Merged

space: preserve tree structure in Jordan spectral results#58
Pavlo3P merged 1 commit into
0.4.2from
57-tree-spectral-results-preserve-tree-structure

Conversation

@Pavlo3P

@Pavlo3P Pavlo3P commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Summary

W3 — tree spectral results can now mirror the space treedef, while the flat forms stay intact for the reduction/norm consumers.

  • TreeSpace.spectrum(x, structured=True) returns a treedef-shaped pytree whose leaves hold each leaf's eigenvalue vector. The default flat spectrum(x) is unchanged — it is load-bearing for SpectralLpNormFunctional (Schatten norm over the whole direct-sum spectrum) and the base trace/determinant reductions.
  • TreeSpectralDecomposition now carries the producing space's treedef (static JAX pytree aux) and gains to_tree(), exposing the eigenvalues in the tree's own (possibly nested) structure. spectral_decompose tags it on.

The decompose → from_spectrum round-trip works on nested trees. A structured spectrum is a treedef-matching pytree but not a valid space member (its leaves are eigenvalue-shaped) — documented and enforced by a check_member-rejects test.

Notes

  • Additive, not breaking: the added treedef field defaults to None (2-arg construction still works); flat spectrum output is byte-identical to before.
  • SpectralLpNormFunctional's gradient over a tree domain was already unsupported (it 2-tuple-unpacks spectral_decompose); W3 doesn't change that — the regression test uses flat domains.

Testing

  • New tests in tests/spaces/test_tree_spectral_decomposition.py: structured spectrum carries treedef + flatten_tree recovers per-leaf spectra; to_tree (flat + nested); nested decompose→from_spectrum round-trip (incl. a Hermitian leaf and a complex-dtype tree); arity-1 branch; JAX pytree round-trip preserves treedef; structured spectrum rejected by check_member; and a flat-spectrum/SpectralLpNormFunctional regression.
  • Full suite: 3397 passed, 170 skipped; ruff / ruff-D / jit_audit / docstring_audit all clean.

Verification

An adversarial multi-agent review (JAX/pytree aux change, equality/hash, structure-preservation, consumer safety) found no bugs — the PyTreeSpec-as-static-aux move round-trips through jit/vmap (including the stacked-vmap-over-tree path), and the flat path is unchanged. Test gaps it surfaced (arity-1, non-member, complex) were added.

🤖 Generated with Claude Code

W3 — a tree's spectral results can now mirror the space treedef:

- TreeSpace.spectrum(x, structured=True) returns a treedef-shaped pytree whose
  leaves hold each leaf's eigenvalue vector. The default flat spectrum() is
  unchanged (it is load-bearing for SpectralLpNormFunctional and the base
  trace/determinant reductions).
- TreeSpectralDecomposition carries the producing space's treedef (static JAX
  pytree aux) and gains to_tree(), exposing the eigenvalues in the tree's own
  (possibly nested) structure. spectral_decompose tags it on.

Round-trips decompose -> from_spectrum on nested trees. A structured spectrum is
a treedef-matching pytree but NOT a space member (its leaves are eigenvalue-
shaped), documented and covered by a check_member-rejects test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Pavlo3P
Pavlo3P merged commit 86919df into 0.4.2 Jul 1, 2026
5 checks passed
@Pavlo3P
Pavlo3P deleted the 57-tree-spectral-results-preserve-tree-structure branch July 1, 2026 18:11
@Pavlo3P Pavlo3P mentioned this pull request Jul 1, 2026
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.

1 participant