IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ticket #307: testFFT.c

File testFFT.c, 3.6 KB (added by Paul Price, 21 years ago)

testFFT.c

Line 
1#include <stdio.h>
2#include <math.h>
3#include "pslib.h"
4
5double getTime(void)
6/* Gets the current time. Got this from Nick Kaiser's fetchpix.c */
7{
8 struct timeval tv;
9 gettimeofday(&tv, NULL);
10 return(tv.tv_sec + 1.e-6 * tv.tv_usec);
11}
12
13
14int main(int argc, char **argv)
15{
16 if (argc != 2) {
17 fprintf(stderr, "Generates an image and FFTs it, outputting timing statistics.\n"
18 "Usage: %s SIZE\n"
19 "where SIZE is the size (in pixels) of the square image generated.\n"
20 "\n", argv[0]);
21 exit(EXIT_SUCCESS);
22 }
23 int size = atoi(argv[1]); // Size of image
24 double startTime = getTime(); // Start time
25
26 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Seed RNG automagically.
27 float yPeriod = psRandomUniform(rng) * size / 2.0;
28 float xPeriod = psRandomUniform(rng) * size / 2.0;
29 float xPhase = psRandomUniform(rng) * 2.0 * M_PI;
30 float yPhase = psRandomUniform(rng) * 2.0 * M_PI;
31 psFree(rng);
32
33 // Generate the image
34 psImage *image = psImageAlloc(size, size, PS_TYPE_F32);
35 for (int j = 0; j < size; j++) {
36 float yValue = 2.0 * M_PI / yPeriod * (float)j + yPhase;
37 for (int i = 0; i < size; i++) {
38 float xValue = 2.0 * M_PI / xPeriod * (float)i + xPhase;
39 image->data.F32[j][i] = cos(xValue) * cos(yValue);
40 }
41 }
42
43 // Write image out
44 psFits *imageFile = psFitsAlloc("!image.fits");
45 if (!psFitsWriteImage(imageFile, NULL, image, 0, NULL)) {
46 psErrorStackPrint(stderr, "Unable to write image: input.fits\n");
47 }
48 psFree(imageFile);
49 printf("%dx%d image (image.fits) constructed after %f sec.\n", size, size, getTime() - startTime);
50
51 // Forward FFT
52 psImage *fft = psImageFFT(NULL, image, PS_FFT_FORWARD);
53 printf("%dx%d FFT image constructed after %f sec.\n", fft->numCols, fft->numRows, getTime() - startTime);
54
55 // Inverse FFT
56 psImage *back = psImageFFT(NULL, fft, PS_FFT_REVERSE | PS_FFT_REAL_RESULT);
57 printf("%dx%d inverse FFT image constructed after %f sec.\n", back->numCols, back->numRows,
58 getTime() - startTime);
59 if (back->numRows != image->numRows || back->numCols != image->numCols) {
60 printf("Sizes of original image (%dx%d) and end image (%dx%d) do not match!\n", image->numCols,
61 image->numRows, back->numCols, back->numRows);
62 }
63
64 // Power spectrum
65 psImage *power = psImagePowerSpectrum(NULL, fft);
66 printf("%dx%d power spectrum constructed after %f sec.\n", power->numCols, power->numRows, getTime() - startTime);
67
68 // Write out power spectrum
69 psFits *powerFile = psFitsAlloc("!power.fits");
70 if (!psFitsWriteImage(powerFile, NULL, power, 0, NULL)) {
71 psErrorStackPrint(stderr, "Unable to write image: power.fits\n");
72 }
73 psFree(powerFile);
74 printf("Power spectrum image written to power.fits after %f sec.\n", getTime() - startTime);
75
76 // Subtract input and inverse FFT image and compare
77 (void)psBinaryOp(back, back, "/", psScalarAlloc(size*size, PS_TYPE_F32));
78 psImage *sub = (psImage*)psBinaryOp(NULL, back, "-", image);
79 psFits *subFile = psFitsAlloc("!sub.fits");
80 if (!psFitsWriteImage(subFile, NULL, sub, 0, NULL)) {
81 psErrorStackPrint(stderr, "Unable to write image: sub.fits\n");
82 }
83 psFree(subFile);
84
85 printf("%dx%d subtracted image constructed and written to sub.fits at %f sec.\n", size, size,
86 getTime() - startTime);
87
88 psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV);
89 psImageStats(stats, sub, NULL, 0);
90 printf("Subtracted image: mean = %g, stdev = %g\n", stats->sampleMean, stats->sampleStdev);
91 psFree(stats);
92
93 psFree(fft);
94 psFree(power);
95 psFree(back);
96 psFree(sub);
97 psFree(image);
98}