27#include "Wigner3jm.hpp"
33#include "utils/simError.h"
166 void Wigner3jm(RealType l1, RealType l2, RealType l3, RealType m1,
167 RealType& m2min, RealType& m2max, RealType* thrcof,
int ndim,
171#ifdef SINGLE_PRECISION
172 RealType MaxFloat = FLT_MAX;
174 RealType MaxFloat = DBL_MAX;
177 const RealType zero = 0.0, eps = 0.01, one = 1.0, two = 2.0;
179 int nfin, nlim, i, n, index, lstep, nfinp1, nfinp2, nfinp3, nstep2;
180 RealType oldfac, dv, newfac,
181 sumbac = 0.0, thresh, a1s, sumfor, sumuni, sum1, sum2, x, y, m2, m3, x1,
182 x2, x3, y1, y2, y3, cnorm, ratio, a1, c1, c2, c1old = 0.0, sign1, sign2;
192 RealType hugeRealType = sqrt(MaxFloat / 20.0), srhuge = sqrt(hugeRealType),
193 tiny = one / hugeRealType, srtiny = one / srhuge;
198 if (l1 - fabs(m1) + eps < zero ||
199 fmod(l1 + fabs(m1) + eps, one) >= eps + eps) {
202 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"%s: %s",
204 "l1-abs(m1) less than zero or l1+abs(m1) not integer.");
205 painCave.isFatal = 1;
209 }
else if (l1 + l2 - l3 < -eps || l1 - l2 + l3 < -eps ||
210 -(l1) + l2 + l3 < -eps) {
213 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"%s: %s",
215 "l1, l2, l3 do not satisfy triangular condition.");
216 painCave.isFatal = 1;
220 }
else if (fmod(l1 + l2 + l3 + eps, one) >= eps + eps) {
223 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"%s: %s",
224 "ThreeJSymbolM",
"l1+l2+l3 not integer.");
225 painCave.isFatal = 1;
232 m2min = MpMax(-l2, -l3 - m1);
233 m2max = MpMin(l2, l3 - m1);
236 if (fmod(m2max - m2min + eps, one) >= eps + eps) {
239 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"%s: %s",
240 "ThreeJSymbolM",
"m2max-m2min not integer.");
241 painCave.isFatal = 1;
246 if (m2min < m2max - eps)
goto L20;
247 if (m2min < m2max + eps)
goto L10;
252 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"%s: %s",
253 "ThreeJSymbolM",
"m2min greater than m2max.");
254 painCave.isFatal = 1;
262 thrcof[1] = (odd(
int(fabs(l2 - l3 - m1) + eps)) ? -one : one) /
263 sqrt(l1 + l2 + l3 + one);
270 nfin = int(m2max - m2min + one + eps);
271 if (ndim - nfin >= 0)
goto L23;
276 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"%s: %s",
278 "Dimension of result array for 3j coefficients too small.");
279 painCave.isFatal = 1;
300 a1 = (l2 - m2 + one) * (l2 + m2) * (l3 + m3 + one) * (l3 - m3);
303 dv = (l1 + l2 + l3 + one) * (l2 + l3 - l1) -
304 (l2 - m2 + one) * (l3 + m3 + one) - (l2 + m2 - one) * (l3 - m3 - one);
306 if (lstep - 2 > 0) c1old = fabs(c1);
311 if (lstep > 2)
goto L60;
318 sum1 += tiny * c1 * c1;
319 if (lstep == nfin)
goto L220;
323 c2 = -oldfac / newfac;
326 x = c1 * thrcof[lstep - 1] + c2 * thrcof[lstep - 2];
330 if (lstep == nfin)
goto L100;
334 if (fabs(x) < srhuge)
goto L80;
341 for (i = 1; i <= lstep; ++i) {
342 if (fabs(thrcof[i]) < srtiny) thrcof[i] = zero;
345 sum1 /= hugeRealType;
346 sumfor /= hugeRealType;
355 if (c1old - fabs(c1) > 0.0)
goto L30;
362 nstep2 = nfin - lstep + 3;
364 x2 = thrcof[lstep - 1];
365 x3 = thrcof[lstep - 2];
374 thrcof[nfin] = srtiny;
384 a1s = (l2 - m2 + two) * (l2 + m2 - one) * (l3 + m3 + two) * (l3 - m3 - one);
386 dv = (l1 + l2 + l3 + one) * (l2 + l3 - l1) -
387 (l2 - m2 + one) * (l3 + m3 + one) - (l2 + m2 - one) * (l3 - m3 - one);
389 if (lstep > 2)
goto L120;
395 thrcof[nfin - 1] = y;
396 if (lstep == nstep2)
goto L200;
402 c2 = -oldfac / newfac;
406 y = c1 * thrcof[nfinp2 - lstep] + c2 * thrcof[nfinp3 - lstep];
408 if (lstep == nstep2)
goto L200;
410 thrcof[nfinp1 - lstep] = y;
416 if (fabs(y) < srhuge)
goto L110;
424 for (i = 1; i <= lstep; ++i) {
425 index = nfin - i + 1;
426 if (fabs(thrcof[index]) < srtiny) thrcof[index] = zero;
427 thrcof[index] /= srhuge;
429 sum2 /= hugeRealType;
430 sumbac /= hugeRealType;
440 y2 = thrcof[nfinp2 - lstep];
441 y1 = thrcof[nfinp3 - lstep];
446 ratio = (x1 * y1 + x2 * y2 + x3 * y3) / (x1 * x1 + x2 * x2 + x3 * x3);
447 nlim = nfin - nstep2 + 1;
449 if (fabs(ratio) < one)
goto L211;
450 for (n = 1; n <= nlim; ++n)
451 thrcof[n] = ratio * thrcof[n];
452 sumuni = ratio * ratio * sumfor + sumbac;
458 for (n = nlim; n <= nfin; ++n)
459 thrcof[n] = ratio * thrcof[n];
460 sumuni = sumfor + ratio * ratio * sumbac;
469 cnorm = one / sqrt((l1 + l1 + one) * sumuni);
474 sign1 = sign(thrcof[nfin]);
475 sign2 = odd(
int(fabs(l2 - l3 - m1) + eps)) ? -one : one;
476 if (sign1 * sign2 <= 0.0)
485 if (fabs(cnorm) < one)
goto L250;
487 for (n = 1; n <= nfin; ++n)
488 thrcof[n] = cnorm * thrcof[n];
492 thresh = tiny / fabs(cnorm);
493 for (n = 1; n <= nfin; ++n) {
494 if (fabs(thrcof[n]) < thresh) thrcof[n] = zero;
495 thrcof[n] = cnorm * thrcof[n];