跳转到主要内容

计算Wigner 3j和Clebsch-Gordan系数

项目描述

计算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

此实现从WignerSymbols Julia实现中汲取了许多灵感(甚至最初是它的直接翻译),非常感谢他们!此软件包的许可协议与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()

以下是苹果M1 Max(10核心)CPU的结果

角动量 维格纳(此处) 维格纳符号 v0.5 WignerSymbols.jl v2.0 wigxjpf v1.11 sympy v1.11
4 0.190 ms 7.50 ms 2.58 ms 0.228 ms 28.7 ms
8 4.46 ms 227 ms 47.0 ms 7.36 ms 1.36 s
12 34.0 ms 1.94 s 434 ms 66.2 ms 23.1 s
16 156 ms 9.34 s 1.98 s 333 ms /
20 531 ms / 6.35 s 1.21 s /

另一组基准测试检查对大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) 维格纳(此处) 维格纳符号 v0.5 WignerSymbols.jl v2.0 wigxjpf v1.11 sympy v1.11
(300, 100, 250) 38.7 ms 16.5 ms 32.9 ms 7.60 ms 2.31 s

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

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中使用的算法在大j时扩展性不好。

许可

此crate采用MIT许可证和Apache 2.0许可证双重分发。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

wigners-0.3.0.tar.gz (23.2 kB 查看哈希值)

上传时间 源代码

构建分布

wigners-0.3.0-py3-none-win_amd64.whl (169.9 kB 查看哈希值)

上传时间 Python 3 Windows x86-64

wigners-0.3.0-py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.12+ x86-64 manylinux: glibc 2.5+ x86-64

wigners-0.3.0-py3-none-macosx_11_0_arm64.whl (284.0 kB 查看哈希值)

上传于 Python 3 macOS 11.0+ ARM64

wigners-0.3.0-py3-none-macosx_10_9_x86_64.whl (287.6 kB 查看哈希值)

上传于 Python 3 macOS 10.9+ x86-64

由以下支持