racah-py 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- racah_py-0.1.0/.github/workflows/ci.yml +88 -0
- racah_py-0.1.0/.github/workflows/wheels.yml +116 -0
- racah_py-0.1.0/.gitignore +16 -0
- racah_py-0.1.0/AGENTS.md +90 -0
- racah_py-0.1.0/CHANGELOG.md +290 -0
- racah_py-0.1.0/CITATION.cff +16 -0
- racah_py-0.1.0/Cargo.lock +1955 -0
- racah_py-0.1.0/Cargo.toml +93 -0
- racah_py-0.1.0/LICENSE-APACHE +202 -0
- racah_py-0.1.0/LICENSE-MIT +21 -0
- racah_py-0.1.0/PKG-INFO +142 -0
- racah_py-0.1.0/README.md +250 -0
- racah_py-0.1.0/benches/bcd_fr.rs +122 -0
- racah_py-0.1.0/benches/sun_cgc.rs +63 -0
- racah_py-0.1.0/benches/sun_fr.rs +118 -0
- racah_py-0.1.0/benches/sun_product.rs +228 -0
- racah_py-0.1.0/benches/wigner.rs +193 -0
- racah_py-0.1.0/doc/katex-header.html +34 -0
- racah_py-0.1.0/docs/README.md +38 -0
- racah_py-0.1.0/docs/developer/README.md +100 -0
- racah_py-0.1.0/docs/developer/coefficient-cache-audit-timings.jsonl +45 -0
- racah_py-0.1.0/docs/developer/coefficient-cache-audit-trace.jsonl +27 -0
- racah_py-0.1.0/docs/developer/coefficient-cache-audit.md +42 -0
- racah_py-0.1.0/docs/developer/coefficient-cache-budget-pressure.jsonl +15 -0
- racah_py-0.1.0/docs/developer/coefficient-cache-budget-tradeoff.md +45 -0
- racah_py-0.1.0/docs/developer/coefficient-cache-trim-pressure.jsonl +15 -0
- racah_py-0.1.0/docs/developer/coefficient-cache-trim-tradeoff.md +31 -0
- racah_py-0.1.0/docs/gauge.md +454 -0
- racah_py-0.1.0/docs/gauge_soN.md +1000 -0
- racah_py-0.1.0/docs/references.md +227 -0
- racah_py-0.1.0/docs/theory.md +34 -0
- racah_py-0.1.0/docs/theory.pdf +0 -0
- racah_py-0.1.0/docs/theory.tex +1833 -0
- racah_py-0.1.0/docs/user-guide/README.md +44 -0
- racah_py-0.1.0/docs/user-guide/clebsch-gordan.md +166 -0
- racah_py-0.1.0/docs/user-guide/fusion.md +130 -0
- racah_py-0.1.0/docs/user-guide/getting-started.md +126 -0
- racah_py-0.1.0/docs/user-guide/groups.md +207 -0
- racah_py-0.1.0/docs/user-guide/recoupling.md +277 -0
- racah_py-0.1.0/docs/user-guide/representations.md +174 -0
- racah_py-0.1.0/docs/user-guide/resources.md +158 -0
- racah_py-0.1.0/pyproject.toml +40 -0
- racah_py-0.1.0/racah-py/Cargo.toml +24 -0
- racah_py-0.1.0/racah-py/README.md +120 -0
- racah_py-0.1.0/racah-py/racah.pyi +34 -0
- racah_py-0.1.0/racah-py/src/lib.rs +234 -0
- racah_py-0.1.0/racah-py/tests/test_smoke.py +100 -0
- racah_py-0.1.0/racah.pyi +34 -0
- racah_py-0.1.0/src/bcd/catalog/tests.rs +515 -0
- racah_py-0.1.0/src/bcd/catalog.rs +975 -0
- racah_py-0.1.0/src/bcd/fr/tests.rs +224 -0
- racah_py-0.1.0/src/bcd/fr.rs +416 -0
- racah_py-0.1.0/src/bcd/linalg.rs +280 -0
- racah_py-0.1.0/src/bcd/qspace_oracle_tests.rs +661 -0
- racah_py-0.1.0/src/bcd/seeds/tests.rs +292 -0
- racah_py-0.1.0/src/bcd/seeds.rs +682 -0
- racah_py-0.1.0/src/bcd/sweep/tests.rs +613 -0
- racah_py-0.1.0/src/bcd/sweep.rs +1573 -0
- racah_py-0.1.0/src/bcd/tests.rs +526 -0
- racah_py-0.1.0/src/bcd.rs +1344 -0
- racah_py-0.1.0/src/cache.rs +1955 -0
- racah_py-0.1.0/src/cache_audit.rs +264 -0
- racah_py-0.1.0/src/cache_budget_pressure.rs +106 -0
- racah_py-0.1.0/src/cache_trim_pressure.rs +121 -0
- racah_py-0.1.0/src/exact.rs +407 -0
- racah_py-0.1.0/src/frcore.rs +767 -0
- racah_py-0.1.0/src/group.rs +537 -0
- racah_py-0.1.0/src/lib.rs +235 -0
- racah_py-0.1.0/src/primefactor.rs +534 -0
- racah_py-0.1.0/src/su2.rs +2023 -0
- racah_py-0.1.0/src/sun/cgc.rs +966 -0
- racah_py-0.1.0/src/sun/fr.rs +424 -0
- racah_py-0.1.0/src/sun/linalg.rs +239 -0
- racah_py-0.1.0/src/sun.rs +1419 -0
- racah_py-0.1.0/tests/base_cache_contract.rs +132 -0
- racah_py-0.1.0/tests/bcd_fingerprint.rs +53 -0
- racah_py-0.1.0/tests/bcd_fr.rs +307 -0
- racah_py-0.1.0/tests/cache_trim_base.rs +41 -0
- racah_py-0.1.0/tests/cache_trim_generated_routing.rs +63 -0
- racah_py-0.1.0/tests/coefficient_cache_budget_base.rs +36 -0
- racah_py-0.1.0/tests/coefficient_cache_budget_generated.rs +39 -0
- racah_py-0.1.0/tests/coefficient_cache_budget_observation.rs +17 -0
- racah_py-0.1.0/tests/doc_examples.rs +507 -0
- racah_py-0.1.0/tests/fixtures/bcd_fixtures.json +60 -0
- racah_py-0.1.0/tests/fixtures/groupmath_products.txt +26 -0
- racah_py-0.1.0/tests/fixtures/qspace_cgc.txt +2976 -0
- racah_py-0.1.0/tests/fixtures/qspace_generators.txt +230 -0
- racah_py-0.1.0/tests/fixtures/su2_6j_large.txt +44 -0
- racah_py-0.1.0/tests/fixtures/su2_f.txt +109909 -0
- racah_py-0.1.0/tests/fixtures/su2_r.txt +625 -0
- racah_py-0.1.0/tests/fixtures/su3_fr_f.txt +135814 -0
- racah_py-0.1.0/tests/fixtures/su3_fr_r.txt +898 -0
- racah_py-0.1.0/tests/fixtures/sun/sun_fixtures.txt +1814 -0
- racah_py-0.1.0/tests/fixtures/sun_cgc.txt +3782 -0
- racah_py-0.1.0/tests/fixtures_large.rs +96 -0
- racah_py-0.1.0/tests/fr_oracle.rs +82 -0
- racah_py-0.1.0/tests/gauge_golden.rs +547 -0
- racah_py-0.1.0/tests/generated_backend_identity.rs +190 -0
- racah_py-0.1.0/tests/generated_cache_contract.rs +145 -0
- racah_py-0.1.0/tests/global_form.rs +942 -0
- racah_py-0.1.0/tests/groupmath_oracle.rs +145 -0
- racah_py-0.1.0/tests/isomorphism.rs +442 -0
- racah_py-0.1.0/tests/oracle.rs +256 -0
- racah_py-0.1.0/tests/properties.rs +369 -0
- racah_py-0.1.0/tests/spin.rs +404 -0
- racah_py-0.1.0/tests/su2_embedding.rs +128 -0
- racah_py-0.1.0/tests/su2_fingerprint.rs +38 -0
- racah_py-0.1.0/tests/sun_cgc_cache.rs +154 -0
- racah_py-0.1.0/tests/sun_cgc_fixtures.rs +145 -0
- racah_py-0.1.0/tests/sun_fingerprint.rs +45 -0
- racah_py-0.1.0/tests/sun_fr_cache.rs +68 -0
- racah_py-0.1.0/tests/sun_fr_gates.rs +96 -0
- racah_py-0.1.0/tests/sun_fr_su2.rs +211 -0
- racah_py-0.1.0/tests/sun_fr_su3_oracle.rs +163 -0
- racah_py-0.1.0/tests/sun_oracle.rs +172 -0
- racah_py-0.1.0/tests/sun_product_cache.rs +127 -0
- racah_py-0.1.0/tools/README.md +92 -0
- racah_py-0.1.0/tools/gen_bcd_fixtures.jl +88 -0
- racah_py-0.1.0/tools/gen_bcd_fixtures.py +109 -0
- racah_py-0.1.0/tools/gen_fixtures.jl +82 -0
- racah_py-0.1.0/tools/gen_fr_fixtures.jl +83 -0
- racah_py-0.1.0/tools/gen_su3_fr_fixtures.jl +103 -0
- racah_py-0.1.0/tools/gen_sun_cgc_fixtures.jl +72 -0
- racah_py-0.1.0/tools/gen_sun_fixtures.jl +154 -0
- racah_py-0.1.0/tools/groupmath/gen_groupmath_products.wls +113 -0
- racah_py-0.1.0/tools/qspace/README.md +46 -0
- racah_py-0.1.0/tools/qspace/gen_qspace_cgc.m +35 -0
- racah_py-0.1.0/tools/qspace/gen_qspace_generators.m +26 -0
- racah_py-0.1.0/tools/qspace/getCG_maca64_sync.patch +80 -0
- racah_py-0.1.0/tools/qspace/getRC_maca64_sync.patch +66 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
CARGO_TERM_COLOR: always
|
|
10
|
+
RUSTFLAGS: -D warnings
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
fmt:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- run: rustup toolchain install stable --profile minimal --component rustfmt
|
|
18
|
+
- run: cargo fmt --all --check
|
|
19
|
+
|
|
20
|
+
clippy:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- run: rustup toolchain install stable --profile minimal --component clippy
|
|
25
|
+
- uses: Swatinem/rust-cache@v2
|
|
26
|
+
- run: cargo clippy --all-targets --all-features
|
|
27
|
+
|
|
28
|
+
test:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
- run: rustup toolchain install stable --profile minimal
|
|
33
|
+
- uses: Swatinem/rust-cache@v2
|
|
34
|
+
# dev-dependency wigner-symbols pulls gmp-mpfr-sys, which builds GMP
|
|
35
|
+
# from source on first run; rust-cache keeps the build cached across runs.
|
|
36
|
+
- run: cargo test --all-features
|
|
37
|
+
- run: cargo test --no-default-features
|
|
38
|
+
|
|
39
|
+
# Non-blocking coverage measurement for the README badge. Line coverage is
|
|
40
|
+
# auxiliary here — the golden/coherence guards are the primary correctness
|
|
41
|
+
# gates — so this job never fails the pipeline. It publishes a shields.io
|
|
42
|
+
# endpoint JSON to the `badges` branch, which the README badge reads via
|
|
43
|
+
# raw.githubusercontent.com.
|
|
44
|
+
coverage:
|
|
45
|
+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
continue-on-error: true
|
|
48
|
+
permissions:
|
|
49
|
+
contents: write
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v4
|
|
52
|
+
- run: rustup toolchain install stable --profile minimal --component llvm-tools-preview
|
|
53
|
+
- uses: Swatinem/rust-cache@v2
|
|
54
|
+
- uses: taiki-e/install-action@cargo-llvm-cov
|
|
55
|
+
# One instrumented test run; both report formats are re-emitted from it.
|
|
56
|
+
- run: cargo llvm-cov --workspace --all-features --no-report
|
|
57
|
+
- run: cargo llvm-cov report --summary-only --json --output-path coverage.json
|
|
58
|
+
- run: cargo llvm-cov report --codecov --output-path codecov.json
|
|
59
|
+
- uses: codecov/codecov-action@v5
|
|
60
|
+
with:
|
|
61
|
+
files: codecov.json
|
|
62
|
+
fail_ci_if_error: false
|
|
63
|
+
- name: Publish badge JSON to badges branch
|
|
64
|
+
run: |
|
|
65
|
+
pct=$(jq -r '.data[0].totals.lines.percent' coverage.json)
|
|
66
|
+
msg=$(printf '%.1f%%' "$pct")
|
|
67
|
+
color=$(awk -v p="$pct" 'BEGIN{print (p<60)?"red":(p<80)?"yellow":"brightgreen"}')
|
|
68
|
+
jq -n --arg m "$msg" --arg c "$color" \
|
|
69
|
+
'{schemaVersion:1,label:"coverage",message:$m,color:$c}' > badge.json
|
|
70
|
+
git config user.name "github-actions[bot]"
|
|
71
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
72
|
+
# Single-file branch built from plumbing; history is disposable, force-push.
|
|
73
|
+
blob=$(git hash-object -w badge.json)
|
|
74
|
+
tree=$(printf '100644 blob %s\tbadge.json\n' "$blob" | git mktree)
|
|
75
|
+
commit=$(git commit-tree "$tree" -m "coverage badge: $msg ($GITHUB_SHA)")
|
|
76
|
+
git push -f origin "$commit:refs/heads/badges"
|
|
77
|
+
|
|
78
|
+
doc:
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@v4
|
|
82
|
+
- run: rustup toolchain install stable --profile minimal
|
|
83
|
+
- uses: Swatinem/rust-cache@v2
|
|
84
|
+
- run: cargo doc --no-deps --all-features
|
|
85
|
+
env:
|
|
86
|
+
# Same KaTeX header as docs.rs (Cargo.toml [package.metadata.docs.rs]);
|
|
87
|
+
# space-separated flags compose in the one RUSTDOCFLAGS env var.
|
|
88
|
+
RUSTDOCFLAGS: -D warnings --html-in-header doc/katex-header.html
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
name: wheels
|
|
2
|
+
|
|
3
|
+
# Python bindings (`racah-py`): abi3-py312 wheels for linux (x86_64, aarch64),
|
|
4
|
+
# macos (arm64, x86_64), windows (x86_64), plus an sdist.
|
|
5
|
+
#
|
|
6
|
+
# Trusted publishing (OIDC, no tokens), same ladder as tenet-py's release.yml:
|
|
7
|
+
# a `py-v*` tag push dry-runs the artifacts through TestPyPI; publishing a
|
|
8
|
+
# GitHub release whose tag starts with `py-v` ships them to PyPI. The crate's
|
|
9
|
+
# own `v*` releases never touch PyPI, so the two cadences stay independent.
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
branches: [main]
|
|
13
|
+
tags: ["py-v*"]
|
|
14
|
+
pull_request:
|
|
15
|
+
release:
|
|
16
|
+
types: [published]
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
|
|
19
|
+
env:
|
|
20
|
+
CARGO_TERM_COLOR: always
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
# Build the extension in place and run the Python smoke tests.
|
|
24
|
+
test:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
- run: rustup toolchain install stable --profile minimal
|
|
32
|
+
- uses: Swatinem/rust-cache@v2
|
|
33
|
+
- run: pip install maturin pytest numpy
|
|
34
|
+
# `maturin develop` needs an activated virtualenv; the runner's Python is
|
|
35
|
+
# already isolated, so build the wheel and install it.
|
|
36
|
+
- run: maturin build --release --manifest-path racah-py/Cargo.toml --out dist
|
|
37
|
+
- run: pip install --no-index --find-links dist racah-py
|
|
38
|
+
- run: pytest racah-py/tests -q
|
|
39
|
+
|
|
40
|
+
wheels:
|
|
41
|
+
if: >-
|
|
42
|
+
startsWith(github.ref, 'refs/tags/py-v') ||
|
|
43
|
+
github.event_name == 'workflow_dispatch' ||
|
|
44
|
+
(github.event_name == 'release' && startsWith(github.event.release.tag_name, 'py-v'))
|
|
45
|
+
strategy:
|
|
46
|
+
fail-fast: false
|
|
47
|
+
matrix:
|
|
48
|
+
include:
|
|
49
|
+
# linux aarch64 cross-compiles inside maturin-action's manylinux
|
|
50
|
+
# docker image; macos x86_64 cross-compiles from the arm64 runner.
|
|
51
|
+
# The crate is pure Rust, so stock toolchains suffice everywhere.
|
|
52
|
+
- runner: ubuntu-latest
|
|
53
|
+
target: x86_64
|
|
54
|
+
- runner: ubuntu-latest
|
|
55
|
+
target: aarch64
|
|
56
|
+
- runner: macos-14
|
|
57
|
+
target: aarch64
|
|
58
|
+
- runner: macos-14
|
|
59
|
+
target: x86_64
|
|
60
|
+
- runner: windows-latest
|
|
61
|
+
target: x64
|
|
62
|
+
runs-on: ${{ matrix.runner }}
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v4
|
|
65
|
+
- uses: actions/setup-python@v5
|
|
66
|
+
with:
|
|
67
|
+
python-version: "3.12"
|
|
68
|
+
- uses: PyO3/maturin-action@v1
|
|
69
|
+
with:
|
|
70
|
+
target: ${{ matrix.target }}
|
|
71
|
+
# abi3-py312: one wheel per platform covers CPython >= 3.12.
|
|
72
|
+
args: --release --out dist --manifest-path racah-py/Cargo.toml
|
|
73
|
+
manylinux: auto
|
|
74
|
+
- uses: actions/upload-artifact@v4
|
|
75
|
+
with:
|
|
76
|
+
name: wheels-${{ matrix.runner }}-${{ matrix.target }}
|
|
77
|
+
path: dist
|
|
78
|
+
|
|
79
|
+
# Unsupported platforms build from source with a Rust toolchain.
|
|
80
|
+
sdist:
|
|
81
|
+
if: >-
|
|
82
|
+
startsWith(github.ref, 'refs/tags/py-v') ||
|
|
83
|
+
github.event_name == 'workflow_dispatch' ||
|
|
84
|
+
(github.event_name == 'release' && startsWith(github.event.release.tag_name, 'py-v'))
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
steps:
|
|
87
|
+
- uses: actions/checkout@v4
|
|
88
|
+
- uses: PyO3/maturin-action@v1
|
|
89
|
+
with:
|
|
90
|
+
command: sdist
|
|
91
|
+
args: --out dist --manifest-path racah-py/Cargo.toml
|
|
92
|
+
- uses: actions/upload-artifact@v4
|
|
93
|
+
with:
|
|
94
|
+
name: sdist
|
|
95
|
+
path: dist
|
|
96
|
+
|
|
97
|
+
publish:
|
|
98
|
+
needs: [wheels, sdist]
|
|
99
|
+
if: >-
|
|
100
|
+
startsWith(github.ref, 'refs/tags/py-v') ||
|
|
101
|
+
(github.event_name == 'release' && startsWith(github.event.release.tag_name, 'py-v'))
|
|
102
|
+
runs-on: ubuntu-latest
|
|
103
|
+
environment: pypi
|
|
104
|
+
permissions:
|
|
105
|
+
id-token: write
|
|
106
|
+
steps:
|
|
107
|
+
- uses: actions/download-artifact@v4
|
|
108
|
+
with:
|
|
109
|
+
path: dist
|
|
110
|
+
merge-multiple: true
|
|
111
|
+
- if: github.event_name == 'push'
|
|
112
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
113
|
+
with:
|
|
114
|
+
repository-url: https://test.pypi.org/legacy/
|
|
115
|
+
- if: github.event_name == 'release'
|
|
116
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/target
|
|
2
|
+
Cargo.lock
|
|
3
|
+
.DS_Store
|
|
4
|
+
# Developer-local tenferro-rs override (see AGENTS.md); never committed.
|
|
5
|
+
/.cargo/
|
|
6
|
+
|
|
7
|
+
# Python bindings dev venv (racah-py); never committed.
|
|
8
|
+
/racah-py/.venv/
|
|
9
|
+
__pycache__/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
|
|
12
|
+
# LaTeX build artifacts (docs/theory.tex); the built theory.pdf IS committed.
|
|
13
|
+
docs/*.aux
|
|
14
|
+
docs/*.log
|
|
15
|
+
docs/*.out
|
|
16
|
+
docs/*.toc
|
racah_py-0.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# racah Agent Policy
|
|
2
|
+
|
|
3
|
+
Design authority: the architecture, acceptance criteria, and reference-role
|
|
4
|
+
map recorded in the upstream design discussion. Read them before any
|
|
5
|
+
non-trivial change.
|
|
6
|
+
|
|
7
|
+
## Boundaries
|
|
8
|
+
|
|
9
|
+
- Pure representation mathematics only. No fusion-category trait vocabulary,
|
|
10
|
+
no sector identity types, no tensor-network concepts, and no dependency on
|
|
11
|
+
any tensor-network engine crate.
|
|
12
|
+
- Base crate: exact SU(2) only; dependencies stay minimal (big-integer
|
|
13
|
+
arithmetic at most).
|
|
14
|
+
- `cgc-gen` feature: all runtime generation (SU(N)/SO(N)/Sp(2N)) and every
|
|
15
|
+
dense-kernel dependency live behind this feature. Factorizations
|
|
16
|
+
(nullspace/QR/least-squares) and CGC contractions route through the
|
|
17
|
+
selected dense backend; hand-rolled numeric kernels are not accepted.
|
|
18
|
+
- CGC are a legitimate public output of this crate; recoupling (F/R)
|
|
19
|
+
derivation and its caches live here, next to the gauge contract.
|
|
20
|
+
|
|
21
|
+
## Acceptance criteria (every coefficient-affecting change)
|
|
22
|
+
|
|
23
|
+
1. Combinatorial structure exact (integer/rational; no floats in
|
|
24
|
+
enumeration, multiplicities, or weights).
|
|
25
|
+
2. Discrete data exact (duals, Frobenius–Schur phases, signs, basis order).
|
|
26
|
+
3. Gauge fixing deterministic: pivot rules and sign conventions are part of
|
|
27
|
+
the specification; discrete gauge flips across runs/backends are defects.
|
|
28
|
+
4. The gauge is a **frozen normative specification** (`docs/gauge.md`,
|
|
29
|
+
`docs/gauge_soN.md`): the documents are the authority, the code implements
|
|
30
|
+
them. A change that moves a coefficient value is a bug unless it ships as a
|
|
31
|
+
specification correction — spec edit, fingerprint `epoch` bump, CHANGELOG
|
|
32
|
+
breaking-change entry, regenerated `tests/gauge_golden.rs` values, one PR
|
|
33
|
+
(`docs/gauge.md`, "Status").
|
|
34
|
+
5. Floating-point stages verification-gated: orthogonality, unitarity,
|
|
35
|
+
pentagon/hexagon checks run at generation time; violations are typed
|
|
36
|
+
errors, never silently degraded coefficients.
|
|
37
|
+
|
|
38
|
+
## Guard inventory (every port PR)
|
|
39
|
+
|
|
40
|
+
Reference guards that live *outside* the expression being ported are the
|
|
41
|
+
recurring defect class tracked in issue #15 (dropped `@assert`s, type
|
|
42
|
+
constraints, and unreachable-by-construction assumptions). Every port PR must:
|
|
43
|
+
|
|
44
|
+
1. Enumerate, in the PR body, each guard on the reference path being ported —
|
|
45
|
+
`@assert`/`@check`, type or domain constraints, and invariants the reference
|
|
46
|
+
relies on as unreachable-by-construction.
|
|
47
|
+
2. Map each to exactly one of: a typed error, a documented loud-panic invariant,
|
|
48
|
+
or an explicit N/A with justification. An unmapped guard blocks merge.
|
|
49
|
+
3. Ensure every fast-path / special-case branch runs the same verification
|
|
50
|
+
gates as the general path, or prove those gates vacuous for that branch.
|
|
51
|
+
|
|
52
|
+
## tenferro-rs dependency (cgc-gen)
|
|
53
|
+
|
|
54
|
+
The `cgc-gen` feature depends on `tenferro-{linalg,cpu,runtime}` via a **git
|
|
55
|
+
dependency pinned to an exact revision** (`Cargo.toml`), so a standalone CI
|
|
56
|
+
checkout with no sibling `tenferro-rs` on disk resolves. Bumping the pinned
|
|
57
|
+
`rev` is an ordinary reviewed commit (it can change coefficient values — see the
|
|
58
|
+
gauge semver contract).
|
|
59
|
+
|
|
60
|
+
To develop against an in-progress local `tenferro-rs` checkout, use a
|
|
61
|
+
**developer-local, never-committed** override: a gitignored `.cargo/config.toml`
|
|
62
|
+
with
|
|
63
|
+
|
|
64
|
+
```toml
|
|
65
|
+
[patch."https://github.com/tensor4all/tenferro-rs"]
|
|
66
|
+
tenferro-linalg = { path = "../tenferro-rs/crates/tenferro-linalg" }
|
|
67
|
+
tenferro-cpu = { path = "../tenferro-rs/crates/tenferro-cpu" }
|
|
68
|
+
tenferro-runtime = { path = "../tenferro-rs/crates/tenferro-runtime" }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`.cargo/` is gitignored. CI and every reviewed build use the pinned git rev, not
|
|
72
|
+
the patch.
|
|
73
|
+
|
|
74
|
+
## Verification
|
|
75
|
+
|
|
76
|
+
- Oracles are independent: reference-implementation outputs (WignerSymbols,
|
|
77
|
+
SUNRepresentations, GroupMath, QSpace after gauge alignment), checked-in
|
|
78
|
+
fixtures with provenance, and self-consistency identities. Values derived
|
|
79
|
+
from the code under test are not oracles.
|
|
80
|
+
- **Reference-inventory rule.** Any "existing X" a spec/issue/PR relies on
|
|
81
|
+
(function, symbol, test, fixture) must be cited as `file::symbol` and
|
|
82
|
+
verified to exist before it is built on. Unverified references block merge.
|
|
83
|
+
- **Warm-no-resweep rule.** Adding or touching a coefficient-generation API
|
|
84
|
+
requires a test proving a warm second call is served from cache without
|
|
85
|
+
re-sweeping. Consumer-only strands (they call an existing decomposition)
|
|
86
|
+
are exempt.
|
|
87
|
+
- Fixture strands document normalization, OM-axis convention, and label
|
|
88
|
+
format in their header (`tools/README.md`, "Fixture and spec rules").
|
|
89
|
+
- `cargo fmt` and `cargo test` (all feature combinations touched) before
|
|
90
|
+
every commit; fine-grained commits, each building and testing green.
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this crate are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project
|
|
5
|
+
follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html) with the
|
|
6
|
+
value/gauge rule noted below.
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.0] - 2026-08-18
|
|
11
|
+
|
|
12
|
+
**Value/gauge status of this release:** the one value-affecting change is the
|
|
13
|
+
[#90](https://github.com/Ryo-wtnb11/racah/issues/90) base-case frame
|
|
14
|
+
correction below — `SO(2r+1)`/`SO(2r)`/`Spin(N)` coefficient values move and
|
|
15
|
+
`bcd_authority_fingerprint()` is now `epoch=2`; persisted B/D coefficients
|
|
16
|
+
generated under `epoch=1` must be regenerated. `Sp(2r)` values are
|
|
17
|
+
byte-identical, and the SU(2) and SU(N) fingerprints do not move. No
|
|
18
|
+
coefficient, gauge, normalization or fingerprint change has landed since that
|
|
19
|
+
`epoch=2` correction; everything else in this release is API surface
|
|
20
|
+
(`racah::group`, `Spin(N)`, `from_dynkin_in`, the `BcdError` rename), docs,
|
|
21
|
+
tests and CI.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Documentation reorganized into five layers** with a top-level index
|
|
26
|
+
([`docs/README.md`](docs/README.md)). New task-oriented **User Guide**
|
|
27
|
+
(`docs/user-guide/`): getting started, representations, choosing a group,
|
|
28
|
+
fusion, Clebsch–Gordan, recoupling (F/R), and numerical behaviour/resources.
|
|
29
|
+
New `docs/developer/` index; the coefficient-cache audit and trade-off
|
|
30
|
+
documents and their raw JSONL moved there, marked non-user-facing. The README
|
|
31
|
+
is roughly 60% shorter: the provider contract, cache contract, layering
|
|
32
|
+
diagram, kernel routing and verification-strategy prose moved to the User
|
|
33
|
+
Guide, the crate rustdoc and the developer docs rather than being duplicated.
|
|
34
|
+
Rustdoc gained per-item examples and explicit **Returns** sections stating
|
|
35
|
+
array shapes, axis order and multiplicity-index meaning for the CGC / F / R
|
|
36
|
+
surfaces; `tests/doc_examples.rs` compiles and runs every code block in the
|
|
37
|
+
README and the guide. Documentation only — no API, convention, gauge or
|
|
38
|
+
coefficient value changes.
|
|
39
|
+
|
|
40
|
+
- **`sun::Irrep::from_dynkin_in(&GroupId, &[i64])`** — the `A`-series
|
|
41
|
+
form-aware constructor, matching `bcd::Irrep::from_dynkin_in`
|
|
42
|
+
([#87](https://github.com/Ryo-wtnb11/racah/issues/87)). `SU(N)/Z_k` (`k | N`)
|
|
43
|
+
and `PSU(N)` now restrict the admissible highest weights by `N`-ality; the
|
|
44
|
+
rule itself stays in `GroupId::admits` and `sun` does not restate it.
|
|
45
|
+
`from_dynkin` is unchanged and remains the simply connected `SU(N)`. **No
|
|
46
|
+
coefficient value, basis ordering, phase, normalization or fingerprint
|
|
47
|
+
moves**: a global form gates which weights may be requested, and every
|
|
48
|
+
admissible weight goes through the one Gelfand–Tsetlin engine and the same
|
|
49
|
+
(form-free) cache entry.
|
|
50
|
+
- **`Spin(N)` — the spinor irreps of the `B`/`D` covers**
|
|
51
|
+
([#54](https://github.com/Ryo-wtnb11/racah/issues/54), stage (b) of
|
|
52
|
+
[#87](https://github.com/Ryo-wtnb11/racah/issues/87)). `Irrep::from_dynkin_in`
|
|
53
|
+
takes a `GroupId`, so `GroupId::spin(N)` admits the spinor labels that
|
|
54
|
+
`SO(N)` rejects; their dimensions, duals, Frobenius–Schur indicators, fusion,
|
|
55
|
+
CGC and F/R are produced by the same bootstrap. Three parts:
|
|
56
|
+
- `bcd::Irrep` now stores the **doubled** ε-basis weight `2λ`, so a spinor's
|
|
57
|
+
half-integer highest weight is exact (`Irrep::two_partition`,
|
|
58
|
+
`Irrep::is_spinor`; `Irrep::partition` returns `Option`, `None` on a
|
|
59
|
+
spinor, and `Irrep::weight_multiplicities` likewise, with
|
|
60
|
+
`two_weight_multiplicities` always available).
|
|
61
|
+
- `bcd::spinor_seeds` — the second base case: the Clifford/Fock generator
|
|
62
|
+
seeds for `ω_r` (`B_r`) and `ω_{r-1}`, `ω_r` (`D_r`), gated by the same
|
|
63
|
+
exact `check_commutators`, specified in
|
|
64
|
+
[`docs/gauge_soN.md`](docs/gauge_soN.md) §16 and pinned by new
|
|
65
|
+
`tests/gauge_golden.rs` rows (`Spin(5)`, `Spin(6)`, `Spin(7)`, `Spin(10)`).
|
|
66
|
+
- The canonical-parent candidate set is **class-indexed** (§14.2): a tensor
|
|
67
|
+
irrep's parents are searched in the tensor sublattice only. **Every shipped
|
|
68
|
+
`SO(N)`/`Sp(2N)` coefficient is byte-identical** and the `bcd` `epoch` stays
|
|
69
|
+
at `1` at this stage; `bcd_authority_fingerprint()` gains no tag (§16.4
|
|
70
|
+
states why). (The separate #90 correction under **Changed** below is what
|
|
71
|
+
later moves the `bcd` epoch to `2`.)
|
|
72
|
+
|
|
73
|
+
Oracles in `tests/isomorphism.rs` and `tests/spin.rs`: `Spin(6) ≅ SU(4)` and
|
|
74
|
+
`Spin(5) ≅ Sp(4)` now agree on the **whole** weight lattice (dimensions,
|
|
75
|
+
duals, every ordered product, Frobenius–Schur), and `Spin(3) ≅ SU(2)` is the
|
|
76
|
+
form-aware low-rank redirect.
|
|
77
|
+
|
|
78
|
+
- **`racah::group` — root datum plus global form** (stage (a) of
|
|
79
|
+
[#87](https://github.com/Ryo-wtnb11/racah/issues/87)). `RootSystem`,
|
|
80
|
+
`GlobalForm`, `CenterSubgroup`, `GroupId` with fallible named constructors
|
|
81
|
+
(`GroupId::su/su_quotient/psu/sp/psp/spin/so/pso/half_spin_plus/
|
|
82
|
+
half_spin_minus`), and `GroupId::admits(&[i64])` — the central-character
|
|
83
|
+
predicate that says which dominant weights are representations of which
|
|
84
|
+
connected compact group. Ungated (pure integer arithmetic). `bcd`'s spinor
|
|
85
|
+
rejection is now the one call site of that predicate, and
|
|
86
|
+
`Series::root_system(r)` is the single bridge to the label-lattice type.
|
|
87
|
+
Conventions pinned in [`docs/references.md`](docs/references.md): the
|
|
88
|
+
`D_r`-odd `Z4` generator `[ω_r]`, and the `D_r`-even half-spin forms named
|
|
89
|
+
by the class they retain. **No coefficient value changes**; no `epoch` moves.
|
|
90
|
+
|
|
91
|
+
- **Frozen gauge specification.** [`docs/gauge.md`](docs/gauge.md) and
|
|
92
|
+
[`docs/gauge_soN.md`](docs/gauge_soN.md) are declared **normative**: the
|
|
93
|
+
documents are the authority and the code implements them. `docs/gauge.md` also
|
|
94
|
+
now specifies the base SU(2) conventions (§12) and marks the rules the
|
|
95
|
+
implementation fixes only implicitly. **No coefficient value changes** from
|
|
96
|
+
this declaration itself; all three `epoch` tags stayed at `1` at this stage
|
|
97
|
+
(the #90 correction below is the release's one epoch move). What changes is the meaning of the authority
|
|
98
|
+
fingerprints: they are now **specification versions**, moving only on a
|
|
99
|
+
specification correction (spec edit + `epoch` bump + CHANGELOG breaking-change
|
|
100
|
+
entry + regenerated goldens, in one PR), never because a refactor moved a
|
|
101
|
+
value. A refactor that moves a value is now a bug by definition.
|
|
102
|
+
([#84](https://github.com/Ryo-wtnb11/racah/issues/84))
|
|
103
|
+
- **`tests/gauge_golden.rs`**: the in-repo gauge tripwire — a small committed
|
|
104
|
+
table of SU(3) CGC (including the OM = 2 adjoint vertex), SU(3) F, and signed
|
|
105
|
+
SO(5)/Sp(4) CGC and F values, asserted at `1e-12` in the default `cgc-gen` test
|
|
106
|
+
run. It covers the drift the external oracles miss by default: SU(3) F symbols
|
|
107
|
+
are otherwise pinned only by an `#[ignore]`d heavy table oracle, and the QSpace
|
|
108
|
+
B/C/D anchor compares an isotypic projector that is blind to the coupled-side
|
|
109
|
+
gauge. It is a drift detector, not an oracle.
|
|
110
|
+
- **`racah-py`**: PyO3/maturin Python bindings for the SU(N) surface, built as
|
|
111
|
+
a workspace member with `cgc-gen` always on. Import name `racah`,
|
|
112
|
+
distribution `racah-py`; abi3-py312 wheels are built by the `wheels`
|
|
113
|
+
workflow. See [`racah-py/README.md`](racah-py/README.md).
|
|
114
|
+
- **Coverage badges** — self-hosted llvm-cov badge branch plus Codecov
|
|
115
|
+
integration ([#93](https://github.com/Ryo-wtnb11/racah/pull/93)).
|
|
116
|
+
- **`CITATION.cff`**, README badges and a Citation section
|
|
117
|
+
([#92](https://github.com/Ryo-wtnb11/racah/pull/92)).
|
|
118
|
+
|
|
119
|
+
### Changed
|
|
120
|
+
|
|
121
|
+
- **BREAKING (error variant renamed): `BcdError::SpinorLabel` is now
|
|
122
|
+
`BcdError::NotAdmissible { group: GroupId, dynkin: Vec<i64> }`**
|
|
123
|
+
([#87](https://github.com/Ryo-wtnb11/racah/issues/87)). The old name was
|
|
124
|
+
mathematically misleading: the variant is returned whenever
|
|
125
|
+
`group.admits(dynkin)` is false, and `PSp(2r)`, `PSO(2r)` and the two
|
|
126
|
+
half-spin forms all reject *non-spinor* weights through it — `C_r` has no
|
|
127
|
+
spinor sector at all. It now carries the rejecting `GroupId` rather than just
|
|
128
|
+
the `Series`. Pre-1.0, no deprecation shim: the variant is renamed outright,
|
|
129
|
+
and the meaning is exactly "a dominant integral highest weight of the cover
|
|
130
|
+
that is not a genuine representation of the selected global form", kept
|
|
131
|
+
distinct from the invalid-label, rank, excluded-rank, generation and
|
|
132
|
+
verification errors.
|
|
133
|
+
- `SunError` gains `NotAdmissible`, `UnsupportedRootSystem` and
|
|
134
|
+
`LabelRankMismatch` for the new `sun::Irrep::from_dynkin_in` guards.
|
|
135
|
+
|
|
136
|
+
- **BREAKING (gauge specification correction, B/D coefficient values move):
|
|
137
|
+
the B/D defining-rep base case is re-framed into the sweep's descending-weight
|
|
138
|
+
order; `bcd_authority_fingerprint()` moves to `epoch=2`**
|
|
139
|
+
([#90](https://github.com/Ryo-wtnb11/racah/issues/90)). The QSpace-ported
|
|
140
|
+
defining seed was stored in QSpace's `Setup_*` state order while every
|
|
141
|
+
rediscovery of the same irrep inside a product was produced in the sweep's
|
|
142
|
+
descending-weight order, and `assemble_cgc` exempted base cases from both the
|
|
143
|
+
coherence guard and the intertwiner alignment — so the two frames were mixed
|
|
144
|
+
silently inside a contraction. Measured on `epoch=1`: the `B_2` vector
|
|
145
|
+
pentagon residual `0.285_239_560_970_874_55`, the `D_3` vector pentagon
|
|
146
|
+
residual `0.129_099_444_873_580_74`, and `B_2 F(1,v,v;adj|v,adj) = 0.0` where
|
|
147
|
+
unitarity forces `1.0`. The seed is now put through one §1–§8 sweep pass over
|
|
148
|
+
its own carrier before it enters the catalog (`docs/gauge_soN.md` §14.2,
|
|
149
|
+
"Base-case frame"), so there is one frame convention in the crate, and the
|
|
150
|
+
base-case exemption is **removed**: the coherence guard and the alignment now
|
|
151
|
+
bind every block, base cases included, which makes this defect class
|
|
152
|
+
impossible to reintroduce silently. Consequences for consumers: persisted
|
|
153
|
+
`SO(2r+1)`/`SO(2r)`/`Spin(N)` coefficients derived under `epoch=1` are stale
|
|
154
|
+
and must be regenerated; `Sp(2r)` (the `C` family) values are **unchanged** —
|
|
155
|
+
`Setup_SpN`'s order was already descending-weight, which is why the C gates
|
|
156
|
+
always closed. `tests/gauge_golden.rs` is regenerated for the moved entries.
|
|
157
|
+
|
|
158
|
+
- **`BcdError::ExcludedRank::redirect` is form-aware** (stage (b) of #87, Q3):
|
|
159
|
+
the low-rank isomorphism is an isomorphism of *groups*, so `Spin(3)` now
|
|
160
|
+
redirects to `"use SU(2) instead"` while `SO(3)` redirects to `"use SU(2)
|
|
161
|
+
with integer j only instead"` (likewise `Spin(4)`/`SO(4)`). Diagnostic strings
|
|
162
|
+
only; no coefficient value changes.
|
|
163
|
+
- **`bcd::Irrep::partition` returns `Option<Vec<i64>>`** and
|
|
164
|
+
`bcd::Irrep::weight_multiplicities` returns `Option<…>`, both `None` on a
|
|
165
|
+
spinor irrep, whose ε-basis weights are half-integers. The always-exact
|
|
166
|
+
doubled forms are `two_partition` / `two_weight_multiplicities`.
|
|
167
|
+
- Docs: replaced the "no label ceiling" absolute with the machine-word label
|
|
168
|
+
bounds that report a typed overflow, and corrected "selectable dense
|
|
169
|
+
backend" to the single Tenferro seam with no public backend-selection API.
|
|
170
|
+
- **`wheels` workflow: full abi3 wheel matrix + PyPI trusted publishing for
|
|
171
|
+
`racah-py`** ([#103](https://github.com/Ryo-wtnb11/racah/pull/103)): linux
|
|
172
|
+
x86_64/aarch64, macOS arm64/x86_64, windows x86_64, plus an sdist. Publishing
|
|
173
|
+
is gated on `py-v*` tags/releases, so the crate's own `v*` releases never
|
|
174
|
+
touch PyPI. `racah-py` itself is unversioned by this release (stays 0.1.0,
|
|
175
|
+
`publish = false` for crates.io) and releases separately.
|
|
176
|
+
|
|
177
|
+
## [0.1.1] - 2026-08-12
|
|
178
|
+
|
|
179
|
+
This release publishes the generated-provider dependency closure against the
|
|
180
|
+
published Tenferro 0.3.0 registry line.
|
|
181
|
+
|
|
182
|
+
### Changed
|
|
183
|
+
|
|
184
|
+
- Use registry `tenferro-* = "0.3.0"` dependencies for `cgc-gen`.
|
|
185
|
+
- Document crates.io installation and the published feature configuration.
|
|
186
|
+
|
|
187
|
+
Generated-provider (`cgc-gen`) observability and convention-identity surface
|
|
188
|
+
(issue [#47](https://github.com/Ryo-wtnb11/racah/issues/47)). This whole surface
|
|
189
|
+
is **unstable: shape may change while the generated-provider contract is
|
|
190
|
+
negotiated** — Cargo features cannot express instability tiers, so the rustdoc
|
|
191
|
+
labels plus issue #47 are the ledger.
|
|
192
|
+
|
|
193
|
+
### Added
|
|
194
|
+
|
|
195
|
+
- **Per-tier coefficient-cache trim**: `trim_to(CoefficientCacheTier, bytes)`
|
|
196
|
+
releases the oldest FIFO prefix of exactly one tier and reports its
|
|
197
|
+
linearization-point charged-entry accounting in `CacheTrimReport`. It is a
|
|
198
|
+
process-global single-owner lifecycle operation; it preserves the one-shot
|
|
199
|
+
cache budget and makes no allocator/RSS release claim.
|
|
200
|
+
|
|
201
|
+
- **One-shot coefficient-cache budgets**: `CoefficientCacheBudgets`,
|
|
202
|
+
`CoefficientCacheTier`, `configure_cache_budgets`, and `cache_budgets` let
|
|
203
|
+
applications shrink independent process-local tier caps before first use.
|
|
204
|
+
Zero retains no entry; reset preserves the selected policy.
|
|
205
|
+
|
|
206
|
+
- **Shared SU(N) product tier** (`cgc-gen`, issue #59): exact
|
|
207
|
+
`directproduct` decompositions are retained once as sorted shared channels
|
|
208
|
+
under an order-normalized irrep pair. The unchanged public API reconstructs
|
|
209
|
+
its `BTreeMap`; Racah-private multiplicity and channel consumers use the
|
|
210
|
+
shared value directly. The tier is bounded at 256 entries and a 128 KiB
|
|
211
|
+
retained-charge backstop, sized from the checked-in collector and a
|
|
212
|
+
downstream SU(3)+SU(4) Generic HomSpace/topology probe.
|
|
213
|
+
- **Generated-tier cache stats** (`cgc-gen`): `generated_cache_stats() ->
|
|
214
|
+
GeneratedCacheStats` (`#[non_exhaustive]`, reusing `TierStats`) reports the
|
|
215
|
+
five generated tiers (SU(N) product / CGC / F, B/C/D CGC / F) per-tier plus a
|
|
216
|
+
field-wise `total()`. `GeneratedCacheStats` `bytes` fields are conservative
|
|
217
|
+
retained charges of cache-owned entries, with container scaffolding,
|
|
218
|
+
allocator/RSS costs, external clones, and returned values excluded.
|
|
219
|
+
`GENERATED_CACHE_MAX_BYTES` (640 MiB + 128 KiB) is the documented aggregate
|
|
220
|
+
retained-charge cap, tied to the per-tier caps by a `const` assertion.
|
|
221
|
+
Two-layer cache story: base = `BASE_CACHE_MAX_BYTES`, generated =
|
|
222
|
+
`GENERATED_CACHE_MAX_BYTES`, whole = the documented sum; no cross-feature
|
|
223
|
+
constant. `reset()` clears the generated tiers alongside the base ones.
|
|
224
|
+
- **Generated authority fingerprints** (`cgc-gen`):
|
|
225
|
+
`sun::sun_authority_fingerprint()` and `bcd::bcd_authority_fingerprint()`
|
|
226
|
+
(`&'static [u8]`). Their contract is weaker than the exact SU(2) fingerprint —
|
|
227
|
+
equal fingerprints identify the same convention, generation pipeline, and
|
|
228
|
+
tolerance policy, but do not imply byte-identical values or independently prove
|
|
229
|
+
numerical agreement (verification gates and oracles own that). Epochs are
|
|
230
|
+
per-family and independent. Backend identity is excluded by design.
|
|
231
|
+
- **Backend structural-identity gate** (`cgc-gen`, D2): a test asserting the
|
|
232
|
+
discrete/structural generation outputs are a function of the convention alone
|
|
233
|
+
(stable across independent in-process runs), the single-backend reduction of
|
|
234
|
+
the cross-backend gate.
|
|
235
|
+
|
|
236
|
+
## [0.1.0] - 2026-07-24
|
|
237
|
+
|
|
238
|
+
First tagged release of the v0 scope: the full representation-theory
|
|
239
|
+
coefficient set for SU(2), SU(N), SO(N), and Sp(2N), computed on demand with no
|
|
240
|
+
label ceiling.
|
|
241
|
+
|
|
242
|
+
### Added
|
|
243
|
+
|
|
244
|
+
- **Exact SU(2)** (default build, no features): 3j, 6j, Clebsch–Gordan, and
|
|
245
|
+
F / R / Frobenius–Schur symbols in closed-form big-rational arithmetic with a
|
|
246
|
+
single final rounding. Dependency-light (`num-bigint` / `num-rational` /
|
|
247
|
+
`num-traits` only).
|
|
248
|
+
- **Generated SU(N)** (`cgc-gen` feature): the Gelfand–Tsetlin pipeline — CGC,
|
|
249
|
+
F, and R with outer-multiplicity indices.
|
|
250
|
+
- **Generated SO(N) / Sp(2N)** (`cgc-gen` feature): the generator-bootstrap
|
|
251
|
+
pipeline over the B/C/D Cartan series — CGC, F, and R.
|
|
252
|
+
- **Base SU(2) provider contract:**
|
|
253
|
+
- `su2_authority_fingerprint()` — opaque bytes identifying the value-fixing
|
|
254
|
+
convention set; compared by equality, changed only on a value-affecting
|
|
255
|
+
breaking release.
|
|
256
|
+
- Checked representation surface — `Su2Irrep` (with `dj` / `dim` / `dual` /
|
|
257
|
+
`fusion`), `Su2Fusion`, `Su2Error` / `AdmissibilityViolation`, and the
|
|
258
|
+
`wigner_3j_checked` / `wigner_6j_checked` / `clebsch_gordan_checked` /
|
|
259
|
+
`su2_f_symbol_checked` / `su2_r_symbol_checked` functions. Additive over the
|
|
260
|
+
infallible zero-convention functions; distinguishes `Ok(0)` (an admissible
|
|
261
|
+
accidental zero) from `Err(NotAdmissible)` (a forbidden coupling).
|
|
262
|
+
- Cache resource contract — `BASE_CACHE_MAX_BYTES` static partition over the
|
|
263
|
+
three base tiers, `base_cache_stats()` / `BaseCacheStats` / `TierStats`
|
|
264
|
+
per-tier statistics (entries, bytes, hits, misses, evictions), and
|
|
265
|
+
single-owner `reset()`.
|
|
266
|
+
- **Self-check / oracle batteries**, shipped as public API and used as
|
|
267
|
+
generation gates: CGC orthogonality, F-unitarity, R-orthogonality, and the
|
|
268
|
+
pentagon / hexagon identities.
|
|
269
|
+
|
|
270
|
+
### Notes
|
|
271
|
+
|
|
272
|
+
- Not published to crates.io: the `cgc-gen` feature depends on the unpublished
|
|
273
|
+
`tenferro-rs`, so a crates.io release is blocked upstream. The git dependency
|
|
274
|
+
is the supported path.
|
|
275
|
+
|
|
276
|
+
### Versioning policy
|
|
277
|
+
|
|
278
|
+
Coefficient *values* are floating point, but the *computation* is exact:
|
|
279
|
+
combinatorial structure, discrete data (duals, signs, Frobenius–Schur phases),
|
|
280
|
+
and gauge fixing are deterministic. Any change that can alter a coefficient
|
|
281
|
+
value, its normalization, or its canonical gauge is a **breaking** change, so
|
|
282
|
+
consumers may key caches and persisted data on the crate version. For the base
|
|
283
|
+
SU(2) provider this rule is mechanized by `su2_authority_fingerprint()`: its
|
|
284
|
+
epoch is bumped only on such a value-affecting release, so a fingerprint change
|
|
285
|
+
and a breaking release are one reviewable event.
|
|
286
|
+
|
|
287
|
+
[Unreleased]: https://github.com/Ryo-wtnb11/racah/compare/v0.2.0...HEAD
|
|
288
|
+
[0.2.0]: https://github.com/Ryo-wtnb11/racah/compare/v0.1.1...v0.2.0
|
|
289
|
+
[0.1.1]: https://github.com/Ryo-wtnb11/racah/releases/tag/v0.1.1
|
|
290
|
+
[0.1.0]: https://github.com/Ryo-wtnb11/racah/releases/tag/v0.1.0
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
type: software
|
|
4
|
+
title: racah
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: Watanabe
|
|
7
|
+
given-names: Ryo
|
|
8
|
+
repository-code: "https://github.com/Ryo-wtnb11/racah"
|
|
9
|
+
license:
|
|
10
|
+
- MIT
|
|
11
|
+
- Apache-2.0
|
|
12
|
+
abstract: >-
|
|
13
|
+
A Rust library for Racah-Wigner calculus: Clebsch-Gordan and recoupling
|
|
14
|
+
(F/R) coefficients for SU(2), SU(N), SO(N), and Sp(2N), computed on demand
|
|
15
|
+
for any admissible labels under a gauge frozen as a normative specification,
|
|
16
|
+
with Python bindings.
|