21 #include <lal/LALConstants.h>
42 (*wave)->n_modes = n_modes;
43 (*wave)->lvals =
XLALCalloc(n_modes,
sizeof(
int));
44 (*wave)->mvals =
XLALCalloc(n_modes,
sizeof(
int));
45 (*wave)->n_times = n_times;
46 gsl_vector **modes_real_part =
XLALMalloc(n_modes *
sizeof(*modes_real_part));
47 gsl_vector **modes_imag_part =
XLALMalloc(n_modes *
sizeof(*modes_imag_part));
48 (*wave)->modes_real_part = modes_real_part;
49 (*wave)->modes_imag_part = modes_imag_part;
53 for (
int i=0;
i<n_modes;
i++) {
54 (*wave)->lvals[
i] = ell;
55 (*wave)->mvals[
i] =
m;
56 (*wave)->modes_real_part[
i] = gsl_vector_calloc(n_times);
57 (*wave)->modes_imag_part[
i] = gsl_vector_calloc(n_times);
95 int n_entries = 4*
LMax+1;
97 (*cp)->n_entries = n_entries;
99 gsl_vector **real_part =
XLALMalloc(n_entries *
sizeof(*real_part));
100 gsl_vector **imag_part =
XLALMalloc(n_entries *
sizeof(*imag_part));
101 (*cp)->real_part = real_part;
102 (*cp)->imag_part = imag_part;
104 for (
int i=0;
i<n_entries;
i++) {
105 (*cp)->real_part[
i] = gsl_vector_calloc(n_times);
106 (*cp)->imag_part[
i] = gsl_vector_calloc(n_times);
137 int n_entries = 2*
LMax+1;
139 (*rp)->n_entries = n_entries;
141 gsl_vector **powers =
XLALMalloc(n_entries *
sizeof(*powers));
142 (*rp)->powers = powers;
144 for (
int i=0;
i<n_entries;
i++) {
145 (*rp)->powers[
i] = gsl_vector_calloc(n_times);
169 if (!matrices) exit(1);
175 for (
int ell=2; ell<=
LMax; ell++) {
176 n_entries += (2*ell+1) * (2*ell+1);
179 (*matrices)->LMax =
LMax;
180 (*matrices)->n_entries = n_entries;
181 (*matrices)->n_times = n_times;
183 gsl_vector **real_part =
XLALMalloc(n_entries *
sizeof(*real_part));
184 gsl_vector **imag_part =
XLALMalloc(n_entries *
sizeof(*imag_part));
185 (*matrices)->real_part = real_part;
186 (*matrices)->imag_part = imag_part;
188 for (
int i=0;
i<n_entries;
i++) {
189 (*matrices)->real_part[
i] = gsl_vector_calloc(n_times);
190 (*matrices)->imag_part[
i] = gsl_vector_calloc(n_times);
198 if (!matrices)
return;
217 int i0 = (ell*(ell*ell*4 - 1))/3 - 10;
218 int res = i0 + (2*ell+1)*(ell+
m) + (ell+mp);
223 if (n <= 0)
return 1.0;
228 if (n <= k)
return 1.0;
252 gsl_vector_set_zero(tmpx);
253 gsl_vector_set_zero(tmpy);
256 gsl_vector_add(tmpx, y1);
257 gsl_vector_mul(tmpx, y2);
258 gsl_vector_add(tmpy, x1);
259 gsl_vector_mul(tmpy, y2);
262 gsl_vector_mul(x1, x2);
263 gsl_vector_mul(y1, x2);
266 gsl_vector_sub(x1, tmpx);
267 gsl_vector_add(y1, tmpy);
291 REAL8 t13, t14, t24, denom1, denom2, denom3;
292 REAL8 A1, A2, A3, A4, B1, B2, B3, B4,
C1,
C2,
C3,
C4;
306 denom1 = t12 * t13 * t14;
307 denom2 = t12 * t23 * t24;
308 denom3 = t13 * t23 * t34;
312 dx_vec[1] = t45 * t45 / 2.0;
313 dx_vec[2] = t45 * t45 * t45 / 3.0;
314 dx_vec[3] = dx_vec[1] * dx_vec[1];
317 A1 = -1.0 * t24 * t34 / denom1;
318 A2 = t14 * t34 / denom2;
319 A3 = -1.0 * t14 * t24 / denom3;
320 A4 = -1 * (A1 + A2 + A3);
323 B1 = -1.0 * (t24 + t34) / denom1;
324 B2 = (t14 + t34) / denom2;
325 B3 = -1.0 * (t14 + t24) / denom3;
326 B4 = -1 * (B1 + B2 + B3);
335 for (
i=0;
i<dim;
i++) {
336 tmp_coef =
k4[
i] * dx_vec[0];
337 tmp_coef += (A1 *
k1[
i] + A2 *
k2[
i] + A3 *
k3[
i] + A4 *
k4[
i]) * dx_vec[1];
338 tmp_coef += (B1 *
k1[
i] + B2 *
k2[
i] + B3 *
k3[
i] + B4 *
k4[
i]) * dx_vec[2];
353 gsl_vector *tmp = gsl_vector_calloc(
x->size);
354 gsl_vector *z_mag_sqr = gsl_vector_calloc(
x->size);
358 gsl_vector_add_constant(cp->
real_part[
i], 1.0);
366 for (power=2; power <= 2*cp->
LMax; power++) {
370 gsl_vector_mul(tmp,
x);
372 gsl_vector_set_zero(tmp);
376 gsl_vector_mul(tmp,
y);
378 gsl_vector_set_zero(tmp);
382 gsl_vector_mul(tmp,
x);
384 gsl_vector_set_zero(tmp);
388 gsl_vector_mul(tmp,
y);
390 gsl_vector_set_zero(tmp);
396 for (power=1; power <= 2*cp->
LMax; power++) {
397 i = 2*cp->
LMax + power;
398 j = 2*cp->
LMax - power;
402 gsl_vector_mul(tmp, tmp);
403 gsl_vector_add(z_mag_sqr, tmp);
404 gsl_vector_set_zero(tmp);
406 gsl_vector_mul(tmp, tmp);
407 gsl_vector_add(z_mag_sqr, tmp);
408 gsl_vector_set_zero(tmp);
412 gsl_vector_div(cp->
real_part[j], z_mag_sqr);
414 gsl_vector_div(cp->
imag_part[j], z_mag_sqr);
416 gsl_vector_set_zero(z_mag_sqr);
419 gsl_vector_free(tmp);
420 gsl_vector_free(z_mag_sqr);
430 gsl_vector *tmp = gsl_vector_calloc(
x->size);
433 gsl_vector_add_constant(rp->
powers[0], 1.0);
436 gsl_vector_add(rp->
powers[1],
x);
439 for (power=2; power <= 2*rp->
LMax; power++) {
441 gsl_vector_add(tmp, rp->
powers[power-1]);
442 gsl_vector_mul(tmp,
x);
443 gsl_vector_add(rp->
powers[power], tmp);
444 gsl_vector_set_zero(tmp);
447 gsl_vector_free(tmp);
465 int i, j, ell,
m, mp;
466 int n_times = h_coorb->
n_times;
469 gsl_vector *cosmphi = gsl_vector_alloc(n_times);
470 gsl_vector *sinmphi = gsl_vector_alloc(n_times);
471 gsl_vector *tmp_vec = gsl_vector_alloc(n_times);
478 for (
m = -1*lmax;
m <= lmax;
m++) {
481 for (ell = 2; ell <= lmax; ell++) {
487 for (j=0; j<n_times; j++) {
488 gsl_vector_set(cosmphi, j, cos(
m * gsl_vector_get(orbphase, j)));
489 gsl_vector_set(sinmphi, j, sin(
m * gsl_vector_get(orbphase, j)));
495 for (ell = lmin; ell<=lmax; ell++) {
496 i = ell*(ell+1) - 4 +
m;
499 gsl_vector_set_zero(tmp_vec);
501 gsl_vector_mul(tmp_vec, cosmphi);
504 gsl_vector_set_zero(tmp_vec);
506 gsl_vector_mul(tmp_vec, sinmphi);
509 gsl_vector_set_zero(tmp_vec);
511 gsl_vector_mul(tmp_vec, cosmphi);
514 gsl_vector_set_zero(tmp_vec);
516 gsl_vector_mul(tmp_vec, sinmphi);
527 for (ell = 2; ell <= lmax; ell++) {
528 for (
m= -1 * ell;
m <= ell;
m++) {
529 i = ell*(ell+1) - 4 +
m;
530 for (mp = -1 * ell; mp <= ell; mp++) {
531 j = ell*(ell+1) - 4 + mp;
534 gsl_vector_set_zero(tmp_vec);
536 gsl_vector_mul(tmp_vec, matrices->
real_part[matrix_index]);
540 gsl_vector_set_zero(tmp_vec);
542 gsl_vector_mul(tmp_vec, matrices->
imag_part[matrix_index]);
546 gsl_vector_set_zero(tmp_vec);
548 gsl_vector_mul(tmp_vec, matrices->
real_part[matrix_index]);
552 gsl_vector_set_zero(tmp_vec);
554 gsl_vector_mul(tmp_vec, matrices->
imag_part[matrix_index]);
561 gsl_vector_free(cosmphi);
562 gsl_vector_free(sinmphi);
563 gsl_vector_free(tmp_vec);
579 int n_times = quat[0]->size;
580 int i, j, ell,
m, mp, rho_min, rho_max, rho;
581 REAL8 tmp_re, tmp_im, tmp_abs_sqr, coef,
c;
582 REAL8 eps_sqr = 1.0e-24;
588 gsl_vector_int *index_types = gsl_vector_int_calloc(n_times);
589 gsl_vector *safe_ra_mag_sqr = gsl_vector_calloc(n_times);
590 gsl_vector *safe_rb_mag_sqr = gsl_vector_calloc(n_times);
591 gsl_vector *safe_ra_real = gsl_vector_calloc(n_times);
592 gsl_vector *safe_ra_imag = gsl_vector_calloc(n_times);
593 gsl_vector *safe_rb_real = gsl_vector_calloc(n_times);
594 gsl_vector *safe_rb_imag = gsl_vector_calloc(n_times);
595 gsl_vector_add(safe_ra_real, quat[0]);
596 gsl_vector_sub(safe_ra_imag, quat[3]);
597 gsl_vector_sub(safe_rb_real, quat[2]);
598 gsl_vector_sub(safe_rb_imag, quat[1]);
599 for (
i=0;
i<n_times;
i++) {
600 tmp_re = gsl_vector_get(quat[2],
i);
601 tmp_im = gsl_vector_get(quat[1],
i);
602 tmp_abs_sqr = tmp_re*tmp_re + tmp_im*tmp_im;
603 if (tmp_abs_sqr < eps_sqr) {
604 gsl_vector_int_set(index_types,
i, 2);
605 gsl_vector_set(safe_rb_mag_sqr,
i, 0.5);
606 gsl_vector_set(safe_rb_real,
i, 0.25);
607 gsl_vector_set(safe_rb_imag,
i, 0.25);
609 gsl_vector_set(safe_rb_mag_sqr,
i, tmp_abs_sqr);
612 tmp_re = gsl_vector_get(quat[0],
i);
613 tmp_im = gsl_vector_get(quat[3],
i);
614 tmp_abs_sqr = tmp_re*tmp_re + tmp_im*tmp_im;
615 if (tmp_abs_sqr < eps_sqr) {
616 gsl_vector_int_set(index_types,
i, 1);
617 gsl_vector_set(safe_ra_mag_sqr,
i, 0.5);
618 gsl_vector_set(safe_ra_real,
i, 0.25);
619 gsl_vector_set(safe_ra_imag,
i, 0.25);
621 gsl_vector_set(safe_ra_mag_sqr,
i, tmp_abs_sqr);
626 gsl_vector *safe_abs_rb_over_ra_sqr = gsl_vector_calloc(n_times);
627 gsl_vector_add(safe_abs_rb_over_ra_sqr, safe_rb_mag_sqr);
628 gsl_vector_div(safe_abs_rb_over_ra_sqr, safe_ra_mag_sqr);
648 for (ell=2; ell <= matrices->
LMax; ell++) {
649 for (
m = -1*ell;
m <= ell;
m++) {
650 for (mp = -1*ell; mp <= ell; mp++) {
653 gsl_vector_set_zero(safe_ra_mag_sqr);
665 safe_rb_real, safe_rb_imag);
666 gsl_vector_scale(matrices->
real_part[
i], coef);
667 gsl_vector_scale(matrices->
imag_part[
i], coef);
672 rho_min = (mp >
m) ? (mp -
m) : 0;
673 rho_max = (mp > -1*
m) ? (ell-
m) : (ell+mp);
674 for (rho=rho_min; rho <= rho_max; rho++) {
680 gsl_vector_set_zero(safe_rb_mag_sqr);
681 gsl_vector_add(safe_rb_mag_sqr, abs_rb_over_ra_sqr_powers->
powers[rho]);
682 gsl_vector_scale(safe_rb_mag_sqr,
c);
683 gsl_vector_add(safe_ra_mag_sqr, safe_rb_mag_sqr);
687 gsl_vector_mul(matrices->
real_part[
i], safe_ra_mag_sqr);
688 gsl_vector_mul(matrices->
imag_part[
i], safe_ra_mag_sqr);
697 for (j=0; j<n_times; j++) {
698 rho = gsl_vector_int_get(index_types, j);
700 for (ell=2; ell <= matrices->
LMax; ell++) {
701 for (
m=-1*ell;
m <= ell;
m++) {
702 for (mp = -1*ell; mp <= ell; mp++) {
706 if (rho==1 && (mp == -
m)) {
708 tmp_re = -1 * gsl_vector_get(quat[2], j);
709 tmp_im = -1 * gsl_vector_get(quat[1], j);
712 for (k=0; k < 2*
m; k++) {
714 zx = zx*tmp_re - zy*tmp_im;
717 if ((ell+
m)%2 == 0) {
721 gsl_vector_set(matrices->
real_part[
i], j, zx);
722 gsl_vector_set(matrices->
imag_part[
i], j, zy);
723 }
else if (rho==2 && (mp ==
m)) {
725 tmp_re = gsl_vector_get(quat[0], j);
726 tmp_im = -1 * gsl_vector_get(quat[3], j);
729 for (k=0; k < 2*
m; k++) {
731 zx = zx*tmp_re - zy*tmp_im;
734 gsl_vector_set(matrices->
real_part[
i], j, zx);
735 gsl_vector_set(matrices->
imag_part[
i], j, zy);
737 gsl_vector_set(matrices->
real_part[
i], j, zx);
738 gsl_vector_set(matrices->
imag_part[
i], j, zy);
746 gsl_vector_int_free(index_types);
747 gsl_vector_free(safe_ra_mag_sqr);
748 gsl_vector_free(safe_rb_mag_sqr);
749 gsl_vector_free(safe_ra_real);
750 gsl_vector_free(safe_ra_imag);
751 gsl_vector_free(safe_rb_real);
752 gsl_vector_free(safe_rb_imag);
753 gsl_vector_free(safe_abs_rb_over_ra_sqr);
768 const REAL8 normSqr =
q[0]*
q[0] +
q[1]*
q[1] +
q[2]*
q[2] +
q[3]*
q[3];
769 qInv[0] =
q[0]/normSqr;
770 for (
int i=1;
i<4;
i++) {
771 qInv[
i] = -
q[
i]/normSqr;
805 REAL8 vec_quat[4] = {0, vec[0], vec[1], vec[2]};
815 REAL8 new_vec_quat[4];
819 new_vec[0] = new_vec_quat[1];
820 new_vec[1] = new_vec_quat[2];
821 new_vec[2] = new_vec_quat[3];
836 REAL8 tmp_new_vec[3];
841 REAL8 *z = vec[2]->data;
843 REAL8 *q0 = quat[0]->data;
848 int n = quat[0]->size;
849 for (
int i=0;
i<n;
i++) {
862 x[
i] = tmp_new_vec[0];
863 y[
i] = tmp_new_vec[1];
864 z[
i] = tmp_new_vec[2];
875 REAL8 *omegaMin_dimless,
876 REAL8 *omegaRef_dimless,
883 *omegaMin_dimless = (Mtot_sec * fMin) *
LAL_PI;
887 *omegaRef_dimless = *omegaMin_dimless;
890 *omegaRef_dimless = (Mtot_sec * fRef) *
LAL_PI;
893 if (*omegaRef_dimless + 1
e-13 < *omegaMin_dimless){
static REAL8 UNUSED q3(REAL8 e0, REAL8 f0, REAL8 inc, REAL8 bet, REAL8 FPlus, REAL8 FCross)
static REAL8 UNUSED C2(REAL8 e0, REAL8 f0)
static REAL8 UNUSED C1(REAL8 Mtotal)
static REAL8 UNUSED C4(REAL8 e0, REAL8 f0)
static REAL8 UNUSED q2(REAL8 e0, REAL8 f0, REAL8 inc, REAL8 bet, REAL8 FPlus, REAL8 FCross)
static REAL8 UNUSED q1(REAL8 e0, REAL8 f0, REAL8 inc, REAL8 bet, REAL8 FPlus, REAL8 FCross)
static REAL8 UNUSED C3(REAL8 e0, REAL8 f0)
static void WignerDMatrices_Compute(WignerDMatrices *matrices, gsl_vector **quat)
Computes all the Wigner D Matrices.
static int WignerDMatrix_Index(int ell, int m, int mp)
Computes the index of the (ell, m, mp) component in a WignerDMatices structure.
static void NRSur_ab4_dy(REAL8 *dy, REAL8 *k1, REAL8 *k2, REAL8 *k3, REAL8 *k4, REAL8 t12, REAL8 t23, REAL8 t34, REAL8 t45, int dim)
static UNUSED int quatInv(REAL8 *qInv, REAL8 *q)
Computes inverse, qInv, of a quaternion q such that q*qInv = 1.
static void ComplexPowers_Init(ComplexPowers **cp, int LMax, int n_times)
Initialize a ComplexPowers structure.
static void MultiModalWaveform_Destroy(MultiModalWaveform *wave)
Destroy a MultiModalWaveform structure; free all associated memory.
static void WignerDMatrices_Destroy(WignerDMatrices *matrices)
Destroy a WignerDMatrices structure; free all associated memory.
static void complex_vector_mult(gsl_vector *x1, gsl_vector *y1, gsl_vector *x2, gsl_vector *y2, gsl_vector *tmpx, gsl_vector *tmpy)
Multiplies z1(t) * z2(t) = (x1(t) + i*y1(t)) * (x2(t) + i*y2(t)), storing the result in x1 and y1.
static void RealPowers_Compute(RealPowers *rp, gsl_vector *x)
Computes all powers of x(t) needed for WignerDMatrices.
static void TransformModesCoorbitalToInertial(MultiModalWaveform *h, MultiModalWaveform *h_coorb, gsl_vector **quat, gsl_vector *orbphase)
Transforms modes from the coorbital frame to the inertial frame.
static void MultiModalWaveform_Init(MultiModalWaveform **wave, int LMax, int n_times)
Initialize a MultiModalWaveforme.
static void WignerDMatrices_Init(WignerDMatrices **matrices, int n_times, int LMax)
Initialize a WignerDMatrices structure.
static UNUSED int multiplyQuats(REAL8 *prod, REAL8 *q1, REAL8 *q2)
Multiplies two quaternions.
static void ComplexPowers_Compute(ComplexPowers *cp, gsl_vector *x, gsl_vector *y)
Computes all powers of z(t) = x(t) + i*y(t) needed for WignerDMatrices.
static UNUSED int get_dimless_omega(REAL8 *omegaMin_dimless, REAL8 *omegaRef_dimless, const REAL8 fMin, const REAL8 fRef, const REAL8 Mtot_sec)
Wrapper to get dimensionless omegaMin/omegaRef from fMin/fRef.
static void ComplexPowers_Destroy(ComplexPowers *cp)
Destroy a ComplexPowers structure; free all associated memory.
static UNUSED int transformTimeDependentVector(gsl_vector **vec, gsl_vector **quat)
Transforms a vector from the coprecessing frame to the inertial frame using the coprecessing frame qu...
static UNUSED int quaternionTransformVector(REAL8 *new_vec, REAL8 *quat, REAL8 *vec)
Given a coprecessing frame quaternion (quat), transforms a 3-vector (vec) from the coprecessing frame...
static void RealPowers_Destroy(RealPowers *rp)
Destroy a RealPowers structure; free all associated memory.
static REAL8 wigner_coef(int ell, int mp, int m)
static REAL8 factorial(int n)
static REAL8 factorial_ratio(int n, int k)
static void RealPowers_Init(RealPowers **rp, int LMax, int n_times)
Initialize a RealPowers structure.
static REAL8 binomial(int n, int k)
void * XLALCalloc(size_t m, size_t n)
void * XLALMalloc(size_t n)
#define XLAL_ERROR_VOID(...)
Helper structure for computing WignerDMatrices, which require z(t)^n for many values of n.
int n_entries
Number of entries in **powers.
gsl_vector ** imag_part
The imag part of z^n.
int LMax
Maximum L; powers computed depend on LMax.
gsl_vector ** real_part
The real part of z^n.
Helper structure for computing WignerDMatrices, which require x(t)^n for many values of n.
gsl_vector ** powers
The data; x^n.
int LMax
Maximum L; powers computed depend on LMax.
int n_entries
Number of entries in **powers.
int LMax
Includes (ell, m) modes with 2 <= ell <= LMax.
gsl_vector ** imag_part
The imaginary part of each entry.
int n_entries
Number of (ell, m, m') entries.
gsl_vector ** real_part
The real part of each entry.