Skip to main content

GPU-accelerated Wigner 3j/6j/9j symbols via Apple MLX — the world's first GPU implementation

Project description

mlx-wigner

GPU-accelerated Wigner 3j/6j/9j symbols for Apple Silicon via MLX. Fully vectorized -- evaluate millions of symbols in a single call.

Why

Wigner 3j/6j/9j symbols appear everywhere in quantum mechanics, atomic physics, and nuclear structure calculations. Every existing implementation (sympy, wigxjpf, SHTOOLS) is CPU-only and computes symbols one at a time. For modern applications that require millions of coupling coefficients (e.g., spherical tensor networks, many-body perturbation theory, angular power spectra), serial CPU evaluation is the bottleneck.

mlx-wigner solves this by:

  • GPU-vectorized Racah formula — all symbols in a batch are computed simultaneously
  • Log-gamma numerics — stable for angular momenta up to j ~ 100
  • Zero CPU loops — the entire computation graph runs on GPU

Installation

pip install mlx-wigner

Or from source:

git clone https://github.com/akaiHuang/mlx-wigner.git
cd mlx-wigner
pip install -e ".[dev]"

Requires Python >= 3.10 and Apple Silicon (M1/M2/M3/M4).

Quick start

from mlx_wigner import wigner_3j, wigner_6j, wigner_9j, clebsch_gordan

# Single symbol
w = wigner_3j(1, 1, 2, 0, 0, 0)

# Clebsch-Gordan coefficient <j1 m1; j2 m2 | J M>
cg = clebsch_gordan(1, 0, 1, 0, 2, 0)

# Batch: 100,000 symbols at once on GPU
import mlx.core as mx
j1 = mx.ones(100_000)
j2 = mx.ones(100_000)
j3 = 2 * mx.ones(100_000)
m1 = mx.zeros(100_000)
m2 = mx.zeros(100_000)
m3 = mx.zeros(100_000)
result = wigner_3j(j1, j2, j3, m1, m2, m3)  # all on GPU

# 6j and 9j symbols
s6 = wigner_6j(1, 1, 1, 1, 1, 1)
s9 = wigner_9j(1, 1, 0, 1, 1, 0, 0, 0, 0)

API

Function Signature Description
wigner_3j (j1, j2, j3, m1, m2, m3) Wigner 3j symbol
wigner_6j (j1, j2, j3, j4, j5, j6) Wigner 6j symbol (Racah W)
wigner_9j (j1, ..., j9) Wigner 9j symbol
clebsch_gordan (j1, m1, j2, m2, J, M) Clebsch-Gordan coefficient

All functions accept scalars or MLX arrays. Array inputs are batch-computed on GPU.

Benchmark

python benchmark.py

Typical results on M3 Max (vs sympy on CPU):

Batch size mlx-wigner (GPU) sympy (CPU) Speedup
1 ~0.5 ms ~2 ms 4x
1,000 ~1 ms ~2,000 ms 2,000x
100,000 ~10 ms

The GPU advantage grows with batch size due to massive parallelism.

Algorithm

  • Wigner 3j: Racah formula with log-gamma (Lanczos approximation) for numerical stability
  • Wigner 6j: Direct Racah sum formula (not built from 3j products)
  • Wigner 9j: Sum over 6j triple products with internal summation variable
  • Selection rules: Vectorized boolean masks applied before computation

Half-integer angular momenta are fully supported.

Testing

pip install -e ".[dev]"
pytest tests/ -v

Tests validate against exact values from sympy.physics.wigner.

License

MIT License. Copyright (c) 2026 Sheng-Kai Huang.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mlx_wigner-0.1.0.tar.gz (12.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mlx_wigner-0.1.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file mlx_wigner-0.1.0.tar.gz.

File metadata

  • Download URL: mlx_wigner-0.1.0.tar.gz
  • Upload date:
  • Size: 12.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for mlx_wigner-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e83d804bc93955c6d3e0f7bc0eab112f52289ddd6c38a9d3b795a316dc1c557a
MD5 c45f88e7df31683c0bd5c88b0c6c9597
BLAKE2b-256 da5cf36609bd223c5db943e3eac81ef8e60769796a559ceb4ae73fa37b26a93d

See more details on using hashes here.

File details

Details for the file mlx_wigner-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mlx_wigner-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for mlx_wigner-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 51f8b73701d014ffbd2c528042a6b7f8e75800235fb16894496bb95c4ef974e1
MD5 80163c56f52c07c5a705c7462089d30e
BLAKE2b-256 044e174ea09b1bd633a22da0a12eca9815afce26e9379e9f3908ba2a3c16f9aa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page