Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALGSLTest.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 LALGSL_h
23 * \author Creighton, J. D. E.
24 *
25 * This program tests the LAL macros for GSL function calls. It makes sure
26 * that a nominal status is returned if the GSL function succeeds, and that
27 * an error code is returned if the GSL function fails.
28 *
29 */
30
31/** \cond DONT_DOXYGEN */
32
33#include <math.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <lal/LALStdlib.h>
37#include <lal/LALGSL.h>
38#include <lal/LALConstants.h>
39#include <gsl/gsl_sf.h>
40#include <gsl/gsl_integration.h>
41#include <gsl/gsl_errno.h>
42
43#ifdef __GNUC__
44#define UNUSED __attribute__ ((unused))
45#else
46#define UNUSED
47#endif
48
49/* macro for testing status */
50#define TESTSTATUS( pstatus, code ) \
51 if ( (pstatus)->statusCode != code ) { REPORTSTATUS(pstatus); exit(1); } \
52 else ((void)(0))
53
54/* macro for testing handler */
55extern gsl_error_handler_t *gsl_error_handler;
56gsl_error_handler_t *original_handler;
57#define TESTHANDLER \
58 if ( original_handler != gsl_error_handler ) \
59 { fprintf( stderr, "Error: handler was not restored!\n" ); exit(2); } \
60 else ((void)(0))
61
62/* function for clearing status pointer */
63static void ClearStatus( LALStatus *status )
64{
65 if ( status->statusPtr )
66 {
67 ClearStatus( status->statusPtr );
69 }
70 return;
71}
72
73
74/*
75 *
76 * Basic tests: call the logarithm with both positive and negative values.
77 *
78 */
79
80
81/* call the GSL log routine to test the GSL macros */
82static void Logarithm( LALStatus *status, REAL8 *output, REAL8 input )
83{
86
87 CALLGSL( *output = gsl_sf_log( input ), status );
89
90 /* just for fun, use the TRYGSL macro to do the same thing too */
91 TRYGSL( *output = gsl_sf_log( input ), status );
92
94 RETURN( status );
95}
96
97
98/*
99 *
100 * More complex tests: integrate the Heaviside function, but code the
101 * Heaviside function stupidly so that it can cause failures. This tests
102 * that the GSL-macros are reenterant-safe.
103 *
104 */
105
106
107/* here is a really stupid Heaviside function: take the log of x;
108 * return 1 if no error otherwise return 0 */
109static double Heaviside( double x, void UNUSED * params )
110{
111 LALStatus newStatus;
112 double dummy;
113 double ans;
114
115 /* blank the new status structure */
116 memset( &newStatus, 0, sizeof( newStatus ) );
117
118 /* call the LAL function */
119 Logarithm( &newStatus, &dummy, x );
120 if ( newStatus.statusCode )
121 {
122 ClearStatus( &newStatus );
123 ans = 0;
124 }
125 else
126 ans = 1;
127
128 return ans;
129}
130
131static void Integral( LALStatus *status, REAL8 *y, REAL8 a, REAL8 b, REAL8 eps )
132{
133 gsl_integration_workspace *work = NULL;
134 gsl_function F;
135 REAL8 err;
138
139 F.function = &Heaviside;
140 F.params = NULL;
141
142 TRYGSL( work = gsl_integration_workspace_alloc( 100 ), status );
143 CALLGSL( gsl_integration_qags( &F, a, b, eps, eps, 100, work, y, &err ),
144 status );
146 TRYGSL( gsl_integration_workspace_free( work ), status );
147 ENDFAIL( status );
148 TRYGSL( gsl_integration_workspace_free( work ), status );
149
150 /* if eps is set too small the integration is supposed to fail, but on
151 * some systems it may happen that it doesn't... in this case, just make
152 * this routine fail with a recursive error */
153 if ( eps < LAL_REAL8_EPS )
154 {
155 TRY( Logarithm( status->statusPtr, y, 0 ), status );
156 }
157
159 RETURN( status );
160}
161
162
163
164int main( void )
165{
166 static LALStatus status;
167 double x;
168 double y;
169
170 original_handler = gsl_error_handler;
171
172 /* these are simple tests of a LAL routine that calls a GSL function */
173
174 /* this should succeed */
175 x = 10;
176 Logarithm( &status, &y, x );
177 TESTSTATUS( &status, 0 ); /* expect error code 0 */
178 TESTHANDLER;
179
180 /* this should fail */
181 x = 0;
182 Logarithm( &status, &y, x );
183 TESTSTATUS( &status, -1 ); /* expect error code -1 */
184 TESTHANDLER;
185 ClearStatus( &status );
186
187 /* this should succeed again */
188 x = 10;
189 Logarithm( &status, &y, x );
190 TESTSTATUS( &status, 0 ); /* expect error code 0 */
191 TESTHANDLER;
192
193
194 /* these are more complicated tests of a LAL routine that calls a GSL
195 * function that ultimately calls another LAL function, which in turn
196 * calls a GSL function... to make sure that everything is reenterant */
197
198 /* this should pass */
199 Integral( &status, &y, -1, 1, 1e-7 );
200 TESTSTATUS( &status, 0 ); /* expect error code 0 */
201 TESTHANDLER;
202
203 /* this should fail */
204 Integral( &status, &y, -1, 1, LAL_REAL8_MIN );
205 TESTSTATUS( &status, -1 ); /* expect error code -1 */
206 TESTHANDLER;
207 ClearStatus( &status );
208
210
211 return 0;
212}
213
214/** \endcond */
#define TESTSTATUS(s)
#define TRYGSL(statement, statusptr)
Definition: LALGSL.h:135
#define CALLGSL(statement, statusptr)
Definition: LALGSL.h:115
void LALCheckMemoryLeaks(void)
Definition: LALMalloc.c:784
#define CHECKSTATUSPTR(statusptr)
#define ENDFAIL(statusptr)
#define TRY(func, statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define BEGINFAIL(statusptr)
int main(int argc, char *argv[])
Definition: cache.c:25
#define LAL_REAL8_EPS
Difference between 1 and the next resolvable REAL8 2^-52.
Definition: LALConstants.h:61
#define LAL_REAL8_MIN
Smallest normalized REAL8 number 2^-1022.
Definition: LALConstants.h:60
double REAL8
Double precision real floating-point number (8 bytes).
static const REAL4 eps
Definition: Random.c:84
static const INT4 a
Definition: Random.c:79
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
INT4 statusCode
A numerical code identifying the type of error, or 0 for nominal status; Negative values are reserved...
Definition: LALDatatypes.h:948
void output(int gps_sec, int output_type)
Definition: tconvert.c:440