21 #include <lal/SphericalHarmonics.h>
22 #include <lal/LALError.h>
23 #include <lal/XLALGSL.h>
25 #include <gsl/gsl_sf_legendre.h>
26 #include <gsl/gsl_sf_gamma.h>
56 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |s| <= l\n", __func__, s, l,
m );
61 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |m| <= l\n", __func__, s, l,
m );
72 fac = sqrt( 5.0 / ( 64.0 *
LAL_PI ) ) * ( 1.0 - cos( theta ))*( 1.0 - cos( theta ));
75 fac = sqrt( 5.0 / ( 16.0 *
LAL_PI ) ) * sin( theta )*( 1.0 - cos( theta ));
79 fac = sqrt( 15.0 / ( 32.0 *
LAL_PI ) ) * sin( theta )*sin( theta );
83 fac = sqrt( 5.0 / ( 16.0 *
LAL_PI ) ) * sin( theta )*( 1.0 + cos( theta ));
87 fac = sqrt( 5.0 / ( 64.0 *
LAL_PI ) ) * ( 1.0 + cos( theta ))*( 1.0 + cos( theta ));
90 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |m| <= l\n", __func__, s, l,
m );
100 fac = sqrt(21.0/(2.0*
LAL_PI))*cos(theta/2.0)*pow(sin(theta/2.0),5.0);
103 fac = sqrt(7.0/(4.0*
LAL_PI))*(2.0 + 3.0*cos(theta))*pow(sin(theta/2.0),4.0);
106 fac = sqrt(35.0/(2.0*
LAL_PI))*(sin(theta) + 4.0*sin(2.0*theta) - 3.0*sin(3.0*theta))/32.0;
109 fac = (sqrt(105.0/(2.0*
LAL_PI))*cos(theta)*pow(sin(theta),2.0))/4.0;
112 fac = -sqrt(35.0/(2.0*
LAL_PI))*(sin(theta) - 4.0*sin(2.0*theta) - 3.0*sin(3.0*theta))/32.0;
116 fac = sqrt(7.0/
LAL_PI)*pow(cos(theta/2.0),4.0)*(-2.0 + 3.0*cos(theta))/2.0;
120 fac = -sqrt(21.0/(2.0*
LAL_PI))*pow(cos(theta/2.0),5.0)*sin(theta/2.0);
124 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |m| <= l\n", __func__, s, l,
m );
134 fac = 3.0*sqrt(7.0/
LAL_PI)*pow(cos(theta/2.0),2.0)*pow(sin(theta/2.0),6.0);
137 fac = 3.0*sqrt(7.0/(2.0*
LAL_PI))*cos(theta/2.0)*(1.0 + 2.0*cos(theta))*pow(sin(theta/2.0),5.0);
141 fac = (3.0*(9.0 + 14.0*cos(theta) + 7.0*cos(2.0*theta))*pow(sin(theta/2.0),4.0))/(4.0*sqrt(
LAL_PI));
144 fac = (3.0*(3.0*sin(theta) + 2.0*sin(2.0*theta) + 7.0*sin(3.0*theta) - 7.0*sin(4.0*theta)))/(32.0*sqrt(2.0*
LAL_PI));
147 fac = (3.0*sqrt(5.0/(2.0*
LAL_PI))*(5.0 + 7.0*cos(2.0*theta))*pow(sin(theta),2.0))/16.0;
150 fac = (3.0*(3.0*sin(theta) - 2.0*sin(2.0*theta) + 7.0*sin(3.0*theta) + 7.0*sin(4.0*theta)))/(32.0*sqrt(2.0*
LAL_PI));
153 fac = (3.0*pow(cos(theta/2.0),4.0)*(9.0 - 14.0*cos(theta) + 7.0*cos(2.0*theta)))/(4.0*sqrt(
LAL_PI));
156 fac = -3.0*sqrt(7.0/(2.0*
LAL_PI))*pow(cos(theta/2.0),5.0)*(-1.0 + 2.0*cos(theta))*sin(theta/2.0);
159 fac = 3.0*sqrt(7.0/
LAL_PI)*pow(cos(theta/2.0),6.0)*pow(sin(theta/2.0),2.0);
162 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |m| <= l\n", __func__, s, l,
m );
172 fac = sqrt(330.0/
LAL_PI)*pow(cos(theta/2.0),3.0)*pow(sin(theta/2.0),7.0);
175 fac = sqrt(33.0/
LAL_PI)*pow(cos(theta/2.0),2.0)*(2.0 + 5.0*cos(theta))*pow(sin(theta/2.0),6.0);
178 fac = (sqrt(33.0/(2.0*
LAL_PI))*cos(theta/2.0)*(17.0 + 24.0*cos(theta) + 15.0*cos(2.0*theta))*pow(sin(theta/2.0),5.0))/4.0;
181 fac = (sqrt(11.0/
LAL_PI)*(32.0 + 57.0*cos(theta) + 36.0*cos(2.0*theta) + 15.0*cos(3.0*theta))*pow(sin(theta/2.0),4.0))/8.0;
184 fac = (sqrt(77.0/
LAL_PI)*(2.0*sin(theta) + 8.0*sin(2.0*theta) + 3.0*sin(3.0*theta) + 12.0*sin(4.0*theta) - 15.0*sin(5.0*theta)))/256.0;
187 fac = (sqrt(1155.0/(2.0*
LAL_PI))*(5.0*cos(theta) + 3.0*cos(3.0*theta))*pow(sin(theta),2.0))/32.0;
190 fac = sqrt(77.0/
LAL_PI)*(-2.0*sin(theta) + 8.0*sin(2.0*theta) - 3.0*sin(3.0*theta) + 12.0*sin(4.0*theta) + 15.0*sin(5.0*theta))/256.0;
193 fac = sqrt(11.0/
LAL_PI)*pow(cos(theta/2.0),4.0)*(-32.0 + 57.0*cos(theta) - 36.0*cos(2.0*theta) + 15.0*cos(3.0*theta))/8.0;
196 fac = -sqrt(33.0/(2.0*
LAL_PI))*pow(cos(theta/2.0),5.0)*(17.0 - 24.0*cos(theta) + 15.0*cos(2.0*theta))*sin(theta/2.0)/4.0;
199 fac = sqrt(33.0/
LAL_PI)*pow(cos(theta/2.0),6.0)*(-2.0 + 5.0*cos(theta))*pow(sin(theta/2.0),2.0);
202 fac = -sqrt(330.0/
LAL_PI)*pow(cos(theta/2.0),7.0)*pow(sin(theta/2.0),3.0);
205 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |m| <= l\n", __func__, s, l,
m );
215 fac = (3.*sqrt(715./
LAL_PI)*pow(cos(theta/2.0),4)*pow(sin(theta/2.0),8))/2.0;
218 fac = (sqrt(2145./
LAL_PI)*pow(cos(theta/2.0),3)*(1. + 3.*cos(theta))*pow(sin(theta/2.0),7))/2.0;
221 fac = (sqrt(195./(2.0*
LAL_PI))*pow(cos(theta/2.0),2)*(35. + 44.*cos(theta)
222 + 33.*cos(2.*theta))*pow(sin(theta/2.0),6))/8.0;
225 fac = (3.*sqrt(13./
LAL_PI)*cos(theta/2.0)*(98. + 185.*cos(theta) + 110.*cos(2*theta)
226 + 55.*cos(3.*theta))*pow(sin(theta/2.0),5))/32.0;
229 fac = (sqrt(13./
LAL_PI)*(1709. + 3096.*cos(theta) + 2340.*cos(2.*theta) + 1320.*cos(3.*theta)
230 + 495.*cos(4.*theta))*pow(sin(theta/2.0),4))/256.0;
233 fac = (sqrt(65./(2.0*
LAL_PI))*cos(theta/2.0)*(161. + 252.*cos(theta) + 252.*cos(2.*theta)
234 + 132.*cos(3.*theta) + 99.*cos(4.*theta))*pow(sin(theta/2.0),3))/64.0;
237 fac = (sqrt(1365./
LAL_PI)*(35. + 60.*cos(2.*theta) + 33.*cos(4.*theta))*pow(sin(theta),2))/512.0;
240 fac = (sqrt(65./(2.0*
LAL_PI))*pow(cos(theta/2.0),3)*(161. - 252.*cos(theta) + 252.*cos(2.*theta)
241 - 132.*cos(3.*theta) + 99.*cos(4.*theta))*sin(theta/2.0))/64.0;
244 fac = (sqrt(13./
LAL_PI)*pow(cos(theta/2.0),4)*(1709. - 3096.*cos(theta) + 2340.*cos(2.*theta)
245 - 1320*cos(3*theta) + 495*cos(4*theta)))/256.0;
248 fac = (-3.*sqrt(13./
LAL_PI)*pow(cos(theta/2.0),5)*(-98. + 185.*cos(theta) - 110.*cos(2*theta)
249 + 55.*cos(3.*theta))*sin(theta/2.0))/32.0;
252 fac = (sqrt(195./(2.0*
LAL_PI))*pow(cos(theta/2.0),6)*(35. - 44.*cos(theta)
253 + 33.*cos(2*theta))*pow(sin(theta/2.0),2))/8.0;
256 fac = -(sqrt(2145./
LAL_PI)*pow(cos(theta/2.0),7)*(-1. + 3.*cos(theta))*pow(sin(theta/2.0),3))/2.0;
259 fac = (3.*sqrt(715./
LAL_PI)*pow(cos(theta/2.0),8)*pow(sin(theta/2.0),4))/2.0;
262 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |m| <= l\n", __func__, s, l,
m );
272 fac = sqrt(15015./(2.0*
LAL_PI))*pow(cos(theta/2.0),5)*pow(sin(theta/2.0),9);
275 fac = (sqrt(2145./
LAL_PI)*pow(cos(theta/2.0),4)*(2. + 7.*cos(theta))*pow(sin(theta/2.0),8))/2.0;
278 fac = (sqrt(165./(2.0*
LAL_PI))*pow(cos(theta/2.0),3)*(93. + 104.*cos(theta)
279 + 91.*cos(2.*theta))*pow(sin(theta/2.0),7))/8.0;
282 fac = (sqrt(165./(2.0*
LAL_PI))*pow(cos(theta/2.0),2)*(140. + 285.*cos(theta)
283 + 156.*cos(2.*theta) + 91.*cos(3.*theta))*pow(sin(theta/2.0),6))/16.0;
286 fac = (sqrt(15./(2.0*
LAL_PI))*cos(theta/2.0)*(3115. + 5456.*cos(theta) + 4268.*cos(2.*theta)
287 + 2288.*cos(3.*theta) + 1001.*cos(4.*theta))*pow(sin(theta/2.0),5))/128.0;
290 fac = (sqrt(15./
LAL_PI)*(5220. + 9810.*cos(theta) + 7920.*cos(2.*theta) + 5445.*cos(3.*theta)
291 + 2860.*cos(4.*theta) + 1001.*cos(5.*theta))*pow(sin(theta/2.0),4))/512.0;
294 fac = (3.*sqrt(5./(2.0*
LAL_PI))*cos(theta/2.0)*(1890. + 4130.*cos(theta) + 3080.*cos(2.*theta)
295 + 2805.*cos(3.*theta) + 1430.*cos(4.*theta) + 1001.*cos(5*theta))*pow(sin(theta/2.0),3))/512.0;
298 fac = (3.*sqrt(35./
LAL_PI)*cos(theta)*(109. + 132.*cos(2.*theta)
299 + 143.*cos(4.*theta))*pow(sin(theta),2))/512.0;
302 fac = (3.*sqrt(5./(2.0*
LAL_PI))*pow(cos(theta/2.0),3)*(-1890. + 4130.*cos(theta) - 3080.*cos(2.*theta)
303 + 2805.*cos(3.*theta) - 1430.*cos(4.*theta) + 1001.*cos(5.*theta))*sin(theta/2.0))/512.0;
306 fac = (sqrt(15./
LAL_PI)*pow(cos(theta/2.0),4)*(-5220. + 9810.*cos(theta) - 7920.*cos(2.*theta)
307 + 5445.*cos(3.*theta) - 2860.*cos(4.*theta) + 1001.*cos(5.*theta)))/512.0;
310 fac = -(sqrt(15./(2.0*
LAL_PI))*pow(cos(theta/2.0),5)*(3115. - 5456.*cos(theta) + 4268.*cos(2.*theta)
311 - 2288.*cos(3.*theta) + 1001.*cos(4.*theta))*sin(theta/2.0))/128.0;
314 fac = (sqrt(165./(2.0*
LAL_PI))*pow(cos(theta/2.0),6)*(-140. + 285.*cos(theta) - 156.*cos(2*theta)
315 + 91.*cos(3.*theta))*pow(sin(theta/2.0),2))/16.0;
318 fac = -(sqrt(165./(2.0*
LAL_PI))*pow(cos(theta/2.0),7)*(93. - 104.*cos(theta)
319 + 91.*cos(2.*theta))*pow(sin(theta/2.0),3))/8.0;
322 fac = (sqrt(2145./
LAL_PI)*pow(cos(theta/2.0),8)*(-2. + 7.*cos(theta))*pow(sin(theta/2.0),4))/2.0;
325 fac = -(sqrt(15015./(2.0*
LAL_PI))*pow(cos(theta/2.0),9)*pow(sin(theta/2.0),5));
328 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |m| <= l\n", __func__, s, l,
m );
338 fac = sqrt(34034./
LAL_PI)*pow(cos(theta/2.0),6)*pow(sin(theta/2.0),10);
341 fac = sqrt(17017./(2.0*
LAL_PI))*pow(cos(theta/2.0),5)*(1. + 4.*cos(theta))*pow(sin(theta/2.0),9);
344 fac = sqrt(255255./
LAL_PI)*pow(cos(theta/2.0),4)*(1. + 2.*cos(theta))
345 *sin(
LAL_PI/4.0 - theta/2.0)*sin(
LAL_PI/4.0 + theta/2.0)*pow(sin(theta/2.0),8);
348 fac = (sqrt(12155./(2.0*
LAL_PI))*pow(cos(theta/2.0),3)*(19. + 42.*cos(theta)
349 + 21.*cos(2.*theta) + 14.*cos(3.*theta))*pow(sin(theta/2.0),7))/8.0;
352 fac = (sqrt(935./(2.0*
LAL_PI))*pow(cos(theta/2.0),2)*(265. + 442.*cos(theta) + 364.*cos(2.*theta)
353 + 182.*cos(3.*theta) + 91.*cos(4.*theta))*pow(sin(theta/2.0),6))/32.0;
356 fac = (sqrt(561./(2.0*
LAL_PI))*cos(theta/2.0)*(869. + 1660.*cos(theta) + 1300.*cos(2.*theta)
357 + 910.*cos(3.*theta) + 455.*cos(4.*theta) + 182.*cos(5.*theta))*pow(sin(theta/2.0),5))/128.0;
360 fac = (sqrt(17./
LAL_PI)*(7626. + 14454.*cos(theta) + 12375.*cos(2.*theta) + 9295.*cos(3.*theta)
361 + 6006.*cos(4.*theta) + 3003.*cos(5.*theta) + 1001.*cos(6.*theta))*pow(sin(theta/2.0),4))/512.0;
364 fac = (sqrt(595./(2.0*
LAL_PI))*cos(theta/2.0)*(798. + 1386.*cos(theta) + 1386.*cos(2.*theta)
365 + 1001.*cos(3.*theta) + 858.*cos(4.*theta) + 429.*cos(5.*theta) + 286.*cos(6.*theta))*pow(sin(theta/2.0),3))/512.0;
368 fac = (3.*sqrt(595./
LAL_PI)*(210. + 385.*cos(2.*theta) + 286.*cos(4.*theta)
369 + 143.*cos(6.*theta))*pow(sin(theta),2))/4096.0;
372 fac = (sqrt(595./(2.0*
LAL_PI))*pow(cos(theta/2.0),3)*(798. - 1386.*cos(theta) + 1386.*cos(2.*theta)
373 - 1001.*cos(3.*theta) + 858.*cos(4.*theta) - 429.*cos(5.*theta) + 286.*cos(6.*theta))*sin(theta/2.0))/512.0;
376 fac = (sqrt(17./
LAL_PI)*pow(cos(theta/2.0),4)*(7626. - 14454.*cos(theta) + 12375.*cos(2.*theta)
377 - 9295.*cos(3.*theta) + 6006.*cos(4.*theta) - 3003.*cos(5.*theta) + 1001.*cos(6.*theta)))/512.0;
380 fac = -(sqrt(561./(2.0*
LAL_PI))*pow(cos(theta/2.0),5)*(-869. + 1660.*cos(theta) - 1300.*cos(2.*theta)
381 + 910.*cos(3.*theta) - 455.*cos(4.*theta) + 182.*cos(5.*theta))*sin(theta/2.0))/128.0;
384 fac = (sqrt(935./(2.0*
LAL_PI))*pow(cos(theta/2.0),6)*(265. - 442.*cos(theta) + 364.*cos(2.*theta)
385 - 182.*cos(3.*theta) + 91.*cos(4.*theta))*pow(sin(theta/2.0),2))/32.0;
388 fac = -(sqrt(12155./(2.0*
LAL_PI))*pow(cos(theta/2.0),7)*(-19. + 42.*cos(theta) - 21.*cos(2.*theta)
389 + 14.*cos(3.*theta))*pow(sin(theta/2.0),3))/8.0;
392 fac = sqrt(255255./
LAL_PI)*pow(cos(theta/2.0),8)*(-1. + 2.*cos(theta))*sin(
LAL_PI/4.0 - theta/2.0)
393 *sin(
LAL_PI/4.0 + theta/2.0)*pow(sin(theta/2.0),4);
396 fac = -(sqrt(17017./(2.0*
LAL_PI))*pow(cos(theta/2.0),9)*(-1. + 4.*cos(theta))*pow(sin(theta/2.0),5));
399 fac = sqrt(34034./
LAL_PI)*pow(cos(theta/2.0),10)*pow(sin(theta/2.0),6);
402 XLALPrintError(
"XLAL Error - %s: Invalid mode s=%d, l=%d, m=%d - require |m| <= l\n", __func__, s, l,
m );
409 XLALPrintError(
"XLAL Error - %s: Unsupported mode l=%d (only l in [2,8] implemented)\n", __func__, l);
415 XLALPrintError(
"XLAL Error - %s: Unsupported mode s=%d (only s=-2 implemented)\n", __func__, s);
419 ans =
cpolar(1.0,
m*phi) * fac;
442 INT4 absM = abs(
m );
444 if ( absM > (
INT4) l )
451 XLAL_CALLGSL( gslStatus = gsl_sf_legendre_sphPlm_e((
INT4)l, absM, cos(theta), &pLm ) );
452 if (gslStatus != GSL_SUCCESS)
462 if (
m < 0 && absM % 2 == 1 )
503 double f1 = (
x-1)/2.0, f2 = (
x+1)/2.0;
506 if( n == 0 )
return 1.0;
507 for( s=0; n-s >= 0; s++ ){
509 val *= gsl_sf_choose( n+alpha, s );
510 val *= gsl_sf_choose( n+beta, n-s );
511 if( n-s != 0 ) val *= pow( f1, n-s );
512 if( s != 0 ) val*= pow( f2, s );
529 #define MIN(a,b) ((a) < (b) ? (a) : (b))
543 }
else if(k == l-
m) {
546 }
else if(k == l+mp) {
549 }
else if(k == l-mp) {
555 double pref = pow(-1, lam) * sqrt(gsl_sf_choose( 2*l-k, k+
a )) / sqrt(gsl_sf_choose( k+b, b ));
582 return cexp( -(1.0I)*mp*alpha ) *
584 cexp( -(1.0I)*
m*gam );
#define MIN(a, b)
Computes the 'little' d Wigner matrix for the Euler angle beta.
int XLALPrintError(const char *fmt,...)
#define XLAL_CALLGSL(statement)
#define LAL_PI
Archimedes's constant, pi.
#define cpolar(r, th)
Construct a COMPLEX16 from polar modulus and argument.
double complex COMPLEX16
Double-precision floating-point complex number (16 bytes total)
double REAL8
Double precision real floating-point number (8 bytes).
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
float REAL4
Single precision real floating-point number (4 bytes).
double XLALWignerdMatrix(int l, int mp, int m, double beta)
COMPLEX16 XLALWignerDMatrix(int l, int mp, int m, double alpha, double beta, double gam)
Computes the full Wigner D matrix for the Euler angle alpha, beta, and gamma with major index 'l' and...
double XLALJacobiPolynomial(int n, int alpha, int beta, double x)
Computes the n-th Jacobi polynomial for polynomial weights alpha and beta.
COMPLEX16 XLALSpinWeightedSphericalHarmonic(REAL8 theta, REAL8 phi, int s, int l, int m)
Computes the (s)Y(l,m) spin-weighted spherical harmonic.
int XLALScalarSphericalHarmonic(COMPLEX16 *y, UINT4 l, INT4 m, REAL8 theta, REAL8 phi)
Computes the scalar spherical harmonic .
INT4 XLALSphHarm(COMPLEX16 *out, UINT4 L, INT4 M, REAL4 theta, REAL4 phi)
Computes the spin 2 weighted spherical harmonic.
#define XLAL_ERROR_VAL(val,...)
Macro to invoke the XLALError() function and return with code val (it should not really be used itsel...
#define xlalErrno
Modifiable lvalue containing the XLAL error number.
#define XLAL_ERROR(...)
Macro to invoke a failure from a XLAL routine returning an integer.
#define XLAL_PRINT_DEPRECATION_WARNING(replacement)
Prints a deprecation warning at the "warning" verbosity level.
@ XLAL_SUCCESS
Success return value (not an error number)
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
@ XLAL_EINVAL
Invalid argument.