38#define WIGNER3 fw3jja6
53 const int a = (2 * j1).toInt(),
b = (2 * j2).toInt(),
c = (2 * j3).toInt(),
54 d = (2 * m1).toInt(), e = (2 * m2).toInt(), f = (2 * m3).toInt();
56 const int j = std::max({std::abs(
a),
65 wig_thread_temp_init(j);
85 const int a = (2 * j1).toInt(),
b = (2 * j2).toInt(),
c = (2 * j3).toInt(),
86 d = (2 * l1).toInt(), e = (2 * l2).toInt(), f = (2 * l3).toInt();
88 const int j = std::max({std::abs(
a),
95 wig_thread_temp_init(j);
108 std::pair<Rational, Rational>
b) {
109 const bool invalid =
a.first.isUndefined() or
b.first.isUndefined();
114 std::pair<Rational, Rational> out{
max(
a.first,
b.first),
115 min(
a.second,
b.second)};
123 fastwigxj_load(FAST_WIGNER_PATH_3J, 3, NULL);
125 fastwigxj_thread_dyn_init(3, fastest);
127 fastwigxj_dyn_init(3, fastest);
130 wig_table_init(largest, 3);
137 fastwigxj_load(FAST_WIGNER_PATH_3J, 3, NULL);
138 fastwigxj_load(FAST_WIGNER_PATH_6J, 6, NULL);
140 fastwigxj_thread_dyn_init(3, fastest);
141 fastwigxj_thread_dyn_init(6, fastest);
143 fastwigxj_dyn_init(3, fastest);
144 fastwigxj_dyn_init(6, fastest);
147 wig_table_init(largest * 2, 6);
156 extern int wigxjpf_max_prime_decomp;
157 return not(j > wigxjpf_max_prime_decomp);
161 const int test = J.
toInt(6) / 2 + 1;
166 const int test = J.
toInt(4) + 1;
173 for (
Index I = 1; I <= j; I++) cjm *= (1. - .5 /
static_cast<Numeric>(I));
174 for (
Index K = 1; K <= m; K++)
175 cjm *=
static_cast<Numeric>(j + 1 - K) /
static_cast<Numeric>(j + K);
180 if (J1 < 0 or J2 < 0 or J < 0)
return GCM;
182 Index J0 = std::abs(J1 - J2);
183 if (J > JM or J < J0)
return GCM;
184 Index JS = std::max(J1, J2);
185 Index JI = std::min(J1, J2);
187 if (MA > JI)
return GCM;
188 Index UN = 1 - 2 * (JS % 2);
191 GCM =
static_cast<Numeric>(UN) *
192 std::sqrt(CJM(JI, MA) / CJM(JS, MA) * CJM(J0, 0) /
193 static_cast<Numeric>(JS + JS + 1));
196 Index AJ02 = AJ0 * AJ0;
197 Index AJM2 = AJM * AJM;
199 for (
Index I = J0 + 1; I <= J; I++) {
202 Numeric ACG = std::sqrt((AJM2 - AI2) * (AI2 - AJ02));
204 (
static_cast<Numeric>(QM) *
static_cast<Numeric>(I + I - 1) * GCM -
216 if (std::abs(A - C) > F or std::abs(B - D) > F or (A + C) < F or (B + D < F))
241 (
static_cast<Numeric>(F + B + D + 1) *
static_cast<Numeric>(F + B + D) *
242 static_cast<Numeric>(B + D - F) *
static_cast<Numeric>(B + D - (1 + F)));
243 TERM /= (4. *
static_cast<Numeric>(2 * B + 1) *
static_cast<Numeric>(B) *
245 static_cast<Numeric>(2 * D - 1) *
static_cast<Numeric>(2 * D + 1));
250 TERM = (
static_cast<Numeric>(F + B + D + 1) *
251 static_cast<Numeric>(F + B - D + 1) *
252 static_cast<Numeric>(F + D - B) *
static_cast<Numeric>(B + D - F));
253 TERM /= (4. *
static_cast<Numeric>(B) *
static_cast<Numeric>(2 * B + 1) *
255 static_cast<Numeric>(2 * D + 1) *
static_cast<Numeric>(2 * D - 1));
262 (
static_cast<Numeric>(F + D - B) *
static_cast<Numeric>(F + D - B - 1) *
263 static_cast<Numeric>(F + B - D + 2) *
264 static_cast<Numeric>(F + B - D + 1));
265 TERM /= (4. *
static_cast<Numeric>(2 * B + 1) *
static_cast<Numeric>(B + 1) *
266 static_cast<Numeric>(2 * B + 3) *
static_cast<Numeric>(2 * D - 1) *
283 (
static_cast<Numeric>(F + B + D + 1) *
static_cast<Numeric>(D + B - F) *
284 static_cast<Numeric>(F + B - D) *
static_cast<Numeric>(F + D - B + 1));
285 TERM /= (4. *
static_cast<Numeric>(2 * B + 1) *
static_cast<Numeric>(B) *
297 std::sqrt(4. *
static_cast<Numeric>(B) *
static_cast<Numeric>(B + 1) *
305 (
static_cast<Numeric>(F + D + B + 2) *
306 static_cast<Numeric>(F + B - D + 1) *
307 static_cast<Numeric>(B + D - F + 1) *
static_cast<Numeric>(F + D - B));
308 TERM /= (4. *
static_cast<Numeric>(2 * B + 1) *
static_cast<Numeric>(B + 1) *
326 (
static_cast<Numeric>(F + B - D) *
static_cast<Numeric>(F + B - D - 1) *
327 static_cast<Numeric>(F + D - B + 2) *
328 static_cast<Numeric>(F + D - B + 1));
329 TERM /= (4. *
static_cast<Numeric>(2 * B + 1) *
static_cast<Numeric>(B) *
331 static_cast<Numeric>(2 * D + 1) *
static_cast<Numeric>(2 * D + 3));
337 (
static_cast<Numeric>(F + D + B + 2) *
338 static_cast<Numeric>(B + D - F + 1) *
339 static_cast<Numeric>(F + D - B + 1) *
static_cast<Numeric>(F + B - D));
340 TERM /= (4. *
static_cast<Numeric>(B) *
static_cast<Numeric>(2 * B + 1) *
347 TERM = (
static_cast<Numeric>(F + D + B + 3) *
348 static_cast<Numeric>(F + B + D + 2) *
349 static_cast<Numeric>(B + D - F + 2) *
350 static_cast<Numeric>(B + D - F + 1));
351 TERM /= (4. *
static_cast<Numeric>(2 * B + 3) *
static_cast<Numeric>(B + 1) *
352 static_cast<Numeric>(2 * B + 1) *
static_cast<Numeric>(2 * D + 3) *
base max(const Array< base > &x)
Max function.
base min(const Array< base > &x)
Min function.
Header file for helper functions for OpenMP.
Helper macros for debugging.
#define ARTS_USER_ERROR(...)
constexpr Index pow_negative_one(Index x) noexcept
Computes std::pow(-1, x) without std::pow.
NUMERIC Numeric
The type to use for all floating point numbers.
INDEX Index
The type to use for all integer numbers and indices.
#define RATIONAL_UNDEFINED
Implements rational numbers to work with other ARTS types.
constexpr int toInt(int n=1) const noexcept
Converts the value to int by n-scaled division in Index form.
bool is_wigner_ready(int j)
Tells if the function can deal with the input integer.
Numeric dwigner6j(Index A, Index B, Index C, Index D, Index F)
Computes the wigner 6J symbol with floating point precision.
Numeric wigner6j(const Rational j1, const Rational j2, const Rational j3, const Rational l1, const Rational l2, const Rational l3)
Wigner 6J symbol.
bool is_wigner3_ready(const Rational &J)
Tells if the function is ready for Wigner 3J calculations.
Index make_wigner_ready(int largest, int fastest, int size)
Ready Wigner.
Numeric dwigner3j(Index M, Index J1, Index J2, Index J)
Computes the wigner 3J symbol with floating point precision.
bool is_wigner6_ready(const Rational &J)
Tells if the function is ready for Wigner 6J calculations.
Numeric wigner3j(const Rational j1, const Rational j2, const Rational j3, const Rational m1, const Rational m2, const Rational m3)
Wigner 3J symbol.
std::pair< Rational, Rational > wigner_limits(std::pair< Rational, Rational > a, std::pair< Rational, Rational > b)
Wigner symbol interactions.