Loading [MathJax]/extensions/TeX/AMSmath.js
LAL 7.7.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
IntegrateTest.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton
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/**
21 * \file
22 * \ingroup Integrate_h
23 *
24 * \brief Tests the routines in \ref Integrate_h by performing a suite of numerical
25 * integrations and checking the accuracy of the results.
26 *
27 * ### Usage ###
28 *
29 * \code
30 * IntegrateTest [options]
31 * Options:
32 * -h print this message
33 * -q quiet: run silently
34 * -v verbose: print extra information
35 * -d level set lalDebugLevel to level
36 * \endcode
37 *
38 * ### Exit codes ###
39 *
40 * <table><tr><th>Code</th><th>Explanation</th></tr>
41 * <tr><td>0</td><td>Success, normal exit.</td></tr>
42 * <tr><td>1</td><td>Subroutine failed.</td></tr>
43 * </table>
44 *
45 */
46
47/** \cond DONT_DOXYGEN */
48#include <config.h>
49
50#include <stdio.h>
51#include <string.h>
52#include <stdlib.h>
53#include <math.h>
54
55#include <lal/LALStdlib.h>
56#include <lal/LALgetopt.h>
57#include <lal/Integrate.h>
58#include <lal/LALString.h>
59
60#ifdef __GNUC__
61#define UNUSED __attribute__ ((unused))
62#else
63#define UNUSED
64#endif
65
66#define CODES_(x) #x
67#define CODES(x) CODES_(x)
68
69/*
70 *
71 * These functions are used as integrands for the test integrations.
72 *
73 */
74
75
76static REAL8 xff1 (REAL8 x, void *p)
77{
78 REAL8 y;
79 REAL8 x2 = x*x;
80 REAL8 x4 = x2*x2;
81 INT4 *n;
82 if (p == NULL)
84 ++(*(n = (INT4 *)p));
85 y = x4*log(x + sqrt(x2 + 1));
86 return y;
87}
88
89static REAL8 xff2 (REAL8 x, void *p)
90{
91 REAL8 y;
92 INT4 *n;
93 if (p == NULL)
95 ++(*(n = (INT4 *)p));
96 y = 1/(x*x*x);
97 return y;
98}
99
100static REAL8 xff3 (REAL8 x, void *p)
101{
102 REAL8 y;
103 INT4 *n;
104 if (p == NULL)
106 ++(*(n = (INT4 *)p));
107 y = exp(-x*x/2);
108 return y;
109}
110
111static REAL8 xff4 (REAL8 x, void *p)
112{
113 REAL8 y;
114 INT4 *n;
115 if (p == NULL)
117 ++(*(n = (INT4 *)p));
118 y = 1/sqrt(x);
119 return y;
120}
121
122static REAL8 xff5 (REAL8 x, void *p)
123{
124 REAL8 y;
125 INT4 *n;
126 if (p == NULL)
128 ++(*(n = (INT4 *)p));
129 y = x + 1/sqrt(5 - x);
130 return y;
131}
132
133/*
134 *
135 * This function produces random numbers. Integration of this function should
136 * not converge. Make this routine fast... no status handling!
137 *
138 */
139static REAL8 xbbad (REAL8 UNUSED x, void *p)
140{
141 return (REAL8)(++(*(INT4 *)p));
142}
143
144
145
146int verbose = 0;
147
148static void Usage (const char *program, int exitflag);
149
150static void ParseOptions (int argc, char *argv[]);
151
152int main (int argc, char *argv[])
153{
154 const REAL8 depsilon = 1e-13; /* not as good as expected (1e-15) */
155 REAL8 dresult;
156 long double expect;
157 INT4 count;
158
159 ParseOptions (argc, argv);
160
161
162 /*
163 *
164 * Test 1: Integrate a regular function over a closed interval.
165 *
166 */
167
168
169 if ( verbose )
170 printf ("Test 1:"
171 " Integrate a regular function over a closed interval.\n");
172 count = 0;
173 expect = 8.153364119811650205L;
174 dresult = XLALREAL8RombergIntegrate (&xff1, &count, 0, 2, ClosedInterval);
175 if (xlalErrno)
176 XLAL_ERROR_MAIN(xlalErrno, "xlalErrno=%i (%s) at line %i", xlalErrno, XLALErrorString(xlalErrno), __LINE__);
177 else if (verbose)
178 printf("\nXLALREAL8RombergIntegrate exitted with xlalErrno: %d\n", xlalErrno);
179 if ( verbose )
180 printf ("number of function calls: %d\n", count);
181 if ( verbose )
182 printf ("result: %.15f\n", dresult);
183 if ( verbose )
184 printf ("expect: %.15Lf\n", expect);
185 if (fabsl(dresult - expect) > depsilon*fabsl(expect))
186 {
187 if ( verbose )
188 fprintf (stderr, "Integration did not achieve desired accuracy!\n");
189 return 1;
190 }
191
192
193 /*
194 *
195 * Test 2: Integrate to infinity a function with power-law fall-off.
196 *
197 */
198
199
200 if ( verbose )
201 printf ("\nTest 2:"
202 " Integrate to infinity a function with power-law fall-off.\n");
203 count = 0;
204 expect = 1.0L/200.0L;
205 dresult = XLALREAL8RombergIntegrate (&xff2, &count, 10, 1e300, InfiniteDomainPow);
206 if (xlalErrno)
207 XLAL_ERROR_MAIN(xlalErrno, "xlalErrno=%i (%s) at line %i", xlalErrno, XLALErrorString(xlalErrno), __LINE__);
208 else if (verbose)
209 printf("\nXLALREAL8RombergIntegrate exitted with xlalErrno: %d\n", xlalErrno);
210 if ( verbose )
211 printf ("number of function calls: %d\n", count);
212 if ( verbose )
213 printf ("result: %.15f\n", dresult);
214 if ( verbose )
215 printf ("expect: %.15Lf\n", expect);
216 if (fabsl(dresult - expect) > depsilon*fabsl(expect))
217 {
218 if ( verbose )
219 fprintf (stderr, "Integration did not achieve desired accuracy!\n");
220 return 1;
221 }
222
223
224 /*
225 *
226 * Test 3: Integrate to infinity a function that falls off exponentially.
227 *
228 */
229
230
231 if ( verbose )
232 printf ("\nTest 3:"
233 " Integrate to infinity a function that falls off exponentially.");
234 count = 0;
235 expect = 0.0570261239928920483L;
236 dresult = XLALREAL8RombergIntegrate (&xff3, &count, 2, 1e300, InfiniteDomainExp);
237 if (xlalErrno)
238 XLAL_ERROR_MAIN(xlalErrno, "xlalErrno=%i (%s) at line %i", xlalErrno, XLALErrorString(xlalErrno), __LINE__);
239 else if (verbose)
240 printf("\nXLALREAL8RombergIntegrate exitted with xlalErrno: %d\n", xlalErrno);
241 if ( verbose )
242 printf ("number of function calls: %d\n", count);
243 if ( verbose )
244 printf ("result: %.15f\n", dresult);
245 if ( verbose )
246 printf ("expect: %.15Lf\n", expect);
247 if (fabsl(dresult - expect) > depsilon*fabsl(expect))
248 {
249 if ( verbose )
250 fprintf (stderr, "Integration did not achieve desired accuracy!\n");
251 return 1;
252 }
253
254
255 /*
256 *
257 * Test 4: Integrate an integrable singularity at the lower limit.
258 *
259 */
260
261
262 if ( verbose )
263 printf ("\nTest 4:"
264 " Integrate an integrable singularity at the lower limit.\n");
265 count = 0;
266 expect = 2.0L;
267 dresult = XLALREAL8RombergIntegrate (&xff4, &count, 0, 1, SingularLowerLimit);
268 if (xlalErrno)
269 XLAL_ERROR_MAIN(xlalErrno, "xlalErrno=%i (%s) at line %i", xlalErrno, XLALErrorString(xlalErrno), __LINE__);
270 else if (verbose)
271 printf("\nXLALREAL8RombergIntegrate exitted with xlalErrno: %d\n", xlalErrno);
272 if ( verbose )
273 printf ("number of function calls: %d\n", count);
274 if ( verbose )
275 printf ("result: %.15f\n", dresult);
276 if ( verbose )
277 printf ("expect: %.15Lf\n", expect);
278 if (fabsl(dresult - expect) > depsilon*fabsl(expect))
279 {
280 if ( verbose )
281 fprintf (stderr, "Integration did not achieve desired accuracy!\n");
282 return 1;
283 }
284
285
286 /*
287 *
288 * Test 5: Integrate an integrable singularity at the upper limit.
289 *
290 */
291
292
293 if ( verbose )
294 printf ("\nTest 5:"
295 " Integrate an integrable singularity at the upper limit.\n");
296 count = 0;
297 expect = 6.5L;
298 dresult = XLALREAL8RombergIntegrate (&xff5, &count, 4, 5, SingularUpperLimit);
299 if (xlalErrno)
300 XLAL_ERROR_MAIN(xlalErrno, "xlalErrno=%i (%s) at line %i", xlalErrno, XLALErrorString(xlalErrno), __LINE__);
301 else if (verbose)
302 printf("\nXLALREAL8RombergIntegrate exitted with xlalErrno: %d\n", xlalErrno);
303 if ( verbose )
304 printf ("number of function calls: %d\n", count);
305 if ( verbose )
306 printf ("result: %.15f\n", dresult);
307 if ( verbose )
308 printf ("expect: %.15Lf\n", expect);
309 if (fabsl(dresult - expect) > depsilon*fabsl(expect))
310 {
311 if ( verbose )
312 fprintf (stderr, "Integration did not achieve desired accuracy!\n");
313 return 1;
314 }
315
316
318
319
320 /*
321 *
322 * Check error conditions.
323 *
324 */
325
326 if ( verbose )
327 printf ("\nChecking error conditions:\n");
328
329 if ( verbose )
330 printf ("\nUnknown integral type:\r");
331 dresult = XLALREAL8RombergIntegrate (&xff1, &count, 0, 2, 999);
332 if (xlalErrno == XLAL_EINVAL)
333 xlalErrno = 0;
334 else
335 XLAL_ERROR_MAIN(xlalErrno, "xlalErrno=%i (%s) at line %i", xlalErrno, XLALErrorString(xlalErrno), __LINE__);
336 if ( verbose )
337 printf ("Unknown integral type check passed.\n");
338
339 if ( verbose )
340 printf ("\nMaximum iterations exceeded:\r");
341 dresult = XLALREAL8RombergIntegrate (&xbbad, &count, 0, 2, ClosedInterval);
343 xlalErrno = 0;
344 else
345 XLAL_ERROR_MAIN(xlalErrno, "xlalErrno=%i (%s) at line %i", xlalErrno, XLALErrorString(xlalErrno), __LINE__);
346 if ( verbose )
347 printf ("Maximum iterations exceeded check passed.\n");
348
349 if ( verbose )
350 printf ("\nRecursive error:\r");
351 dresult = XLALREAL8RombergIntegrate (&xff1, NULL, 0, 2, ClosedInterval);
353 xlalErrno = 0;
354 else
355 XLAL_ERROR_MAIN(xlalErrno, "xlalErrno=%i (%s) at line %i", xlalErrno, XLALErrorString(xlalErrno), __LINE__);
356 if ( verbose )
357 printf ("Recursive error check passed.\n");
358
359 return 0;
360}
361
362
363/*
364 * Usage ()
365 *
366 * Prints a usage message for program program and exits with code exitcode.
367 *
368 */
369static void
370Usage (const char *program, int exitcode)
371{
372 fprintf (stderr, "Usage: %s [options]\n", program);
373 fprintf (stderr, "Options:\n");
374 fprintf (stderr, " -h print this message\n");
375 fprintf (stderr, " -q quiet: run silently\n");
376 fprintf (stderr, " -v verbose: print extra information\n");
377 fprintf (stderr, " -d level set lalDebugLevel to level\n");
378 exit (exitcode);
379}
380
381
382/*
383 * ParseOptions ()
384 *
385 * Parses the argc - 1 option strings in argv[].
386 *
387 */
388static void
389ParseOptions (int argc, char *argv[])
390{
391 FILE *fp;
392
393 while (1)
394 {
395 int c = -1;
396
397 c = LALgetopt (argc, argv, "hqvd:");
398 if (c == -1)
399 {
400 break;
401 }
402
403 switch (c)
404 {
405 case 'd': /* set debug level */
406 break;
407
408 case 'v': /* verbose */
409 ++verbose;
410 break;
411
412 case 'q': /* quiet: run silently */
413 fp = freopen ("/dev/null", "w", stderr);
414 if (fp == NULL)
415 {
416 fprintf(stderr, "Error: Unable to open /dev/null\n");
417 exit(1);
418 }
419 fp = freopen ("/dev/null", "w", stdout);
420 if (fp == NULL)
421 {
422 fprintf(stderr, "Error: Unable to open /dev/null\n");
423 exit(1);
424 }
425 break;
426
427 case 'h':
428 Usage (argv[0], 0);
429 break;
430
431 default:
432 Usage (argv[0], 1);
433 }
434
435 }
436
437 if (LALoptind < argc)
438 {
439 Usage (argv[0], 1);
440 }
441
442 return;
443}
444
445/** \endcond */
const char * program
void LALCheckMemoryLeaks(void)
Definition: LALMalloc.c:784
int LALgetopt(int argc, char *const *argv, const char *optstring)
Definition: LALgetopt.c:172
int LALoptind
Definition: LALgetopt.c:79
#define fprintf
static void Usage(const char *program, int exitcode)
Definition: XLALChisqTest.c:70
static void ParseOptions(int argc, char *argv[])
Definition: XLALChisqTest.c:88
int main(int argc, char *argv[])
Definition: cache.c:25
REAL8 XLALREAL8RombergIntegrate(REAL8(*f)(REAL8 x, void *params), void *params, REAL8 xmin, REAL8 xmax, IntegralType type)
Definition: Integrate.c:233
@ InfiniteDomainExp
integrate infinite domain with exponential falloff
Definition: Integrate.h:142
@ ClosedInterval
evaluate integral on a closed interval
Definition: Integrate.h:137
@ SingularLowerLimit
integrate an inv sqrt singularity at lower limit
Definition: Integrate.h:139
@ SingularUpperLimit
integrate an inv sqrt singularity at upper limit
Definition: Integrate.h:140
@ InfiniteDomainPow
integrate infinite domain with power-law falloff
Definition: Integrate.h:141
double REAL8
Double precision real floating-point number (8 bytes).
int32_t INT4
Four-byte signed integer.
const char * XLALErrorString(int code)
Returns the error message associated with an error number.
Definition: XLALError.c:409
#define XLAL_ERROR_REAL8(...)
Macro to invoke a failure from a XLAL routine returning a REAL8.
Definition: XLALError.h:752
#define xlalErrno
Modifiable lvalue containing the XLAL error number.
Definition: XLALError.h:571
#define XLAL_ERROR_MAIN(...)
Macro to invoke a failure from a C main() routine.
Definition: XLALError.h:765
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_EMAXITER
Exceeded maximum number of iterations.
Definition: XLALError.h:455
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409
int verbose
Definition: tconvert.c:103
FILE * fp
Definition: tconvert.c:105