wignernj 0.4.1__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.
- wignernj-0.4.1/LICENSE +28 -0
- wignernj-0.4.1/PKG-INFO +18 -0
- wignernj-0.4.1/README.md +286 -0
- wignernj-0.4.1/pyproject.toml +26 -0
- wignernj-0.4.1/setup.cfg +4 -0
- wignernj-0.4.1/setup.py +50 -0
- wignernj-0.4.1/src/bigint.c +1007 -0
- wignernj-0.4.1/src/clebsch.c +124 -0
- wignernj-0.4.1/src/fano_x.c +157 -0
- wignernj-0.4.1/src/gaunt.c +668 -0
- wignernj-0.4.1/src/pfrac.c +389 -0
- wignernj-0.4.1/src/primes.c +20 -0
- wignernj-0.4.1/src/python/wignernjmodule.c +355 -0
- wignernj-0.4.1/src/racah.c +57 -0
- wignernj-0.4.1/src/scratch.c +205 -0
- wignernj-0.4.1/src/wigner3j.c +355 -0
- wignernj-0.4.1/src/wigner6j.c +316 -0
- wignernj-0.4.1/src/wigner9j.c +481 -0
- wignernj-0.4.1/src/wigner_exact.c +246 -0
- wignernj-0.4.1/src/xalloc.c +61 -0
- wignernj-0.4.1/wignernj/__init__.py +55 -0
- wignernj-0.4.1/wignernj.egg-info/PKG-INFO +18 -0
- wignernj-0.4.1/wignernj.egg-info/SOURCES.txt +24 -0
- wignernj-0.4.1/wignernj.egg-info/dependency_links.txt +1 -0
- wignernj-0.4.1/wignernj.egg-info/requires.txt +7 -0
- wignernj-0.4.1/wignernj.egg-info/top_level.txt +1 -0
wignernj-0.4.1/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Susi Lehtola
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
9
|
+
this list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
16
|
+
may be used to endorse or promote products derived from this software
|
|
17
|
+
without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
wignernj-0.4.1/PKG-INFO
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wignernj
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Exact Wigner 3j/6j/9j symbols and related coefficients via prime factorization
|
|
5
|
+
License-Expression: BSD-3-Clause
|
|
6
|
+
Classifier: Programming Language :: C
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
10
|
+
Requires-Python: >=3.7
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Provides-Extra: test
|
|
13
|
+
Requires-Dist: pytest; extra == "test"
|
|
14
|
+
Requires-Dist: sympy; extra == "test"
|
|
15
|
+
Provides-Extra: numpy
|
|
16
|
+
Requires-Dist: numpy; extra == "numpy"
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
Dynamic: requires-python
|
wignernj-0.4.1/README.md
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# libwignernj
|
|
2
|
+
|
|
3
|
+
Exact evaluation of Wigner 3j, 6j, and 9j symbols, Clebsch-Gordan coefficients,
|
|
4
|
+
Racah W-coefficients, Fano X-coefficients, and Gaunt coefficients in C99.
|
|
5
|
+
|
|
6
|
+
All intermediate arithmetic is exact integer arithmetic using a prime-factorization
|
|
7
|
+
representation; floating-point conversion happens only at the final step. Results
|
|
8
|
+
are accurate to the last bit of the chosen output precision.
|
|
9
|
+
|
|
10
|
+
Algorithm: prime factorization of factorials (Dodds & Wiechers,
|
|
11
|
+
Comput. Phys. Commun. **4**, 268, 1972;
|
|
12
|
+
doi:[10.1016/0010-4655(72)90019-7](https://doi.org/10.1016/0010-4655(72)90019-7);
|
|
13
|
+
refined in subsequent work) combined with the multiword-integer
|
|
14
|
+
Racah sum of Johansson & Forssén, SIAM J. Sci. Comput. **38**(1),
|
|
15
|
+
A376–A384, 2016
|
|
16
|
+
(doi:[10.1137/15M1021908](https://doi.org/10.1137/15M1021908)).
|
|
17
|
+
|
|
18
|
+
Language interfaces: C (primary), C++ (header-only wrapper, links against `libwignernj`), Python (CPython extension),
|
|
19
|
+
Fortran 90 (iso_c_binding).
|
|
20
|
+
|
|
21
|
+
## Argument convention
|
|
22
|
+
|
|
23
|
+
All angular momentum arguments are passed as **twice their value** so that
|
|
24
|
+
half-integers are represented exactly as odd integers:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
j = 3/2 → tj = 3
|
|
28
|
+
m = -1/2 → tm = -1
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This applies to the C, C++, and Fortran interfaces. The Python interface also
|
|
32
|
+
accepts plain floats (e.g. `0.5`) and `fractions.Fraction` objects.
|
|
33
|
+
|
|
34
|
+
## Building
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
cmake -B build && cmake --build build
|
|
38
|
+
ctest --test-dir build
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
CMake options:
|
|
42
|
+
|
|
43
|
+
| Option | Default | Description |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `BUILD_SHARED_LIBS` | `ON` | Shared library |
|
|
46
|
+
| `BUILD_FORTRAN` | `ON` | Fortran interface |
|
|
47
|
+
| `BUILD_TESTS` | `ON` | C/Fortran test suite |
|
|
48
|
+
| `BUILD_CXX_TESTS` | `ON` | C++ header tests |
|
|
49
|
+
| `BUILD_EXAMPLES` | `ON` | Build and run the language-binding example programs as ctest tests |
|
|
50
|
+
| `BUILD_LTO` | `ON` | Link-time optimisation; auto-disabled if the toolchain does not support it (and on MSVC, where it conflicts with `WINDOWS_EXPORT_ALL_SYMBOLS`) |
|
|
51
|
+
| `BUILD_PYTHON` | `OFF` | Python extension (dynamically linked against `libwignernj`) |
|
|
52
|
+
| `BUILD_QUADMATH` | `OFF` | libquadmath / IEEE 754 binary128 (`__float128`) interface |
|
|
53
|
+
| `BUILD_MPFR` | `OFF` | MPFR arbitrary-precision interface |
|
|
54
|
+
| `BUILD_FLINT` | `OFF` | Use FLINT/GMP/MPFR for the bigint backend (instead of the in-tree schoolbook with Karatsuba) — sub-quadratic multiplication at large *j* via Toom-Cook / Schönhage--Strassen |
|
|
55
|
+
| `BUILD_COVERAGE` | `OFF` | Build with `--coverage -O0` for lcov / Codecov (gcc, clang) |
|
|
56
|
+
|
|
57
|
+
A separate preprocessor switch `-DBIGINT_FORCE_PORTABLE` (passed via
|
|
58
|
+
`CMAKE_C_FLAGS`) forces the multiword-integer back-end onto its pure-C99
|
|
59
|
+
fallback path even on compilers that support `__uint128_t`; this is
|
|
60
|
+
exercised in the CI matrix to verify that the native and fallback code
|
|
61
|
+
paths produce bit-identical output.
|
|
62
|
+
|
|
63
|
+
## C API
|
|
64
|
+
|
|
65
|
+
```c
|
|
66
|
+
#include "wignernj.h"
|
|
67
|
+
|
|
68
|
+
/* Wigner 3j: ( j1 j2 j3 ) */
|
|
69
|
+
/* ( m1 m2 m3 ) */
|
|
70
|
+
double wigner3j (int tj1, int tj2, int tj3, int tm1, int tm2, int tm3);
|
|
71
|
+
float wigner3j_f(int tj1, int tj2, int tj3, int tm1, int tm2, int tm3);
|
|
72
|
+
long double wigner3j_l(int tj1, int tj2, int tj3, int tm1, int tm2, int tm3);
|
|
73
|
+
|
|
74
|
+
/* Wigner 6j: { j1 j2 j3 } */
|
|
75
|
+
/* { j4 j5 j6 } */
|
|
76
|
+
double wigner6j (int tj1, int tj2, int tj3, int tj4, int tj5, int tj6);
|
|
77
|
+
float wigner6j_f(int tj1, int tj2, int tj3, int tj4, int tj5, int tj6);
|
|
78
|
+
long double wigner6j_l(int tj1, int tj2, int tj3, int tj4, int tj5, int tj6);
|
|
79
|
+
|
|
80
|
+
/* Wigner 9j (row-major order) */
|
|
81
|
+
double wigner9j (int tj11, int tj12, int tj13,
|
|
82
|
+
int tj21, int tj22, int tj23,
|
|
83
|
+
int tj31, int tj32, int tj33);
|
|
84
|
+
|
|
85
|
+
/* Clebsch-Gordan: <j1 m1; j2 m2 | J M> */
|
|
86
|
+
double clebsch_gordan (int tj1, int tm1, int tj2, int tm2, int tJ, int tM);
|
|
87
|
+
|
|
88
|
+
/* Racah W-coefficient: W(j1 j2 J j3; j12 j23) */
|
|
89
|
+
double racah_w (int tj1, int tj2, int tJ, int tj3, int tj12, int tj23);
|
|
90
|
+
|
|
91
|
+
/* Fano X-coefficient: X(j1 j2 j12; j3 j4 j34; j13 j24 J)
|
|
92
|
+
* = sqrt[(2j12+1)(2j34+1)(2j13+1)(2j24+1)] * {9j} */
|
|
93
|
+
double fano_x (int tj1, int tj2, int tj12,
|
|
94
|
+
int tj3, int tj4, int tj34,
|
|
95
|
+
int tj13, int tj24, int tJ);
|
|
96
|
+
|
|
97
|
+
/* Gaunt coefficient: integral Y_{l1}^{m1} Y_{l2}^{m2} Y_{l3}^{m3} dΩ */
|
|
98
|
+
double gaunt (int tl1, int tm1, int tl2, int tm2, int tl3, int tm3);
|
|
99
|
+
|
|
100
|
+
/* Real-spherical-harmonic Gaunt coefficient (Wikipedia/Condon-Shortley) */
|
|
101
|
+
double gaunt_real(int tl1, int tm1, int tl2, int tm2, int tl3, int tm3);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Each function is available in three precisions: `double` (no suffix), `float`
|
|
105
|
+
(`_f`), and `long double` (`_l`). When the library is built with
|
|
106
|
+
`-DBUILD_QUADMATH=ON`, an additional `_q` variant returning `__float128`
|
|
107
|
+
is exposed in `wignernj_quadmath.h` (see below). Functions return 0 for
|
|
108
|
+
symbols that vanish by selection rules; selection-rule violations are not
|
|
109
|
+
errors.
|
|
110
|
+
|
|
111
|
+
Linking: `pkg-config --libs libwignernj` or `-lwignernj -lm`.
|
|
112
|
+
|
|
113
|
+
## libquadmath API
|
|
114
|
+
|
|
115
|
+
Build with `-DBUILD_QUADMATH=ON` (requires a compiler with `__float128`
|
|
116
|
+
support: GCC, Clang, or Intel ICC/ICX on Linux/macOS; not Apple Clang or
|
|
117
|
+
MSVC). Include `wignernj_quadmath.h` in addition to `wignernj.h`. Each public
|
|
118
|
+
symbol gains a `_q` variant returning `__float128` (IEEE 754 binary128,
|
|
119
|
+
113-bit mantissa):
|
|
120
|
+
|
|
121
|
+
```c
|
|
122
|
+
#include "wignernj.h"
|
|
123
|
+
#include "wignernj_quadmath.h"
|
|
124
|
+
|
|
125
|
+
__float128 v = wigner6j_q(4, 4, 4, 4, 4, 4);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The Fortran module also exposes the corresponding `wigner3j_q`,
|
|
129
|
+
`wigner6j_q`, ..., `gaunt_real_q` `bind(c)` interfaces and the real-valued
|
|
130
|
+
convenience wrappers `w3jq`, `w6jq`, `w9jq`, `wcgq`, `wracahwq`, `wgauntq`,
|
|
131
|
+
`wgaunt_realq` that take `real(real128)` arguments.
|
|
132
|
+
|
|
133
|
+
## MPFR API
|
|
134
|
+
|
|
135
|
+
Build with `-DBUILD_MPFR=ON` (requires libmpfr). Include `wignernj_mpfr.h` in
|
|
136
|
+
addition to `wignernj.h`. Set the output precision on `rop` via `mpfr_init2`
|
|
137
|
+
before calling; the rounding mode is the last argument and may be any of the
|
|
138
|
+
standard MPFR modes (`MPFR_RNDN`, `MPFR_RNDZ`, `MPFR_RNDD`, `MPFR_RNDU`,
|
|
139
|
+
`MPFR_RNDA`).
|
|
140
|
+
|
|
141
|
+
```c
|
|
142
|
+
#include "wignernj.h"
|
|
143
|
+
#include "wignernj_mpfr.h"
|
|
144
|
+
|
|
145
|
+
mpfr_t v;
|
|
146
|
+
mpfr_init2(v, 256); /* 256-bit precision */
|
|
147
|
+
|
|
148
|
+
wigner3j_mpfr(v, 4, 4, 0, 2, -2, 0, MPFR_RNDN);
|
|
149
|
+
wigner6j_mpfr(v, 2, 2, 0, 2, 2, 0, MPFR_RNDN);
|
|
150
|
+
wigner9j_mpfr(v, 2, 2, 2, 2, 2, 2, 2, 2, 2, MPFR_RNDN);
|
|
151
|
+
clebsch_gordan_mpfr(v, 2, 2, 2, -2, 4, 0, MPFR_RNDN);
|
|
152
|
+
racah_w_mpfr(v, 2, 2, 4, 2, 4, 4, MPFR_RNDN);
|
|
153
|
+
gaunt_mpfr(v, 4, 2, 4, -2, 4, 0, MPFR_RNDN);
|
|
154
|
+
gaunt_real_mpfr(v, 4, 2, 4, -2, 0, 0, MPFR_RNDN);
|
|
155
|
+
|
|
156
|
+
mpfr_clear(v);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Link with `-lwignernj -lmpfr -lm`.
|
|
160
|
+
|
|
161
|
+
## C++ API
|
|
162
|
+
|
|
163
|
+
The header-only wrapper `wignernj.hpp` provides a template interface that accepts
|
|
164
|
+
either `2*j` integers or real-valued doubles (half-integers). The wrapper has
|
|
165
|
+
no separate translation unit, but every function forwards to a C symbol in
|
|
166
|
+
`libwignernj`, so you still need to link the C library (`-lwignernj -lm`):
|
|
167
|
+
|
|
168
|
+
```cpp
|
|
169
|
+
#include "wignernj.hpp"
|
|
170
|
+
|
|
171
|
+
// Integer 2*j form
|
|
172
|
+
double v = wignernj::symbol3j<double>(2, 2, 0, 0, 0, 0);
|
|
173
|
+
float f = wignernj::symbol6j<float> (2, 2, 2, 2, 2, 2);
|
|
174
|
+
|
|
175
|
+
// Real-valued form (throws std::invalid_argument if not a half-integer)
|
|
176
|
+
double v = wignernj::symbol3j(1.0, 1.0, 0.0, 0.0, 0.0, 0.0);
|
|
177
|
+
double c = wignernj::cg(0.5, 0.5, 0.5, -0.5, 1.0, 0.0);
|
|
178
|
+
|
|
179
|
+
// Available functions: symbol3j, symbol6j, symbol9j, cg, racahw, gaunt, gauntreal
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Link with `-lwignernj -lm` (and `-lmpfr` if `BUILD_MPFR=ON`).
|
|
183
|
+
|
|
184
|
+
## Python API
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
pip install wignernj # from PyPI (pre-built wheels for
|
|
188
|
+
# Linux x86_64/aarch64, macOS arm64,
|
|
189
|
+
# and Windows x86_64; sdist fallback
|
|
190
|
+
# for any other target)
|
|
191
|
+
pip install -e . # or build from a checkout
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
import wignernj
|
|
196
|
+
|
|
197
|
+
wignernj.wigner3j(1, 1, 0, 0, 0, 0) # integer 2*j form
|
|
198
|
+
wignernj.wigner3j(0.5, 0.5, 1, 0.5, -0.5, 0) # real half-integer form
|
|
199
|
+
wignernj.wigner6j(1, 1, 2, 1, 1, 2)
|
|
200
|
+
wignernj.wigner9j(1, 1, 2, 1, 1, 2, 2, 2, 4)
|
|
201
|
+
wignernj.clebsch_gordan(1, 1, 1, -1, 2, 0)
|
|
202
|
+
wignernj.racah_w(1, 1, 2, 1, 2, 2)
|
|
203
|
+
wignernj.fano_x(1, 1, 2, 1, 1, 2, 2, 2, 4)
|
|
204
|
+
wignernj.gaunt(2, 1, 2, -1, 2, 0, precision='longdouble')
|
|
205
|
+
wignernj.gaunt_real(2, 1, 2, -1, 0, 0)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The optional `precision=` keyword selects `'float'`, `'double'` (default), or
|
|
209
|
+
`'longdouble'`. Arguments may be integers, floats, or `fractions.Fraction`.
|
|
210
|
+
|
|
211
|
+
## Fortran API
|
|
212
|
+
|
|
213
|
+
The `wignernj` module provides real-valued wrappers `w3j`, `w6j`, `w9j`, `wcg`,
|
|
214
|
+
`wracahw`, `wfanox`, `wgaunt`, and `wgaunt_real` that accept double-precision
|
|
215
|
+
real arguments:
|
|
216
|
+
|
|
217
|
+
```fortran
|
|
218
|
+
use wignernj
|
|
219
|
+
real(8) :: v
|
|
220
|
+
v = w3j(1.0d0, 1.0d0, 0.0d0, 0.0d0, 0.0d0, 0.0d0)
|
|
221
|
+
v = w6j(1.0d0, 1.0d0, 2.0d0, 1.0d0, 1.0d0, 2.0d0)
|
|
222
|
+
v = wcg(0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.0d0, 0.0d0)
|
|
223
|
+
v = wfanox(1.0d0, 1.0d0, 2.0d0, 1.0d0, 1.0d0, 2.0d0, 2.0d0, 2.0d0, 4.0d0)
|
|
224
|
+
v = wgaunt(2.0d0, 1.0d0, 2.0d0, -1.0d0, 2.0d0, 0.0d0)
|
|
225
|
+
v = wgaunt_real(2.0d0, 1.0d0, 2.0d0, -1.0d0, 0.0d0, 0.0d0)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Raw `bind(c)` interfaces using `2*j` integers are also available for all
|
|
229
|
+
three precisions (the `long double` variants require gfortran or Cray
|
|
230
|
+
Fortran), plus the `_q` (`real(real128)`) variants when the library is
|
|
231
|
+
built with `BUILD_QUADMATH=ON`.
|
|
232
|
+
|
|
233
|
+
Link with `-lwignernj_f03 -lwignernj -lm`.
|
|
234
|
+
|
|
235
|
+
## Limits
|
|
236
|
+
|
|
237
|
+
The prime list and its inverse-lookup index are hard-coded into the compiled
|
|
238
|
+
library (≈49 kB of read-only data), which is what lets the library work with
|
|
239
|
+
**no caller-side initialization step**. The default sieve limit was chosen
|
|
240
|
+
on a rule of thumb that ~50 kB is a reasonable upper bound for compile-time
|
|
241
|
+
constant tables; the resulting prime table covers factorials up to 20020!,
|
|
242
|
+
which translates to:
|
|
243
|
+
|
|
244
|
+
- 3j / 6j / CG / Racah W / complex Gaunt / real Gaunt: j1+j2+j3 ≤ 20019 (equal-j: **j ≤ 6673**)
|
|
245
|
+
- 9j / Fano X: equal-j **j ≤ 5004** (k-dependent triangle denominators reach (4j+1)!; Fano X delegates to the 9j pipeline)
|
|
246
|
+
|
|
247
|
+
Exceeding these limits prints a diagnostic to stderr and aborts. The ceiling is
|
|
248
|
+
**not architectural**: it is set by the size of the compile-time prime table
|
|
249
|
+
(`PRIME_SIEVE_LIMIT` in the auto-generated `src/prime_table_macros.h`) and can
|
|
250
|
+
be raised by regenerating the table with `tools/gen_prime_table.py` and
|
|
251
|
+
rebuilding, at the cost of a proportionally larger compiled-in table.
|
|
252
|
+
`MAX_FACTORIAL_ARG` in the same header is derived from the sieve limit, so
|
|
253
|
+
contributors do not need to keep the two values in sync by hand.
|
|
254
|
+
|
|
255
|
+
The 9j is also O(j⁴) in computation time; evaluations with j > a few hundred
|
|
256
|
+
can be slow. See [docs/reference.md](docs/reference.md#limitations) for details.
|
|
257
|
+
|
|
258
|
+
## Documentation
|
|
259
|
+
|
|
260
|
+
Full API reference with mathematical definitions, selection rules, and
|
|
261
|
+
per-language examples: [docs/reference.md](docs/reference.md).
|
|
262
|
+
|
|
263
|
+
## Repository layout
|
|
264
|
+
|
|
265
|
+
- `include/`, `src/` — C99 core library and language wrappers
|
|
266
|
+
- `tests/` — C/C++/Fortran unit tests, OOM-injection harness, symmetry
|
|
267
|
+
oracles; Python tests under `tests/python/`
|
|
268
|
+
- `tests/gen_refs.py` — regenerates the sympy-based reference tables
|
|
269
|
+
consumed by `tests/test_3j.c`, `test_6j.c`, etc.
|
|
270
|
+
- `tests/cmake_downstream/` — minimal out-of-tree project demonstrating
|
|
271
|
+
consumption via `find_package(wignernj REQUIRED COMPONENTS Fortran)`
|
|
272
|
+
- `benchmarks/` — library-versioning microbenches and profile drivers
|
|
273
|
+
(`bench_term_cache.c`, `bench_sweep.c`, `bench_mul.c`, `bench_div128.c`,
|
|
274
|
+
`profile_3j_4000.c`, …) used to validate libwignernj changes against
|
|
275
|
+
prior versions; see `benchmarks/README.md`. Comparative benchmarks
|
|
276
|
+
against external libraries (WIGXJPF, GSL) are published with the
|
|
277
|
+
paper as supplementary material rather than living in this repo.
|
|
278
|
+
- `examples/` — single-file demonstrations of every public symbol in
|
|
279
|
+
C, C++, Fortran, and Python; built and run as ctest tests when
|
|
280
|
+
`BUILD_EXAMPLES=ON` (the default).
|
|
281
|
+
- `tools/` — prime-table and source-list generators run at build time
|
|
282
|
+
- `docs/` — extended reference and the descriptor paper
|
|
283
|
+
|
|
284
|
+
## License
|
|
285
|
+
|
|
286
|
+
BSD 3-Clause — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
# Copyright (c) 2026 Susi Lehtola
|
|
3
|
+
[build-system]
|
|
4
|
+
requires = ["setuptools>=77", "wheel"]
|
|
5
|
+
build-backend = "setuptools.build_meta"
|
|
6
|
+
|
|
7
|
+
[project]
|
|
8
|
+
name = "wignernj"
|
|
9
|
+
version = "0.4.1"
|
|
10
|
+
description = "Exact Wigner 3j/6j/9j symbols and related coefficients via prime factorization"
|
|
11
|
+
requires-python = ">=3.7"
|
|
12
|
+
license = "BSD-3-Clause"
|
|
13
|
+
license-files = ["LICENSE"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: C",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
18
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.optional-dependencies]
|
|
22
|
+
test = ["pytest", "sympy"]
|
|
23
|
+
numpy = ["numpy"]
|
|
24
|
+
|
|
25
|
+
[tool.pytest.ini_options]
|
|
26
|
+
testpaths = ["tests/python"]
|
wignernj-0.4.1/setup.cfg
ADDED
wignernj-0.4.1/setup.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
# Copyright (c) 2026 Susi Lehtola
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
from setuptools import setup, Extension
|
|
6
|
+
|
|
7
|
+
sources = [
|
|
8
|
+
"src/python/wignernjmodule.c",
|
|
9
|
+
"src/xalloc.c",
|
|
10
|
+
"src/primes.c",
|
|
11
|
+
"src/bigint.c",
|
|
12
|
+
"src/pfrac.c",
|
|
13
|
+
"src/scratch.c",
|
|
14
|
+
"src/wigner_exact.c",
|
|
15
|
+
"src/wigner3j.c",
|
|
16
|
+
"src/wigner6j.c",
|
|
17
|
+
"src/wigner9j.c",
|
|
18
|
+
"src/clebsch.c",
|
|
19
|
+
"src/racah.c",
|
|
20
|
+
"src/fano_x.c",
|
|
21
|
+
"src/gaunt.c",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
# MSVC has no -std=c99 / -O2 spelling and bundles libm into the
|
|
25
|
+
# default C runtime; the GCC/Clang flags would either be passed
|
|
26
|
+
# silently as cl warnings or, in the libm case, produce a hard
|
|
27
|
+
# linker error (LNK1181: cannot open input file 'm.lib').
|
|
28
|
+
if sys.platform == "win32":
|
|
29
|
+
extra_compile_args = ["/O2"]
|
|
30
|
+
libraries = []
|
|
31
|
+
else:
|
|
32
|
+
extra_compile_args = ["-O2", "-std=c99"]
|
|
33
|
+
libraries = ["m"]
|
|
34
|
+
|
|
35
|
+
ext = Extension(
|
|
36
|
+
name="wignernj._wignernj",
|
|
37
|
+
sources=sources,
|
|
38
|
+
include_dirs=["src", "include"],
|
|
39
|
+
extra_compile_args=extra_compile_args,
|
|
40
|
+
libraries=libraries,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
setup(
|
|
44
|
+
name="wignernj",
|
|
45
|
+
version="0.4.1",
|
|
46
|
+
description="Exact Wigner 3j/6j/9j symbols and related coefficients via prime factorization",
|
|
47
|
+
packages=["wignernj"],
|
|
48
|
+
ext_modules=[ext],
|
|
49
|
+
python_requires=">=3.7",
|
|
50
|
+
)
|