5#include <gsl/gsl_sf_coupling.h>
44constexpr int l_k(
int ka) {
return (ka > 0) ? ka : -ka - 1; }
46constexpr int twoj_k(
int ka) {
return (ka > 0) ? 2 * ka - 1 : -2 * ka - 1; }
49 return (ka % 2 == 0) ? ((ka > 0) ? 1 : -1) : ((ka < 0) ? 1 : -1);
52constexpr int parity_l(
int l) {
return (l % 2 == 0) ? 1 : -1; }
54constexpr int l_tilde_k(
int ka) {
return (ka > 0) ? ka - 1 : -ka; }
57 return ((2 * l - twoj) * (twoj + 1)) / 2;
61 const auto l_minus = (twoj - 1) / 2;
62 const auto l_minus_pi = (l_minus % 2 == 0) ? 1 : -1;
63 const auto l = l_minus_pi == pi ? l_minus : l_minus + 1;
67inline constexpr bool zeroQ(
double x,
double eps = 1.0e-10) {
68 return x >= 0 ? x < eps : x > -eps;
99 return (ka < 0) ? std::uint64_t(-2 * ka - 2) : std::uint64_t(2 * ka - 1);
105 return (i % 2 == 0) ? int(-(i + 2) / 2) : int((i + 1) / 2);
111 return (i % 2 == 0) ? int(i + 1) : int(i);
117 return (i % 2 == 0) ? int(i / 2) : int((i + 1) / 2);
133 const std::uint64_t nn =
static_cast<std::uint64_t
>(n);
134 return nn * nn - 2 * nn + 1;
180 const auto n = 1 + int(std::sqrt(nk_index));
187inline std::pair<int, std::uint64_t>
189 const auto n = 1 + int(std::sqrt(nk_index));
191 return {n, kappa_index};
197 const auto n = 1 + int(std::sqrt(nk_index));
205 const auto n = 1 + int(std::sqrt(nk_index));
213 const auto n = 1 + int(std::sqrt(
double(nk_index) + 0.01));
220constexpr bool evenQ(
int a) {
return (a % 2 == 0); }
222constexpr bool evenQ_2(
int two_a) {
return (two_a % 4 == 0); }
230constexpr int parity(
int la,
int lb,
int k) {
231 return evenQ(la + lb + k) ? 1 : 0;
238 return ((j1 + j2 < J) || (std::abs(j1 - j2) > J)) ? 0 : 1;
242 return (m1 + m2 + m3 != 0) ? 0 : 1;
251inline double threej_2(
int two_j1,
int two_j2,
int two_j3,
int two_m1,
252 int two_m2,
int two_m3) {
256 return gsl_sf_coupling_3j(two_j1, two_j2, two_j3, two_m1, two_m2, two_m3);
265 if (
triangle(two_j1, two_j2, two_k) == 0)
268 auto s =
evenQ_2(two_j1 + 1) ? 1.0 : -1.0;
269 return s / std::sqrt(two_j1 + 1);
271 return gsl_sf_coupling_3j(two_j1, two_j2, two_k, -1, 1, 0);
276inline double cg_2(
int two_j1,
int two_m1,
int two_j2,
int two_m2,
int two_J,
287 if ((two_j1 - two_j2 + two_M) % 4 == 0)
289 return sign * std::sqrt(two_J + 1.) *
290 gsl_sf_coupling_3j(two_j1, two_j2, two_J, two_m1, two_m2, -two_M);
295inline bool sixj_zeroQ(
int a,
int b,
int c,
int d,
int e,
int f) {
308 if (!
evenQ(a + b + c))
310 if (!
evenQ(c + d + e))
312 if (!
evenQ(b + d + f))
314 if (!
evenQ(e + f + a))
322inline bool sixjTriads(std::optional<int> a, std::optional<int> b,
323 std::optional<int> c, std::optional<int> d,
324 std::optional<int> e, std::optional<int> f) {
327 if (a && b && c &&
triangle(*a, *b, *c) == 0)
329 if (c && d && e &&
triangle(*c, *d, *e) == 0)
331 if (a && e && f &&
triangle(*a, *e, *f) == 0)
333 if (b && d && f &&
triangle(*b, *d, *f) == 0)
341inline double sixj_2(
int two_j1,
int two_j2,
int two_j3,
int two_j4,
int two_j5,
349 if (
sixj_zeroQ(two_j1, two_j2, two_j3, two_j4, two_j5, two_j6))
351 return gsl_sf_coupling_6j(two_j1, two_j2, two_j3, two_j4, two_j5, two_j6);
356inline double ninej_2(
int two_j1,
int two_j2,
int two_j3,
int two_j4,
357 int two_j5,
int two_j6,
int two_j7,
int two_j8,
366 return gsl_sf_coupling_9j(two_j1, two_j2, two_j3, two_j4, two_j5, two_j6,
367 two_j7, two_j8, two_j9);
372inline double Ck_kk(
int k,
int ka,
int kb)
383 auto sign =
evenQ_2(two_ja + 1) ? 1 : -1;
384 auto f = std::sqrt((two_ja + 1) * (two_jb + 1));
390inline double Ck_kk_mmq(
int k,
int ka,
int kb,
int twoma,
int twomb,
int twoq) {
391 const auto tja =
twoj_k(ka);
392 const auto tjb =
twoj_k(kb);
394 threej_2(tja, 2 * k, tjb, -twoma, twoq, twomb) *
Ck_kk(k, ka, kb);
410 return m1tjph *
Ck_kk(k, ka, kb);
419 const auto aka = std::abs(ka);
420 const auto akb = std::abs(kb);
422 auto kmin = std::abs(aka - akb);
423 auto kmax = aka + akb - 1;
445inline double S_kk(
int ka,
int kb) {
453 auto sign = (((tja + 2 * la + 3) / 2) % 2 == 0) ? 1 : -1;
454 auto f = std::sqrt((tja + 1) * (tjb + 1) * 1.5);
456 auto sixj_sign = ((ka + kb) % 2 == 0) ? 1.0 : -1.0;
457 auto sixj = 0.5 * sixj_sign *
458 std::sqrt(std::fabs(((ka - 1) * (ka - 1) - kb * kb) /
459 (3.0 * ka * (1.0 + 2.0 * ka))));
460 return sign * f * sixj;
Angular provides functions and classes for calculating and storing angular factors (3,...
Definition CkTable.cpp:7
constexpr std::uint64_t kappa_to_kindex(int ka)
returns kappa_index, given kappa
Definition Wigner369j.hpp:98
constexpr bool zeroQ(double x, double eps=1.0e-10)
Checks if a double is within eps of 0.0 [eps=1.0e-10 by default].
Definition Wigner369j.hpp:67
constexpr std::uint64_t nk_to_index(int n, int k)
Returns nk_index, given {n, kappa}.
Definition Wigner369j.hpp:172
constexpr int kindex_to_kappa(std::uint64_t i)
Returns kappa, given kappa_index.
Definition Wigner369j.hpp:104
std::pair< int, int > index_to_nk(std::uint64_t nk_index)
Returns {n, kappa} given nk_index.
Definition Wigner369j.hpp:178
std::pair< int, int > kminmax_Ck(int ka, int kb)
Returns [k_min, k_kmax] for C^k (min/max non-zero k, given kappa_a, kappa_b) Accounts for parity.
Definition Wigner369j.hpp:415
double Ck_kk_mmq(int k, int ka, int kb, int twoma, int twomb, int twoq)
Full C^k_q matrix element - rarely used.
Definition Wigner369j.hpp:390
double threej_2(int two_j1, int two_j2, int two_j3, int two_m1, int two_m2, int two_m3)
Calculates wigner 3j symbol. Takes in 2*j (or 2*l) - intput is integer.
Definition Wigner369j.hpp:251
double cg_2(int two_j1, int two_m1, int two_j2, int two_m2, int two_J, int two_M)
Clebsh-Gordon coeficient <j1 m1, j2 m2 | J M> [takes 2*j, as int].
Definition Wigner369j.hpp:276
double sixj_2(int two_j1, int two_j2, int two_j3, int two_j4, int two_j5, int two_j6)
6j symbol {j1 j2 j3 \ j4 j5 j6} - [takes 2*j as int]
Definition Wigner369j.hpp:341
int nkindex_to_kappa(std::uint64_t nk_index)
Returns kappa, given nk_index.
Definition Wigner369j.hpp:196
constexpr int neg1pow(int a)
Evaluates (-1)^{a} (for integer a)
Definition Wigner369j.hpp:224
std::pair< int, std::uint64_t > nkindex_to_n_kindex(std::uint64_t nk_index)
Returns {n, kappa_index} given nk_index.
Definition Wigner369j.hpp:188
constexpr int kappa_twojl(int twoj, int l)
returns kappa, given 2j and l
Definition Wigner369j.hpp:56
int nkindex_to_twoj(std::uint64_t nk_index)
Returns 2*j, given nk_index.
Definition Wigner369j.hpp:204
double tildeCk_kk(int k, int ka, int kb)
tildeCk_kk = (-1)^{ja+1/2}*Ck_kk
Definition Wigner369j.hpp:407
double S_kk(int ka, int kb)
Reduced spin angular ME: (for spin 1/2): <ka||S||kb>
Definition Wigner369j.hpp:445
constexpr int sumsToZero(int m1, int m2, int m3)
Checks if three ints sum to zero, returns 1 if they do.
Definition Wigner369j.hpp:241
constexpr int l_k(int ka)
returns l given kappa
Definition Wigner369j.hpp:44
constexpr std::uint64_t states_below_n(int n)
Returns number of possible states below given n (i.e., n' < n)
Definition Wigner369j.hpp:132
constexpr int parity_l(int l)
returns parity [(-1)^l] given l
Definition Wigner369j.hpp:52
constexpr bool evenQ_2(int two_a)
Returns true if a (an int) is even, given 2*a (true if two_a/2 is even)
Definition Wigner369j.hpp:222
constexpr int kappa_twojpi(const int twoj, const int pi)
returns kappa, given 2*j and parity (+/-1),
Definition Wigner369j.hpp:60
double special_threej_2(int two_j1, int two_j2, int two_k)
Special (common) 3js case: (j1 j2 k, -0.5, 0.5, 0)
Definition Wigner369j.hpp:264
bool Ck_kk_SR(int k, int ka, int kb)
Ck selection rule only. Returns false if C^k=0, true if non-zero.
Definition Wigner369j.hpp:398
constexpr int l_tilde_k(int ka)
"Complimentary" l := (2j-l) = l+/-1, for j=l+/-1/2
Definition Wigner369j.hpp:54
constexpr int kindex_to_twoj(std::uint64_t i)
returns 2j, given kappa_index
Definition Wigner369j.hpp:110
constexpr int kindex_to_l(std::uint64_t i)
returns l, given kappa_index
Definition Wigner369j.hpp:116
constexpr int neg1pow_2(int two_a)
Evaluates (-1)^{two_a/2} (for integer a; two_a is even)
Definition Wigner369j.hpp:226
constexpr int parity(int la, int lb, int k)
Parity rule. Returns 1 only if la+lb+k is even.
Definition Wigner369j.hpp:230
constexpr int parity_k(int ka)
returns parity [(-1)^l] given kappa
Definition Wigner369j.hpp:48
bool sixj_zeroQ(int a, int b, int c, int d, int e, int f)
Checks triangle conditions for 6j symbols (for 2*j)
Definition Wigner369j.hpp:295
constexpr int triangle(int j1, int j2, int J)
Returns 1 if triangle rule is satisfied. nb: works with j OR twoj!
Definition Wigner369j.hpp:236
double ninej_2(int two_j1, int two_j2, int two_j3, int two_j4, int two_j5, int two_j6, int two_j7, int two_j8, int two_j9)
9j symbol {j1 j2 j3 \ j4 j5 j6 \ j7 j8 j9} [takes 2*j as int]
Definition Wigner369j.hpp:356
int nkindex_to_l(std::uint64_t nk_index)
Returns l, given nk_index.
Definition Wigner369j.hpp:212
bool sixjTriads(std::optional< int > a, std::optional< int > b, std::optional< int > c, std::optional< int > d, std::optional< int > e, std::optional< int > f)
Checks if a 6j symbol is valid - each input is optional.
Definition Wigner369j.hpp:322
constexpr int twoj_k(int ka)
returns 2j given kappa
Definition Wigner369j.hpp:46
constexpr bool evenQ(int a)
Returns true if a is even - for integer values.
Definition Wigner369j.hpp:220
double Ck_kk(int k, int ka, int kb)
Reduced (relativistic) angular ME: <ka||C^k||kb> [takes k and kappa].
Definition Wigner369j.hpp:372