// ../src/tools/tools__double_factorial.cpp ================================================= // // // Catalyst Lib is free software: you can redistribute it and/or modifyit under the terms of // the GNU General Public License as published bythe Free Software Foundation, either version // 3 of the License, or(at your option) any later version. // // Catalyst Lib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with Catalyst Lib. // If not, see <http://www.gnu.org/licenses/>. // // ========================================================================================== // // // // /// @param [in] a An integer number, where @f$ 0 < a \leq 297 @f$ // /// @brief Calls the GSL library to compute the double factorial of /// the given @c a. // /// @return @f$ a!! @f$. If @f$ a @f$ is out of range, the function /// returns one. // /// @cite gsl // inline double double_factorial(const int &a) { switch(a <= 0 or a > GSL_SF_DOUBLEFACT_NMAX) { case false: return gsl_sf_doublefact(a); break; case true: return 1.0; break; } };
/** * Function to calculate the numerical prefix in the Newtonian amplitude. Eqs. 5 - 7. */ static int CalculateThisMultipolePrefix( COMPLEX16 *prefix, /**<< OUTPUT, Prefix value */ const REAL8 m1, /**<< mass 1 */ const REAL8 m2, /**<< mass 2 */ const INT4 l, /**<< Mode l */ const INT4 m /**<< Mode m */ ) { COMPLEX16 n; REAL8 c; REAL8 x1, x2; /* Scaled versions of component masses */ REAL8 mult1, mult2; REAL8 totalMass; REAL8 eta; INT4 epsilon; INT4 sign; /* To give the sign of some additive terms */ n = 0.0; totalMass = m1 + m2; epsilon = ( l + m ) % 2; x1 = m1 / totalMass; x2 = m2 / totalMass; eta = m1*m2/(totalMass*totalMass); if ( abs( m % 2 ) == 0 ) { sign = 1; } else { sign = -1; } /* * Eq. 7 of Damour, Iyer and Nagar 2008. * For odd m, c is proportional to dM = m1-m2. In the equal-mass case, c = dM = 0. * In the equal-mass unequal-spin case, however, when spins are different, the odd m term is generally not zero. * In this case, c can be written as c0 * dM, while spins terms in PN expansion may take the form chiA/dM. * Although the dM's cancel analytically, we can not implement c and chiA/dM with the possibility of dM -> 0. * Therefore, for this case, we give numerical values of c0 for relevant modes, and c0 is calculated as * c / dM in the limit of dM -> 0. Consistently, for this case, we implement chiA instead of chiA/dM * in LALSimIMRSpinEOBFactorizedWaveform.c. */ if ( m1 != m2 || sign == 1 ) { c = pow( x2, l + epsilon - 1 ) + sign * pow(x1, l + epsilon - 1 ); } else { switch( l ) { case 2: c = -1.0; break; case 3: c = -1.0; break; case 4: c = -0.5; break; default: c = 0.0; break; } } /* Eqs 5 and 6. Dependent on the value of epsilon (parity), we get different n */ if ( epsilon == 0 ) { n = I * m; n = cpow( n, (REAL8)l ); mult1 = 8.0 * LAL_PI / gsl_sf_doublefact(2u*l + 1u); mult2 = (REAL8)((l+1) * (l+2)) / (REAL8)(l * ((INT4)l - 1)); mult2 = sqrt(mult2); n *= mult1; n *= mult2; } else if ( epsilon == 1 ) { n = I * m; n = cpow( n, (REAL8)l ); n = -n; mult1 = 16.*LAL_PI / gsl_sf_doublefact( 2u*l + 1u ); mult2 = (REAL8)( (2*l + 1) * (l+2) * (l*l - m*m) ); mult2 /= (REAL8)( (2*l - 1) * (l+1) * l * (l-1) ); mult2 = sqrt(mult2); n *= I * mult1; n *= mult2; } else { XLALPrintError( "Epsilon must be 0 or 1.\n"); XLAL_ERROR( XLAL_EINVAL ); } *prefix = n * eta * c; return XLAL_SUCCESS; }