Skip to content

Nicole 0.3.3

Choose a tag to compare

@Phy-David-Zhang Phy-David-Zhang released this 21 Apr 09:31
· 79 commits to stable since this release

Nicole 0.3.3 - Benchmark Modernization and oplus Extension

Release Date: April 21, 2026

Version 0.3.3 modernizes the benchmark suite to use einsum and the chainable method API introduced in v0.3.2, replacing multi-step functional contraction chains with concise subscript notation. The release also extends oplus to accept tensors whose non-merged axes carry partially overlapping charge sectors: only sectors present in both tensors must agree in dimension; sectors exclusive to one tensor are brought into the output via sector union.

✨ Enhancements

Benchmark Modernization

The five benchmark modules have been refactored to demonstrate idiomatic use of the APIs introduced in v0.3.2:

  • einsum for contractions: Multi-step contract chains replaced by single einsum calls with explicit subscript strings, e.g. einsum('abg,gh,adh->bd', Anow.conj(), H0, Anow) in place of sequential contract + contract calls. This makes the index flow of tensor-network algorithms directly readable from the code.
  • Method-based API: Functional calls replaced by chainable methods throughout — tensor.permute(...) instead of permute(tensor, ...), tensor.conj().transpose() instead of transpose(conj(tensor))
  • Cleaner imports: Functional-form imports (contract, conj, permute, transpose) removed from module headers in favour of einsum and the method API

Modules: bench/network.py, bench/conductor.py, bench/fermionic.py, bench/bosonic.py, bench/system.py

oplus — Relaxed Non-Merged Axis Constraint

Before (≤ 0.3.2): Non-merged axes in oplus required both tensors to carry identical charge sector sets. Any sector-set mismatch, even when the shared sectors agreed in dimension, raised:

ValueError: Index i (non-merged): Must have identical charge sectors, got ... and ...

After (0.3.3): The constraint is relaxed to the physically correct rule:

  • Charge sectors present in both tensors on a non-merged axis must have the same dimension (unchanged).
  • Charge sectors present in only one tensor are accepted without restriction and are included in the output index via sector union.

The output index for a non-merged axis is now built as the union of sectors from both tensors, using each sector's own dimension. Block data for exclusive sectors is taken directly from whichever tensor owns the sector; positions corresponding to the other tensor are left as zero.

This makes oplus consistent with how the merged-axis output is constructed and removes a practical obstacle for tensors with partially overlapping sector structures — a pattern that arises naturally when working with SU(2) tensors of varying spin content.

Source: src/nicole/maneuver.py

🧪 Test Suite (1536 tests)

  • 1526 tests pass, 10 skipped (accelerator-only tests on CPU-only CI)
  • Six new tests added to tests/operations/test_oplus.py:
    • test_oplus_non_merged_axes_disjoint_sectors — fully disjoint sector sets on non-merged axis accepted without error
    • test_oplus_non_merged_axes_shared_dim_mismatch_still_errors — dimension conflicts on shared sectors still raise ValueError
    • test_oplus_non_merged_axis_exclusive_sector_in_A — sector exclusive to A is present in output with correct values
    • test_oplus_non_merged_axis_exclusive_sector_in_B — sector exclusive to B is present in output with correct values
    • test_oplus_non_merged_axis_partial_overlap — partial sector overlap: shared sectors match, exclusive sectors included
    • test_oplus_non_merged_axis_exclusive_sector_block_values — numerical content of exclusive-sector blocks is preserved exactly

📖 Documentation

  • oplus API page (docs/api/arithmetic/oplus.md): Description and Notes sections updated to describe the sector-union semantics for non-merged axes and clarify that only shared sectors impose a dimension constraint.

📊 Statistics

Code Changes

  • 13 commits since v0.3.2
  • 8 files changed: 426 insertions, 209 deletions
  • Bench modules modernized: bench/network.py, bench/conductor.py, bench/fermionic.py, bench/bosonic.py, bench/system.py
  • Source module touched: src/nicole/maneuver.py
  • Test module touched: tests/operations/test_oplus.py
  • Docs page touched: docs/api/arithmetic/oplus.md

✅ Compatibility

Breaking Changes: None. The oplus change relaxes a precondition — all previously valid calls continue to work unchanged.

Requirements:

  • Python ≥ 3.11
  • PyTorch ≥ 2.5
  • Yuzuha ≥ 0.1.5

🙏 Notes

The benchmark modernization demonstrates that real tensor-network algorithms — exact diagonalization over spin chains, fermionic and bosonic models — read cleanly with einsum notation and the chainable method API. The oplus extension removes a constraint inherited from the original Abelian implementation; with the broader tensor constructions enabled by SU(2) support, partially overlapping sector sets on shared axes arise naturally and the old restriction was an unnecessary obstacle.