Alice 0.2.7
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 exactly0.0
or not finite (inf/nan). Previouslymath.isclose(n, 0.0, abs_tol=1e-15)rejected
any norm below1e-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_mpsinTestNormalizeandtest_redistribute_norm_small_norm_ok
inTestMPO(test_network.py): scale a canonical network to norm1e-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_compactsinTestNormalMPOMatmul
(test_thermal.py): square a unit-norm identityNormalMPOon anL = 100spin-1/2
chain (Frobenius norm2^(-50)), thencompact()it and verifylog_scale,
unit internal norm, andlog_trace()against their closed forms. - Existing zero-norm tests in
test_network.pyandtest_observe.pyupdated to match
the new error messages.
📦 Metadata
pyproject.toml: author email moves toc.zhang@ideogenesis.ai; newmaintainers
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(), andNormalMPO.from_mpo()no longer raise on
norms in(0, 1e-15); they proceed and succeed. Code that relied on catching
ValueErrorfor such inputs will now receive a normalized network instead.- The
ValueErrormessages 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.