Repository navigation
Conversation
`lower_weight_CGC!` obtained the CGCs of every weight from those of its parent weights through the lowering equations alone. This recursion is unstable: rounding errors along the other irreps in s1 ⊗ s2 are amplified at every step, which compounds to ~binomial(J′ + J, 2J) for SU(2), so that e.g. the SU(2) CGCs diverge from 2j ≈ 40 on (error 0.2 at 2j = 40, 1e12 at 2j = 70), and larger SU(3) and SU(4) irreps are affected as well. Now the raising equations are imposed too, and both are solved in the least-squares sense. This has the same (unique) solution in exact arithmetic, so the gauge is unchanged, but damps instead of amplifies the errors. The CGC disk cache file names now carry a version, so that coefficients computed by the old code are not read back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dgrinko
force-pushed
the
claude/compassionate-lamport-7kx3at
branch
2 times, most recently
from
October 23, 2026 03:10
27ecfbf to
d2e9d92
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I got severe numerical instabilities with large number of systems, so I asked Claude to fix it.
Numerically stable computation of lower-weight CGCs
lower_weight_CGC!obtains the CGCs of every non-highest weight from those of its parentweights by solving the lowering equations
weight by weight. This recursion is numerically unstable: rounding errors along the other irreps
s3′ ⊂ s1 ⊗ s2are amplified at every step. For SU(2), the factor per step isc_{J′}(M) / c_J(M) > 1forJ′ > J, which compounds tobinomial(J′ + J, 2J)over a fullweight chain. For
CGC(SUNIrrep{2}(2j, 0), SUNIrrep{2}(2j, 0), s3), the largest error over alls3compared with the exact Racah formula is:
After the fix the error stays at 1e-14 up to
2j = 100; that floor comes frompurge!droppingentries below
TOL_PURGE = 1e-14.Larger SU(3) and SU(4) irreps are affected too. The table gives the largest violation of the defining
properties of the CGCs (isometry,
J± C = C J±₃for all simple roots):(6,3,0) ⊗ (6,3,0) →all 25(14,0,0) ⊗ (14,14,0) → (14,7,0)(16,0,0) ⊗ (16,16,0) → (16,8,0)(10,0,0,0) ⊗ (10,10,10,0) → (10,5,5,0)Fix
At every weight, the raising equations
(J⁺₁ ⊗ 𝕀 + 𝕀 ⊗ J⁺₂) X = Y J⁺₃(withJ⁺ = J⁻ᵀ) are nowimposed as well, and both sets are solved in the least-squares sense. Let
LₗandKₗbe theblocks of
J⁻ₗons1 ⊗ s2and ons3from the parent weightw3 + αₗtow3, and letYₗbethe CGC block of that parent. Then
has the normal equations
X A + B X = R, where:A = ∑ₗ Kₗ Kₗᵀis small and positive definite;B = ∑ₗ Lₗ Lₗᵀis positive semidefinite. The sum runs over alll, including those wherew3 + αₗis not a weight ofs3; for those, the raising equations readLₗᵀ X = 0;R = 2 ∑ₗ Lₗ Yₗ Kₗᵀ.The exact CGCs satisfy both sets of equations, and the solution is unique, so nothing changes in
exact arithmetic, including the gauge. On all 1323 CGCs between small irreps of SU(2) to SU(5), the
old and new code agree to 1e-12, which is the old code's own error.
For SU(2), each step now multiplies the error along
J′by2ab / (a² + b²) ≤ 1(witha = c_{J′},b = c_J) instead ofa / b. For SU(N ≥ 3) this is not an exact statement per irrep,because
∑ₗ J⁻ₗ J⁺ₗover the simple roots is not diagonal in the irrep decomposition. The tablesabove show the same damping in practice.
The system is solved by diagonalizing
Aand doing one dense Cholesky factorization ofB + μₖ 𝕀per eigenvalueμₖ.Bis accumulated from the sparse columns of the raising operators.In
lower_weight_CGC!itself, only theqr!solve is replaced (bylowering_solve). The otheradditions are the helpers
lowering_solve,raising_columnsandraising_gram.Cost
Computing all CGCs between irreps of dimension ≤ 31 (SU(2)), ≤ 64 (SU(3), SU(4)) and ≤ 50 (SU(5))
takes 1.3–2.0× as long as before. Single larger products, like those in the tables above, take
2–2.7× as long. The dense Cholesky factorization of the weight-space block is the main extra cost.
CGCs are cached in RAM and on disk, so this cost is paid once per CGC.
Disk cache
Cached CGCs written by the old code can be wrong, so the cache file names now carry a version
suffix (
CGC_CACHE_VERSION = "v2"), and old entries are never read back. As a result, existing diskcaches get recomputed. The old files stay on disk until
clear_disk_cache!()is called.Tests
test/clebschgordan.jlexisted but was empty and was not included inruntests.jl. It nowcontains:
SU2Irrep(fromWignerSymbols);
J⁻ C = C J⁻₃) checks for SU(3) and SU(4) products, includingouter multiplicities 3 and 4.
On
main, 12 of these 19 tests fail.The full test suite passes locally (fusion trees, pentagon/hexagon, caching, Aqua), and Runic
reports no formatting changes.