Contents ======== 1. Purpose 2. License 3. Compilation 3a. Building in a separate directory 4. Command-line evaluation of single symbols 5. Library interfaces 5a. Simple C interface 5b. Simple FORTRAN interface 5c. Python-interface 5d. Native interface 6. Acknowledgements (referencing) 7. Contact 1. Purpose ========== WIGXJPF evaluates Wigner 3j, 6j and 9j symbols accurately using prime factorisation and multi-word integer arithmetic. 2. License ========== WIGXJPF is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WIGXJPF is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with WIGXJPF. If not, see . For details, see the files COPYING.LESSER and COPYING. 3. Compilation ============== All necessary configuration is performed during build. The library is compiled by issuing: make Test evaluation of some small symbols (< 1 s runtime) can be performed by: make test Some large and huge symbols can also be tested, but they require more time and memory (~30 s, 30 MiB and ~25 min, 30.2 GiB, respectively): make test-large make test-huge The C functions can also be directly used from C++, to test: make ccsimple.test The fortran interface is pure C code and compiled with the library above. Testing it requires a fortran compiler, e.g. gfortran: make fsimple.test FC=gfortran The basic functions of the library are as such thread-safe, see below for details. openMP is required to check threaded operation with the simple C interface: make cthreadedsimple.test The python interface requires numpy and cffi, and can be tested: make pysimple.test make pysimple2.test # For explicit python2 make pysimple3.test # For explicit python3 3a. Building in a separate directory ==================================== To compile from another directory (to not change in files in the source directory), VPATH can be used: mkdir wigxjpf-build cd wigxjpf-build make -f ../wigxjpf-VERSION/Makefile VPATH=../wigxjpf-VERSION/ test Notes: It does not work if the code was already compiled in the source directory (use 'make clean'). It does currently not work to compile the python interface with VPATH. 4. Command-line evaluation of single symbols ============================================ Individual symbols can be evaluated directly from the command line by the bin/wigxjpf program. Half-integer arguments are given as .5. Examples: bin/wigxjpf --3j=1.5,1.5,1,1.5,-0.5,-1 bin/wigxjpf --6j=2,2,1,2,1,1 bin/wigxjpf --9j=20,20,40,20,20,40,20,20,40 5. Library interfaces ===================== WIGXJPF can be used as a library within other programs. Several interfaces are provided and described below. They all follow the same scheme: 1) Setup of precalculated table of prime-factorised factorials. The table must be large enough to handle the largest symbol that shall be evaluated. For multi-threaded programs, this is done once (globally). The limit max_two_j is chosen as the largest two_j in any symbol calculated, and wigner_type as the (largest of) 3, 6, or 9 for 3j, 6j, or 9j symbols respectively. Only one table is used even if different symbols are evaluated. Note that giving e.g. max_two_j = 2*100 and wigner_type = 9 only requires < 400 kB of memory, such that there is nowadays little point in keeping this limit very tight. The evaluation routines will only use the necessary parts of each prime-factorisation list, so there is only a slight cache penalty for using larger tables than necessary. 2) Allocation of temporary storage for the evaluation routines. Enough space must be allocated for the largest symbol that shall be evaluated. It also depends on the tables above, which must be allocated first. As above, there is little to gain by giving this limit tightly, giving e.g. max_two_j = 2*100 uses less than 50 kB. For multi-threaded programs, this must be done once per thread. 3) Evaluate symbols. Repeat... 4) Free above temporary and table memory. Interfaces: - Simple C interface. This is recommended. - Simple FORTRAN interface. - Native interface. This gives access to long double and quad double (__float128) results. - Python interface. Independent of interface, error handling is brutal: if a symbol that exceeds the tables or temporary storage is evaluated, the library will print an error message and terminate the program. 5a. Simple C interface ====================== See function prototypes in inc/wigxjpf.h (upper part). 0) #include "wigxjpf.h" 1) void wig_table_init(int max_two_j, int wigner_type); 2) void wig_temp_init(int max_two_j); /* Single-threaded */ void wig_thread_temp_init(int max_two_j); /* Multi-threaded. */ When the program is multi-threaded, this routine must be called by each thread that will evaluate symbols. The pointer to the temporary array is kept as a thread-specific global variable. wig_temp_init() and wig_thread_temp_init() do exactly the same thing. By using wig_thread_temp_init(), it is ensured that the WIGXJPF library was compiled with the temporary storage array as a thread-specific variable. 3) double wig3jj(int two_j1, int two_j2, int two_j3, int two_m1, int two_m2, int two_m3); And similar for 6j and 9j symbols. Note that the arguments are to be given as integers, with twice the numeric value (this is what jj tries to indicate). I.e. half-integer arguments will be passed as odd integers. 4) void wig_temp_free(); /* Per-thread when multi-threaded. */ void wig_table_free(); A small example program can be found in example/csimple.c. To compile and link with WIGXJPF: CFLAGS += -Ipath-to-wigxjpf/inc/ LDFLAGS += -Lpath-to-wigxjpf/lib/ LDLIBS += -lwigxjpf -lm 5b. Simple FORTRAN interface ============================ The FORTRAN interface is analog to the C interface described above. A 'f' is prepended to each function name. All arguments are of type 'integer*4' and return values of type 'real*8'. A small example program can be found in example/fsimple.f. The interface specifications are in a module fwigxjpf, which is placed in the mod/ directory during compilation of the FORTRAN test program (which also selects the FORTRAN compiler to use). Compilation of FORTRAN programs thus need to include also that directory: FCFLAGS += -I path-to-wigxjpf/mod/ 5c. Python-interface ==================== The python interface is analog to the C interface described above. A module 'pywigxjpf' is available in pywigxjpf/pywigxjpf.py The use of the module requires numpy and cffi. To build the wrapper (required once): make pywigxjpf_ffi A small example program can be found in example/pysimple.py. As shown in this example, to use the interface in python, the module must be imported with, e.g., import pywigxjpf as wig after which a number of functions (such as wig.wig3jj) become available. Help text is available via e.g. help(wig) # For interfaces. help(wig.pywigxjpf) # For usage information. To find the module, the path can be set in PYTHONPATH, e.g. with bash: export PYTHONPATH=path-to-wigxjpf/pywigxjpf/ example/pysimple.py Alternatively, the module can be installed (first build WIGXJPF): make python setup.py install You may need to add --user to the second command. Note: When evaluating a fair amount of symbols in python, it may be useful to try the numba jit compiler. See example/py_numba_example.py 5d. Native interface ==================== Use of the native interface follows the same structure as the simple interface. For function prototypes, see inc/wigxjpf.h (lower part). Differences are: - The initialisation routines are given the maximum factorial and number of iterations explicitly, and not as max_two_j. See wigxjpf.h for notes on how to calculate these from max_two_j. - The temporary storage allocation returns a pointer to a structure, which must be sent explicitly to the evaluation routines. If running multi-threaded, the same pointer must not be used by several evaluations simultaneously. - The result of evaluations are returned in locations given as argument pointers, not return values. - The evaluation routines are named by the type they return (double, long double or float128). Since __float128 requires additional system libraries, their headers and functions have been separated out, to use them, additionally # include "wigxjpf_quadmath.h" and additionally link with LDLIBS += -lwigxjpf_quadmath -quadmath - Even though explicit routines to check for trivial zeros of symbols are exposed, there is no need to call them unless only that result is required. They are always consulted by the evaluation routines. 6. Acknowledgements (referencing) ================================= The recommended way to refer to WIGXJPF, when used for computations that are published in a research article, is to cite the following paper H. T. Johansson and C. Forssén, Fast and Accurate Evaluation of Wigner 3j, 6j, and 9j Symbols Using Prime Factorization and Multiword Integer Arithmetic, SIAM J. Sci. Comput., 38(1) (2016), A376-A384. @article{johansson2016, author = {H. T. Johansson and C. Forss\’en}, title = {Fast and Accurate Evaluation of Wigner 3\$j\$, 6\$j\$, and 9\$j\$ Symbols Using Prime Factorization and Multiword Integer Arithmetic}, journal = {SIAM Journal on Scientific Computing}, volume = {38}, number = {1}, pages = {A376-A384}, year = {2016}, doi = {10.1137/15M1021908}, URL = {http://dx.doi.org/10.1137/15M1021908}, eprint = {http://dx.doi.org/10.1137/15M1021908} } Pre-print (2015) at arXiv:1504.08329. 7. Contact ========== Håkan T. Johansson e-mail: f96hajo@chalmers.se Subatomic physics Department of Fundamental physics Chalmers University of Technology 412 96 Göteborg Sweden Christian Forssén e-mail: christian.forssen@chalmers.se Nuclear theory and few-body physics Department of Fundamental physics Chalmers University of Technology 412 96 Göteborg Sweden