Skip to content

Nicole 0.3.1

Choose a tag to compare

@Phy-David-Zhang Phy-David-Zhang released this 31 Mar 08:52
· 163 commits to stable since this release

Nicole 0.3.1 - Documentation and GPU Enhancements

Release Date: March 31, 2026

Version 0.3.1 delivers comprehensive documentation coverage for the SU(2) features introduced in v0.3.0, introduces new Getting Started content to lower the barrier for new users, and strengthens end-to-end GPU device propagation across all SU(2) and Abelian tensor operations.

📖 Documentation

New Getting Started Content

  • Landing page with hero section for the documentation site
  • "Why Nicole?" page comparing Nicole against TensorKit, ITensor, and QSpace, including a "Why Python over Julia?" section covering the PyTorch ecosystem, AI coding-agent compatibility, and post-AI performance engineering
  • "Terminology" page precisely defining Axis / Index / Edge, Sector / Block, and the operations reverse / flip / invert / fuse / combine / merge

SU(2) API Reference

  • SU2Group API page: Full reference for the non-Abelian SU(2) group class, including Wigner-Eckart reduced matrix elements and R-W-C decomposition details
  • Bridge API page: Complete reference for the Bridge class and its intertwiner manipulation methods
  • capcup API page: Bond inversion documentation with warnings on the distinction from Tensor.invert()
  • filter_blocks API page: Replaces the old subsector page
  • ProductGroup API page: Extended with non-Abelian examples for fuse_channels and irrep_dim
  • Symmetry overview: Correctly split into Abelian and non-Abelian subsections
  • load_space examples: Added state-convention admonitions for Abelian and SU(2) presets; extended with full U(1)×SU(2) and Z2×SU(2) walkthroughs
  • Tensor members: normalize_sectors, compress, and regularize added to the class reference

Accuracy and Terminology Fixes (25+ pages)

  • Replaced "n-leg tensor" → "nth-order tensor" and "tensor leg" → "tensor index / tensor axis" throughout
  • Replaced "matrix elements" → "tensor elements" in non-second-order contexts
  • Corrected fuse()fuse_unique() across all Abelian examples and API pages
  • Rewrote manipulation examples to demonstrate the chainable method-based API (T.conj(), T.permute(), T.transpose())

⚡ GPU Device Propagation Enhancements

When a user requests GPU execution via an explicit device= argument or torch.set_default_device(), the device is now forwarded through every layer of the computation graph — from high-level factory functions down to low-level CG-symbol transfers — so that no intermediate tensor silently falls back to CPU.

Enhancements Applied

  • Bridge and CG symbols (symmetry/delegate.py): Bridge.from_block now accepts and propagates a device parameter; compute_xsymbol and compute_rsymbol transfer NumPy arrays to the correct device and dtype; Bridge.permute follows the same pattern
  • Identity and isometry (identity.py): identity(), isometry(), and isometry_n() now accept and forward a device keyword argument to all internal torch.eye, torch.zeros, and Bridge.from_block calls
  • Maneuver (maneuver.py): oplus() forwards device=A.device / B.device to torch.zeros; diag() forwards device to Bridge.from_block; merge_axes() propagates device into isometry_n()
  • Decomposition (decomp.py): svd(), qr(), eig(), and decomp() all forward device=T.device to Bridge.from_block calls
  • Contraction (contract.py): trace() forwards device=T.device to torch.full
  • Tensor (tensor.py): Tensor.zeros() and Tensor.random() forward device to Bridge.from_block; regularize() pins the irrep-dimension scalar to the correct device
  • Operator presets (space.py): A new _get_device(option) helper reads the device from the option dict or falls back to torch.get_default_device(); all 8 leaf operator construction functions call .to(device) on every returned Tensor
  • Block schema (blocks.py): _weights_compatible() collinearity check pins its intermediate torch.tensor to the correct device

Integration Tests (tests/integration/test_propagation.py)

  • 31 new tests covering identity, isometry, oplus, diag, merge_axes, decomp (SVD / QR / UR / EIG), contract, trace, and all 10 load_space presets — for both Abelian and SU(2) symmetry groups
  • Strategy: ambient default device is CPU; each test explicitly requests an accelerator device and asserts that all output tensors reside on it
  • 27 tests pass unconditionally; 4 are skipped when MPS is unavailable

✨ Other Enhancements

filter_blocks Rename

  • filter_blocks(): The subsector function in maneuver.py is renamed to filter_blocks to better reflect its semantics (extracting intertwiner blocks for non-Abelian groups)
  • The old name subsector is removed from the public API and from __init__.py

normalize_sectors on Tensor

  • New method Tensor.normalize_sectors(): Prunes unused sectors from all tensor indices, retaining only sectors that actually appear in the block-sparse data structure
  • __str__ and print now call normalize_sectors internally before rendering, so tensor summaries no longer display phantom zero-population sectors
  • Fermionic operator loading functions in space.py migrated from the internal _prune_unused_sectors to the new public method

SU(2) Display Improvements

  • Tensor summary output now appends a sign indicator (+ / -) for SU(2) blocks whose weight matrix reduces to a single scalar value, making the sign of the Wigner-Eckart reduced matrix element immediately visible in print(T) output

Type Hinting

  • Tensor.to(), Tensor.cpu(), Tensor.cuda(), and Tensor._align_for_binary() now use concrete Tensor return type annotations instead of forward-reference strings, improving IDE type-checker integration

🧪 Test Suite (1459 tests)

  • 1459 tests pass, 10 skipped (accelerator-only tests on CPU-only CI)
  • New integration test module: test_propagation.py (31 tests)
  • All existing SU(2) and Abelian tests continue to pass

📊 Statistics

Code Changes

  • 92 commits since v0.3.0
  • 78 files changed: 2,508 insertions, 661 deletions
  • Source modules touched: tensor.py, display.py, maneuver.py, space.py, blocks.py, decomp.py, identity.py, contract.py, symmetry/delegate.py, symmetry/product.py, __init__.py
  • New test module: tests/integration/test_propagation.py

✅ Compatibility

Breaking Changes: subsector() renamed to filter_blocks(). All other changes are backward compatible with v0.3.0.

Requirements:

  • Python ≥ 3.11
  • PyTorch ≥ 2.5
  • Yuzuha ≥ 0.1.4

📋 Remarks

Version 0.3.1 makes the SU(2) capabilities from v0.3.0 fully accessible to new users through comprehensive API references, accurate terminology, and concrete worked examples. The GPU enhancements ensure that an explicit device= argument is honoured consistently across every operation, with a new integration test suite providing ongoing assurance against device-propagation regressions.