24#include <gsl/gsl_math.h>
25#include <gsl/gsl_sf_log.h>
26#include <lal/LALConstants.h>
37 if ( fabs(
delta ) < 1.0e-6 ) {
38 return crect( 1.0, 0.0 );
42 return ( cexp( val ) - 1.0 ) / val;
53 if ( fabs(
delta ) < 1.0e-6 ) {
54 return crect( 0.5, 0.0 );
55 }
else if ( fabs(
delta *
delta - 1.0 ) < 1.0e-6 ) {
56 return crect( -0.25, 0.0 );
74 *ratio =
crectf( 0.0, 0.0 );
75 if ( fabsf( delta1 ) < (
REAL4 )1.0e-6 ) {
76 if ( fabsf( delta0 ) < (
REAL4 )1.0e-6 ) {
77 *ratio =
crectf( 1.0, 0.0 );
78 }
else if ( fabsf( (
REAL4 )( delta0 * delta0 - 1.0 ) ) < (
REAL4 )1.0e-6 ) {
79 *ratio =
crectf( -2.0, 0.0 );
80 }
else if ( fabsf( delta0 - roundf( delta0 ) ) < (
REAL4 )1.0e-6 ) {
85 }
else if ( fabsf( (
REAL4 )( delta1 * delta1 - 1.0 ) ) < (
REAL4 )1.0e-6 ) {
86 if ( fabsf( delta0 ) < (
REAL4 )1.0e-6 ) {
87 *ratio =
crectf( -0.5, 0.0 );
88 }
else if ( fabsf( (
REAL4 )( delta0 * delta0 - 1.0 ) ) < (
REAL4 )1.0e-6 ) {
89 *ratio =
crectf( 1.0, 0.0 );
90 }
else if ( fabsf( delta0 - roundf( delta0 ) ) < (
REAL4 )1.0e-6 ) {
95 }
else if ( fabsf( delta0 - roundf( delta0 ) ) < (
REAL4 )1.0e-6 ) {
106 2.16786447866463034423060819465,
107 -0.05533249018745584258035832802,
108 0.01800392431460719960888319748,
109 -0.00580919269468937714480019814,
110 0.00186523689488400339978881560,
111 -0.00059746524113955531852595159,
112 0.00019125169907783353925426722,
113 -0.00006124996546944685735909697,
114 0.00001963889633130842586440945,
115 -6.3067741254637180272515795142e-06,
116 2.0288698405861392526872789863e-06,
117 -6.5384896660838465981983750582e-07,
118 2.1108698058908865476480734911e-07,
119 -6.8260714912274941677892994580e-08,
120 2.2108560875880560555583978510e-08,
121 -7.1710331930255456643627187187e-09,
122 2.3290892983985406754602564745e-09,
123 -7.5740371598505586754890405359e-10,
124 2.4658267222594334398525312084e-10,
125 -8.0362243171659883803428749516e-11,
126 2.6215616826341594653521346229e-11,
127 -8.5596155025948750540420068109e-12,
128 2.7970831499487963614315315444e-12,
129 -9.1471771211886202805502562414e-13,
130 2.9934720198063397094916415927e-13,
131 -9.8026575909753445931073620469e-14,
132 3.2116773667767153777571410671e-14,
133 -1.0518035333878147029650507254e-14,
134 3.4144405720185253938994854173e-15,
135 -1.0115153943081187052322643819e-15
147 0.0057502277273114339831606096782,
148 0.0004496689534965685038254147807,
149 -0.0001672763153188717308905047405,
150 0.0000615137014913154794776670946,
151 -0.0000223726551711525016380862195,
152 8.0507405356647954540694800545e-06,
153 -2.8671077107583395569766746448e-06,
154 1.0106727053742747568362254106e-06,
155 -3.5265558477595061262310873482e-07,
156 1.2179216046419401193247254591e-07,
157 -4.1619640180795366971160162267e-08,
158 1.4066283500795206892487241294e-08,
159 -4.6982570380537099016106141654e-09,
160 1.5491248664620612686423108936e-09,
161 -5.0340936319394885789686867772e-10,
162 1.6084448673736032249959475006e-10,
163 -5.0349733196835456497619787559e-11,
164 1.5357154939762136997591808461e-11,
165 -4.5233809655775649997667176224e-12,
166 1.2664429179254447281068538964e-12,
167 -3.2648287937449326771785041692e-13,
168 7.1528272726086133795579071407e-14,
169 -9.4831735252566034505739531258e-15,
170 -2.3124001991413207293120906691e-15,
171 2.8406613277170391482590129474e-15,
172 -1.7245370321618816421281770927e-15,
173 8.6507923128671112154695006592e-16,
174 -3.9506563665427555895391869919e-16,
175 1.6779342132074761078792361165e-16,
176 -6.0483153034414765129837716260e-17
188 const REAL8 a[8] = { 3.387132872796366608, 133.14166789178437745,
189 1971.5909503065514427, 13731.693765509461125,
190 45921.953931549871457, 67265.770927008700853,
191 33430.575583588128105, 2509.0809287301226727
194 const REAL8 b[8] = { 1.0, 42.313330701600911252,
195 687.1870074920579083, 5394.1960214247511077,
196 21213.794301586595867, 39307.89580009271061,
197 28729.085735721942674, 5226.495278852854561
208 const REAL8 a[] = { 1.42343711074968357734, 4.6303378461565452959,
209 5.7694972214606914055, 3.64784832476320460504,
210 1.27045825245236838258, 0.24178072517745061177,
211 0.0227238449892691845833, 7.7454501427834140764e-4
214 const REAL8 b[] = { 1.0, 2.05319162663775882187,
215 1.6763848301838038494, 0.68976733498510000455,
216 0.14810397642748007459, 0.0151986665636164571966,
217 5.475938084995344946e-4, 1.05075007164441684324e-9
226 const REAL8 a[] = { 6.6579046435011037772, 5.4637849111641143699,
227 1.7848265399172913358, 0.29656057182850489123,
228 0.026532189526576123093, 0.0012426609473880784386,
229 2.71155556874348757815e-5, 2.01033439929228813265e-7
232 const REAL8 b[] = { 1.0, 0.59983220655588793769,
233 0.13692988092273580531, 0.0148753612908506148525,
234 7.868691311456132591e-4, 1.8463183175100546818e-5,
235 1.4215117583164458887e-7, 2.04426310338993978564e-15
249 for (
i = na - 1;
i > 0;
i-- ) {
250 u =
x *
u +
a[
i - 1];
255 for (
j = nb - 1;
j > 0;
j-- ) {
256 v =
x * v + b[
j - 1];
268 }
else if (
x == 0.0 ) {
274 }
else if (
a == 1.0 ) {
275 return ( exp( -
x / b ) / b );
277 return ( exp( (
a - 1.0 ) *
log(
x / b ) -
x / b - lgamma(
a ) ) / b );
282 const REAL8 amax = 1048576.0;
283 const REAL8 amaxthird = amax - 1.0 / 3.0;
287 xint =
fmax( amaxthird + sqrt( amax /
a ) * ( xint - ( aint - 1.0 / 3.0 ) ), 0.0 );
296 }
else if ( xint == 0.0 ) {
302 }
else if ( xint < aint + 1.0 ) {
306 while ( fabs( del ) >= 100.0 *
epsval( fabs( sum ) ) ) {
308 del = xint * del / ap;
311 REAL8 b = sum * exp( -xint + aint *
log( xint ) - lgamma( aint + 1.0 ) );
312 if ( xint > 0.0 && b > 1.0 ) {
325 REAL8 fac = 1.0 / a1;
329 while ( fabs( g - gold ) >= 100 *
epsval( fabs( g ) ) ) {
332 a0 = ( a1 + a0 * ana ) * fac;
333 b0 = (
b1 +
b0 * ana ) * fac;
335 a1 = xint * a0 + anf * a1;
336 b1 = xint *
b0 + anf *
b1;
341 REAL8 b = exp( -xint + aint *
log( xint ) - lgamma( aint ) ) * g;
356 }
else if (
x < 20.0 ||
x < 0.5 *
a ) {
360 }
else if (
a > 1.0e+06 && (
x -
a ) * (
x -
a ) <
a ) {
366 }
else if (
a <=
x ) {
379 if ( (
x -
a ) * (
x -
a ) <
a ) {
397 XLAL_CHECK(
a >= 0.0 &&
x >= 0.0,
XLAL_EINVAL,
"Invalid input of less than zero (a = %f), or less than zero (x = %f)\n",
a,
x );
400 }
else if (
a == 0.0 ) {
402 }
else if (
x <= 0.5 *
a ) {
409 }
else if (
a >= 1.0e+06 && (
x -
a ) * (
x -
a ) <
a ) {
414 }
else if (
a < 0.2 &&
x < 5.0 ) {
423 }
else if (
a <=
x ) {
424 if (
x <= 1.0e+06 ) {
443 if (
x >
a - sqrt(
a ) ) {
475 if (
x > 0.995 *
a &&
a > 1.0e5 ) {
494 INT4 nlow = (
x >
a ) ? (
x -
a ) : 0;
496 for (
n = 1;
n < nlow;
n++ ) {
497 term *=
x / (
a +
n );
504 term *=
x / (
a +
n );
512 REAL8 tnp1 = (
x / (
a +
n ) ) * term;
513 remainderval = tnp1 / ( 1.0 -
x / (
a +
n + 1.0 ) );
532 const REAL8 pg21 = -2.404113806319188570799476;
534 const REAL8 el = M_EULER + lnx;
536 const REAL8 c2 = M_PI * M_PI / 12.0 - 0.5 * el * el;
537 const REAL8 c3 = el * ( M_PI * M_PI / 12.0 - el * el / 6.0 ) + pg21 / 6.0;
538 const REAL8 c4 = -0.04166666666666666667
539 * ( -1.758243446661483480 + lnx )
540 * ( -0.764428657272716373 + lnx )
541 * ( 0.723980571623507657 + lnx )
542 * ( 4.107554191916823640 + lnx );
543 const REAL8 c5 = -0.0083333333333333333
544 * ( -2.06563396085715900 + lnx )
545 * ( -1.28459889470864700 + lnx )
546 * ( -0.27583535756454143 + lnx )
547 * ( 1.33677371336239618 + lnx )
548 * ( 5.17537282427561550 + lnx );
549 const REAL8 c6 = -0.0013888888888888889
550 * ( -2.30814336454783200 + lnx )
551 * ( -1.65846557706987300 + lnx )
552 * ( -0.88768082560020400 + lnx )
553 * ( 0.17043847751371778 + lnx )
554 * ( 1.92135970115863890 + lnx )
555 * ( 6.22578557795474900 + lnx );
556 const REAL8 c7 = -0.00019841269841269841
557 * ( -2.5078657901291800 + lnx )
558 * ( -1.9478900888958200 + lnx )
559 * ( -1.3194837322612730 + lnx )
560 * ( -0.5281322700249279 + lnx )
561 * ( 0.5913834939078759 + lnx )
562 * ( 2.4876819633378140 + lnx )
563 * ( 7.2648160783762400 + lnx );
564 const REAL8 c8 = -0.00002480158730158730
565 * ( -2.677341544966400 + lnx )
566 * ( -2.182810448271700 + lnx )
567 * ( -1.649350342277400 + lnx )
568 * ( -1.014099048290790 + lnx )
569 * ( -0.191366955370652 + lnx )
570 * ( 0.995403817918724 + lnx )
571 * ( 3.041323283529310 + lnx )
572 * ( 8.295966556941250 + lnx );
573 const REAL8 c9 = -2.75573192239859e-6
574 * ( -2.8243487670469080 + lnx )
575 * ( -2.3798494322701120 + lnx )
576 * ( -1.9143674728689960 + lnx )
577 * ( -1.3814529102920370 + lnx )
578 * ( -0.7294312810261694 + lnx )
579 * ( 0.1299079285269565 + lnx )
580 * ( 1.3873333251885240 + lnx )
581 * ( 3.5857258865210760 + lnx )
582 * ( 9.3214237073814600 + lnx );
583 const REAL8 c10 = -2.75573192239859e-7
584 * ( -2.9540329644556910 + lnx )
585 * ( -2.5491366926991850 + lnx )
586 * ( -2.1348279229279880 + lnx )
587 * ( -1.6741881076349450 + lnx )
588 * ( -1.1325949616098420 + lnx )
589 * ( -0.4590034650618494 + lnx )
590 * ( 0.4399352987435699 + lnx )
591 * ( 1.7702236517651670 + lnx )
592 * ( 4.1231539047474080 + lnx )
593 * ( 10.342627908148680 + lnx );
595 term1 =
a * (
c1 +
a * (
c2 +
a * ( c3 +
a * ( c4 +
a * ( c5 +
a * ( c6 +
a * ( c7 +
a * ( c8 +
a * ( c9 +
a * c10 ) ) ) ) ) ) ) ) );
607 t *= -
x / (
n + 1.0 );
608 sum += (
a + 1.0 ) / (
a +
n + 1.0 ) *
t;
617 term2 = ( 1.0 - term1 ) *
a / (
a + 1.0 ) *
x * sum;
618 *
out = ( term1 + term2 );
629 REAL8 y = ( 2.0 *
x - cs->a - cs->b ) / ( cs->b - cs->a );
632 for (
j = cs->order;
j >= 1;
j-- ) {
634 d = y2 *
d - dd + cs->c[
j];
639 d =
y *
d - dd + 0.5 * cs->c[0];
658 ln_term = ln_u -
u + 1.0;
662 ln_term = log1p(
mu ) -
mu;
665 term1 = exp(
a * ln_term ) / sqrt( 2.0 *
LAL_PI *
a );
666 *
out = term1 / gstar;
679 REAL8 lnr_val = lg - (
x - 0.5 ) * lx +
x -
c;
680 *
out = exp( lnr_val );
681 }
else if (
x < 2.0 ) {
682 REAL8 t = 4.0 / 3.0 * (
x - 0.5 ) - 1.0;
685 }
else if (
x < 10.0 ) {
686 REAL8 t = 0.25 * (
x - 2.0 ) - 1.0;
688 *
out =
c / (
x *
x ) + 1.0 + 1.0 / ( 12.0 *
x );
689 }
else if (
x < 1.0 / 1.2207031250000000e-04 ) {
696 *
out = 1.0 + xi / 12.0 * ( 1.0 + xi / 24.0 * ( 1.0 - xi * ( 139.0 / 180.0 + 571.0 / 8640.0 * xi ) ) );
713 const REAL8 c3 = -1.0 / 1680.0;
714 const REAL8 c4 = 1.0 / 1188.0;
715 const REAL8 c5 = -691.0 / 360360.0;
716 const REAL8 c6 = 1.0 / 156.0;
717 const REAL8 c7 = -3617.0 / 122400.0;
718 const REAL8 ser =
c0 +
y * (
c1 +
y * (
c2 +
y * ( c3 +
y * ( c4 +
y * ( c5 +
y * ( c6 +
y * c7 ) ) ) ) ) );
719 return exp( ser /
x );
738 REAL8 An =
b1 * Anm1 + a1 * Anm2;
739 REAL8 Bn =
b1 * Bnm1 + a1 * Bnm2;
747 An =
b2 * Anm1 +
a2 * Anm2;
748 Bn =
b2 * Bnm1 +
a2 * Bnm2;
752 while (
n < maxiter ) {
760 an = ( GSL_IS_ODD(
n ) ? ( (
n - 1 ) / 2 ) *
x : -(
N + (
n / 2 ) - 1 ) *
x );
762 An =
bn * Anm1 + an * Anm2;
763 Bn =
bn * Bnm1 + an * Bnm2;
765 if ( fabs( An ) > RECUR_BIG || fabs( Bn ) > RECUR_BIG ) {
794 REAL8 ln_term = gsl_sf_log_1plusx_mx(
eps );
795 REAL8 eta = GSL_SIGN(
eps ) * sqrt( -2.0 * ln_term );
802 if ( fabs(
eps ) < 7.4009597974140505e-04 ) {
803 c0 = -1.0 / 3.0 +
eps * ( 1.0 / 12.0 -
eps * ( 23.0 / 540.0 -
eps * ( 353.0 / 12960.0 -
eps * 589.0 / 30240.0 ) ) );
804 c1 = -1.0 / 540.0 -
eps / 288.0;
806 REAL8 rt_term = sqrt( -2.0 * ln_term / (
eps *
eps ) );
808 c0 = ( 1.0 - 1.0 / rt_term ) /
eps;
814 return ( 0.5 * erfcval + R );
823 *
out = (
D * (
a /
x ) * F );
834 REAL8 Cn = 1.0 / smallval;
840 for (
n = 2 ;
n <
nmax ;
n++ ) {
844 if ( GSL_IS_ODD(
n ) ) {
845 an = 0.5 * (
n - 1 ) /
x;
847 an = ( 0.5 *
n -
a ) /
x;
851 if ( fabs( Dn ) < smallval ) {
855 if ( fabs( Cn ) < smallval ) {
885 term *= (
a -
n ) /
x;
886 if ( fabs( term /
last ) > 1.0 ) {
898 return (
D * (
a /
x ) * sum );
905 REAL8 absval = fabs( val );
907 frexp( absval, &exponentval );
909 return ldexp( 1.0, exponentval );
916 REAL4 absval = fabsf( val );
918 frexpf( absval, &exponentval );
920 return ldexpf( 1.0, exponentval );
929 REAL8 Pint = P, Cint =
C, Eint = E;
930 INT8 counterint = counter;
932 if ( countdown != 0 ) {
933 if ( counterint >= 0 ) {
937 Pint *= ( counterint + 1.0 ) / halfdelta;
944 while ( counterint != -1 ) {
945 REAL8 pplus = Pint * Cint;
946 *( computedprob ) += pplus;
948 if ( pplus > *( computedprob ) *
err ) {
953 if ( countdown != 0 && counterint < 0 ) {
960 if ( countdown != 0 ) {
962 Pint *= ( counterint + 1.0 ) / halfdelta;
963 Eint *= ( 0.5 * dof + counterint + 1.0 ) / (
x * 0.5 );
967 Pint *= halfdelta / counterint;
968 Eint *= ( 0.5 *
x ) / ( 0.5 * dof + counterint - 1.0 );
983 REAL8 Pint = P, Cint =
C, Eint = E;
984 INT8 counterint = counter;
985 REAL8 oneoverhalfdelta = 1.0 / halfdelta;
986 REAL8 halfdof = 0.5 * dof;
989 if ( countdown != 0 ) {
990 if ( counterint >= 0 ) {
991 Pint *= ( counterint + 1.0 ) * oneoverhalfdelta;
998 if ( counterint == -1 ) {
1000 }
else if ( countdown != 0 ) {
1001 REAL8 oneoverhalfx = 1.0 / halfx;
1002 while ( counterint != -1 ) {
1003 REAL8 pplus = Pint * Cint;
1004 *( computedprob ) += pplus;
1006 if ( pplus <= *( computedprob ) *
err || counterint < 0 ) {
1011 Pint *= ( counterint + 1 ) * oneoverhalfdelta;
1012 Eint *= ( halfdof + counterint + 1 ) * oneoverhalfx;
1016 while ( counterint != -1 ) {
1017 REAL8 pplus = Pint * Cint;
1018 *( computedprob ) += pplus;
1020 if ( pplus <= *( computedprob ) *
err ) {
1025 Pint *= halfdelta / counterint;
1026 Eint *= halfx / ( halfdof + counterint - 1 );
1036 if ( fabs(
x - np ) < 0.1 * (
x + np ) ) {
1037 REAL8 s = (
x - np ) * (
x - np ) / (
x + np );
1038 REAL8 v = (
x - np ) / (
x + np );
1046 s1 =
s + ej / ( 2.0 * jj + 1.0 );
1055 return x *
log(
x / np ) + np -
x;
static double double delta
void sumseries_eg(REAL8 *computedprob, REAL8 P, REAL8 C, REAL8 E, INT8 counter, REAL8 x, REAL8 dof, REAL8 halfdelta, REAL8 err, INT4 countdown)
REAL8 ran_gamma_pdf(REAL8 x, REAL8 a, REAL8 b)
static cheb_series gstar_a_cs
REAL8 twospect_intermediate(REAL8 r)
REAL8 gamma_inc_Q_asymp_unif(REAL8 a, REAL8 x)
REAL8 twospect_cheb_eval(const cheb_series *cs, REAL8 x)
REAL8 twospect_small(REAL8 q)
INT4 gamma_inc_F_CF(REAL8 *out, REAL8 a, REAL8 x)
INT4 sf_gamma_inc_Q(REAL8 *out, REAL8 a, REAL8 x)
INT4 gamma_inc_Q_CF(REAL8 *out, REAL8 a, REAL8 x)
INT4 sf_gamma_inc_P(REAL8 *out, REAL8 a, REAL8 x)
INT4 gamma_inc_Q_series(REAL8 *out, REAL8 a, REAL8 x)
void sumseries(REAL8 *computedprob, REAL8 P, REAL8 C, REAL8 E, INT8 counter, REAL8 x, REAL8 dof, REAL8 halfdelta, REAL8 err, INT4 countdown)
INT4 twospect_sf_gammastar(REAL8 *out, REAL8 x)
REAL8 gammastar_ser(REAL8 x)
static cheb_series gstar_b_cs
static REAL8 gstar_b_data[]
INT4 DirichletKernalLargeNHannRatio(COMPLEX8 *ratio, const REAL4 delta0, const REAL4 delta1, const REAL4 scaling)
Compute the argument of the ratio of Dirichlet kernels for large N values and the Hann window.
COMPLEX16 DirichletKernelLargeNHann(const REAL8 delta)
Compute the Dirichlet kernel for large N values and the Hann window.
REAL4 epsval_float(REAL4 val)
INT4 gamma_inc_D(REAL8 *out, REAL8 a, REAL8 x)
INT4 gamma_inc_P_series(REAL8 *out, REAL8 a, REAL8 x)
REAL8 sf_exprel_n_CF(REAL8 N, REAL8 x)
REAL8 binodeviance(REAL8 x, REAL8 np)
REAL8 matlab_gamma_inc(REAL8 x, REAL8 a, INT4 upper)
REAL8 gamma_inc_Q_large_x(REAL8 a, REAL8 x)
REAL8 twospect_tail(REAL8 r)
static REAL8 gstar_a_data[30]
COMPLEX16 DirichletKernelLargeN(const REAL8 delta)
Compute the Dirichlet kernel for large N values.
REAL8 rat_eval(const REAL8 a[], const size_t na, const REAL8 b[], const size_t nb, const REAL8 x)
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_VOID(assertion,...)
#define XLAL_CHECK_REAL8(assertion,...)