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 <http://www.gnu.org/licenses/>.

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-1.13/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
