00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <stdio.h>
00060 #include <stdlib.h>
00061 #include <string.h>
00062 #include <math.h>
00063 #include <lal/LALConfig.h>
00064
00065 #ifdef HAVE_UNISTD_H
00066 #include <unistd.h>
00067 #endif
00068
00069 #ifdef HAVE_GETOPT_H
00070 #include <getopt.h>
00071 #endif
00072
00073 #include <lal/LALStdlib.h>
00074 #include <lal/AVFactories.h>
00075 #include <lal/ComplexFFT.h>
00076
00077 #define CODES_(x) #x
00078 #define CODES(x) CODES_(x)
00079
00080 NRCSID( MAIN, "$Id: ComplexFFTTest.c,v 1.14 2007/06/08 14:41:44 bema Exp $" );
00081
00082 extern char *optarg;
00083 extern int optind;
00084
00085 int lalDebugLevel = 0;
00086 int verbose = 0;
00087
00088 static void
00089 Usage( const char *program, int exitflag );
00090
00091 static void
00092 ParseOptions( int argc, char *argv[] );
00093
00094 static void
00095 TestStatus( LALStatus *status, const char *expectedCodes, int exitCode );
00096
00097 static void
00098 ClearStatus( LALStatus *status );
00099
00100 static void
00101 CheckErrorCodes( void );
00102
00103 int
00104 main( int argc, char *argv[] )
00105 {
00106 const UINT4 n = 17;
00107 const REAL4 eps = 1e-6;
00108
00109 static LALStatus status;
00110 ComplexFFTPlan *pfwd = NULL;
00111 ComplexFFTPlan *prev = NULL;
00112 COMPLEX8Vector *avec = NULL;
00113 COMPLEX8Vector *bvec = NULL;
00114 COMPLEX8Vector *cvec = NULL;
00115
00116 FILE *fp;
00117 UINT4 i;
00118
00119 ParseOptions( argc, argv );
00120
00121 fp = verbose ? stdout : NULL ;
00122
00123 LALCCreateVector( &status, &avec, n );
00124 TestStatus( &status, CODES( 0 ), 1 );
00125
00126 LALCCreateVector( &status, &bvec, n );
00127 TestStatus( &status, CODES( 0 ), 1 );
00128
00129 LALCCreateVector( &status, &cvec, n );
00130 TestStatus( &status, CODES( 0 ), 1 );
00131
00132 LALCreateForwardComplexFFTPlan( &status, &pfwd, n, 0 );
00133 TestStatus( &status, CODES( 0 ), 1 );
00134
00135 LALCreateReverseComplexFFTPlan( &status, &prev, n, 0 );
00136 TestStatus( &status, CODES( 0 ), 1 );
00137
00138
00139 for ( i = 0; i < n; ++i )
00140 {
00141 avec->data[i].im = rand() % 5 - 2;
00142 avec->data[i].re = rand() % 3 - 1;
00143 fp ? fprintf( fp, "%+.0f\t%+.0f\n", avec->data[i].re, avec->data[i].im )
00144 : 0;
00145 }
00146 fp ? fprintf( fp, "\n" ) : 0;
00147 fflush( stdout );
00148
00149 LALCOMPLEX8VectorFFT( &status, bvec, avec, pfwd );
00150 TestStatus( &status, CODES( 0 ), 1 );
00151
00152 for ( i = 0; i < n; ++i )
00153 {
00154 fp ? fprintf( fp, "%+f\t%+f\n", bvec->data[i].re, bvec->data[i].im ) : 0;
00155 }
00156 fp ? fprintf( fp, "\n" ) : 0;
00157 fflush( stdout );
00158
00159 LALCOMPLEX8VectorFFT( &status, cvec, bvec, prev );
00160 TestStatus( &status, CODES( 0 ), 1 );
00161
00162 for ( i = 0; i < n; ++i )
00163 {
00164 cvec->data[i].re /= n;
00165 cvec->data[i].im /= n;
00166 fp ? fprintf( fp, "%+.0f\t%+.0f\n", cvec->data[i].re, cvec->data[i].im )
00167 : 0;
00168 fflush( stdout );
00169 if ( fabs( avec->data[i].re - cvec->data[i].re ) > eps )
00170 {
00171 fprintf( stderr, "FAIL: IFFT( FFT( a[] ) ) not equal to a[].\n" );
00172 fprintf( stderr, "avec->data[%d].re = %e\n", i, avec->data[i].re );
00173 fprintf( stderr, "cvec->data[%d].re = %e\n", i, cvec->data[i].re );
00174 return 1;
00175 }
00176 if ( fabs( avec->data[i].im - cvec->data[i].im ) > eps )
00177 {
00178 fprintf( stderr, "FAIL: IFFT( FFT( a[] ) ) not equal to a[].\n" );
00179 fprintf( stderr, "avec->data[%d].im = %e\n", i, avec->data[i].im );
00180 fprintf( stderr, "cvec->data[%d].im = %e\n", i, cvec->data[i].im );
00181 return 1;
00182 }
00183 }
00184
00185 LALDestroyComplexFFTPlan( &status, &prev );
00186 TestStatus( &status, CODES( 0 ), 1 );
00187
00188 LALDestroyComplexFFTPlan( &status, &pfwd );
00189 TestStatus( &status, CODES( 0 ), 1 );
00190
00191 LALCDestroyVector( &status, &cvec );
00192 TestStatus( &status, CODES( 0 ), 1 );
00193
00194 LALCDestroyVector( &status, &bvec );
00195 TestStatus( &status, CODES( 0 ), 1 );
00196
00197 LALCDestroyVector( &status, &avec );
00198 TestStatus( &status, CODES( 0 ), 1 );
00199
00200 fp ? fprintf( fp, "\nChecking error codes:\n\n" ) : 0;
00201 CheckErrorCodes();
00202
00203 LALCheckMemoryLeaks();
00204 return 0;
00205 }
00206
00207
00208 struct
00209 tagComplexFFTPlan
00210 {
00211 INT4 sign;
00212 UINT4 size;
00213 void *plan;
00214 };
00215
00216 static void
00217 CheckErrorCodes( void )
00218 {
00219 #ifndef LAL_NDEBUG
00220 enum { Size = 19 };
00221 const UINT4 size = Size;
00222 static LALStatus status;
00223 ComplexFFTPlan *plan;
00224 ComplexFFTPlan aplan;
00225 COMPLEX8Vector avec;
00226 COMPLEX8Vector bvec;
00227 COMPLEX8 adat[Size];
00228 COMPLEX8 bdat[Size];
00229
00230 if ( ! lalNoDebug )
00231 {
00232 aplan.size = size;
00233
00234 LALCreateForwardComplexFFTPlan( &status, NULL, size, 0 );
00235 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00236 LALCreateReverseComplexFFTPlan( &status, NULL, size, 0 );
00237 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00238
00239 plan = &aplan;
00240 LALCreateForwardComplexFFTPlan( &status, &plan, size, 0 );
00241 TestStatus( &status, CODES( COMPLEXFFTH_ENNUL ), 1 );
00242 LALCreateReverseComplexFFTPlan( &status, &plan, size, 0 );
00243 TestStatus( &status, CODES( COMPLEXFFTH_ENNUL ), 1 );
00244
00245 plan = NULL;
00246 LALCreateForwardComplexFFTPlan( &status, &plan, 0, 0 );
00247 TestStatus( &status, CODES( COMPLEXFFTH_ESIZE ), 1 );
00248 LALCreateReverseComplexFFTPlan( &status, &plan, 0, 0 );
00249 TestStatus( &status, CODES( COMPLEXFFTH_ESIZE ), 1 );
00250
00251 LALDestroyComplexFFTPlan( &status, &plan );
00252 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00253 LALDestroyComplexFFTPlan( &status, NULL );
00254 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00255
00256 plan = &aplan;
00257 avec.length = size;
00258 bvec.length = size;
00259 avec.data = adat;
00260 bvec.data = bdat;
00261 LALCOMPLEX8VectorFFT( &status, NULL, &avec, plan );
00262 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00263 LALCOMPLEX8VectorFFT( &status, &bvec, NULL, plan );
00264 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00265 LALCOMPLEX8VectorFFT( &status, &bvec, &avec, NULL );
00266 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00267
00268 avec.data = NULL;
00269 bvec.data = bdat;
00270 LALCOMPLEX8VectorFFT( &status, &bvec, &avec, plan );
00271 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00272
00273 avec.data = adat;
00274 bvec.data = NULL;
00275 LALCOMPLEX8VectorFFT( &status, &bvec, &avec, plan );
00276 TestStatus( &status, CODES( COMPLEXFFTH_ENULL ), 1 );
00277
00278 avec.data = adat;
00279 bvec.data = adat;
00280 LALCOMPLEX8VectorFFT( &status, &bvec, &avec, plan );
00281 TestStatus( &status, CODES( COMPLEXFFTH_ESAME ), 1 );
00282
00283 aplan.size = 0;
00284 avec.data = adat;
00285 avec.data = bdat;
00286 LALCOMPLEX8VectorFFT( &status, &bvec, &avec, plan );
00287 TestStatus( &status, CODES( COMPLEXFFTH_ESIZE ), 1 );
00288
00289 aplan.size = size;
00290 avec.length = 0;
00291 bvec.length = size;
00292 LALCOMPLEX8VectorFFT( &status, &bvec, &avec, plan );
00293 TestStatus( &status, CODES( COMPLEXFFTH_ESZMM ), 1 );
00294
00295 aplan.size = size;
00296 avec.length = size;
00297 bvec.length = 0;
00298 LALCOMPLEX8VectorFFT( &status, &bvec, &avec, plan );
00299 TestStatus( &status, CODES( COMPLEXFFTH_ESZMM ), 1 );
00300 }
00301 #endif
00302
00303 return;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 static void
00316 TestStatus( LALStatus *status, const char *ignored, int exitcode )
00317 {
00318 char str[64];
00319 char *tok;
00320
00321 if ( verbose )
00322 {
00323 REPORTSTATUS( status );
00324 }
00325
00326 if ( strncpy( str, ignored, sizeof( str ) ) )
00327 {
00328 if ( (tok = strtok( str, " " ) ) )
00329 {
00330 do
00331 {
00332 if ( status->statusCode == atoi( tok ) )
00333 {
00334 return;
00335 }
00336 }
00337 while ( ( tok = strtok( NULL, " " ) ) );
00338 }
00339 else
00340 {
00341 if ( status->statusCode == atoi( tok ) )
00342 {
00343 return;
00344 }
00345 }
00346 }
00347
00348 fprintf( stderr, "\nExiting to system with code %d\n", exitcode );
00349 exit( exitcode );
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 void
00362 ClearStatus( LALStatus *status )
00363 {
00364 if ( status->statusPtr )
00365 {
00366 ClearStatus( status->statusPtr );
00367 DETATCHSTATUSPTR( status );
00368 }
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 static void
00380 Usage( const char *program, int exitcode )
00381 {
00382 fprintf( stderr, "Usage: %s [options]\n", program );
00383 fprintf( stderr, "Options:\n" );
00384 fprintf( stderr, " -h print this message\n" );
00385 fprintf( stderr, " -q quiet: run silently\n" );
00386 fprintf( stderr, " -v verbose: print extra information\n" );
00387 fprintf( stderr, " -d level set lalDebugLevel to level\n" );
00388 exit( exitcode );
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398 static void
00399 ParseOptions( int argc, char *argv[] )
00400 {
00401 while ( 1 )
00402 {
00403 int c = -1;
00404
00405 c = getopt( argc, argv, "hqvd:" );
00406 if ( c == -1 )
00407 {
00408 break;
00409 }
00410
00411 switch ( c )
00412 {
00413 case 'd':
00414 lalDebugLevel = atoi( optarg );
00415 break;
00416
00417 case 'v':
00418 ++verbose;
00419 break;
00420
00421 case 'q':
00422 freopen( "/dev/null", "w", stderr );
00423 freopen( "/dev/null", "w", stdout );
00424 break;
00425
00426 case 'h':
00427 Usage( argv[0], 0 );
00428 break;
00429
00430 default:
00431 Usage( argv[0], 1 );
00432 }
00433
00434 }
00435
00436 if ( optind < argc )
00437 {
00438 Usage( argv[0], 1 );
00439 }
00440
00441 return;
00442 }
00443