Skip to content

Alice 0.2.7

Choose a tag to compare

@changkai-zhang changkai-zhang released this 19 Sep 01:54
· 15 commits to stable since this release

Alice 0.2.7 — Small Norms Are Not Zero

Release Date: September 19, 2026

Version 0.2.7 corrects the zero-norm guards in Network.normalize(),
MPO.redistribute_norm(), and NormalMPO.from_mpo(). These used an absolute tolerance
of 1e-15, which spuriously rejected small but perfectly legitimate norms — most
importantly the d^(-L/2) norm of a squared unit-norm identity-like MPO, the XTRG seed
scenario on long chains. All three now reject only an exact zero or a non-finite norm.
Package metadata is updated with the new author and maintainer contacts. No breaking API
changes.

🔧 Zero-Norm Guards

  • Network.normalize() now raises only when the center tensor's norm is exactly 0.0
    or not finite (inf/nan). Previously math.isclose(n, 0.0, abs_tol=1e-15) rejected
    any norm below 1e-15, even though dividing by such a value is well-conditioned in
    float64.
  • MPO.redistribute_norm() applies the same rule to the total MPO norm before spreading
    it evenly across sites.
  • NormalMPO.from_mpo() applies the same rule to the source MPO's norm before taking
    math.log(n), which stays finite for any non-zero float64.
  • Error messages now report the offending value ("cannot normalize: network norm is 0.0", "cannot redistribute norm: MPO norm is inf", "cannot create NormalMPO from an MPO with norm nan") instead of the generic "numerically zero" / "zero-norm"
    wording.

🧪 Tests

  • New test_small_norm_ok_mps in TestNormalize and test_redistribute_norm_small_norm_ok
    in TestMPO (test_network.py): scale a canonical network to norm 1e-20, assert it
    sits below the old threshold, and check that normalization and redistribution succeed
    with the expected norm.
  • New test_identity_square_small_norm_compacts in TestNormalMPOMatmul
    (test_thermal.py): square a unit-norm identity NormalMPO on an L = 100 spin-1/2
    chain (Frobenius norm 2^(-50)), then compact() it and verify log_scale,
    unit internal norm, and log_trace() against their closed forms.
  • Existing zero-norm tests in test_network.py and test_observe.py updated to match
    the new error messages.

📦 Metadata

  • pyproject.toml: author email moves to c.zhang@ideogenesis.ai; new maintainers
    entry for Ideogenesis AI (developer@ideogenesis.ai).
  • Documentation hero image refreshed.

📊 Statistics

  • 971 tests across 29 test modules (up from 968 / 29 modules in v0.2.6).
  • 7 commits since v0.2.6.
  • 7 files changed, 79 insertions, 18 deletions.
  • 28 source modules in four subpackages: alice.network, alice.physics,
    alice.algorithm.dmrg, alice.algorithm.xtrg (unchanged from v0.2.6).

✅ Compatibility

Breaking Changes: none.

Behavioral Changes:

  • normalize(), redistribute_norm(), and NormalMPO.from_mpo() no longer raise on
    norms in (0, 1e-15); they proceed and succeed. Code that relied on catching
    ValueError for such inputs will now receive a normalized network instead.
  • The ValueError messages for a genuinely zero norm changed wording; callers matching
    on "numerically zero" or "zero-norm" should match on "norm is 0.0" /
    "norm 0.0" instead.

Requirements:

  • Python ≥ 3.11
  • PyTorch ≥ 2.5
  • Nicole ≥ 0.3.7

📝 Notes

The unit-norm identity on a spin-1/2 chain is I / 2^(L/2), so its square has
Frobenius norm 2^(-L/2), which falls below 1e-15 at L = 100. This is the state
XTRG starts from — exp(-τ₀ H) is close to the identity — so the first squaring step
triggered the guard on chains of that length. The failure was not a loss of precision:
float64 represents 2^(-50) exactly, and division by that value is well-conditioned. The
absolute tolerance conflated a small norm with a vanishing one; the fix removes the
tolerance and retains only the two conditions under which the division is genuinely
undefined — an exact 0.0 (every tensor annihilated) and a non-finite norm (overflow or
nan propagated from upstream). Both remain errors.