Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-ea7c608
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
cdfwchisq.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2010, 2011, 2014 Evan Goetz
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20// Program based on Robert Davies C algorithm from his 1980 paper
21// "The distribution of a linear combination of chi^2 random variables"
22// Journal of the Royal Statistical Society. Series C (Applied Statistics)
23// Vol. 29, No. 3, 1980, pp. 323-33
24
25
26#include <math.h>
27#include <lal/LALConstants.h>
28#include <lal/Sort.h>
29#include <gsl/gsl_sf_log.h>
30#include "TwoSpectTypes.h"
31#include "cdfwchisq.h"
32#include "vectormath.h"
33
34//Exp function to avoid underflows
36{
37 if ( x < -700.0 ) {
38 return 0.0;
39 } else {
40 return exp( x );
41 }
42} /* exp1() */
43
44//Special functions
46{
47 return log1p( x );
48} /* twospect_log_1plusx() */
50{
51 return log1p( x ) - x;
52} /* twospect_log_1plusx_mx() */
53
54
55//find order of absolute values of weights
56void order( qfvars *vars )
57{
58
59 INT4 ascend = 1; //To sort descending, set ascend to zero
60 XLAL_CHECK_VOID( XLALHeapIndex( vars->sorting->data, vars->weights->data, vars->weights->length, sizeof( REAL8 ), &ascend, compar ) == XLAL_SUCCESS, XLAL_EFUNC );
61
62 vars->arrayNotSorted = 0; //Signify that we have done the sorting
63
64} /* order() */
65
66//Comparison routine for sorting algorithm (NOTE: Ascending order p=1, descending p=0)
67int compar( void *p, const void *a, const void *b )
68{
69 REAL8 x = *( ( const REAL8 * )a );
70 REAL8 y = *( ( const REAL8 * )b );
71 int ascend = *( int * )p;
72
73 if ( ascend ) {
74 if ( x < y ) {
75 return -1;
76 }
77 if ( x > y ) {
78 return 1;
79 }
80 return 0;
81 }
82
83 if ( x > y ) {
84 return -1;
85 }
86 if ( x < y ) {
87 return 1;
88 }
89 return 0;
90
91} /* compar() */
92
93//find bound on tail probability using mgf, cutoff point returned to *cx
95{
96
97 REAL8 sum1, x, y, xconst;
98
99 ( vars->count )++; //Increase counter
100
101 xconst = u * vars->sigsq; //xconst = u * sigma**2 + sum{ }
102 sum1 = u * xconst; //sum1 = u**2 * sigma**2 + sum{ } this is almost the equation after eq 9 in Davies 1973
103 //without the factor of 1/2 (applied at the end of this function)
104 u *= 2.0;
105 for ( INT4 ii = vars->weights->length - 1; ii >= 0; ii-- ) {
106 x = u * vars->weights->data[ii]; //x=2*u*lambda_j
107 y = 1.0 - x; //y=1-2*u*lambda_j
108 xconst += vars->weights->data[ii] * ( vars->noncentrality->data[ii] / y + vars->dofs->data[ii] ) / y;
109 sum1 += vars->noncentrality->data[ii] * ( x * x / ( y * y ) ) + vars->dofs->data[ii] * ( x * x / y + gsl_sf_log_1plusx_mx( -x ) );
110 }
111 *cx = xconst;
112
113 return exp1( -0.5 * sum1 );
114
115}/* errbound() */
116//Very similar to errbound() but this has no non-centrality parameters and assumes all dofs are 2.0
118{
119
120 REAL8 sum1, x, y, xconst;
121
122 ( vars->count )++; //Increase counter
123
124 xconst = u * vars->sigsq;
125 sum1 = u * xconst;
126 u *= 2.0;
127 for ( INT4 ii = vars->weights->length - 1; ii >= 0; ii-- ) {
128 x = u * vars->weights->data[ii];
129 y = 1.0 - x;
130 xconst += 2.0 * vars->weights->data[ii] / y;
131 sum1 += 2 * ( x * x / y + ( log1p( -x ) + x ) );
132 }
133 *cx = xconst;
134
135 return exp1( -0.5 * sum1 );
136
137} /* errbound_twospect() */
138
139//find cutoff so that p(qf > cutoff) < accx if (upn > 0, p(qf < cutoff) < accx otherwise
140REAL8 cutoff( qfvars *vars, REAL8 accx, REAL8 *upn )
141{
142
143 REAL8 u1, u2, u, rb, xconst, c1, c2;
144
145 u2 = *upn;
146 u1 = 0.0;
147 c1 = vars->wnmean;
148 if ( u2 > 0.0 ) {
149 rb = 2.0 * vars->wnmax;
150 } else {
151 rb = 2.0 * vars->wnmin;
152 }
153
154 u = u2 / ( 1.0 + u2 * rb );
155 while ( errbound( vars, u, &c2 ) > accx ) {
156 u1 = u2;
157 c1 = c2;
158 u2 *= 2.0;
159 u = u2 / ( 1.0 + u2 * rb );
160 }
161
162 u = ( c1 - vars->wnmean ) / ( c2 - vars->wnmean );
163 while ( u < 0.9 ) {
164 u = 0.5 * ( u1 + u2 );
165 if ( errbound( vars, u / ( 1.0 + u * rb ), &xconst ) > accx ) {
166 u1 = u;
167 c1 = xconst;
168 } else {
169 u2 = u;
170 c2 = xconst;
171 }
172 u = ( c1 - vars->wnmean ) / ( c2 - vars->wnmean );
173 }
174 *upn = u2;
175
176 return c2;
177
178} /* cutoff() */
179//Same as cutoff() but uses *_twospect() functions
181{
182
183 REAL8 u1, u2, u, rb, xconst, c1, c2;
184
185 u2 = *upn;
186 u1 = 0.0;
187 c1 = vars->wnmean;
188 if ( u2 > 0.0 ) {
189 rb = 2.0 * vars->wnmax;
190 } else {
191 rb = 2.0 * vars->wnmin;
192 }
193
194 u = u2 / ( 1.0 + u2 * rb );
195 while ( errbound_twospect( vars, u, &c2 ) > accx ) {
196 u1 = u2;
197 c1 = c2;
198 u2 *= 2.0;
199 u = u2 / ( 1.0 + u2 * rb );
200 }
201
202 u = ( c1 - vars->wnmean ) / ( c2 - vars->wnmean );
203 while ( u < 0.9 ) {
204 u = 0.5 * ( u1 + u2 );
205 if ( errbound_twospect( vars, u / ( 1.0 + u * rb ), &xconst ) > accx ) {
206 u1 = u;
207 c1 = xconst;
208 } else {
209 u2 = u;
210 c2 = xconst;
211 }
212 u = ( c1 - vars->wnmean ) / ( c2 - vars->wnmean );
213 }
214 *upn = u2;
215
216 return c2;
217
218} /* cutoff_twospect() */
219
220//bound integration error due to truncation at u
221//Eq. 6, 7, 8 of Davies 1980
223{
224 REAL8 sum1, sum2, prod1, prod2, prod3, x, y, err1, err2;
225 INT4 s;
226
227 //counter(vars);
228 ( vars->count )++; //Increase counter
229
230 sum1 = 0.0; //Calculating N(u) = exp(-2u**2 sum_j(lambda_j**2 delta_j**2/(1+4u**2 lambda_j**2)))
231 prod2 = 0.0; //Calculating product (i)
232 prod3 = 0.0; //Calculating product (ii)
233 s = 0; //Sum of degrees of freedom
234
235 sum2 = ( vars->sigsq + tausq ) * u * u;
236 prod1 = 2.0 * sum2;
237 u *= 2.0; //This produces the factor of 4 in front of the products (U*lambda_j)**2 (i and ii) in Davies 1980
238
239 for ( UINT4 ii = 0; ii < vars->weights->length; ii++ ) {
240 x = ( u * vars->weights->data[ii] ) * ( u * vars->weights->data[ii] ); //(2*U*lambda_j)**2
241 sum1 += vars->noncentrality->data[ii] * x / ( 1.0 + x ); //Sum after eq 4 in Davies 1980
242 if ( x > 1.0 ) {
243 prod2 += vars->dofs->data[ii] * log( x ); //Logarithim of product (ii) produces sum of logorithms
244 prod3 += vars->dofs->data[ii] * gsl_sf_log_1plusx( x ); //Logarithim of product (i) produces sum of logorithms
245 s += vars->dofs->data[ii]; //sum of degrees of freedom
246 } else {
247 prod1 += vars->dofs->data[ii] * gsl_sf_log_1plusx( x );
248 }
249 } /* for ii < vars->weights->length */
250
251 sum1 *= 0.5; //Remove the extra prefactor of 2 before taking the exponential
252 prod2 += prod1;
253 prod3 += prod1;
254 x = exp1( -sum1 - 0.25 * prod2 ) * LAL_1_PI; //Now remove logarithm by computing exponential (eq 6)
255 y = exp1( -sum1 - 0.25 * prod3 ) * LAL_1_PI; //Now remove logarithm by computing exponential (eq 8)
256
257 if ( s == 0 ) {
258 err1 = 1.0;
259 } else {
260 err1 = 2.0 * x / s;
261 }
262
263 if ( prod3 > 1.0 ) {
264 err2 = 2.5 * y; //eq 8
265 } else {
266 err2 = 1.0;
267 }
268
269 if ( err2 < err1 ) {
270 err1 = err2;
271 }
272
273 x = 0.5 * sum2;
274
275 if ( x <= y ) {
276 err2 = 1.0;
277 } else {
278 err2 = y / x;
279 }
280
281 if ( err1 < err2 ) {
282 return err1;
283 } else {
284 return err2;
285 }
286
287} /* truncation() */
288//Same as trunction() but assumes dofs are 2.0 and n.c. values are 0.0
290{
291 REAL8 sum2, prod1, prod2, prod3, x, y, err1, err2;
292 INT4 s;
293
294 ( vars->count )++; //Increase counter
295
296 prod2 = 0.0;
297 prod3 = 0.0;
298 s = 0;
299
300 sum2 = ( vars->sigsq + tausq ) * u * u;
301 prod1 = 2.0 * sum2;
302 u *= 2.0;
303
304 for ( UINT4 ii = 0; ii < vars->weights->length; ii++ ) {
305 x = ( u * vars->weights->data[ii] ) * ( u * vars->weights->data[ii] );
306 if ( x > 1.0 ) {
307 prod2 += 2 * log( x );
308 prod3 += 2 * log1p( x );
309 s += 2;
310 } else {
311 prod1 += 2 * log1p( x );
312 }
313 } /* for ii < vars->weights->length */
314
315 prod2 += prod1;
316 prod3 += prod1;
317 x = exp1( -0.25 * prod2 ) * LAL_1_PI;
318 y = exp1( -0.25 * prod3 ) * LAL_1_PI;
319
320 err1 = 2.0 * x / s;
321
322 if ( prod3 > 1.0 ) {
323 err2 = 2.5 * y;
324 } else {
325 err2 = 1.0;
326 }
327
328 if ( err2 < err1 ) {
329 err1 = err2;
330 }
331
332 x = 0.5 * sum2;
333
334 if ( x <= y ) {
335 err2 = 1.0;
336 } else {
337 err2 = y / x;
338 }
339
340 if ( err1 < err2 ) {
341 return err1;
342 } else {
343 return err2;
344 }
345
346} /* truncation_twospect() */
347
348//find u such that truncation(u) < accx and truncation(u / 1.2) > accx
349void findu( qfvars *vars, REAL8 *utx, REAL8 accx )
350{
351
352 REAL8 u, ut;
353 REAL8 divis[] = {2.0, 1.4, 1.2, 1.1};
354
355 ut = *utx;
356 u = 0.25 * ut;
357 if ( truncation( vars, u, 0.0 ) > accx ) {
358 //for ( u=ut; truncation(vars, u, 0.0)>accx; u=ut) ut *= 4.0;
359 u = ut;
360 while ( truncation( vars, u, 0.0 ) > accx ) {
361 ut *= 4.0;
362 u = ut;
363 }
364 } else {
365 ut = u;
366 //for ( u=0.25*u; truncation(vars, u, 0.0) <= accx; u=0.25*u ) ut = u;
367 u *= 0.25;
368 while ( truncation( vars, u, 0.0 ) <= accx ) {
369 ut = u;
370 u *= 0.25;
371 }
372 }
373
374 for ( UINT4 ii = 0; ii < 4; ii++ ) {
375 u = ut / divis[ii];
376 if ( truncation( vars, u, 0.0 ) <= accx ) {
377 ut = u;
378 }
379 }
380
381 *utx = ut;
382
383} /* findu() */
384//Same as findu() but uses *_twospect() functions
385void findu_twospect( qfvars *vars, REAL8 *utx, REAL8 accx )
386{
387
388 REAL8 u, ut;
389 REAL8 divis[] = {2.0, 1.4, 1.2, 1.1};
390
391 ut = *utx;
392 u = 0.25 * ut;
393 if ( truncation_twospect( vars, u, 0.0 ) > accx ) {
394 u = ut;
395 while ( truncation_twospect( vars, u, 0.0 ) > accx ) {
396 ut *= 4.0;
397 u = ut;
398 }
399 } else {
400 ut = u;
401 u *= 0.25;
402 while ( truncation_twospect( vars, u, 0.0 ) <= accx ) {
403 ut = u;
404 u *= 0.25;
405 }
406 }
407
408 for ( UINT4 ii = 0; ii < 4; ii++ ) {
409 u = ut / divis[ii];
410 if ( truncation_twospect( vars, u, 0.0 ) <= accx ) {
411 ut = u;
412 }
413 }
414
415 *utx = ut;
416
417} /* findu_twospect() */
418
419
420//carry out integration with nterm terms, at stepsize interv. if (! mainx) multiply integrand by 1.0-exp(-0.5*tausq*u^2)
421void integrate( qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx )
422{
423
424 REAL8 inpi, u, sum1, sum2, sum3, x, y, z;
425
426 inpi = interv * LAL_1_PI; //inpi = pi*(k + 1/2)
427
428 for ( INT4 ii = nterm; ii >= 0; ii-- ) {
429 u = ( ii + 0.5 ) * interv; //First part of eq 3 in Davies 1980, eq 9 in Davies 1973
430 sum1 = -2.0 * u * vars->c; //Third sum, eq 13 of Davies 1980, the u*c term, will divide by 2 at the end
431 sum2 = fabs( sum1 ); //Davies 1980 says that the sine term can be replaced by the sum of abs vals of the arguement
432 sum3 = -0.5 * vars->sigsq * u * u; //First part of eq 13 Davies 1980 in the exponential
433
434 for ( INT4 jj = vars->weights->length - 1; jj >= 0; jj-- ) {
435 x = 2.0 * vars->weights->data[jj] * u; //2 * lambda_j * u
436 y = x * x; //4 * lambda_j**2 * u**2
437 sum3 -= 0.25 * vars->dofs->data[jj] * gsl_sf_log_1plusx( y ); //product in eq 13 of Davies 1980
438 y = vars->noncentrality->data[jj] * x / ( 1.0 + y ); //First sum argument in eq 13 of Davies 1980
439 z = vars->dofs->data[jj] * atan( x ) + y; //Third sum argument in eq 13 of Davies 1980
440 sum1 += z; //Third sum in eq 13
441 sum2 += fabs( z );
442 sum3 -= 0.5 * x * y; //Product
443 } /* for jj=vars->weights->length-1 --> 0 */
444
445 x = inpi * exp1( sum3 ) / u;
446 if ( !mainx ) {
447 x *= ( 1.0 - exp1( -0.5 * tausq * u * u ) ); //For auxillary integration, we multiply by this factor)
448 }
449 sum1 = sin( 0.5 * sum1 ) * x; //Now compute the sine
450 sum2 *= 0.5 * x;
451 vars->integrationValue += sum1; //integration value
452 vars->integrationError += sum2; //error on integration
453 } /* for ii=nterm --> 0 */
454
455} /* integrate() */
456//Same as integrate() but assumes dofs are 2.0 and n.c. values are 0.0
457void integrate_twospect( qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx )
458{
459
460 REAL8 inpi, u, sum1, sum2, sum3, x, z;
461
462 inpi = interv * LAL_1_PI;
463 REAL8 neg2timesc = -2.0 * vars->c, neghalftimessigsq = -0.5 * vars->sigsq, neghalftimestausq = -0.5 * tausq;
464
465 for ( INT4 ii = nterm; ii >= 0; ii-- ) {
466 u = ( ii + 0.5 ) * interv;
467 sum1 = neg2timesc * u;
468 sum2 = fabs( sum1 );
469 sum3 = neghalftimessigsq * u * u;
470
471 REAL8 twotimesu = 2.0 * u;
472 for ( INT4 jj = vars->weights->length - 1; jj >= 0; jj-- ) {
473 x = twotimesu * vars->weights->data[jj];
474 sum3 -= 0.5 * log1p( ( x * x ) );
475 z = 2.0 * atan( x );
476 sum1 += z;
477 sum2 += fabs( z );
478 } /* for jj=vars->weights->length-1 --> 0 */
479
480 x = inpi * exp1( sum3 ) / u;
481 if ( !mainx ) {
482 x *= ( 1.0 - exp1( neghalftimestausq * u * u ) );
483 }
484 sum1 = sin( 0.5 * sum1 ) * x;
485 sum2 *= 0.5 * x;
486 vars->integrationValue += sum1;
487 vars->integrationError += sum2;
488 } /* for ii=nterm --> 0 */
489
490} /* integrate_twospect() */
491//This is from eq 13 of Davies 1980 and makes more sense than the integrate() function while giving nearly identical results (last digits of double precision are only slightly different)
492void integrate_eg( qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx )
493{
494
495 for ( INT4 ii = nterm; ii >= 0; ii-- ) {
496 REAL8 u = ( ii + 0.5 ) * interv;
497
498 REAL8 exptermarguementsum = 0.0, logofproductterm = 0.0, sinetermargumentsum = 0.0, sumofabssinesumargs = 0.0;
499 for ( INT4 jj = vars->weights->length - 1; jj >= 0; jj-- ) {
500 exptermarguementsum += ( vars->weights->data[jj] * vars->weights->data[jj] ) * ( vars->noncentrality->data[jj] * vars->noncentrality->data[jj] ) / ( 1.0 + 4.0 * ( u * u ) * ( vars->weights->data[jj] * vars->weights->data[jj] ) );
501
502 logofproductterm += -0.25 * vars->dofs->data[jj] * log1p( 4.0 * ( u * u ) * ( vars->weights->data[jj] * vars->weights->data[jj] ) );
503
504 sinetermargumentsum += 0.5 * vars->dofs->data[jj] * atan( 2.0 * u * vars->weights->data[jj] ) + ( vars->noncentrality->data[jj] * vars->noncentrality->data[jj] ) * u * vars->weights->data[jj] / ( 1.0 + 4.0 * ( u * u ) * ( vars->weights->data[jj] * vars->weights->data[jj] ) );
505
506 sumofabssinesumargs += fabs( 0.5 * ( 2.0 ) * atan( 2.0 * u * vars->weights->data[jj] ) + ( vars->noncentrality->data[jj] * vars->noncentrality->data[jj] ) * u * vars->weights->data[jj] / ( 1.0 + 4.0 * ( u * u ) * ( vars->weights->data[jj] * vars->weights->data[jj] ) ) );
507 }
508 REAL8 firstterm = exp1( -2.0 * ( u * u ) * exptermarguementsum - 0.5 * ( u * u ) * vars->sigsq );
509 REAL8 secondterm = exp1( logofproductterm );
510 REAL8 thirdterm = sin( sinetermargumentsum - u * vars->c );
511 REAL8 together = firstterm * secondterm * thirdterm / ( LAL_PI * ( ii + 0.5 ) );
512 REAL8 together2 = firstterm * secondterm * ( sumofabssinesumargs + fabs( u * vars->c ) ) / ( LAL_PI * ( ii + 0.5 ) );
513 if ( !mainx ) {
514 together *= ( 1.0 - exp1( -0.5 * tausq * u * u ) );
515 together2 *= ( 1.0 - exp1( -0.5 * tausq * u * u ) );
516 }
517
518 vars->integrationValue += together;
519 vars->integrationError += together2;
520 }
521
522}
523//Rewrite of integrate_eg() to make it fast
524void integrate_twospect2( qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx )
525{
526
527 for ( INT4 ii = nterm; ii >= 0; ii-- ) {
528 REAL8 u = ( ii + 0.5 ) * interv;
529 REAL8 oneoverPiTimesiiPlusHalf = 1.0 / ( LAL_PI * ( ii + 0.5 ) );
530
531 REAL8 exptermarguementsum = 0.0, logofproductterm = 0.0, sinetermargumentsum = 0.0, sumofabssinesumargs = 0.0;
532
533 for ( INT4 jj = vars->weights->length - 1; jj >= 0; jj-- ) {
534 REAL8 twoUtimesWeight = 2.0 * u * vars->weights->data[jj];
535 REAL8 atanTwoUtimesWeight = atan( twoUtimesWeight );
536
537 logofproductterm += -0.5 * log1p( twoUtimesWeight * twoUtimesWeight );
538 sinetermargumentsum += atanTwoUtimesWeight;
539 sumofabssinesumargs += fabs( atanTwoUtimesWeight );
540 }
541 REAL8 firstterm = exp1( -2.0 * ( u * u ) * exptermarguementsum );
542 REAL8 secondterm = exp1( logofproductterm );
543 REAL8 thirdterm = sin( sinetermargumentsum - u * vars->c );
544 REAL8 together = firstterm * secondterm * thirdterm * oneoverPiTimesiiPlusHalf;
545 REAL8 together2 = firstterm * secondterm * ( sumofabssinesumargs + fabs( u * vars->c ) ) * oneoverPiTimesiiPlusHalf;
546 if ( !mainx ) {
547 REAL8 scalingfactor = ( 1.0 - exp1( -0.5 * tausq * u * u ) );
548 together *= scalingfactor;
549 together2 *= scalingfactor;
550 }
551
552 vars->integrationValue += together;
553 vars->integrationError += together2;
554 }
555
556}
557//Use fast/SSE/AVX to make the integration even faster
558INT4 fast_integrate_twospect2( qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx )
559{
560
561 alignedREAL8Vector *uVector = NULL, *twoUvector = NULL, *oneoverPiTimesiiPlusHalfVector = NULL, *uVectorTimesThreshold = NULL, *scaledweightvector = NULL, *scaledweightvectorsq = NULL;
562 XLAL_CHECK( ( uVector = createAlignedREAL8Vector( nterm + 1, 32 ) ) != NULL, XLAL_EFUNC );
563 XLAL_CHECK( ( twoUvector = createAlignedREAL8Vector( uVector->length, 32 ) ) != NULL, XLAL_EFUNC );
564 XLAL_CHECK( ( oneoverPiTimesiiPlusHalfVector = createAlignedREAL8Vector( uVector->length, 32 ) ) != NULL, XLAL_EFUNC );
565 XLAL_CHECK( ( uVectorTimesThreshold = createAlignedREAL8Vector( uVector->length, 32 ) ) != NULL, XLAL_EFUNC );
566 XLAL_CHECK( ( scaledweightvector = createAlignedREAL8Vector( vars->weights->length, 32 ) ) != NULL, XLAL_EFUNC );
567 XLAL_CHECK( ( scaledweightvectorsq = createAlignedREAL8Vector( vars->weights->length, 32 ) ) != NULL, XLAL_EFUNC );
568
569 for ( INT4 ii = nterm; ii >= 0; ii-- ) {
570 uVector->data[ii] = ( REAL8 )ii;
571 }
572 XLAL_CHECK( VectorShiftREAL8( uVector, uVector, 0.5, vars->vectorMath ) == XLAL_SUCCESS, XLAL_EFUNC );
573 XLAL_CHECK( VectorScaleREAL8( oneoverPiTimesiiPlusHalfVector, uVector, LAL_PI, vars->vectorMath ) == XLAL_SUCCESS, XLAL_EFUNC );
574 XLAL_CHECK( VectorScaleREAL8( uVector, uVector, interv, vars->vectorMath ) == XLAL_SUCCESS, XLAL_EFUNC );
575 XLAL_CHECK( VectorScaleREAL8( uVectorTimesThreshold, uVector, vars->c, vars->vectorMath ) == XLAL_SUCCESS, XLAL_EFUNC );
576 XLAL_CHECK( VectorScaleREAL8( twoUvector, uVector, 2.0, vars->vectorMath ) == XLAL_SUCCESS, XLAL_EFUNC );
577 XLAL_CHECK( VectorInvertREAL8( oneoverPiTimesiiPlusHalfVector, oneoverPiTimesiiPlusHalfVector, vars->vectorMath ) == XLAL_SUCCESS, XLAL_EFUNC );
578
579 for ( INT4 ii = nterm; ii >= 0; ii-- ) {
580 XLAL_CHECK( VectorScaleREAL8( scaledweightvector, vars->weights, twoUvector->data[ii], vars->vectorMath ) == XLAL_SUCCESS, XLAL_EFUNC );
581 XLAL_CHECK( VectorMultiplyREAL8( scaledweightvectorsq, scaledweightvector, scaledweightvector, vars->vectorMath ) == XLAL_SUCCESS, XLAL_EFUNC );
582
583 REAL8 logofproductterm = 0.0, sinetermargumentsum = 0.0, sumofabssinesumargs = 0.0;
584 for ( UINT4 jj = 0; jj < scaledweightvector->length; jj++ ) {
585 REAL8 atanTwoUtimesWeight = atan( scaledweightvector->data[jj] );
586
587 logofproductterm += log1p( scaledweightvectorsq->data[jj] );
588 sinetermargumentsum += atanTwoUtimesWeight;
589 sumofabssinesumargs += fabs( atanTwoUtimesWeight );
590 }
591 logofproductterm *= -0.5;
592 REAL8 secondterm = exp1( logofproductterm );
593 REAL8 thirdterm = sin( sinetermargumentsum - uVectorTimesThreshold->data[ii] );
594 REAL8 together = secondterm * thirdterm * oneoverPiTimesiiPlusHalfVector->data[ii];
595 REAL8 together2 = secondterm * ( sumofabssinesumargs + fabs( uVectorTimesThreshold->data[ii] ) ) * oneoverPiTimesiiPlusHalfVector->data[ii];
596 if ( !mainx ) {
597 REAL8 scalingfactor = ( 1.0 - exp1( -0.5 * tausq * uVector->data[ii] * uVector->data[ii] ) );
598 together *= scalingfactor;
599 together2 *= scalingfactor;
600 }
601
602 vars->integrationValue += together;
603 vars->integrationError += together2;
604 }
605
606 destroyAlignedREAL8Vector( uVector );
607 destroyAlignedREAL8Vector( twoUvector );
608 destroyAlignedREAL8Vector( oneoverPiTimesiiPlusHalfVector );
609 destroyAlignedREAL8Vector( uVectorTimesThreshold );
610 destroyAlignedREAL8Vector( scaledweightvector );
611 destroyAlignedREAL8Vector( scaledweightvectorsq );
612
613 return XLAL_SUCCESS;
614
615}
616
617
618//Coefficient of tausq in error when convergence factor of exp1(-0.5*tausq*u^2) is used when df is evaluated at x
619//Eq. 10 of Davies 1980
621{
622
623 REAL8 axl, axl1, axl2, sxl, sum1, lj;
624 INT4 t;
625
626 ( vars->count )++;
627
628 //If the sort hasn't been done, then do it now!
629 if ( vars->arrayNotSorted ) {
630 order( vars );
631 if ( vars->arrayNotSorted ) {
632 fprintf( stderr, "%s: order() failed\n.", __func__ );
633 vars->fail = 1;
634 return 1.0;
635 }
636 }
637 axl = fabs( x ); //absolute value of the value of c
638
639 if ( x > 0.0 ) {
640 sxl = 1.0;
641 } else {
642 sxl = -1.0;
643 }
644
645 sum1 = 0.0;
646 for ( INT4 ii = vars->weights->length - 1; ii >= 0; ii-- ) {
647 t = vars->sorting->data[ii];
648 if ( vars->weights->data[t] * sxl > 0.0 ) {
649 lj = fabs( vars->weights->data[t] );
650 axl1 = axl - lj * ( vars->dofs->data[t] + vars->noncentrality->data[t] );
651 axl2 = 8.0 * lj / LAL_LN2;
652 if ( axl1 > axl2 ) {
653 axl = axl1;
654 } else {
655 if ( axl > axl2 ) {
656 axl = axl2;
657 }
658 sum1 = ( axl - axl1 ) / lj;
659 for ( INT4 jj = ii - 1; jj >= 0; jj-- ) {
660 sum1 += ( vars->dofs->data[vars->sorting->data[jj]] + vars->noncentrality->data[vars->sorting->data[jj]] );
661 }
662
663 if ( sum1 > 100.0 ) {
664 vars->fail = 1;
665 return 1.0;
666 } else {
667 return exp2( 0.25 * sum1 ) * LAL_1_PI / ( axl * axl );
668 }
669 }
670 }
671 } /* for ii=vars->weights->length-1 --> 0 */
672
673 if ( sum1 > 100.0 ) {
674 vars->fail = 1;
675 return 1.0;
676 } else {
677 return exp2( 0.25 * sum1 ) * LAL_1_PI / ( axl * axl );
678 }
679
680} /* coeff() */
681//Same as coeff() but assuming dofs are 2.0 and n.c. values are 0.0
683{
684
685 REAL8 axl, axl1, axl2, sxl, sum1, lj;
686 INT4 t;
687
688 ( vars->count )++;
689
690 axl = fabs( x );
691
692 if ( x > 0.0 ) {
693 sxl = 1.0;
694 } else {
695 sxl = -1.0;
696 }
697
698 sum1 = 0.0;
699 for ( INT4 ii = vars->weights->length - 1; ii >= 0; ii-- ) {
700 t = vars->sorting->data[ii];
701 if ( vars->weights->data[t] * sxl > 0.0 ) {
702 lj = fabs( vars->weights->data[t] );
703 axl1 = axl - 2 * lj;
704 axl2 = 8.0 * lj / LAL_LN2;
705 if ( axl1 > axl2 ) {
706 axl = axl1;
707 } else {
708 if ( axl > axl2 ) {
709 axl = axl2;
710 }
711 sum1 = ( axl - axl1 ) / lj;
712 for ( INT4 jj = ii - 1; jj >= 0; jj-- ) {
713 sum1 += 2;
714 }
715
716 if ( sum1 > 100.0 ) {
717 vars->fail = 1;
718 return 1.0;
719 } else {
720 return exp2( 0.25 * sum1 ) * LAL_1_PI / ( axl * axl );
721 }
722 }
723 }
724 } /* for ii=vars->weights->length-1 --> 0 */
725
726 if ( sum1 > 100.0 ) {
727 vars->fail = 1;
728 return 1.0;
729 } else {
730 return exp2( 0.25 * sum1 ) * LAL_1_PI / ( axl * axl );
731 }
732
733} /* coeff_twospect() */
734
735
736/* distribution function of a linear combination of non-central
737 chi-squared random variables :
738
739input:
740 vars cdfwchisq parameters structure
741 sigma coefficient of standard normal variable
742 acc maximum error
743
744output:
745 ifault = 1 required accuracy NOT achieved
746 2 round-off error possibly significant
747 3 invalid parameters
748 4 unable to locate integration parameters
749 5 out of memory */
750
751REAL8 cdfwchisq( qfvars *vars, REAL8 sigma, REAL8 acc, INT4 *ifault )
752{
753
754 INT4 nt, ntm;
755 REAL8 acc1, almx, xlim, xnt, xntm;
756 REAL8 utx, tausq, wnstd, intv, intv1, x, up, un, d1, d2;
757 REAL8 qfval;
758 INT4 rats[] = {1, 2, 4, 8};
759
760 *ifault = 0;
761 vars->count = 0;
762 vars->integrationValue = 0.0;
763 vars->integrationError = 0.0;
764 qfval = -1.0;
765 acc1 = acc;
766 vars->arrayNotSorted = 1;
767 vars->fail = 0;
768 xlim = ( REAL8 )vars->lim;
769
770 /* find wnmean, wnstd, wnmax and wnmin of weights, check that parameter values are valid */
771 vars->sigsq = sigma * sigma; //Sigma squared
772 wnstd = vars->sigsq; //weights*noise standard deviation initial value
773 vars->wnmax = 0.0; //Initial value for weights*noise maximum
774 vars->wnmin = 0.0; //Initial value for weights*noise minimum
775 vars->wnmean = 0.0; //Initial value for weights*noise 'mean'
776 for ( UINT4 ii = 0; ii < vars->weights->length; ii++ ) {
777 if ( vars->dofs->data[ii] < 0 || vars->noncentrality->data[ii] < 0.0 ) {
778 *ifault = 3;
779 return qfval;
780 } /* return error if any degrees of freedom is less than 0 or noncentrality parameter is less than 0.0 */
781
782 wnstd += vars->weights->data[ii] * vars->weights->data[ii] * ( 2 * vars->dofs->data[ii] + 4.0 * vars->noncentrality->data[ii] );
783 vars->wnmean += vars->weights->data[ii] * ( vars->dofs->data[ii] + vars->noncentrality->data[ii] );
784
785 //Find maximum and minimum values
786 if ( vars->wnmax < vars->weights->data[ii] ) {
787 vars->wnmax = vars->weights->data[ii];
788 } else if ( vars->wnmin > vars->weights->data[ii] ) {
789 vars->wnmin = vars->weights->data[ii];
790 }
791 }
792
793 if ( wnstd == 0.0 ) {
794 if ( vars->c > 0.0 ) {
795 qfval = 1.0;
796 } else {
797 qfval = 0.0;
798 }
799 return qfval;
800 }
801
802 if ( vars->wnmin == 0.0 && vars->wnmax == 0.0 && sigma == 0.0 ) {
803 *ifault = 3;
804 return qfval;
805 }
806
807 wnstd = sqrt( wnstd );
808
809 //almx is absolute value maximum of weights
810 if ( vars->wnmax < -vars->wnmin ) {
811 almx = -vars->wnmin;
812 } else {
813 almx = vars->wnmax;
814 }
815
816 /* starting values for findu, cutoff */
817 utx = 16.0 / wnstd;
818 up = 4.5 / wnstd;
819 un = -up;
820
821 /* truncation point with no convergence factor */
822 findu( vars, &utx, 0.5 * acc1 );
823
824 /* does convergence factor help */
825 if ( vars->c != 0.0 && almx > 0.07 * wnstd ) {
826 tausq = 0.25 * acc1 / coeff( vars, vars->c );
827 if ( vars->fail ) {
828 vars->fail = 0;
829 } else if ( truncation( vars, utx, tausq ) < 0.2 * acc1 ) {
830 vars->sigsq += tausq;
831 findu( vars, &utx, 0.25 * acc1 );
832 }
833 }
834 acc1 *= 0.5;
835
836 /* find RANGE of distribution, quit if outside this */
837l1:
838 d1 = cutoff( vars, acc1, &up ) - vars->c;
839 if ( d1 < 0.0 ) {
840 qfval = 1.0;
841 return qfval;
842 }
843 d2 = vars->c - cutoff( vars, acc1, &un );
844 if ( d2 < 0.0 ) {
845 qfval = 0.0;
846 return qfval;
847 }
848
849 /* find integration interval */
850 if ( d1 > d2 ) {
851 intv = LAL_TWOPI / d1;
852 } else {
853 intv = LAL_TWOPI / d2;
854 }
855
856 /* calculate number of terms required for main and auxillary integrations */
857 xnt = utx / intv;
858 xntm = 3.0 / sqrt( acc1 );
859
860 if ( xnt > xntm * 1.5 ) {
861 //parameters for auxillary integration
862 if ( xntm > xlim ) {
863 *ifault = 1;
864 return qfval;
865 }
866 ntm = ( INT4 )round( xntm );
867 intv1 = utx / ntm;
868 x = LAL_TWOPI / intv1;
869 if ( x <= fabs( vars->c ) ) {
870 goto l2;
871 }
872
873 //calculate convergence factor
874 REAL8 coeffvalplusx = coeff( vars, vars->c + x );
875 REAL8 coeffvalminusx = coeff( vars, vars->c - x );
876 tausq = ( 1.0 / 3.0 ) * acc1 / ( 1.1 * ( coeffvalminusx + coeffvalplusx ) );
877 if ( vars->fail ) {
878 goto l2;
879 }
880 acc1 = ( 2.0 / 3.0 ) * acc1;
881
882 //auxillary integration
883 //fprintf(stderr,"Num terms in auxillary integration %d\n", ntm);
884 integrate( vars, ntm, intv1, tausq, 0 );
885 xlim -= xntm;
886 vars->sigsq += tausq;
887
888 //find truncation point with new convergence factor
889 findu( vars, &utx, 0.25 * acc1 );
890 acc1 *= 0.75;
891 goto l1;
892 }
893
894 /* main integration */
895l2:
896 if ( xnt > xlim ) {
897 *ifault = 1;
898 return qfval;
899 }
900 nt = ( INT4 )round( xnt );
901 //fprintf(stderr,"Num terms in main integration %d\n", nt);
902 integrate( vars, nt, intv, 0.0, 1 );
903 qfval = 0.5 - vars->integrationValue;
904
905 /* test whether round-off error could be significant allow for radix 8 or 16 machines */
906 up = vars->integrationError;
907 x = up + 0.1 * acc;
908 for ( UINT4 ii = 0; ii < 4; ii++ ) {
909 if ( rats[ii] * x == rats[ii] * up ) {
910 *ifault = 2;
911 }
912 }
913
914 return qfval;
915} /* cdfwchisq() */
916//Re-write of the cdfwchisq() function, but in a better way, without go-to's and to be more LAL compliant (though not totally!)
917REAL8 cdfwchisq_twospect( qfvars *vars, REAL8 sigma, REAL8 acc, INT4 *ifault )
918{
919
920 INT4 nt, ntm;
921 REAL8 acc1, almx, xlim, xnt, xntm;
922 REAL8 utx, tausq, wnstd, intv, intv1, x, up, un, d1, d2;
923 REAL8 qfval;
924 INT4 rats[] = {1, 2, 4, 8};
925
926 //Initialize values
927 *ifault = 0;
928 vars->count = 0;
929 vars->integrationValue = 0.0;
930 vars->integrationError = 0.0;
931 qfval = -1.0;
932 acc1 = acc;
933 vars->fail = 0;
934 xlim = ( REAL8 )vars->lim;
935
936 /* find wnmean, wnstd, wnmax and wnmin of weights, check that parameter values are valid */
937 vars->sigsq = sigma * sigma; //Sigma squared
938 wnstd = vars->sigsq; //weights*noise standard deviation initial value
939 vars->wnmax = 0.0; //Initial value for weights*noise maximum
940 vars->wnmin = 0.0; //Initial value for weights*noise minimum
941 vars->wnmean = 0.0; //Initial value for weights*noise 'mean'
942 for ( UINT4 ii = 0; ii < vars->weights->length; ii++ ) {
943
944 wnstd += 4 * vars->weights->data[ii] * vars->weights->data[ii]; //weight_i^2 * 2 * 2
945 vars->wnmean += 2 * vars->weights->data[ii]; //2*weight_i
946
947 //Find maximum and minimum values of the weights
948 if ( vars->wnmax < vars->weights->data[ii] ) {
949 vars->wnmax = vars->weights->data[ii];
950 } else if ( vars->wnmin > vars->weights->data[ii] ) {
951 vars->wnmin = vars->weights->data[ii];
952 }
953
954 } /* for ii < vars->weights->length */
955
956 //If somehow the wnstd value was 0, then output either 1 or 0
957 if ( wnstd == 0.0 ) {
958 if ( vars->c > 0.0 ) {
959 qfval = 1.0;
960 } else {
961 qfval = 0.0;
962 }
963 return qfval;
964 } /* if wnstd==0 */
965
966 //If the min and max weight are zero, then there needs to be an error
967 if ( vars->wnmin == 0.0 && vars->wnmax == 0.0 ) {
968 *ifault = 3;
969 return qfval;
970 }
971
972 //Do the square root of wnstd
973 wnstd = sqrt( wnstd );
974
975 //almx is absolute value maximum of weights
976 if ( vars->wnmax < -vars->wnmin ) {
977 almx = -vars->wnmin;
978 } else {
979 almx = vars->wnmax;
980 }
981
982 /* starting values for findu, cutoff */
983 utx = 16.0 / wnstd;
984 up = 4.5 / wnstd;
985 un = -up;
986
987 /* truncation point with no convergence factor */
988 findu_twospect( vars, &utx, 0.5 * acc1 );
989
990 /* does convergence factor help? */
991 if ( vars->c != 0.0 && almx > 0.07 * wnstd ) {
992 tausq = 0.25 * acc1 / coeff_twospect( vars, vars->c );
993 if ( vars->fail ) {
994 vars->fail = 0;
995 } else if ( truncation_twospect( vars, utx, tausq ) < 0.2 * acc1 ) {
996 vars->sigsq += tausq;
997 findu_twospect( vars, &utx, 0.25 * acc1 );
998 }
999 }
1000 acc1 *= 0.5;
1001
1002 BOOLEAN contin = 1;
1003
1004 /* find RANGE of distribution, quit if outside this */
1005 while ( contin ) {
1006 d1 = cutoff_twospect( vars, acc1, &up ) - vars->c;
1007 if ( d1 < 0.0 ) {
1008 qfval = 1.0;
1009 return qfval;
1010 }
1011 d2 = vars->c - cutoff_twospect( vars, acc1, &un );
1012 if ( d2 < 0.0 ) {
1013 qfval = 0.0;
1014 return qfval;
1015 }
1016
1017 /* find integration interval */
1018 if ( d1 > d2 ) {
1019 intv = LAL_TWOPI / d1;
1020 } else {
1021 intv = LAL_TWOPI / d2;
1022 }
1023
1024 /* calculate number of terms required for main and auxillary integrations */
1025 xnt = utx / intv;
1026 xntm = 3.0 / sqrt( acc1 );
1027
1028 if ( xnt > xntm * 1.5 ) {
1029 //parameters for auxillary integration
1030 if ( xntm > xlim ) {
1031 *ifault = 1;
1032 return qfval;
1033 }
1034 ntm = ( INT4 )round( xntm );
1035 intv1 = utx / ntm;
1036 x = LAL_TWOPI / intv1;
1037 if ( x <= fabs( vars->c ) ) {
1038 contin = 0;
1039 } else {
1040 //calculate convergence factor
1041 REAL8 coeffvalplusx = coeff_twospect( vars, vars->c + x );
1042 REAL8 coeffvalminusx = coeff_twospect( vars, vars->c - x );
1043 tausq = acc1 / ( 1.1 * ( coeffvalminusx + coeffvalplusx ) * 3.0 );
1044 if ( vars->fail ) {
1045 contin = 0;
1046 } else {
1047 acc1 = ( 2.0 / 3.0 ) * acc1;
1048
1049 //auxillary integration
1050 //fprintf(stderr,"Num terms in auxillary integration %d\n", ntm);
1051 XLAL_CHECK_REAL8( fast_integrate_twospect2( vars, ntm, intv1, tausq, 0 ) == XLAL_SUCCESS, XLAL_EFUNC );
1052 xlim -= xntm;
1053 vars->sigsq += tausq;
1054
1055 //find truncation point with new convergence factor
1056 findu_twospect( vars, &utx, 0.25 * acc1 );
1057 acc1 *= 0.75;
1058 }
1059 }
1060 } else {
1061 contin = 0;
1062 }
1063 }
1064
1065 /* main integration */
1066 if ( xnt > xlim ) {
1067 *ifault = 1;
1068 return qfval;
1069 }
1070 nt = ( INT4 )round( xnt ); //number of terms in main integration
1071 XLAL_CHECK_REAL8( fast_integrate_twospect2( vars, nt, intv, 0.0, 1 ) == XLAL_SUCCESS, XLAL_EFUNC );
1072 qfval = 0.5 - vars->integrationValue;
1073
1074 /* test whether round-off error could be significant allow for radix 8 or 16 machines */
1075 up = vars->integrationError;
1076 x = up + 0.1 * acc;
1077 for ( UINT4 ii = 0; ii < 4; ii++ ) {
1078 if ( rats[ii] * x == rats[ii] * up ) {
1079 *ifault = 2;
1080 }
1081 }
1082
1083 return qfval;
1084} /* cdfwchisq_twospect() */
#define __func__
log an I/O error, i.e.
const double c1
const double c2
#define fprintf
REAL8 truncation(qfvars *vars, REAL8 u, REAL8 tausq)
Definition: cdfwchisq.c:222
void integrate_twospect2(qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx)
Definition: cdfwchisq.c:524
void findu_twospect(qfvars *vars, REAL8 *utx, REAL8 accx)
Definition: cdfwchisq.c:385
REAL8 coeff(qfvars *vars, REAL8 x)
Definition: cdfwchisq.c:620
REAL8 cutoff(qfvars *vars, REAL8 accx, REAL8 *upn)
Definition: cdfwchisq.c:140
void integrate_twospect(qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx)
Definition: cdfwchisq.c:457
REAL8 cdfwchisq(qfvars *vars, REAL8 sigma, REAL8 acc, INT4 *ifault)
Definition: cdfwchisq.c:751
REAL8 twospect_log_1plusx_mx(REAL8 x)
Definition: cdfwchisq.c:49
REAL8 twospect_log_1plusx(REAL8 x)
Definition: cdfwchisq.c:45
void findu(qfvars *vars, REAL8 *utx, REAL8 accx)
Definition: cdfwchisq.c:349
REAL8 cutoff_twospect(qfvars *vars, REAL8 accx, REAL8 *upn)
Definition: cdfwchisq.c:180
REAL8 truncation_twospect(qfvars *vars, REAL8 u, REAL8 tausq)
Definition: cdfwchisq.c:289
INT4 fast_integrate_twospect2(qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx)
Definition: cdfwchisq.c:558
REAL8 cdfwchisq_twospect(qfvars *vars, REAL8 sigma, REAL8 acc, INT4 *ifault)
Definition: cdfwchisq.c:917
void integrate_eg(qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx)
Definition: cdfwchisq.c:492
REAL8 coeff_twospect(qfvars *vars, REAL8 x)
Definition: cdfwchisq.c:682
REAL8 exp1(REAL8 x)
Definition: cdfwchisq.c:35
int compar(void *p, const void *a, const void *b)
Definition: cdfwchisq.c:67
void order(qfvars *vars)
Definition: cdfwchisq.c:56
REAL8 errbound_twospect(qfvars *vars, REAL8 u, REAL8 *cx)
Definition: cdfwchisq.c:117
void integrate(qfvars *vars, INT4 nterm, REAL8 interv, REAL8 tausq, INT4 mainx)
Definition: cdfwchisq.c:421
REAL8 errbound(qfvars *vars, REAL8 u, REAL8 *cx)
Definition: cdfwchisq.c:94
const double u
const double u2
#define LAL_LN2
#define LAL_PI
#define LAL_1_PI
#define LAL_TWOPI
unsigned char BOOLEAN
double REAL8
uint32_t UINT4
int32_t INT4
static const INT4 a
int XLALHeapIndex(INT4 *indx, void *base, UINT4 nobj, UINT4 size, void *params, int(*compar)(void *, const void *, const void *))
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_VOID(assertion,...)
#define XLAL_CHECK_REAL8(assertion,...)
XLAL_SUCCESS
XLAL_EFUNC
list y
INT4 * data
REAL8 * data
REAL8 wnmax
Definition: cdfwchisq.h:28
INT4Vector * dofs
Definition: cdfwchisq.h:39
REAL8 integrationValue
Definition: cdfwchisq.h:32
INT4Vector * sorting
Definition: cdfwchisq.h:40
INT4 count
Definition: cdfwchisq.h:34
REAL8Vector * noncentrality
Definition: cdfwchisq.h:42
REAL8 wnmean
Definition: cdfwchisq.h:30
REAL8 sigsq
Definition: cdfwchisq.h:27
INT4 arrayNotSorted
Definition: cdfwchisq.h:36
REAL8 wnmin
Definition: cdfwchisq.h:29
INT4 fail
Definition: cdfwchisq.h:37
INT4 lim
Definition: cdfwchisq.h:35
REAL8 integrationError
Definition: cdfwchisq.h:33
REAL8 c
Definition: cdfwchisq.h:31
INT4 vectorMath
Definition: cdfwchisq.h:38
alignedREAL8Vector * weights
Definition: cdfwchisq.h:41
INT4 VectorShiftREAL8(alignedREAL8Vector *output, alignedREAL8Vector *input, REAL8 shift, INT4 vectorMath)
Definition: vectormath.c:269
void destroyAlignedREAL8Vector(alignedREAL8Vector *vector)
Definition: vectormath.c:67
INT4 VectorInvertREAL8(alignedREAL8Vector *output, alignedREAL8Vector *input, INT4 vectorMath)
Definition: vectormath.c:321
INT4 VectorScaleREAL8(alignedREAL8Vector *output, alignedREAL8Vector *input, REAL8 scale, INT4 vectorMath)
Definition: vectormath.c:256
alignedREAL8Vector * createAlignedREAL8Vector(UINT4 length, const size_t align)
Definition: vectormath.c:55
INT4 VectorMultiplyREAL8(alignedREAL8Vector *output, alignedREAL8Vector *input1, alignedREAL8Vector *input2, INT4 vectorMath)
Definition: vectormath.c:308