Examples

Basic interfaces

Most basic interface are wigner3j(), wigner6j(), wigner9j(), clebsch_gordan().

For example, if you want to compute

\[\begin{split}\begin{pmatrix} 0&\frac{1}{2}&\frac{1}{2}\\ 0&\frac{1}{2}&-\frac{1}{2} \end{pmatrix}.\end{split}\]

then pass the doubled value, [0, 1, 1, 0, 1, -1] to wigner3j().

In [1]: py3nj.wigner3j(0, 1, 1,
   ...:                0, 1, -1)
   ...: 
Out[1]: 0.7071067811865476

The arguments should be integer or array of integers.

All the functions of py3nj accept array-like as arguments,

In [2]: py3nj.wigner3j([0, 1], [1, 2], [1, 1],
   ...:                [0, -1], [1, 2], [-1, -1])
   ...: 
Out[2]: array([ 0.70710678, -0.57735027])

where the output has the same size of the input. np.ndarray with more than 1 dimension can be also used.

This vectorization not only reduce the python overhead, but also reusing the result with the same argument. Therefore, if you need to compute these coefficients for many cases, it is recommended to consider how your calculation can be vectorized.

Advanced interfaces

py3nj wraps slatec fortran implementation. The similar interfaces to the original slatec functions, wigner.drc3jj() and drc6j() are also supported.

This function computes all the possible values of \(J_1\) and their corresponding 3j symbol with given \(J_2, J_3, M_2, M_3\) values,

In [3]: two_l1, three_j = py3nj.wigner.drc3jj(1, 1, 1, 1)

In [4]: two_l1
Out[4]: array([0, 1, 2])

In [5]: three_j
Out[5]: array([ 0.        ,  0.        , -0.57735027])

This function can be also vectorized,

In [6]: two_l1, three_j = py3nj.wigner.drc3jj([1, 0], [1, 2], [1, 0], [1, 2])

In [7]: two_l1
Out[7]: array([0, 1, 2])

In [8]: three_j
Out[8]: 
array([[ 0.        ,  0.        , -0.57735027],
       [ 0.        ,  0.        ,  0.57735027]])

Note that even in this advanced interfaces, the vectorized version will be much faster than that sequencial calculation if you need many calcluations.