4#include <gsl/gsl_sf_coupling.h>
43constexpr int l_k(
int ka) {
return (ka > 0) ? ka : -ka - 1; }
45constexpr int twoj_k(
int ka) {
return (ka > 0) ? 2 * ka - 1 : -2 * ka - 1; }
48 return (ka % 2 == 0) ? ((ka > 0) ? 1 : -1) : ((ka < 0) ? 1 : -1);
51constexpr int parity_l(
int l) {
return (l % 2 == 0) ? 1 : -1; }
53constexpr int l_tilde_k(
int ka) {
return (ka > 0) ? ka - 1 : -ka; }
56 return ((2 * l -
twoj) * (
twoj + 1)) / 2;
60 const auto l_minus = (
twoj - 1) / 2;
61 const auto l_minus_pi = (l_minus % 2 == 0) ? 1 : -1;
62 const auto l = l_minus_pi == pi ? l_minus : l_minus + 1;
66inline constexpr bool zeroQ(
double x,
double eps = 1.0e-10) {
67 return x >= 0 ? x < eps : x > -eps;
81 return (ka < 0) ? -2 * ka - 2 : 2 * ka - 1;
85 return (i % 2 == 0) ? -(i + 2) / 2 : (i + 1) / 2;
90constexpr int lFromIndex(
int i) {
return (i % 2 == 0) ? i / 2 : (i + 1) / 2; }
111 const auto n = 1 + int(std::sqrt(index + 0.01));
120 const auto n = 1 + int(std::sqrt(index + 0.01));
129 const auto n = 1 + int(std::sqrt(index + 0.01));
138 const auto n = 1 + int(std::sqrt(index + 0.01));
146constexpr bool evenQ(
int a) {
return (a % 2 == 0); }
148constexpr bool evenQ_2(
int two_a) {
return (two_a % 4 == 0); }
156constexpr int parity(
int la,
int lb,
int k) {
157 return evenQ(la + lb + k) ? 1 : 0;
164 return ((j1 + j2 < J) || (std::abs(j1 - j2) > J)) ? 0 : 1;
168 return (m1 + m2 + m3 != 0) ? 0 : 1;
177inline double threej_2(
int two_j1,
int two_j2,
int two_j3,
int two_m1,
178 int two_m2,
int two_m3) {
182 return gsl_sf_coupling_3j(two_j1, two_j2, two_j3, two_m1, two_m2, two_m3);
191 if (
triangle(two_j1, two_j2, two_k) == 0)
194 auto s =
evenQ_2(two_j1 + 1) ? 1.0 : -1.0;
195 return s / std::sqrt(two_j1 + 1);
197 return gsl_sf_coupling_3j(two_j1, two_j2, two_k, -1, 1, 0);
202inline double cg_2(
int two_j1,
int two_m1,
int two_j2,
int two_m2,
int two_J,
213 if ((two_j1 - two_j2 + two_M) % 4 == 0)
215 return sign * std::sqrt(two_J + 1.) *
216 gsl_sf_coupling_3j(two_j1, two_j2, two_J, two_m1, two_m2, -two_M);
221inline bool sixj_zeroQ(
int a,
int b,
int c,
int d,
int e,
int f) {
234 if (!
evenQ(a + b + c))
236 if (!
evenQ(c + d + e))
238 if (!
evenQ(b + d + f))
240 if (!
evenQ(e + f + a))
248inline bool sixjTriads(std::optional<int> a, std::optional<int> b,
249 std::optional<int> c, std::optional<int> d,
250 std::optional<int> e, std::optional<int> f) {
253 if (a && b && c &&
triangle(*a, *b, *c) == 0)
255 if (c && d && e &&
triangle(*c, *d, *e) == 0)
257 if (a && e && f &&
triangle(*a, *e, *f) == 0)
259 if (b && d && f &&
triangle(*b, *d, *f) == 0)
267inline double sixj_2(
int two_j1,
int two_j2,
int two_j3,
int two_j4,
int two_j5,
275 if (
sixj_zeroQ(two_j1, two_j2, two_j3, two_j4, two_j5, two_j6))
277 return gsl_sf_coupling_6j(two_j1, two_j2, two_j3, two_j4, two_j5, two_j6);
282inline double ninej_2(
int two_j1,
int two_j2,
int two_j3,
int two_j4,
283 int two_j5,
int two_j6,
int two_j7,
int two_j8,
292 return gsl_sf_coupling_9j(two_j1, two_j2, two_j3, two_j4, two_j5, two_j6,
293 two_j7, two_j8, two_j9);
298inline double Ck_kk(
int k,
int ka,
int kb)
309 auto sign =
evenQ_2(two_ja + 1) ? 1 : -1;
310 auto f = std::sqrt((two_ja + 1) * (two_jb + 1));
316inline double Ck_kk_mmq(
int k,
int ka,
int kb,
int twoma,
int twomb,
int twoq) {
317 const auto tja =
twoj_k(ka);
318 const auto tjb =
twoj_k(kb);
320 threej_2(tja, 2 * k, tjb, -twoma, twoq, twomb) *
Ck_kk(k, ka, kb);
336 return m1tjph *
Ck_kk(k, ka, kb);
345 const auto aka = std::abs(ka);
346 const auto akb = std::abs(kb);
348 auto kmin = std::abs(aka - akb);
349 auto kmax = aka + akb - 1;
371inline double S_kk(
int ka,
int kb) {
379 auto sign = (((tja + 2 * la + 3) / 2) % 2 == 0) ? 1 : -1;
380 auto f = std::sqrt((tja + 1) * (tjb + 1) * 1.5);
382 auto sixj_sign = ((ka + kb) % 2 == 0) ? 1.0 : -1.0;
383 auto sixj = 0.5 * sixj_sign *
384 std::sqrt(std::fabs(((ka - 1) * (ka - 1) - kb * kb) /
385 (3.0 * ka * (1.0 + 2.0 * ka))));
386 return sign * f * sixj;
Angular provides functions and classes for calculating and storing angular factors (3,...
Definition CkTable.cpp:7
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:66
int nkindex_to_kappa(int index)
Returns kappa, given nk_index.
Definition Wigner369j.hpp:118
constexpr int states_below_n(int n)
Returns number of possible states below given n.
Definition Wigner369j.hpp:94
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:341
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:316
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:177
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:202
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:267
constexpr int nk_to_index(int n, int k)
return nk_index given {n, kappa}: nk_index(n,k) := n^2 - 2n + 1 + kappa_index
Definition Wigner369j.hpp:104
constexpr int lFromIndex(int i)
returns l, given kappa_index
Definition Wigner369j.hpp:90
constexpr int neg1pow(int a)
Evaluates (-1)^{a} (for integer a)
Definition Wigner369j.hpp:150
int nkindex_to_l(int index)
Returns l, given nk_index.
Definition Wigner369j.hpp:136
constexpr int kappa_twojl(int twoj, int l)
returns kappa, given 2j and l
Definition Wigner369j.hpp:55
double tildeCk_kk(int k, int ka, int kb)
tildeCk_kk = (-1)^{ja+1/2}*Ck_kk
Definition Wigner369j.hpp:333
double S_kk(int ka, int kb)
Reduced spin angular ME: (for spin 1/2): <ka||S||kb>
Definition Wigner369j.hpp:371
constexpr int sumsToZero(int m1, int m2, int m3)
Checks if three ints sum to zero, returns 1 if they do.
Definition Wigner369j.hpp:167
int nkindex_to_twoj(int index)
Returns 2*j, given nk_index.
Definition Wigner369j.hpp:127
constexpr int l_k(int ka)
returns l given kappa
Definition Wigner369j.hpp:43
std::pair< int, int > index_to_nk(int index)
return {n, kappa} given nk_index:
Definition Wigner369j.hpp:109
constexpr int parity_l(int l)
returns parity [(-1)^l] given l
Definition Wigner369j.hpp:51
constexpr int twojFromIndex(int i)
returns 2j, given kappa_index
Definition Wigner369j.hpp:88
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:148
constexpr int kappa_twojpi(const int twoj, const int pi)
returns kappa, given 2*j and parity (+/-1),
Definition Wigner369j.hpp:59
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:190
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:324
constexpr int l_tilde_k(int ka)
"Complimentary" l := (2j-l) = l+/-1, for j=l+/-1/2
Definition Wigner369j.hpp:53
constexpr int neg1pow_2(int two_a)
Evaluates (-1)^{two_a/2} (for integer a; two_a is even)
Definition Wigner369j.hpp:152
constexpr int parity(int la, int lb, int k)
Parity rule. Returns 1 only if la+lb+k is even.
Definition Wigner369j.hpp:156
constexpr int parity_k(int ka)
returns parity [(-1)^l] given kappa
Definition Wigner369j.hpp:47
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:221
constexpr int twoj(int jindex)
Converts jindex to 2*j [helper function].
Definition CkTable.hpp:12
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:162
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:282
constexpr int indexFromKappa(int ka)
returns kappa_index, given kappa
Definition Wigner369j.hpp:80
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:248
constexpr int kappaFromIndex(int i)
Returns kappa, given kappa_index.
Definition Wigner369j.hpp:84
constexpr int twoj_k(int ka)
returns 2j given kappa
Definition Wigner369j.hpp:45
constexpr bool evenQ(int a)
Returns true if a is even - for integer values.
Definition Wigner369j.hpp:146
double Ck_kk(int k, int ka, int kb)
Reduced (relativistic) angular ME: <ka||C^k||kb> [takes k and kappa].
Definition Wigner369j.hpp:298