Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
549 kaklik 1
# include <stdlib.h>
2
# include <stdio.h>
3
# include <time.h>
4
 
5
# include <fftw3.h>
6
 
7
int main ( void );
8
void test01 ( void );
9
void test02 ( void );
10
void test03 ( void );
11
void test04 ( void );
12
double frand ( void );
13
void timestamp ( void );
14
 
15
/******************************************************************************/
16
 
17
int main ( void )
18
 
19
/******************************************************************************/
20
/*
21
  Purpose:
22
 
23
    FFTW3_PRB demonstrates the use of FFTW3.
24
 
25
  Modified:
26
 
27
    05 November 2007
28
 
29
  Author:
30
 
31
    John Burkardt
32
*/
33
{
34
  timestamp ( );
35
 
36
  printf ( "\n" );
37
  printf ( "FFTW3_PRB\n" );
38
  printf ( "  C version\n" );
39
  printf ( "\n" );
40
  printf ( "  Demonstrate the use of the C FFTW3 library.\n" );
41
 
42
 // test01 ( );
43
  test02 ( );
44
 // test03 ( );
45
  //test04 ( );
46
 
47
  printf ( "\n" );
48
  printf ( "FFTW3_PRB\n" );
49
  printf ( "  Normal end of execution.\n" );
50
 
51
  printf ( "\n" );
52
  timestamp ( );
53
 
54
  return 0;
55
}
56
/******************************************************************************/
57
 
58
void test01 ( void )
59
 
60
/******************************************************************************/
61
/*
62
  Purpose:
63
 
64
    TEST01: apply FFT to complex 1D data.
65
 
66
  Discussion:
67
 
68
    In this example, we generate N=100 random complex values stored as
69
    a vector of type FFTW_COMPLEX named "IN".
70
 
71
    We have FFTW3 compute the Fourier transform of this data named "OUT".
72
 
73
    We have FFTW3 compute the inverse Fourier transform of "OUT" to get
74
    "IN2", which should be the original input data, scaled by N.
75
 
76
  Modified:
77
 
78
    04 November 2007
79
*/
80
{
81
  int i;
82
  fftw_complex *in;
83
  fftw_complex *in2;
84
  int n = 100;
85
  fftw_complex *out;
86
  fftw_plan plan_backward;
87
  fftw_plan plan_forward;
88
  unsigned int seed = 123456789;
89
 
90
  printf ( "\n" );
91
  printf ( "TEST01\n" );
92
  printf ( "  Demonstrate FFTW3 on a single vector of complex data.\n" );
93
  printf ( "\n" );
94
  printf ( "  Transform data to FFT coefficients.\n" );
95
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
96
  printf ( "  Compare recovered data to original data.\n" );
97
/*
98
  Create the input array.
99
*/
100
  in = fftw_malloc ( sizeof ( fftw_complex ) * n );
101
 
102
  srand ( seed );
103
 
104
  for ( i = 0; i < n; i++ )
105
  {
106
    in[i][0] = frand ( );
107
    in[i][1] = frand ( );
108
  }
109
 
110
  printf ( "\n" );
111
  printf ( "  Input Data:\n" );
112
  printf ( "\n" );
113
 
114
  for ( i = 0; i < n; i++ )
115
  {
116
    printf ( "  %3d  %12f  %12f\n", i, in[i][0], in[i][1] );
117
  }
118
/*
119
  Create the output array.
120
*/
121
  out = fftw_malloc ( sizeof ( fftw_complex ) * n );
122
 
123
  plan_forward = fftw_plan_dft_1d ( n, in, out, FFTW_FORWARD, FFTW_ESTIMATE );
124
 
125
  fftw_execute ( plan_forward );
126
 
127
  printf ( "\n" );
128
  printf ( "  Output FFT Coefficients:\n" );
129
  printf ( "\n" );
130
 
131
  for ( i = 0; i < n; i++ )
132
  {
133
    printf ( "  %3d  %12f  %12f\n", i, out[i][0], out[i][1] );
134
  }
135
/*
136
  Recreate the input array.
137
*/
138
  in2 = fftw_malloc ( sizeof ( fftw_complex ) * n );
139
 
140
  plan_backward = fftw_plan_dft_1d ( n, out, in2, FFTW_BACKWARD, FFTW_ESTIMATE );
141
 
142
  fftw_execute ( plan_backward );
143
 
144
  printf ( "\n" );
145
  printf ( "  Recovered input data:\n" );
146
  printf ( "\n" );
147
 
148
  for ( i = 0; i < n; i++ )
149
  {
150
    printf ( "  %3d  %12f  %12f\n", i, in2[i][0], in2[i][1] );
151
  }
152
 
153
  printf ( "\n" );
154
  printf ( "  Recovered input data divided by N:\n" );
155
  printf ( "\n" );
156
 
157
  for ( i = 0; i < n; i++ )
158
  {
159
    printf ( "  %3d  %12f  %12f\n", i, 
160
      in2[i][0] / ( double ) ( n ), in2[i][1] / ( double ) ( n ) );
161
  }
162
/*
163
  Free up the allocated memory.
164
*/
165
  fftw_destroy_plan ( plan_forward );
166
  fftw_destroy_plan ( plan_backward );
167
 
168
  fftw_free ( in );
169
  fftw_free ( in2 );
170
  fftw_free ( out );
171
 
172
  return;
173
}
174
/******************************************************************************/
175
 
176
void test02 ( void )
177
 
178
/******************************************************************************/
179
/*
180
  Purpose:
181
 
182
    TEST02: apply FFT to real 1D data.
183
 
184
  Modified:
185
 
186
    23 October 2005
187
*/
188
{
189
  int i;
190
  double *in;
191
  double *in2;
192
  int n = 100;
193
  int nc;
194
  fftw_complex *out;
195
  fftw_plan plan_backward;
196
  fftw_plan plan_forward;
197
  unsigned int seed = 123456789;
198
 
199
  printf ( "\n" );
200
  printf ( "TEST02\n" );
201
  printf ( "  Demonstrate FFTW3 on a single vector of real data.\n" );
202
  printf ( "\n" );
203
  printf ( "  Transform data to FFT coefficients.\n" );
204
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
205
  printf ( "  Compare recovered data to original data.\n" );
206
/*
207
  Set up an array to hold the data, and assign the data.
208
*/
209
  in = fftw_malloc ( sizeof ( double ) * n );
210
 
211
  srand ( seed );
212
 
213
  for ( i = 0; i < n; i++ )
214
  {
215
    in[i] = frand ( );
216
  }
217
 
218
  printf ( "\n" );
219
  printf ( "  Input Data:\n" );
220
  printf ( "\n" );
221
 
222
  for ( i = 0; i < n; i++ )
223
  {
224
    printf ( "  %4d  %12f\n", i, in[i] );
225
  }
226
/*
227
  Set up an array to hold the transformed data,
228
  get a "plan", and execute the plan to transform the IN data to
229
  the OUT FFT coefficients.
230
*/
231
  nc = ( n / 2 ) + 1;
232
 
233
  out = fftw_malloc ( sizeof ( fftw_complex ) * nc );
234
 
235
  plan_forward = fftw_plan_dft_r2c_1d ( n, in, out, FFTW_ESTIMATE );
236
 
237
  fftw_execute ( plan_forward );
238
 
239
  printf ( "\n" );
240
  printf ( "  Output FFT Coefficients:\n" );
241
  printf ( "\n" );
242
 
243
  for ( i = 0; i < nc; i++ )
244
  {
245
    printf ( "  %4d  %12f  %12f\n", i, out[i][0], out[i][1] );
246
  }
247
/*
248
  Set up an arrray to hold the backtransformed data IN2,
249
  get a "plan", and execute the plan to backtransform the OUT
250
  FFT coefficients to IN2.
251
*/
252
  in2 = fftw_malloc ( sizeof ( double ) * n );
253
 
254
  plan_backward = fftw_plan_dft_c2r_1d ( n, out, in2, FFTW_ESTIMATE );
255
 
256
  fftw_execute ( plan_backward );
257
 
258
  printf ( "\n" );
259
  printf ( "  Recovered input data divided by N:\n" );
260
  printf ( "\n" );
261
 
262
  for ( i = 0; i < n; i++ )
263
  {
264
    printf ( "  %4d  %12f\n", i, in2[i] / ( double ) ( n ) );
265
  }
266
/*
267
  Release the memory associated with the plans.
268
*/
269
  fftw_destroy_plan ( plan_forward );
270
  fftw_destroy_plan ( plan_backward );
271
 
272
  fftw_free ( in );
273
  fftw_free ( in2 );
274
  fftw_free ( out );
275
 
276
  return;
277
}
278
/******************************************************************************/
279
 
280
void test03 ( void )
281
 
282
/******************************************************************************/
283
/*
284
  Purpose:
285
 
286
    TEST03: apply FFT to complex 2D data.
287
 
288
  Discussion:
289
 
290
    In this example, we generate NX=8 by NY=10 random complex values 
291
    stored as an NX by NY array of type FFTW_COMPLEX named "IN".
292
 
293
    We have FFTW3 compute the Fourier transform of this data named "OUT".
294
 
295
    We have FFTW3 compute the inverse Fourier transform of "OUT" to get
296
    "IN2", which should be the original input data, scaled by NX * NY.
297
 
298
    For a 2D complex NX by NY array used by FFTW, we need to access elements
299
    as follows:
300
 
301
      a[i*ny+j][0] is the real      part of A(I,J).
302
      a[i*ny+j][1] is the imaginary part of A(I,J)..
303
 
304
  Modified:
305
 
306
    05 November 2007
307
 
308
  Author:
309
 
310
    John Burkardt
311
*/
312
{
313
  int i;
314
  fftw_complex *in;
315
  fftw_complex *in2;
316
  int j;
317
  int nx = 8;
318
  int ny = 10;
319
  fftw_complex *out;
320
  fftw_plan plan_backward;
321
  fftw_plan plan_forward;
322
  unsigned int seed = 123456789;
323
 
324
  printf ( "\n" );
325
  printf ( "TEST03\n" );
326
  printf ( "  Demonstrate FFTW3 on a %d by %d array of complex data.\n",
327
    nx, ny );
328
  printf ( "\n" );
329
  printf ( "  Transform data to FFT coefficients.\n" );
330
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
331
  printf ( "  Compare recovered data to original data.\n" );
332
/*
333
  Create the input array.
334
*/
335
  in = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );
336
 
337
  srand ( seed );
338
 
339
  for ( i = 0; i < nx; i++ )
340
  {
341
    for ( j = 0; j < ny; j++ )
342
    {
343
      in[i*ny+j][0] = frand ( );
344
      in[i*ny+j][1] = frand ( );
345
    }
346
  }
347
 
348
  printf ( "\n" );
349
  printf ( "  Input Data:\n" );
350
  printf ( "\n" );
351
 
352
  for ( i = 0; i < nx; i++ )
353
  {
354
    for ( j = 0; j < ny; j++ )
355
    {
356
      printf ( "  %4d  %4d  %12f  %12f\n", i, j, in[i*ny+j][0], in[i*ny+j][1] );
357
    }
358
  }
359
/*
360
  Create the output array.
361
*/
362
  out = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );
363
 
364
  plan_forward = fftw_plan_dft_2d ( nx, ny, in, out, FFTW_FORWARD, 
365
    FFTW_ESTIMATE );
366
 
367
  fftw_execute ( plan_forward );
368
 
369
  printf ( "\n" );
370
  printf ( "  Output FFT Coefficients:\n" );
371
  printf ( "\n" );
372
 
373
  for ( i = 0; i < nx; i++ )
374
  {
375
    for ( j = 0; j < ny; j++ )
376
    {
377
      printf ( "  %4d  %4d  %12f  %12f\n", i, j, out[i*ny+j][0], out[i*ny+j][1] );
378
    }
379
  }
380
/*
381
  Recreate the input array.
382
*/
383
  in2 = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );
384
 
385
  plan_backward = fftw_plan_dft_2d ( nx, ny, out, in2, FFTW_BACKWARD, 
386
    FFTW_ESTIMATE );
387
 
388
  fftw_execute ( plan_backward );
389
 
390
  printf ( "\n" );
391
  printf ( "  Recovered input data divided by NX * NY:\n" );
392
  printf ( "\n" );
393
 
394
  for ( i = 0; i < nx; i++ )
395
  {
396
    for ( j = 0; j < ny; j++ )
397
    {
398
      printf ( "  %4d  %4d  %12f  %12f\n",  i, j,
399
      in2[i*ny+j][0] / ( double ) ( nx * ny ),
400
      in2[i*ny+j][1] / ( double ) ( nx * ny ) );
401
    }
402
  }
403
/*
404
  Free up the allocated memory.
405
*/
406
  fftw_destroy_plan ( plan_forward );
407
  fftw_destroy_plan ( plan_backward );
408
 
409
  fftw_free ( in );
410
  fftw_free ( in2 );
411
  fftw_free ( out );
412
 
413
  return;
414
}
415
/******************************************************************************/
416
 
417
void test04 ( void )
418
 
419
/******************************************************************************/
420
/*
421
  Purpose:
422
 
423
    TEST04: apply FFT to real 2D data.
424
 
425
  Discussion:
426
 
427
    In this example, we generate NX=8 by NY=10 random real values 
428
    stored as an NX by NY array of type DOUBLE named "IN".
429
 
430
    We have FFTW3 compute the Fourier transform of this data named "OUT".
431
 
432
    We have FFTW3 compute the inverse Fourier transform of "OUT" to get
433
    "IN2", which should be the original input data, scaled by NX * NY.
434
 
435
    The Fourier coefficients are stored in an NX by NYH array where
436
    NYH = (NY/2) + 1.  We only compute about half the data because
437
    of real data implies symmetric FFT coefficients.
438
 
439
      a[i*nyh+j][0] is the real      part of A(I,J).
440
      a[i*nyh+j][1] is the imaginary part of A(I,J)..
441
 
442
  Modified:
443
 
444
    05 November 2007
445
 
446
  Author:
447
 
448
    John Burkardt
449
*/
450
{
451
  int i;
452
  double *in;
453
  double *in2;
454
  int j;
455
  int nx = 8;
456
  int ny = 10;
457
  int nyh;
458
  fftw_complex *out;
459
  fftw_plan plan_backward;
460
  fftw_plan plan_forward;
461
  unsigned int seed = 123456789;
462
 
463
  printf ( "\n" );
464
  printf ( "TEST04\n" );
465
  printf ( "  Demonstrate FFTW3 on a %d by %d array of real data.\n",
466
    nx, ny );
467
  printf ( "\n" );
468
  printf ( "  Transform data to FFT coefficients.\n" );
469
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
470
  printf ( "  Compare recovered data to original data.\n" );
471
/*
472
  Create the input array, an NX by NY array of doubles.
473
*/
474
  in = malloc ( sizeof ( double ) * nx * ny );
475
 
476
  srand ( seed );
477
 
478
  for ( i = 0; i < nx; i++ )
479
  {
480
    for ( j = 0; j < ny; j++ )
481
    {
482
      in[i*ny+j] = frand ( );
483
    }
484
  }
485
 
486
  printf ( "\n" );
487
  printf ( "  Input Data:\n" );
488
  printf ( "\n" );
489
 
490
  for ( i = 0; i < nx; i++ )
491
  {
492
    for ( j = 0; j < ny; j++ )
493
    {
494
      printf ( "  %4d  %4d  %12f\n", i, j, in[i*ny+j] );
495
    }
496
  }
497
/*
498
  Create the output array OUT, which is of type FFTW_COMPLEX,
499
  and of a size NX * NYH that is roughly half the dimension of the input data
500
  (ignoring the fact that the input data is real, and the FFT
501
  coefficients are complex).
502
*/
503
  nyh = ( ny / 2 ) + 1;
504
 
505
  out = fftw_malloc ( sizeof ( fftw_complex ) * nx * nyh );
506
 
507
  plan_forward = fftw_plan_dft_r2c_2d ( nx, ny, in, out, FFTW_ESTIMATE );
508
 
509
  fftw_execute ( plan_forward );
510
 
511
  printf ( "\n" );
512
  printf ( "  Output FFT Coefficients:\n" );
513
  printf ( "\n" );
514
 
515
  for ( i = 0; i < nx; i++ )
516
  {
517
    for ( j = 0; j < nyh; j++ )
518
    {
519
      printf ( "  %4d  %4d  %12f  %12f\n", 
520
      i, j, out[i*nyh+j][0], out[i*nyh+j][1] );
521
    }
522
  }
523
/*
524
  Recreate the input array.
525
*/
526
  in2 = malloc ( sizeof ( double ) * nx * ny );
527
 
528
  plan_backward = fftw_plan_dft_c2r_2d ( nx, ny, out, in2, FFTW_ESTIMATE );
529
 
530
  fftw_execute ( plan_backward );
531
 
532
  printf ( "\n" );
533
  printf ( "  Recovered input data divided by NX * NY:\n" );
534
  printf ( "\n" );
535
 
536
  for ( i = 0; i < nx; i++ )
537
  {
538
    for ( j = 0; j < ny; j++ )
539
    {
540
      printf ( "  %4d  %4d  %12f\n",  
541
        i, j, in2[i*ny+j] / ( double ) ( nx * ny ) );
542
    }
543
  }
544
/*
545
  Free up the allocated memory.
546
*/
547
  fftw_destroy_plan ( plan_forward );
548
  fftw_destroy_plan ( plan_backward );
549
 
550
  free ( in );
551
  free ( in2 );
552
  fftw_free ( out );
553
 
554
  return;
555
}
556
//*****************************************************************************/
557
 
558
double frand ( void )
559
 
560
//*****************************************************************************/
561
/*
562
  Purpose:
563
 
564
    FRAND returns random values between 0 and 1.
565
 
566
  Discussion:
567
 
568
    The random seed can be set by a call to SRAND ( unsigned int ).
569
 
570
    Note that Kernighan and Ritchie suggest using
571
 
572
      ( ( double ) rand ( ) / ( RAND_MAX + 1 ) )
573
 
574
    but this seems to result in integer overflow for RAND_MAX + 1,
575
    resulting in negative values for the random numbers.
576
 
577
  Modified:
578
 
579
    23 October 2005
580
 
581
  Author:
582
 
583
    John Burkardt
584
 
585
  Reference:
586
 
587
    Brian Kernighan, Dennis Ritchie,
588
    The C Programming Language,
589
    Prentice Hall, 1988.
590
 
591
  Parameters:
592
 
593
    Output, double FRAND, a random value between 0 and 1.
594
*/
595
{
596
  double value;
597
 
598
  value = ( ( double ) rand ( ) / ( RAND_MAX ) );
599
 
600
  return value;
601
}
602
//*****************************************************************************/
603
 
604
void timestamp ( void )
605
 
606
/******************************************************************************/
607
/*
608
  Purpose:
609
 
610
    TIMESTAMP prints the current YMDHMS date as a time stamp.
611
 
612
  Example:
613
 
614
    31 May 2001 09:45:54 AM
615
 
616
  Modified:
617
 
618
    24 September 2003
619
 
620
  Author:
621
 
622
    John Burkardt
623
 
624
  Parameters:
625
 
626
    None
627
*/
628
{
629
# define TIME_SIZE 40
630
 
631
  static char time_buffer[TIME_SIZE];
632
  const struct tm *tm;
633
  size_t len;
634
  time_t now;
635
 
636
  now = time ( NULL );
637
  tm = localtime ( &now );
638
 
639
  len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
640
 
641
  printf ( "%s\n", time_buffer );
642
 
643
  return;
644
# undef TIME_SIZE
645
}