• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #ifdef PFFFT_ENABLE_FLOAT
3 #include "pffft.h"
4 #endif
5 
6 
7 #ifdef PFFFT_ENABLE_DOUBLE
8 #include "pffft_double.h"
9 #endif
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <assert.h>
14 
15 
16 
17 #ifdef PFFFT_ENABLE_FLOAT
test_float(int TL)18 int test_float(int TL)
19 {
20   PFFFT_Setup * S;
21 
22   for (int dir_i = 0; dir_i <= 1; ++dir_i)
23   {
24     for (int cplx_i = 0; cplx_i <= 1; ++cplx_i)
25     {
26       const pffft_direction_t dir = (!dir_i) ? PFFFT_FORWARD : PFFFT_BACKWARD;
27       const pffft_transform_t cplx = (!cplx_i) ? PFFFT_REAL : PFFFT_COMPLEX;
28       const int N_min = pffft_min_fft_size(cplx);
29       const int N_max = N_min * 11 + N_min;
30       int NTL = pffft_nearest_transform_size(TL, cplx, (!dir_i));
31       double near_off = (NTL - TL) * 100.0 / (double)TL;
32 
33       fprintf(stderr, "testing float, %s, %s ..\tminimum transform %d; nearest transform for %d is %d (%.2f%% off)\n",
34           (!dir_i) ? "FORWARD" : "BACKWARD", (!cplx_i) ? "REAL" : "COMPLEX", N_min, TL, NTL, near_off );
35 
36       for (int N = (N_min/2); N <= N_max; N += (N_min/2))
37       {
38         int R = N, f2 = 0, f3 = 0, f5 = 0, tmp_f;
39         const int factorizable = pffft_is_valid_size(N, cplx);
40         while (R >= 5*N_min && (R % 5) == 0) {  R /= 5; ++f5; }
41         while (R >= 3*N_min && (R % 3) == 0) {  R /= 3; ++f3; }
42         while (R >= 2*N_min && (R % 2) == 0) {  R /= 2; ++f2; }
43         tmp_f = (R == N_min) ? 1 : 0;
44         assert( factorizable == tmp_f );
45 
46         S = pffft_new_setup(N, cplx);
47 
48         if ( S && !factorizable )
49         {
50           fprintf(stderr, "fft setup successful, but NOT factorizable into min(=%d), 2^%d, 3^%d, 5^%d for N = %d (R = %d)\n", N_min, f2, f3, f5, N, R);
51           return 1;
52         }
53         else if ( !S && factorizable)
54         {
55           fprintf(stderr, "fft setup UNsuccessful, but factorizable into min(=%d), 2^%d, 3^%d, 5^%d for N = %d (R = %d)\n", N_min, f2, f3, f5, N, R);
56           return 1;
57         }
58 
59         if (S)
60           pffft_destroy_setup(S);
61       }
62 
63     }
64   }
65   return 0;
66 }
67 
68 #endif
69 
70 
71 #ifdef PFFFT_ENABLE_DOUBLE
test_double(int TL)72 int test_double(int TL)
73 {
74   PFFFTD_Setup * S;
75   for (int dir_i = 0; dir_i <= 1; ++dir_i)
76   {
77     for (int cplx_i = 0; cplx_i <= 1; ++cplx_i)
78     {
79       const pffft_direction_t dir = (!dir_i) ? PFFFT_FORWARD : PFFFT_BACKWARD;
80       const pffft_transform_t cplx = (!cplx_i) ? PFFFT_REAL : PFFFT_COMPLEX;
81       const int N_min = pffftd_min_fft_size(cplx);
82       const int N_max = N_min * 11 + N_min;
83       int NTL = pffftd_nearest_transform_size(TL, cplx, (!dir_i));
84       double near_off = (NTL - TL) * 100.0 / (double)TL;
85 
86       fprintf(stderr, "testing double, %s, %s ..\tminimum transform %d; nearest transform for %d is %d (%.2f%% off)\n",
87           (!dir_i) ? "FORWARD" : "BACKWARD", (!cplx_i) ? "REAL" : "COMPLEX", N_min, TL, NTL, near_off );
88 
89       for (int N = (N_min/2); N <= N_max; N += (N_min/2))
90       {
91         int R = N, f2 = 0, f3 = 0, f5 = 0, tmp_f;
92         const int factorizable = pffftd_is_valid_size(N, cplx);
93         while (R >= 5*N_min && (R % 5) == 0) {  R /= 5; ++f5; }
94         while (R >= 3*N_min && (R % 3) == 0) {  R /= 3; ++f3; }
95         while (R >= 2*N_min && (R % 2) == 0) {  R /= 2; ++f2; }
96         tmp_f = (R == N_min) ? 1 : 0;
97         assert( factorizable == tmp_f );
98 
99         S = pffftd_new_setup(N, cplx);
100 
101         if ( S && !factorizable )
102         {
103           fprintf(stderr, "fft setup successful, but NOT factorizable into min(=%d), 2^%d, 3^%d, 5^%d for N = %d (R = %d)\n", N_min, f2, f3, f5, N, R);
104           return 1;
105         }
106         else if ( !S && factorizable)
107         {
108           fprintf(stderr, "fft setup UNsuccessful, but factorizable into min(=%d), 2^%d, 3^%d, 5^%d for N = %d (R = %d)\n", N_min, f2, f3, f5, N, R);
109           return 1;
110         }
111 
112         if (S)
113           pffftd_destroy_setup(S);
114       }
115 
116     }
117   }
118   return 0;
119 }
120 
121 #endif
122 
123 
124 
main(int argc,char * argv[])125 int main(int argc, char *argv[])
126 {
127   int N = (1 < argc) ? atoi(argv[1]) : 2;
128 
129   int r = 0;
130 #ifdef PFFFT_ENABLE_FLOAT
131   r = test_float(N);
132   if (r)
133     return r;
134 #endif
135 
136 #ifdef PFFFT_ENABLE_DOUBLE
137   r = test_double(N);
138 #endif
139 
140   return r;
141 }
142 
143