Skip to content

Nicole 0.3.7

Latest

Choose a tag to compare

@Phy-David-Zhang Phy-David-Zhang released this 17 May 13:22

Nicole 0.3.7 — Squeeze Method for Tensors

Release Date: May 17, 2026

Version 0.3.7 adds Tensor.squeeze(position) as the exact inverse of insert_index, removing a trivial index (neutral charge, dimension 1) from the tensor in-place. For SU(2) tensors, a new Bridge.remove_edge helper handles the corresponding intertwiner update. No public API is changed beyond these additions.

✨ New Features

Tensor.squeeze

Tensor.squeeze(position) removes the trivial index at position from the tensor in-place. It squeezes the singleton axis from all data blocks and rebuilds the block-key mapping with the neutral charge at position dropped. The method raises ValueError if:

  • position is out of range [0, len(self.indices) - 1]
  • the index at position is not trivial (not a single sector with neutral charge and dimension 1)
  • the result would leave exactly one index (single-index tensors are not a valid state)

For SU(2) tensors, each Bridge intertwiner is updated via Bridge.remove_edge (see below); the outer-multiplicity dimension is preserved exactly. squeeze is the structural inverse of insert_index: a round-trip through either order recovers the original tensor.

Bridge.remove_edge

Bridge.remove_edge(position) is the internal counterpart that backs Tensor.squeeze for SU(2) tensors. Given the 0-based position of a spin-0 (neutral-charge) edge, it computes the inverse permutation that slides the edge to position 0, applies the corresponding R-symbol to the weight matrix, then rebuilds the CGSpec from all remaining edges. Raises ValueError if the edge at position is not spin-0.

🧪 Test Suite (1625 tests)

  • 1615 tests pass, 10 skipped (accelerator-only tests on CPU-only CI)
  • 22 new tests in tests/operations/test_maneuver.py covering squeeze at beginning, middle, and end positions; itag removal; data-value preservation; sequential multi-squeeze; all three error paths; Z2 and product-group variants; complex dtype; in-place mutation; label and sorted-keys-cache behaviour; and SU(2) weight roundtrips at all three positions

📊 Statistics

Code Changes

  • 6 commits since v0.3.6
  • 4 files changed: 566 insertions, 7 deletions
  • Source modules touched: src/nicole/tensor.py, src/nicole/symmetry/delegate.py
  • Test module touched: tests/operations/test_maneuver.py

✅ Compatibility

Breaking Changes: None. All previously valid calls continue to work unchanged. The new squeeze method does not conflict with any existing public name.

Requirements:

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

📝 Notes

squeeze and insert_index form a strict inverse pair: a round-trip through either order recovers the original tensor exactly. The restriction against leaving exactly one index reflects a symmetry requirement — a single-index tensor cannot satisfy charge conservation. For SU(2) tensors, removing a spin-0 edge is lossless: the physical tensor R @ W is unchanged, and Bridge.remove_edge applies the inverse R-symbol so the operation is exactly reversible.