LAL  7.5.0.1-fe68b98
ComplexFFTTest.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Duncan Brown, 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 ComplexFFT_h
23  *
24  * \brief Tests the routines in \ref ComplexFFT.h.
25  *
26  * ### Usage ###
27  *
28  * \code
29  * ComplexFFTTest [options]
30  * Options:
31  * -h print this message
32  * -q quiet: run silently
33  * -v verbose: print extra information
34  * -d level set lalDebugLevel to level
35  * \endcode
36  *
37  * ### Exit codes ###
38  *
39  * <table><tr><th>Code</th><th>Explanation</th></tr>
40  * <tr><td>0</td><td>Success, normal exit.</td></tr>
41  * <tr><td>1</td><td>Subroutine failed.</td></tr>
42  * </table>
43  *
44  * ### Uses ###
45  *
46  *
47  * ### Notes ###
48  *
49  */
50 
51 /** \cond DONT_DOXYGEN */
52 #include <config.h>
53 
54 #include <complex.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include <math.h>
59 
60 #include <lal/LALStdlib.h>
61 #include <lal/LALgetopt.h>
62 #include <lal/AVFactories.h>
63 #include <lal/ComplexFFT.h>
64 #include <lal/LALString.h>
65 #include <config.h>
66 
67 #define CODES_(x) #x
68 #define CODES(x) CODES_(x)
69 
70 int verbose = 0;
71 
72 static void
73 Usage( const char *program, int exitflag );
74 
75 static void
76 ParseOptions( int argc, char *argv[] );
77 
78 static void
79 TestStatus( LALStatus *status, const char *expectedCodes, int exitCode );
80 
81 int
82 main( int argc, char *argv[] )
83 {
84  const UINT4 n = 17;
85 #if LAL_CUDA_ENABLED
86  const REAL4 eps = 1e-4;
87 #else
88  const REAL4 eps = 1e-6;
89 #endif
90 
91  static LALStatus status;
92  ComplexFFTPlan *pfwd = NULL;
93  ComplexFFTPlan *prev = NULL;
94  COMPLEX8Vector *avec = NULL;
95  COMPLEX8Vector *bvec = NULL;
96  COMPLEX8Vector *cvec = NULL;
97 
98  FILE *fp;
99  UINT4 i;
100 
101 
102  ParseOptions( argc, argv );
103 
104  fp = verbose ? stdout : NULL ;
105 
106  LALCCreateVector( &status, &avec, n );
107  TestStatus( &status, CODES( 0 ), 1 );
108 
109  LALCCreateVector( &status, &bvec, n );
110  TestStatus( &status, CODES( 0 ), 1 );
111 
112  LALCCreateVector( &status, &cvec, n );
113  TestStatus( &status, CODES( 0 ), 1 );
114 
115  pfwd = XLALCreateForwardCOMPLEX8FFTPlan( n, 0 );
116 
117  prev = XLALCreateReverseCOMPLEX8FFTPlan( n, 0 );
118 
119 
120  for ( i = 0; i < n; ++i )
121  {
122  avec->data[i] = rand() % 5 - 2;
123  avec->data[i] += I * (rand() % 3 - 1);
124  fp ? fprintf( fp, "%+.0f\t%+.0f\n", crealf(avec->data[i]), cimagf(avec->data[i]) )
125  : 0;
126  }
127  fp ? fprintf( fp, "\n" ) : 0;
128  fflush( stdout );
129 
130  XLALCOMPLEX8VectorFFT( bvec, avec, pfwd );
131 
132  for ( i = 0; i < n; ++i )
133  {
134  fp ? fprintf( fp, "%+f\t%+f\n", crealf(bvec->data[i]), cimagf(bvec->data[i]) ) : 0;
135  }
136  fp ? fprintf( fp, "\n" ) : 0;
137  fflush( stdout );
138 
139  XLALCOMPLEX8VectorFFT( cvec, bvec, prev );
140 
141  for ( i = 0; i < n; ++i )
142  {
143  cvec->data[i] /= n;
144  fp ? fprintf( fp, "%+.0f\t%+.0f\n", crealf(cvec->data[i]), cimagf(cvec->data[i]) )
145  : 0;
146  fflush( stdout );
147  if ( fabs( creal(avec->data[i] - cvec->data[i]) ) > eps )
148  {
149  fprintf( stderr, "FAIL: IFFT( FFT( a[] ) ) not equal to a[].\n" );
150  fprintf( stderr, "Re(avec->data[%d]) = %e\n", i, crealf(avec->data[i]) );
151  fprintf( stderr, "Re(cvec->data[%d]) = %e\n", i, crealf(cvec->data[i]) );
152  return 1;
153  }
154  if ( fabs( cimag(avec->data[i] - cvec->data[i]) ) > eps )
155  {
156  fprintf( stderr, "FAIL: IFFT( FFT( a[] ) ) not equal to a[].\n" );
157  fprintf( stderr, "Im(avec->data[%d]) = %e\n", i, cimagf(avec->data[i]) );
158  fprintf( stderr, "Im(cvec->data[%d]) = %e\n", i, cimagf(cvec->data[i]) );
159  return 1;
160  }
161  }
162 
165 
166  /* Null pointers should be a no-op */
167  prev = NULL;
168  pfwd = NULL;
171 
172  LALCDestroyVector( &status, &cvec );
173  TestStatus( &status, CODES( 0 ), 1 );
174 
175  LALCDestroyVector( &status, &bvec );
176  TestStatus( &status, CODES( 0 ), 1 );
177 
178  LALCDestroyVector( &status, &avec );
179  TestStatus( &status, CODES( 0 ), 1 );
180 
182  return 0;
183 }
184 
185 
186 /*
187  * TestStatus()
188  *
189  * Routine to check that the status code status->statusCode agrees with one of
190  * the codes specified in the space-delimited string ignored; if not,
191  * exit to the system with code exitcode.
192  *
193  */
194 static void
195 TestStatus( LALStatus *status, const char *ignored, int exitcode )
196 {
197  char str[64];
198  char *tok;
199 
200  if ( verbose )
201  {
202  REPORTSTATUS( status );
203  }
204 
205  if ( XLALStringCopy( str, ignored, sizeof( str ) ) )
206  {
207  if ( (tok = strtok( str, " " ) ) )
208  {
209  do
210  {
211  if ( status->statusCode == atoi( tok ) )
212  {
213  return;
214  }
215  }
216  while ( ( tok = strtok( NULL, " " ) ) );
217  }
218  else
219  {
220  if ( status->statusCode == atoi( str ) )
221  {
222  return;
223  }
224  }
225  }
226 
227  fprintf( stderr, "\nExiting to system with code %d\n", exitcode );
228  exit( exitcode );
229 }
230 
231 /*
232  *
233  * Usage()
234  *
235  * Prints a usage message for program program and exits with code exitcode.
236  *
237  */
238 static void
239 Usage( const char *program, int exitcode )
240 {
241  fprintf( stderr, "Usage: %s [options]\n", program );
242  fprintf( stderr, "Options:\n" );
243  fprintf( stderr, " -h print this message\n" );
244  fprintf( stderr, " -q quiet: run silently\n" );
245  fprintf( stderr, " -v verbose: print extra information\n" );
246  fprintf( stderr, " -d level set lalDebugLevel to level\n" );
247  exit( exitcode );
248 }
249 
250 
251 /*
252  * ParseOptions()
253  *
254  * Parses the argc - 1 option strings in argv[].
255  *
256  */
257 static void
258 ParseOptions( int argc, char *argv[] )
259 {
260  FILE *fp;
261 
262  while ( 1 )
263  {
264  int c = -1;
265 
266  c = LALgetopt( argc, argv, "hqvd:" );
267  if ( c == -1 )
268  {
269  break;
270  }
271 
272  switch ( c )
273  {
274  case 'd': /* set debug level */
275  break;
276 
277  case 'v': /* verbose */
278  ++verbose;
279  break;
280 
281  case 'q': /* quiet: run silently (ignore error messages) */
282  fp = freopen( "/dev/null", "w", stderr );
283  if (fp == NULL)
284  {
285  fprintf(stderr, "Error: Unable to open /dev/null\n");
286  exit(1);
287  }
288  fp = freopen( "/dev/null", "w", stdout );
289  if (fp == NULL)
290  {
291  fprintf(stderr, "Error: Unable to open /dev/null\n");
292  exit(1);
293  }
294  break;
295 
296  case 'h':
297  Usage( argv[0], 0 );
298  break;
299 
300  default:
301  Usage( argv[0], 1 );
302  }
303 
304  }
305 
306  if ( LALoptind < argc )
307  {
308  Usage( argv[0], 1 );
309  }
310 
311  return;
312 }
313 
314 /** \endcond */
const char * program
void REPORTSTATUS(LALStatus *status)
Definition: LALError.c:322
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
COMPLEX8FFTPlan * XLALCreateReverseCOMPLEX8FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX8FFTPlan for a reverse transform.
int XLALCOMPLEX8VectorFFT(COMPLEX8Vector *_LAL_RESTRICT_ output, const COMPLEX8Vector *_LAL_RESTRICT_ input, const COMPLEX8FFTPlan *plan)
Perform a COMPLEX8Vector to COMPLEX8Vector FFT.
COMPLEX8FFTPlan * XLALCreateForwardCOMPLEX8FFTPlan(UINT4 size, int measurelvl)
Returns a new COMPLEX8FFTPlan for a forward transform.
#define ComplexFFTPlan
Definition: ComplexFFT.h:83
void XLALDestroyCOMPLEX8FFTPlan(COMPLEX8FFTPlan *plan)
Destroys a COMPLEX8FFTPlan.
uint32_t UINT4
Four-byte unsigned integer.
float REAL4
Single precision real floating-point number (4 bytes).
size_t XLALStringCopy(char *dst, const char *src, size_t size)
Copy sources string src to destination string dst.
Definition: LALString.c:104
static const REAL4 eps
Definition: Random.c:84
void LALCCreateVector(LALStatus *, COMPLEX8Vector **, UINT4)
void LALCDestroyVector(LALStatus *, COMPLEX8Vector **)
Vector of type COMPLEX8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:163
COMPLEX8 * data
Pointer to the data array.
Definition: LALDatatypes.h:168
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
int verbose
Definition: tconvert.c:103
FILE * fp
Definition: tconvert.c:105