Nicole 0.3.5
Nicole 0.3.5 — New Arithmetics and SVD Diagnostics
Release Date: April 26, 2026
Version 0.3.5 completes the Tensor arithmetic surface with equality operators, numerical near-equality via allclose, unary negation, and scalar division. The svd function gains an optional requires_info parameter that exposes truncation-loss diagnostics without changing the default return signature. A set of documentation and test-coverage improvements round out the release.
✨ New Features
Equality — Tensor.__eq__ and Bridge.__eq__
Tensor and Bridge now implement the Python equality operator ==.
Tensor.__eq__ performs a staged comparison: index count and full index structure first; then block key sets; then exact element-wise comparison of every dense block via torch.equal; and — for non-Abelian tensors — intertwiner equality via Bridge.__eq__.
Bridge.__eq__ checks structural compatibility (same charge keys and edge structure) then compares the weights tensor of each Clebsch–Gordan entry exactly.
allclose — Numerical Near-Equality
A new allclose(A, B, rtol=1e-5, atol=1e-8) function tests numerical equality within floating-point tolerances. For Abelian tensors each dense block is compared with torch.allclose. For SU(2) tensors the physical tensor R @ W is compared block-by-block, making the check gauge-invariant: two tensors that represent the same physical content but differ in their internal (R, W) factorization still compare as equal.
Structural mismatches (different tensor order, incompatible symmetry groups or index directions) raise ValueError; differing block key sets return False without raising.
Unary Negation and Scalar Division
Tensor.__neg__ adds the unary minus operator -T, negating every dense block. Tensor.__truediv__ adds scalar division T / scalar, dividing every dense block by the given scalar. Both are implemented through the existing __mul__ path and therefore support autograd and all device and dtype combinations.
SVD requires_info — Truncation-Loss Monitoring
svd now accepts a keyword-only parameter requires_info: bool = False. When True, the return value is a 4-tuple whose last element is an info dict; when False (the default), the usual 3-tuple is returned. The dict currently contains one key, "discarded_weight", recording the sum of all singular values truncated away across all charge sectors — zero when no truncation was applied.
🧪 Test Suite (1603 tests)
- 1593 tests pass, 10 skipped (accelerator-only tests on CPU-only CI)
- New tests in
tests/operations/test_arithmetic.pycoveringTensor.__eq__for Abelian and SU(2) tensors (including mismatched structure, intertwiner presence, and non-tensor operands), unary negation, and scalar division - New tests in
tests/operations/test_maneuver.pycoveringallclosefor Abelian and SU(2) tensors, tolerance boundaries, structural mismatch errors, and gauge-invariance underregularize - New tests in
tests/symmetry/test_delegate.pyforBridge.__eq__covering identical, same-content, and structurally differing bridges - New tests in
tests/operations/test_factorize.pyfor SVDrequires_infoand"discarded_weight"values against knownnkeep,thresh, and combined truncations - New tests in
tests/support/test_display.pyforindex_summaryoutput across U(1), Z2, SU(2), and ProductGroup indices
📖 Documentation
allcloseAPI page (docs/api/arithmetic/allclose.md): New reference covering the function signature, SU(2) gauge-invariance guarantee, and behaviour on structural mismatches; cross-links toTensor.__eq__andBridge- SVD page (
docs/api/decomposition/svd.md): Documents therequires_infoparameter and the"discarded_weight"entry in the returnedinfodict - Decomposition examples (
docs/examples/operations/decomposition-examples.md): Extended with a worked example demonstrating truncation-loss monitoring viarequires_info=True - Addition page (
docs/api/arithmetic/addition.md): Added cross-link toallclosefor numerical equality
📊 Statistics
Code Changes
- 43 commits since v0.3.4
- 32 files changed: 1,028 insertions, 105 deletions
- Source modules touched:
src/nicole/tensor.py,src/nicole/maneuver.py,src/nicole/decomp.py,src/nicole/symmetry/delegate.py,src/nicole/__init__.py - Dead code removed:
_axes_from_nameshelper indecomp.py, superseded since v0.3.2 einsumsubscript convention standardized inbench/conductor.py,bench/network.py,iter_diag_ferm, anditer_diag_spin
✅ Compatibility
Breaking Changes: None. All previously valid calls continue to work unchanged.
The new __eq__ operator performs value-based comparison rather than identity comparison. Code that relied on == returning True by object identity will now receive the correct value-based result instead.
Requirements:
- Python ≥ 3.11
- PyTorch ≥ 2.5
- Yuzuha ≥ 0.1.5
📝 Notes
allclose and Tensor.__eq__ serve complementary roles: __eq__ tests exact equality of the internal representation while allclose tests approximate equality of the physical tensor. For SU(2) tensors the distinction matters — __eq__ returns False for two physically identical tensors that differ in gauge, while allclose is gauge-invariant and returns True. Use __eq__ to verify that an operation is a pure permutation or relabelling; use allclose after numerical manipulations.