LALGSLTest.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Jolien Creighton
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /**** <lalVerbatim file="LALGSLTestCV">
00021  * Author: Creighton, J. D. E.
00022  * $Id: LALGSLTest.c,v 1.3 2007/06/08 14:41:54 bema Exp $
00023  **** </lalVerbatim> */
00024 
00025 /* <lalLaTeX>
00026 \subsection{Program \texttt{LALGSLTest.c}}
00027 \label{ss:LALGSLTest.c}
00028 
00029 This program tests the LAL macros for GSL function calls.  It makes sure
00030 that a nominal status is returned if the GSL function succeeds, and that
00031 an error code is returned if the GSL function fails.
00032 
00033 \vfill{\footnotesize\input{LALGSLTestCV}}
00034 </lalLaTeX> */
00035 
00036 #include <math.h>
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <lal/LALStdlib.h>
00040 #include <lal/LALGSL.h>
00041 #include <lal/LALConstants.h>
00042 #include <gsl/gsl_sf.h>
00043 #include <gsl/gsl_integration.h>
00044 #include <gsl/gsl_errno.h>
00045 
00046 NRCSID( LALGSLTESTC, "$Id: LALGSLTest.c,v 1.3 2007/06/08 14:41:54 bema Exp $" );
00047 
00048 /* macro for testing status */
00049 #define TESTSTATUS( pstatus, code ) \
00050   if ( (pstatus)->statusCode != code ) { REPORTSTATUS(pstatus); exit(1); } \
00051   else ((void)(0))
00052 
00053 /* macro for testing handler */
00054 extern gsl_error_handler_t *gsl_error_handler;
00055 gsl_error_handler_t *original_handler;
00056 #define TESTHANDLER \
00057   if ( original_handler != gsl_error_handler ) \
00058     { fprintf( stderr, "Error: handler was not restored!\n" ); exit(2); } \
00059   else ((void)(0))
00060 
00061 /* function for clearing status pointer */
00062 static void ClearStatus( LALStatus *status )
00063 {
00064   if ( status->statusPtr )
00065   {
00066     ClearStatus( status->statusPtr );
00067     DETATCHSTATUSPTR( status );
00068   }
00069   return;
00070 }
00071 
00072 
00073 /*
00074  *
00075  * Basic tests: call the logarithm with both positive and negative values.
00076  *
00077  */
00078 
00079 
00080 /* call the GSL log routine to test the GSL macros */
00081 static void Logarithm( LALStatus *status, REAL8 *output, REAL8 input )
00082 {
00083   INITSTATUS( status, "Logarithm", LALGSLTESTC );
00084   ATTATCHSTATUSPTR( status );
00085 
00086   CALLGSL( *output = gsl_sf_log( input ), status );
00087   CHECKSTATUSPTR( status );
00088 
00089   /* just for fun, use the TRYGSL macro to do the same thing too */
00090   TRYGSL( *output = gsl_sf_log( input ), status );
00091 
00092   DETATCHSTATUSPTR( status );
00093   RETURN( status );
00094 }
00095 
00096 
00097 /*
00098  *
00099  * More complex tests: integrate the Heaviside function, but code the
00100  * Heaviside function stupidly so that it can cause failures.  This tests
00101  * that the GSL-macros are reenterant-safe.
00102  *
00103  */
00104 
00105 
00106 /* here is a really stupid Heaviside function: take the log of x;
00107  * return 1 if no error otherwise return 0 */
00108 static double Heaviside( double x, void * params )
00109 {
00110   LALStatus newStatus;
00111   double dummy;
00112   double ans;
00113 
00114   params = NULL;
00115 
00116   /* blank the new status structure */
00117   memset( &newStatus, 0, sizeof( newStatus ) );
00118 
00119   /* call the LAL function */
00120   Logarithm( &newStatus, &dummy, x );
00121   if ( newStatus.statusCode )
00122   {
00123     ClearStatus( &newStatus );
00124     ans = 0;
00125   }
00126   else
00127     ans = 1;
00128 
00129   return ans;
00130 }
00131 
00132 static void Integral( LALStatus *status, REAL8 *y, REAL8 a, REAL8 b, REAL8 eps )
00133 {
00134   gsl_integration_workspace *work = NULL;
00135   gsl_function F;
00136   REAL8  err;
00137   INITSTATUS( status, "Integral", LALGSLTESTC );
00138   ATTATCHSTATUSPTR( status );
00139 
00140   F.function = &Heaviside;
00141   F.params   = NULL;
00142 
00143   TRYGSL( work = gsl_integration_workspace_alloc( 100 ), status );
00144   CALLGSL( gsl_integration_qags( &F, a, b, eps, eps, 100, work, y, &err ),
00145       status );
00146   BEGINFAIL( status )
00147     TRYGSL( gsl_integration_workspace_free( work ), status );
00148   ENDFAIL( status );
00149   TRYGSL( gsl_integration_workspace_free( work ), status );
00150 
00151   /* if eps is set too small the integration is supposed to fail, but on
00152    * some systems it may happen that it doesn't... in this case, just make
00153    * this routine fail with a recursive error */
00154   if ( eps < LAL_REAL8_EPS )
00155   {
00156     TRY( Logarithm( status->statusPtr, y, 0 ), status );
00157   }
00158 
00159   DETATCHSTATUSPTR( status );
00160   RETURN( status );
00161 }
00162 
00163 
00164 
00165 int main( void )
00166 {
00167   static LALStatus status;
00168   double x;
00169   double y;
00170 
00171   original_handler = gsl_error_handler;
00172   /* lalDebugLevel = LALTRACE | LALERROR; */
00173 
00174   /* these are simple tests of a LAL routine that calls a GSL function */
00175 
00176   /* this should succeed */
00177   x = 10;
00178   Logarithm( &status, &y, x );
00179   TESTSTATUS( &status, 0 );             /* expect error code 0 */
00180   TESTHANDLER;
00181 
00182   /* this should fail */
00183   x = 0;
00184   Logarithm( &status, &y, x );
00185   TESTSTATUS( &status, -1 );            /* expect error code -1 */
00186   TESTHANDLER;
00187   ClearStatus( &status );
00188 
00189   /* this should succeed again */
00190   x = 10;
00191   Logarithm( &status, &y, x );
00192   TESTSTATUS( &status, 0 );             /* expect error code 0 */
00193   TESTHANDLER;
00194 
00195 
00196   /* these are more complicated tests of a LAL routine that calls a GSL
00197    * function that ultimately calls another LAL function, which in turn
00198    * calls a GSL function... to make sure that everything is reenterant */
00199 
00200   /* this should pass */
00201   Integral( &status, &y, -1, 1, 1e-7 );
00202   TESTSTATUS( &status, 0 );             /* expect error code 0 */
00203   TESTHANDLER;
00204 
00205   /* this should fail */
00206   Integral( &status, &y, -1, 1, LAL_REAL8_MIN );
00207   TESTSTATUS( &status, -1 );             /* expect error code -1 */
00208   TESTHANDLER;
00209   ClearStatus( &status );
00210 
00211   LALCheckMemoryLeaks();
00212 
00213   return 0;
00214 }

Generated on Tue Oct 14 02:31:56 2008 for LAL by  doxygen 1.5.2