Skip to main content

Calculation of Wigner symbols and related constants

This package computes Wigner 3j coefficients, Clebsch-Gordan coefficients, and complex Wigner D-matrices in pure Rust. The 3j/CG calculation is based on the prime factorization of the different factorials involved in the coefficients, keeping the values in a rational root form (sign * \sqrt{s / n}) for as long as possible. The Wigner D-matrix uses the Risbo/Trapani-Navaza recurrence to compute all matrices for j from 0 to j_max simultaneously.

Wigner 3j / Clebsch-Gordan algorithm:

H. T. Johansson and C. Forssén, SIAM Journal on Scientific Compututing 38 (2016) 376-384

Wigner D-matrix algorithm:

This implementation takes a lot of inspiration from the WignerSymbols Julia implementation (and even started as a direct translation of it), many thanks to them! This package is available under the same license as the Julia package.

Usage

From python

pip install wigners

And then call one of the exported function:

import wigners

w3j = wigners.wigner_3j(j1, j2, j3, m1, m2, m3)

cg = wigners.clebsch_gordan(j1, m1, j2, m1, j3, m3)

# full array of Clebsch-Gordan coefficients, computed in parallel
cg_array = wigners.clebsch_gordan_array(ji, j2, j3)

# we have an internal cache for recently computed CG coefficients, if you
# need to clean it up you can use this function
wigners.clear_wigner_3j_cache()

# Wigner D matrices for all j up to max_j, using ZYZ Euler angles
matrices = wigners.wigner_D_array(max_j, alpha, beta, gamma)
# matrices[j] is a (2*j+1) x (2*j+1) complex128 matrix

From rust

Add this crate to your Cargo.toml dependencies section:

wigners = "0.3"

And then call one of the exported function:

let w3j = wigners::wigner_3j(j1, j2, j3, m1, m2, m3);

let cg = wigners::clebsch_gordan(j1, m1, j2, m1, j3, m3);

wigners::clear_wigner_3j_cache();

// Wigner D matrices for all j up to max_j, using ZYZ Euler angles
let mut output = vec![0.0; 2 * total_d_matrix_size(max_j)];
wigners::wigner_d_array(max_j, alpha, beta, gamma, &mut output);

Limitations

Only Wigner 3j symbols for full integers (no half-integers) are implemented, since that's the only part I need for my own work.

6j and 9j symbols can also be computed with this approach; and support for half-integers should be feasible as well. I'm open to pull-request implementing these!

The Wigner D-matrix implementation uses the ZYZ convention and only supports full-integer j (no half-integers). It is limited to j ≤ 100 for numerical stability of the recurrence.

Benchmarks

This benchmark measure the time to compute all possible Wigner 3j symbols up to a fixed maximal angular momentum; clearing up any cached values from previous angular momentum before starting the loop. In pseudo code, the benchmark looks like this:

if cached_wigner_3j:
    clear_wigner_3j_cache()

# only measure the time taken by the loop
start = time.now()
for j1 in range(max_angular):
    for j2 in range(max_angular):
        for j3 in range(max_angular):
            for m1 in range(-j1, j1 + 1):
                for m2 in range(-j2, j2 + 1):
                    for m3 in range(-j3, j3 + 1):
                        w3j = wigner_3j(j1, j2, j3, m1, m2, m3)

elapsed = start - time.now()

Here are the results on an Apple M1 Max (10 cores) CPU, against a handful of other libraries:

code & version max_angular=4 8 12 16 20
wigners (this) 0.190 ms 4.60 ms 36.5 ms 172 ms 572 ms
wigner-symbols v0.5 6.00 ms 181 ms 1.53 s 7.32 s /
WignerSymbols.jl v2.0 1.09 ms 21.1 ms 179 ms 902 ms 3.09 s
wigxjpf v1.11 0.237 ms 7.65 ms 68.3 ms 342 ms 1.24 s
0382/WignerSymbol vf8c8dce 0.070 ms 2.26 ms 19.3 ms 93.5 ms 320 ms
sympy v1.11 24.8 ms 1.15 s 20.8 s / /

A second set of benchmarks checks computing Wigner symbols for large j, with the corresponding m varying from -10 to 10, i.e. in pseudo code:

if cached_wigner_3j:
    clear_wigner_3j_cache()

# only measure the time taken by the loop
start = time.now()
for m1 in range(-10, 10 + 1):
    for m2 in range(-10, 10 + 1):
        for m3 in range(-10, 10 + 1):
            w3j = wigner_3j(j1, j2, j3, m1, m2, m3)

elapsed = start - time.now()
code & version j1=300, j2=100, j3=250
wigners (this) 29.2 ms
wigner-symbols v0.5 13.8 ms
WignerSymbols.jl v2.0 11.5 ms
wigxjpf v1.11 7.45 ms
0382/WignerSymbol vf8c8dce / (wrong result)
sympy v1.11 2.34 s

To run the benchmarks yourself on your own machine, execute the following commands:

cd benchmarks
cargo bench # this gives the results for wigners, wigner-symbols, wigxjpf and 0382/WignerSymbol

python sympy-bench.py # this gives the results for sympy

julia wigner-symbol.jl # this gives the results for WignerSymbols.jl

Comparison to wigner-symbols

There is another Rust implementation of wigner symbols: the wigner-symbols crate. wigner-symbols also implements 6j and 9j symbols, but it was not usable for my case since it relies on rug for arbitrary precision integers and through it on the GMP library. The GMP library might be problematic for you for one of these reason:

  • it is relatively slow (see the benchmarks above)
  • it is distributed under LGPL (this crate is distributed under Apache/MIT);
  • it is written in C and C++; and as such is hard to cross-compile or compile to WASM;
  • it does not support the MSVC compiler on windows, only the GNU compilers

As you can see in the benchmarks above, this usage of GMP becomes an advantage for large j, where the algorithm used in this crate does not scale as well.

License

This crate is distributed under both the MIT license and the Apache 2.0 license.

Metadata

Release files for wigners 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wigners 0.4.1
File Size Uploaded Provenance
wigners-0.4.1.tar.gz 32.1 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for wigners 0.4.1
File
wigners-0.4.1-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
wigners-0.4.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
wigners-0.4.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
wigners-0.4.1-py3-none-macosx_11_0_x86_64.whl Python 3 none macOS 11.0+ x86-64 Details
wigners-0.4.1-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details

Total release size: 1.4 MB

Release files / wigners-0.4.1.tar.gz

Download URL wigners-0.4.1.tar.gz
Size 32.1 kB
Tags Source
SHA-256 checksum
How to use checksums
df356a0bbfb2bbcd44f4d0d03e2e901bf1cd23f9a8715ddcf5ec06da87bec18b
BLAKE2b-256 checksum
How to use checksums
1fd34093911979c492663d465a1758653d3c7cbd181942f7b1b1011ac1d1b627
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / wigners-0.4.1-py3-none-win_amd64.whl

Download URL wigners-0.4.1-py3-none-win_amd64.whl
Size 172.2 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
a87c04045e11d77352c2b91397aade2a7ec72585b579beba35bdb9077ef1002a
BLAKE2b-256 checksum
How to use checksums
7f5114f98e3b80bd109c68b68d02d6fb5d18f9b350fba8990fae7dd23269b42a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / wigners-0.4.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL wigners-0.4.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 319.0 kB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
f31433df45744681c990ac57b40c4ea4d3eaf1b0a2228b39a172fdf9b6895be8
BLAKE2b-256 checksum
How to use checksums
e60677f0eba1e17dbbe9b37efcd0d5ec1a66c2dd605f4771ca132d147e721603
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / wigners-0.4.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl

Download URL wigners-0.4.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Size 309.1 kB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
09f253e0f771d81015427f50e83081f04945390852a31c795afd0e794869596f
BLAKE2b-256 checksum
How to use checksums
70950bf099550b56115c66dc55fcf19f03e22af2a1ed2cd298a7601dcc044648
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / wigners-0.4.1-py3-none-macosx_11_0_x86_64.whl

Download URL wigners-0.4.1-py3-none-macosx_11_0_x86_64.whl
Size 276.8 kB
Tags Python 3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
38d5a6a4029ce26f9198330924cc03eda1a54e363c127894a8dcab58c61042de
BLAKE2b-256 checksum
How to use checksums
5717da685253bda51e4f0e15dabe9df511c7c771ee1ebf926f0b0cb44743cba8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / wigners-0.4.1-py3-none-macosx_11_0_arm64.whl

Download URL wigners-0.4.1-py3-none-macosx_11_0_arm64.whl
Size 269.1 kB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a83f06b240c6db701f73287c961c766a2eec659a44475e1c84479af254a69b3f
BLAKE2b-256 checksum
How to use checksums
e9b71b820919eb1fc43ab85b3e2b718513bde6cd45b6db2f8233e7eb8c3965d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Security for wigners 0.4.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page