#coefficients #wigner #compute #calculations #pure #package #clebsch-gordan

wigners

使用纯 Rust 计算 Wigner 3j 和 Clebsch-Gordan 系数

5 个不稳定版本

0.3.0 2023 年 3 月 28 日
0.2.1 2022 年 4 月 5 日
0.2.0 2022 年 4 月 4 日
0.1.1 2022 年 2 月 3 日
0.1.0 2022 年 2 月 3 日

#206科学

每月 28 下载

MIT/Apache

48KB
887

Wigner 符号和相关常数的计算

此包使用纯 Rust 计算 Wigner 3j 系数和 Clebsch-Gordan 系数。计算基于系数中不同阶乘的素因子分解,尽可能长时间地保持值为有理根形式(sign * \sqrt{s / n}),此算法的想法在

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

此实现从 Julia 实现 WignerSymbols 中汲取了大量的灵感(甚至最初是它的直接翻译),非常感谢他们!此包的许可与 Julia 包相同。

用法

从 Python

pip install wigners

然后调用其中一个导出函数

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()

从 Rust

将此 crate 添加到您的 Cargo.toml 依赖项部分

wigners = "0.3"

然后调用其中一个导出函数

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 3j 符号,因为这是我自身工作中唯一需要的部分。

6j 和 9j 符号也可以使用这种方法计算;并且半整数的支持应该是可行的。我对实现这些功能的 pull-request 开放。

基准测试

此基准测试测量计算所有可能的 Wigner 3j 符号所需的时间,直到固定的最大角动量;在开始循环之前清除先前角动量的任何缓存值。在伪代码中,基准测试看起来像这样

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()

以下是在 Apple M1 Max(10 核心)CPU 上的结果

角动量 wigners(本实现) wigner-symbols v0.5 WignerSymbols.jl v2.0 wigxjpf v1.11 sympy v1.11
4 0.190 毫秒 7.50 毫秒 2.58 毫秒 0.228 毫秒 28.7 毫秒
8 4.46 毫秒 227 毫秒 47.0 毫秒 7.36 毫秒 1.36 秒
12 34.0 毫秒 1.94 秒 434 毫秒 66.2 毫秒 23.1 秒
16 156 毫秒 9.34 秒 1.98 秒 333 毫秒 /
20 531 毫秒 / 6.35 秒 1.21秒 /

另一组基准测试检查大j的Wigner符号计算,相应的m从-10变化到10,即伪代码如下

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()
(j1, j2, j3) wigners(本实现) wigner-symbols v0.5 WignerSymbols.jl v2.0 wigxjpf v1.11 sympy v1.11
(300, 100, 250) 38.7毫秒 16.5毫秒 32.9毫秒 7.60毫秒 2.31秒

要在您的机器上运行基准测试,请执行以下命令

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

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

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

wigner-symbols的比较

还有一个Rust实现的Wigner符号:名为wigner-symbols的crate。 wigner-symbols也实现了6j和9j符号,但由于它依赖于rug进行任意精度整数计算,并通过它依赖于GMP库,所以它不适合我的情况。GMP库可能有以下问题

  • 它相对较慢(见上面的基准测试)
  • 它以LGPL许可证分发(这个crate以Apache/MIT许可证分发);
  • 它用C和C++编写,因此难以交叉编译或编译到WASM;
  • 它不支持Windows上的MSVC编译器,只支持GNU编译器

如上图基准测试所示,对于大j,这种GMP的使用成为优势,因为此crate中使用的算法在扩展性方面表现不佳。

许可证

此crate同时以MIT许可证和Apache 2.0许可证分发。

依赖项

~3.5–9MB
~73K SLoC