File Coverage

lib/PDL/FFT/fftn.c
Criterion Covered Total %
statement 1207 1898 63.5
branch 240 698 34.3
condition n/a
subroutine n/a
pod n/a
total 1447 2596 55.7


line stmt bran cond sub pod time code
1             /*--------------------------------*-C-*---------------------------------*
2             * File:
3             * fftn.c
4             *
5             * multivariate complex Fourier transform, computed in place
6             * using mixed-radix Fast Fourier Transform algorithm.
7             *
8             * Fortran code by:
9             * RC Singleton, Stanford Research Institute, Sept. 1968
10             * NIST Guide to Available Math Software.
11             * Source for module FFT from package GO.
12             * Retrieved from NETLIB on Wed Jul 5 11:50:07 1995.
13             * translated by f2c (version 19950721) and with lots of cleanup
14             * to make it resemble C by:
15             * MJ Olesen, Queen's University at Kingston, 1995-97
16             */
17             /*{{{ Copyright: */
18             /*
19             * Copyright(c)1995,97 Mark Olesen
20             * Queen's Univ at Kingston (Canada)
21             *
22             * Permission to use, copy, modify, and distribute this software for
23             * any purpose without fee is hereby granted, provided that this
24             * entire notice is included in all copies of any software which is
25             * or includes a copy or modification of this software and in all
26             * copies of the supporting documentation for such software.
27             *
28             * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
29             * IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR QUEEN'S
30             * UNIVERSITY AT KINGSTON MAKES ANY REPRESENTATION OR WARRANTY OF ANY
31             * KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
32             * FITNESS FOR ANY PARTICULAR PURPOSE.
33             *
34             * All of which is to say that you can do what you like with this
35             * source code provided you don't try to sell it as your own and you
36             * include an unaltered copy of this message (including the
37             * copyright).
38             *
39             * It is also implicitly understood that bug fixes and improvements
40             * should make their way back to the general Internet community so
41             * that everyone benefits.
42             *----------------------------------------------------------------------*/
43             /*}}}*/
44             /*{{{ notes: */
45             /*
46             * Public:
47             * fftn / fftnf / fftnl
48             * (these are documented in the header file)
49             *
50             * Private:
51             * fftradix / fftradixf
52             *
53             * ----------------------------------------------------------------------*
54             * int fftradix (REAL Re[], REAL Im[], size_t nTotal, size_t nPass,
55             * size_t nSpan, int iSign, size_t maxFactors,
56             * size_t maxPerm);
57             *
58             * RE and IM hold the real and imaginary components of the data, and
59             * return the resulting real and imaginary Fourier coefficients.
60             * Multidimensional data *must* be allocated contiguously. There is
61             * no limit on the number of dimensions.
62             *
63             *
64             * Although there is no limit on the number of dimensions, fftradix()
65             * must be called once for each dimension, but the calls may be in
66             * any order.
67             *
68             * NTOTAL = the total number of complex data values
69             * NPASS = the dimension of the current variable
70             * NSPAN/NPASS = the spacing of consecutive data values while indexing
71             * the current variable
72             * ISIGN - see above documentation
73             *
74             * example:
75             * tri-variate transform with Re[n1][n2][n3], Im[n1][n2][n3]
76             *
77             * fftradix (Re, Im, n1*n2*n3, n1, n1, 1, maxf, maxp);
78             * fftradix (Re, Im, n1*n2*n3, n2, n1*n2, 1, maxf, maxp);
79             * fftradix (Re, Im, n1*n2*n3, n3, n1*n2*n3, 1, maxf, maxp);
80             *
81             * single-variate transform,
82             * NTOTAL = N = NSPAN = (number of complex data values),
83             *
84             * fftradix (Re, Im, n, n, n, 1, maxf, maxp);
85             *
86             * The data can also be stored in a single array with alternating
87             * real and imaginary parts, the magnitude of ISIGN is changed to 2
88             * to give correct indexing increment, and data [0] and data [1] used
89             * to pass the initial addresses for the sequences of real and
90             * imaginary values,
91             *
92             * example:
93             * REAL data [2*NTOTAL];
94             * fftradix (&data[0], &data[1], NTOTAL, nPass, nSpan, 2, maxf, maxp);
95             *
96             * for temporary allocation:
97             *
98             * MAXFACTORS >= the maximum prime factor of NPASS
99             * MAXPERM >= the number of prime factors of NPASS. In addition,
100             * if the square-free portion K of NPASS has two or more prime
101             * factors, then MAXPERM >= (K-1)
102             *
103             * storage in FACTOR for a maximum of 15 prime factors of NPASS. if
104             * NPASS has more than one square-free factor, the product of the
105             * square-free factors must be <= 210 array storage for maximum prime
106             * factor of 23 the following two constants should agree with the
107             * array dimensions.
108             * ----------------------------------------------------------------------*/
109             /*}}}*/
110             /*{{{ Revisions: */
111             /*
112             * 26 July 95 John Beale
113             * - added maxf and maxp as parameters to fftradix()
114             *
115             * 28 July 95 Mark Olesen
116             * - cleaned-up the Fortran 66 goto spaghetti, only 3 labels remain.
117             *
118             * - added fft_free() to provide some measure of control over
119             * allocation/deallocation.
120             *
121             * - added fftn() wrapper for multidimensional FFTs
122             *
123             * - use -DFFT_NOFLOAT or -DFFT_NODOUBLE to avoid compiling that
124             * precision. Note suffix `f' on the function names indicates
125             * float precision.
126             *
127             * - revised documentation
128             *
129             * 31 July 95 Mark Olesen
130             * - added GNU Public License
131             * - more cleanup
132             * - define SUN_BROKEN_REALLOC to use malloc() instead of realloc()
133             * on the first pass through, apparently needed for old libc
134             * - removed #error directive in favour of some code that simply
135             * won't compile (generate an error that way)
136             *
137             * 1 Aug 95 Mark Olesen
138             * - define FFT_RADIX4 to only have radix 2, radix 4 transforms
139             * - made fftradix /fftradixf () static scope, just use fftn()
140             * instead. If you have good ideas about fixing the factors
141             * in fftn() please do so.
142             *
143             * 8 Jan 95 mj olesen
144             * - fixed typo's, including one that broke scaling for scaling by
145             * total number of matrix elements or the square root of same
146             * - removed unnecessary casts from allocations
147             *
148             * 10 Dec 96 mj olesen
149             * - changes defines to compile *without* float support by default,
150             * use -DFFT_FLOAT to enable.
151             * - shifted some variables to local scope (better hints for optimizer)
152             * - added Michael Steffens
153             * Fortran 90 module
154             * - made it simpler to pass dimensions for 1D FFT.
155             *
156             * 23 Feb 97 Mark Olesen
157             * - removed the GNU Public License (see 21 July 1995 entry),
158             * which should make it clear why I have the right to do so.
159             * - Added copyright notice and submitted to netlib
160             * - Moved documentation for the public functions to the header
161             * files where is will always be available.
162             *
163             * 11 Nov 97 Robin Williams
164             * - fixed all temporaries to double precision using REALFIX,
165             * following suggestion from Scott Wurcer
166             * ----------------------------------------------------------------------*/
167             /*}}}*/
168             #ifndef _FFTN_C
169             #define _FFTN_C
170             /* we use CPP to re-include this same file for double/float cases */
171              
172             #include
173             #include
174             #include
175             #include "fftn.h"
176              
177             /*{{{ defines/constants */
178             #ifndef M_PI
179             # define M_PI 3.14159265358979323846264338327950288
180             #endif
181              
182             #define FFT_STR(x) #x
183             #define FFT_CONCAT(x, y) FFT_CONCAT_(x, y)
184             #define FFT_CONCAT_(x, y) x ## y /* second call forces arg expansion */
185              
186             #ifndef SIN60
187             # define SIN60 0.86602540378443865 /* sin(60 deg) */
188             # define COS72 0.30901699437494742 /* cos(72 deg) */
189             # define SIN72 0.95105651629515357 /* sin(72 deg) */
190             #endif
191             /*}}}*/
192              
193             #define NFACTOR 11
194             #define REALFIX long double
195              
196             /*
197             * use macros to access the Real/Imaginary parts so that it's possible
198             * to substitute different macros if a complex struct is used
199             */
200             #define Re_Data(i) Re[i]
201             #define Im_Data(i) Im[i]
202              
203             /* return the number of factors */
204             static int
205 10964           factorize (int nPass, int * kt, int *factor)
206             {
207 10964           int nFactor = 0;
208             int j, jj;
209              
210 10964           *kt = 0;
211             /* determine the factors of n */
212 20948 100         while ((nPass % 16) == 0) /* factors of 4 */
213             {
214 9984           factor [nFactor++] = 4;
215 9984           nPass /= 16;
216             }
217 10964           j = 3; jj = 9; /* factors of 3, 5, 7, ... */
218             do {
219 11242 50         while ((nPass % jj) == 0)
220             {
221 0           factor [nFactor++] = j;
222 0           nPass /= jj;
223             }
224 11242           j += 2;
225 11242           jj = j * j;
226 11242 100         } while (jj <= nPass);
227 10964 100         if (nPass <= 4)
228             {
229 8           *kt = nFactor;
230 8           factor [nFactor] = nPass;
231 8 50         if (nPass != 1)
232 8           nFactor++;
233             }
234             else
235             {
236 10956 100         if (nPass - (nPass / 4 << 2) == 0)
237             {
238 10128           factor [nFactor++] = 2;
239 10128           nPass /= 4;
240             }
241 10956           *kt = nFactor;
242 10956           j = 2;
243             do {
244 23364 100         if ((nPass % j) == 0)
245             {
246 21768           factor [nFactor++] = j;
247 21768           nPass /= j;
248             }
249 23364           j = ((j + 1) / 2 << 1) + 1;
250 23364 100         } while (j <= nPass);
251             }
252 10964 100         if (*kt)
253             {
254 10128           j = *kt;
255             do
256 20112           factor [nFactor++] = factor [--j];
257 20112 100         while (j);
258             }
259              
260 10964           return nFactor;
261             }
262              
263             /*{{{ defines for re-including long double precision */
264             #ifdef FFT_LDOUBLE
265             # undef REAL
266             # undef FFT_SUFFIX
267             # define FFT_SUFFIX l
268             # define REAL long double
269             # include "fftn.c" /* include this file again */
270             #endif
271             /*}}}*/
272              
273             /*{{{ defines for re-including double precision */
274             #ifdef FFT_DOUBLE
275             # undef REAL
276             # undef FFT_SUFFIX
277             # define FFT_SUFFIX
278             # define REAL double
279             # include "fftn.c" /* include this file again */
280             #endif
281             /*}}}*/
282              
283             /*{{{ defines for re-including float precision */
284             #ifdef FFT_FLOAT
285             # undef REAL
286             # undef FFT_SUFFIX
287             # define FFT_SUFFIX f
288             # define REAL float
289             # include "fftn.c" /* include this file again */
290             #endif
291             /*}}}*/
292             #else /* _FFTN_C */
293              
294             # undef FFTN
295             # undef FFTNS
296             # undef FFTRADIX
297             # undef FFTRADIXS
298             # define FFTN FFT_CONCAT(fftn, FFT_SUFFIX) /* maybe trailing [fl] */
299             # define FFTNS FFT_STR(FFTN) /* name for error message */
300             # define FFTRADIX FFT_CONCAT(fftradix, FFT_SUFFIX) /* maybe trailing [fl] */
301             # define FFTRADIXS FFT_STR(FFTRADIX) /* name for error message */
302              
303             /*----------------------------------------------------------------------*/
304             /*
305             * singleton's mixed radix routine
306             */
307             static int
308 10964           FFTRADIX (REAL Re [],
  2308            
  8656            
  0            
309             REAL Im [],
310             size_t nTotal,
311             size_t nPass,
312             size_t nSpan,
313             int iSign,
314             int maxFactors,
315             int maxPerm)
316             {
317             #ifndef FFTRADIX_RETURN
318             #define FFTRADIX_RETURN(v) \
319             do { \
320             if (Rtmp) free(Rtmp); \
321             if (Itmp) free(Itmp); \
322             if (Cos) free(Cos); \
323             if (Sin) free(Sin); \
324             if (Perm) free(Perm); \
325             return v; \
326             } while (0)
327             #endif
328             #ifndef FFTRADIX_MALLOC
329             #define FFTRADIX_MALLOC(t, p, n) \
330             do { p = malloc(sizeof(t) * n); if (!p) FFTRADIX_RETURN(-1); } while (0)
331             #endif
332 10964 50         if (nPass < 2)
  2308 50          
  8656 0          
  0            
333 0           return 0;
  0            
  0            
  0            
334              
335             int ii, nFactor, factor[NFACTOR], kspan, ispan, inc;
336             int j, jc, jf, jj, k, k1, k3, kk, kt, nn, ns, nt;
337              
338             REALFIX radf;
339             REALFIX c1, c2, c3, cd;
340             REALFIX s1, s2, s3, sd;
341              
342 10964           REALFIX *Rtmp=NULL, *Itmp=NULL, *Cos=NULL, *Sin=NULL;
  2308            
  8656            
  0            
343 10964           int *Perm=NULL;
  2308            
  8656            
  0            
344 10964 50         FFTRADIX_MALLOC(REALFIX, Rtmp, maxFactors); /* temp space for real part */
  2308 0          
  8656 0          
  0 0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
345 10964 50         FFTRADIX_MALLOC(REALFIX, Itmp, maxFactors); /* temp space for imag part */
  2308 0          
  8656 0          
  0 0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
346 10964 50         FFTRADIX_MALLOC(REALFIX, Cos, maxFactors); /* Cosine values */
  2308 0          
  8656 0          
  0 0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
347 10964 50         FFTRADIX_MALLOC(REALFIX, Sin, maxFactors); /* Sine values */
  2308 0          
  8656 0          
  0 0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
348 10964 50         FFTRADIX_MALLOC(int, Perm, maxPerm);
  2308 0          
  8656 0          
  0 0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
349              
350             #ifndef FFT_RADIX4
351 10964           REALFIX s60 = SIN60; /* sin(60 deg) */
  2308            
  8656            
  0            
352 10964           REALFIX s72 = SIN72; /* sin(72 deg) */
  2308            
  8656            
  0            
353 10964           REALFIX c72 = COS72; /* cos(72 deg) */
  2308            
  8656            
  0            
354             #endif
355 10964           REALFIX pi2 = M_PI; /* use PI first, 2 PI later */
  2308            
  8656            
  0            
356              
357             /* gcc complains about k3 being uninitialized, but I can't find out where
358             * or why ... it looks okay to me.
359             *
360             * initialize to make gcc happy
361             */
362 10964           k3 = 0;
  2308            
  8656            
  0            
363              
364             /* gcc complains about c2, c3, s2,s3 being uninitialized, but they're
365             * only used for the radix 4 case and only AFTER the (s1 == 0.0) pass
366             * through the loop at which point they will have been calculated.
367             *
368             * initialize to make gcc happy
369             */
370 10964           c2 = c3 = s2 = s3 = 0.0;
  2308            
  8656            
  0            
371              
372             /* Parameter adjustments, was fortran so fix zero-offset */
373 10964           Re--;
  2308            
  8656            
  0            
374 10964           Im--;
  2308            
  8656            
  0            
375              
376             /*
377             * Function Body
378             */
379 10964           inc = iSign;
  2308            
  8656            
  0            
380 10964 100         if (iSign < 0)
  2308 100          
  8656 0          
  0            
381             {
382             #ifndef FFT_RADIX4
383 6584           s60 = -s60;
  1154            
  5430            
  0            
384 6584           s72 = -s72;
  1154            
  5430            
  0            
385             #endif
386 6584           pi2 = -pi2;
  1154            
  5430            
  0            
387 6584           inc = -inc; /* absolute value */
  1154            
  5430            
  0            
388             }
389              
390             /* adjust for strange increments */
391 10964           nt = inc * nTotal;
  2308            
  8656            
  0            
392 10964           ns = inc * nSpan;
  2308            
  8656            
  0            
393 10964           kspan = ns;
  2308            
  8656            
  0            
394              
395 10964           nn = nt - inc;
  2308            
  8656            
  0            
396 10964           jc = ns / nPass;
  2308            
  8656            
  0            
397 10964           radf = pi2 * (double) jc;
  2308            
  8656            
  0            
398 10964           pi2 *= 2.0; /* use 2 PI from here on */
  2308            
  8656            
  0            
399              
400 10964           ii = 0;
  2308            
  8656            
  0            
401 10964           jf = 0;
  2308            
  8656            
  0            
402             /* determine the factors of n */
403              
404 10964           nFactor = factorize (nPass, &kt, factor);
  2308            
  8656            
  0            
405             /* test that nFactors is in range */
406 10964 50         if (nFactor > NFACTOR)
  2308 50          
  8656 0          
  0            
407             {
408 0           fprintf (stderr, "Error: " FFTRADIXS "() - exceeded number of factors\n");
  0            
  0            
  0            
409 0           goto Memory_Error;
  0            
  0            
  0            
410             }
411              
412             /* compute fourier transform */
413             for (;;) {
414 62000           sd = radf / (double) kspan;
  13828            
  48172            
  0            
415 62000           cd = sin (sd);
  13828            
  48172            
  0            
416 62000           cd = 2.0 * cd * cd;
  13828            
  48172            
  0            
417 62000           sd = sin (sd + sd);
  13828            
  48172            
  0            
418 62000           kk = 1;
  13828            
  48172            
  0            
419 62000           ii++;
  13828            
  48172            
  0            
420              
421 62000           switch (factor [ii - 1]) {
  13828            
  48172            
  0            
422 31004           case 2:
  6912            
  24092            
  0            
423             /* transform for factor of 2 (including rotation factor) */
424 31004           kspan /= 2;
  6912            
  24092            
  0            
425 31004           k1 = kspan + 2;
  6912            
  24092            
  0            
426             do {
427             do {
428             REALFIX tmpr;
429             REALFIX tmpi;
430             int k2;
431              
432 600668           k2 = kk + kspan;
  138240            
  462428            
  0            
433 600668           tmpr = Re_Data (k2);
  138240            
  462428            
  0            
434 600668           tmpi = Im_Data (k2);
  138240            
  462428            
  0            
435 600668           Re_Data (k2) = Re_Data (kk) - tmpr;
  138240            
  462428            
  0            
436 600668           Im_Data (k2) = Im_Data (kk) - tmpi;
  138240            
  462428            
  0            
437 600668           Re_Data (kk) += tmpr;
  138240            
  462428            
  0            
438 600668           Im_Data (kk) += tmpi;
  138240            
  462428            
  0            
439 600668           kk = k2 + kspan;
  138240            
  462428            
  0            
440 600668 100         } while (kk <= nn);
  138240 100          
  462428 0          
  0            
441 31004           kk -= nn;
  6912            
  24092            
  0            
442 31004 50         } while (kk <= jc);
  6912 50          
  24092 0          
  0            
443 31004 50         if (kk > kspan)
  6912 100          
  24092 0          
  0            
444 144           goto Permute_Results; /* exit infinite loop */
  0            
  144            
  0            
445             do {
446             int k2;
447              
448 30860           c1 = 1.0 - cd;
  6912            
  23948            
  0            
449 30860           s1 = sd;
  6912            
  23948            
  0            
450             do {
451             REALFIX tmp;
452             do {
453             do {
454             REALFIX tmpr;
455             REALFIX tmpi;
456              
457 5154944           k2 = kk + kspan;
  1188864            
  3966080            
  0            
458 5154944           tmpr = Re_Data (kk) - Re_Data (k2);
  1188864            
  3966080            
  0            
459 5154944           tmpi = Im_Data (kk) - Im_Data (k2);
  1188864            
  3966080            
  0            
460 5154944           Re_Data (kk) += Re_Data (k2);
  1188864            
  3966080            
  0            
461 5154944           Im_Data (kk) += Im_Data (k2);
  1188864            
  3966080            
  0            
462 5154944           Re_Data (k2) = c1 * tmpr - s1 * tmpi;
  1188864            
  3966080            
  0            
463 5154944           Im_Data (k2) = s1 * tmpr + c1 * tmpi;
  1188864            
  3966080            
  0            
464 5154944           kk = k2 + kspan;
  1188864            
  3966080            
  0            
465 5154944 100         } while (kk < nt);
  1188864 100          
  3966080 0          
  0            
466 731888           k2 = kk - nt;
  168192            
  563696            
  0            
467 731888           c1 = -c1;
  168192            
  563696            
  0            
468 731888           kk = k1 - k2;
  168192            
  563696            
  0            
469 731888 100         } while (kk > k2);
  168192 100          
  563696 0          
  0            
470 381064           tmp = c1 - (cd * c1 + sd * s1);
  87552            
  293512            
  0            
471 381064           s1 = sd * c1 - cd * s1 + s1;
  87552            
  293512            
  0            
472 381064           c1 = 2.0 - (tmp * tmp + s1 * s1);
  87552            
  293512            
  0            
473 381064           s1 *= c1;
  87552            
  293512            
  0            
474 381064           c1 *= tmp;
  87552            
  293512            
  0            
475 381064           kk += jc;
  87552            
  293512            
  0            
476 381064 100         } while (kk < k2);
  87552 100          
  293512 0          
  0            
477 30860           k1 += (inc + inc);
  6912            
  23948            
  0            
478 30860           kk = (k1 - kspan) / 2 + jc;
  6912            
  23948            
  0            
479 30860 50         } while (kk <= jc + jc);
  6912 50          
  23948 0          
  0            
480 30860           break;
  6912            
  23948            
  0            
481              
482 19976           case 4: /* transform for factor of 4 */
  4612            
  15364            
  0            
483 19976           ispan = kspan;
  4612            
  15364            
  0            
484 19976           kspan /= 4;
  4612            
  15364            
  0            
485              
486             do {
487 19976           c1 = 1.0;
  4612            
  15364            
  0            
488 19976           s1 = 0.0;
  4612            
  15364            
  0            
489             do {
490             do {
491             REALFIX ajm, ajp, akm, akp;
492             REALFIX bjm, bjp, bkm, bkp;
493             int k2;
494              
495 1916936           k1 = kk + kspan;
  442372            
  1474564            
  0            
496 1916936           k2 = k1 + kspan;
  442372            
  1474564            
  0            
497 1916936           k3 = k2 + kspan;
  442372            
  1474564            
  0            
498 1916936           akp = Re_Data (kk) + Re_Data (k2);
  442372            
  1474564            
  0            
499 1916936           akm = Re_Data (kk) - Re_Data (k2);
  442372            
  1474564            
  0            
500              
501 1916936           ajp = Re_Data (k1) + Re_Data (k3);
  442372            
  1474564            
  0            
502 1916936           ajm = Re_Data (k1) - Re_Data (k3);
  442372            
  1474564            
  0            
503              
504 1916936           bkp = Im_Data (kk) + Im_Data (k2);
  442372            
  1474564            
  0            
505 1916936           bkm = Im_Data (kk) - Im_Data (k2);
  442372            
  1474564            
  0            
506              
507 1916936           bjp = Im_Data (k1) + Im_Data (k3);
  442372            
  1474564            
  0            
508 1916936           bjm = Im_Data (k1) - Im_Data (k3);
  442372            
  1474564            
  0            
509              
510 1916936           Re_Data (kk) = akp + ajp;
  442372            
  1474564            
  0            
511 1916936           Im_Data (kk) = bkp + bjp;
  442372            
  1474564            
  0            
512 1916936           ajp = akp - ajp;
  442372            
  1474564            
  0            
513 1916936           bjp = bkp - bjp;
  442372            
  1474564            
  0            
514 1916936 100         if (iSign < 0)
  442372 100          
  1474564 0          
  0            
515             {
516 1105924           akp = akm + bjm;
  221186            
  884738            
  0            
517 1105924           bkp = bkm - ajm;
  221186            
  884738            
  0            
518 1105924           akm -= bjm;
  221186            
  884738            
  0            
519 1105924           bkm += ajm;
  221186            
  884738            
  0            
520             }
521             else
522             {
523 811012           akp = akm - bjm;
  221186            
  589826            
  0            
524 811012           bkp = bkm + ajm;
  221186            
  589826            
  0            
525 811012           akm += bjm;
  221186            
  589826            
  0            
526 811012           bkm -= ajm;
  221186            
  589826            
  0            
527             }
528             /* avoid useless multiplies */
529 1916936 100         if (s1 == 0.0)
  442372 100          
  1474564 0          
  0            
530             {
531 968456           Re_Data (k1) = akp;
  223492            
  744964            
  0            
532 968456           Re_Data (k2) = ajp;
  223492            
  744964            
  0            
533 968456           Re_Data (k3) = akm;
  223492            
  744964            
  0            
534 968456           Im_Data (k1) = bkp;
  223492            
  744964            
  0            
535 968456           Im_Data (k2) = bjp;
  223492            
  744964            
  0            
536 968456           Im_Data (k3) = bkm;
  223492            
  744964            
  0            
537             }
538             else
539             {
540 948480           Re_Data (k1) = akp * c1 - bkp * s1;
  218880            
  729600            
  0            
541 948480           Re_Data (k2) = ajp * c2 - bjp * s2;
  218880            
  729600            
  0            
542 948480           Re_Data (k3) = akm * c3 - bkm * s3;
  218880            
  729600            
  0            
543 948480           Im_Data (k1) = akp * s1 + bkp * c1;
  218880            
  729600            
  0            
544 948480           Im_Data (k2) = ajp * s2 + bjp * c2;
  218880            
  729600            
  0            
545 948480           Im_Data (k3) = akm * s3 + bkm * c3;
  218880            
  729600            
  0            
546             }
547 1916936           kk = k3 + kspan;
  442372            
  1474564            
  0            
548 1916936 100         } while (kk <= nt);
  442372 100          
  1474564 0          
  0            
549              
550 968456           c2 = c1 - (cd * c1 + sd * s1);
  223492            
  744964            
  0            
551 968456           s1 = sd * c1 - cd * s1 + s1;
  223492            
  744964            
  0            
552 968456           c1 = 2.0 - (c2 * c2 + s1 * s1);
  223492            
  744964            
  0            
553 968456           s1 *= c1;
  223492            
  744964            
  0            
554 968456           c1 *= c2;
  223492            
  744964            
  0            
555             /* values of c2, c3, s2, s3 that will get used next time */
556 968456           c2 = c1 * c1 - s1 * s1;
  223492            
  744964            
  0            
557 968456           s2 = 2.0 * c1 * s1;
  223492            
  744964            
  0            
558 968456           c3 = c2 * c1 - s2 * s1;
  223492            
  744964            
  0            
559 968456           s3 = c2 * s1 + s2 * c1;
  223492            
  744964            
  0            
560 968456           kk = kk - nt + jc;
  223492            
  744964            
  0            
561 968456 100         } while (kk <= kspan);
  223492 100          
  744964 0          
  0            
562 19976           kk = kk - kspan + inc;
  4612            
  15364            
  0            
563 19976 50         } while (kk <= jc);
  4612 50          
  15364 0          
  0            
564 19976 100         if (kspan == jc)
  4612 100          
  15364 0          
  0            
565 9992           goto Permute_Results; /* exit infinite loop */
  2308            
  7684            
  0            
566 9984           break;
  2304            
  7680            
  0            
567              
568 11020           default:
  2304            
  8716            
  0            
569             /* transform for odd factors */
570             #ifdef FFT_RADIX4
571             fprintf (stderr, "Error: " FFTRADIXS "(): compiled for radix 2/4 only\n");
572             FFTRADIX_RETURN(-1);
573             break;
574             #else /* FFT_RADIX4 */
575 11020           ispan = kspan;
  2304            
  8716            
  0            
576 11020           k = factor [ii - 1];
  2304            
  8716            
  0            
577 11020           kspan /= factor [ii - 1];
  2304            
  8716            
  0            
578              
579 11020           switch (factor [ii - 1]) {
  2304            
  8716            
  0            
580 1269508           case 3: /* transform for factor of 3 (optional code) */
  292608            
  976900            
  0            
581             do {
582             do {
583             REALFIX aj, tmpr;
584             REALFIX bj, tmpi;
585             int k2;
586              
587 1279562           k1 = kk + kspan;
  294912            
  984650            
  0            
588 1279562           k2 = k1 + kspan;
  294912            
  984650            
  0            
589 1279562           tmpr = Re_Data (kk);
  294912            
  984650            
  0            
590 1279562           tmpi = Im_Data (kk);
  294912            
  984650            
  0            
591 1279562           aj = Re_Data (k1) + Re_Data (k2);
  294912            
  984650            
  0            
592 1279562           bj = Im_Data (k1) + Im_Data (k2);
  294912            
  984650            
  0            
593 1279562           Re_Data (kk) = tmpr + aj;
  294912            
  984650            
  0            
594 1279562           Im_Data (kk) = tmpi + bj;
  294912            
  984650            
  0            
595 1279562           tmpr -= 0.5 * aj;
  294912            
  984650            
  0            
596 1279562           tmpi -= 0.5 * bj;
  294912            
  984650            
  0            
597 1279562           aj = (Re_Data (k1) - Re_Data (k2)) * s60;
  294912            
  984650            
  0            
598 1279562           bj = (Im_Data (k1) - Im_Data (k2)) * s60;
  294912            
  984650            
  0            
599 1279562           Re_Data (k1) = tmpr - bj;
  294912            
  984650            
  0            
600 1279562           Re_Data (k2) = tmpr + bj;
  294912            
  984650            
  0            
601 1279562           Im_Data (k1) = tmpi + aj;
  294912            
  984650            
  0            
602 1279562           Im_Data (k2) = tmpi - aj;
  294912            
  984650            
  0            
603 1279562           kk = k2 + kspan;
  294912            
  984650            
  0            
604 1279562 100         } while (kk < nn);
  294912 100          
  984650 0          
  0            
605 81482           kk -= nn;
  18432            
  63050            
  0            
606 81482 100         } while (kk <= kspan);
  18432 100          
  63050 0          
  0            
607 10054           break;
  2304            
  7750            
  0            
608              
609 758           case 5: /* transform for factor of 5 (optional code) */
  0            
  758            
  0            
610 758           c2 = c72 * c72 - s72 * s72;
  0            
  758            
  0            
611 758           s2 = 2.0 * c72 * s72;
  0            
  758            
  0            
612             do {
613             do {
614             REALFIX aa, aj, ak, ajm, ajp, akm, akp;
615             REALFIX bb, bj, bk, bjm, bjp, bkm, bkp;
616             int k2, k4;
617              
618 2206           k1 = kk + kspan;
  0            
  2206            
  0            
619 2206           k2 = k1 + kspan;
  0            
  2206            
  0            
620 2206           k3 = k2 + kspan;
  0            
  2206            
  0            
621 2206           k4 = k3 + kspan;
  0            
  2206            
  0            
622 2206           akp = Re_Data (k1) + Re_Data (k4);
  0            
  2206            
  0            
623 2206           akm = Re_Data (k1) - Re_Data (k4);
  0            
  2206            
  0            
624 2206           bkp = Im_Data (k1) + Im_Data (k4);
  0            
  2206            
  0            
625 2206           bkm = Im_Data (k1) - Im_Data (k4);
  0            
  2206            
  0            
626 2206           ajp = Re_Data (k2) + Re_Data (k3);
  0            
  2206            
  0            
627 2206           ajm = Re_Data (k2) - Re_Data (k3);
  0            
  2206            
  0            
628 2206           bjp = Im_Data (k2) + Im_Data (k3);
  0            
  2206            
  0            
629 2206           bjm = Im_Data (k2) - Im_Data (k3);
  0            
  2206            
  0            
630 2206           aa = Re_Data (kk);
  0            
  2206            
  0            
631 2206           bb = Im_Data (kk);
  0            
  2206            
  0            
632 2206           Re_Data (kk) = aa + akp + ajp;
  0            
  2206            
  0            
633 2206           Im_Data (kk) = bb + bkp + bjp;
  0            
  2206            
  0            
634 2206           ak = akp * c72 + ajp * c2 + aa;
  0            
  2206            
  0            
635 2206           bk = bkp * c72 + bjp * c2 + bb;
  0            
  2206            
  0            
636 2206           aj = akm * s72 + ajm * s2;
  0            
  2206            
  0            
637 2206           bj = bkm * s72 + bjm * s2;
  0            
  2206            
  0            
638 2206           Re_Data (k1) = ak - bj;
  0            
  2206            
  0            
639 2206           Re_Data (k4) = ak + bj;
  0            
  2206            
  0            
640 2206           Im_Data (k1) = bk + aj;
  0            
  2206            
  0            
641 2206           Im_Data (k4) = bk - aj;
  0            
  2206            
  0            
642 2206           ak = akp * c2 + ajp * c72 + aa;
  0            
  2206            
  0            
643 2206           bk = bkp * c2 + bjp * c72 + bb;
  0            
  2206            
  0            
644 2206           aj = akm * s2 - ajm * s72;
  0            
  2206            
  0            
645 2206           bj = bkm * s2 - bjm * s72;
  0            
  2206            
  0            
646 2206           Re_Data (k2) = ak - bj;
  0            
  2206            
  0            
647 2206           Re_Data (k3) = ak + bj;
  0            
  2206            
  0            
648 2206           Im_Data (k2) = bk + aj;
  0            
  2206            
  0            
649 2206           Im_Data (k3) = bk - aj;
  0            
  2206            
  0            
650 2206           kk = k4 + kspan;
  0            
  2206            
  0            
651 2206 0         } while (kk < nn);
  0 100          
  2206 0          
  0            
652 1586           kk -= nn;
  0            
  1586            
  0            
653 1586 0         } while (kk <= kspan);
  0 100          
  1586 0          
  0            
654 758           break;
  0            
  758            
  0            
655              
656 208           default:
  0            
  208            
  0            
657 208           k = factor [ii - 1];
  0            
  208            
  0            
658 208 0         if (jf != k)
  0 50          
  208 0          
  0            
659             {
660 208           jf = k;
  0            
  208            
  0            
661 208           s1 = pi2 / (double) jf;
  0            
  208            
  0            
662 208           c1 = cos (s1);
  0            
  208            
  0            
663 208           s1 = sin (s1);
  0            
  208            
  0            
664 208 0         if (jf > maxFactors)
  0 50          
  208 0          
  0            
665 0           goto Memory_Error;
  0            
  0            
  0            
666 208           Cos [jf - 1] = 1.0;
  0            
  208            
  0            
667 208           Sin [jf - 1] = 0.0;
  0            
  208            
  0            
668 208           j = 1;
  0            
  208            
  0            
669             do {
670 1184           Cos [j - 1] = Cos [k - 1] * c1 + Sin [k - 1] * s1;
  0            
  1184            
  0            
671 1184           Sin [j - 1] = Cos [k - 1] * s1 - Sin [k - 1] * c1;
  0            
  1184            
  0            
672 1184           k--;
  0            
  1184            
  0            
673 1184           Cos [k - 1] = Cos [j - 1];
  0            
  1184            
  0            
674 1184           Sin [k - 1] = -Sin [j - 1];
  0            
  1184            
  0            
675 1184           j++;
  0            
  1184            
  0            
676 1184 0         } while (j < k);
  0 100          
  1184 0          
  0            
677             }
678             do {
679             do {
680             REALFIX aa, ak;
681             REALFIX bb, bk;
682             int k2;
683              
684 900           aa = ak = Re_Data (kk);
  0            
  900            
  0            
685 900           bb = bk = Im_Data (kk);
  0            
  900            
  0            
686              
687 900           k1 = kk;
  0            
  900            
  0            
688 900           k2 = kk + ispan;
  0            
  900            
  0            
689 900           j = 1;
  0            
  900            
  0            
690 900           k1 += kspan;
  0            
  900            
  0            
691             do {
692 4380           k2 -= kspan;
  0            
  4380            
  0            
693 4380           Rtmp [j] = Re_Data (k1) + Re_Data (k2);
  0            
  4380            
  0            
694 4380           ak += Rtmp [j];
  0            
  4380            
  0            
695 4380           Itmp [j] = Im_Data (k1) + Im_Data (k2);
  0            
  4380            
  0            
696 4380           bk += Itmp [j];
  0            
  4380            
  0            
697 4380           j++;
  0            
  4380            
  0            
698 4380           Rtmp [j] = Re_Data (k1) - Re_Data (k2);
  0            
  4380            
  0            
699 4380           Itmp [j] = Im_Data (k1) - Im_Data (k2);
  0            
  4380            
  0            
700 4380           j++;
  0            
  4380            
  0            
701 4380           k1 += kspan;
  0            
  4380            
  0            
702 4380 0         } while (k1 < k2);
  0 100          
  4380 0          
  0            
703 900           Re_Data (kk) = ak;
  0            
  900            
  0            
704 900           Im_Data (kk) = bk;
  0            
  900            
  0            
705              
706 900           k1 = kk;
  0            
  900            
  0            
707 900           k2 = kk + ispan;
  0            
  900            
  0            
708 900           j = 1;
  0            
  900            
  0            
709             do {
710 4380           REALFIX aj = 0.0;
  0            
  4380            
  0            
711 4380           REALFIX bj = 0.0;
  0            
  4380            
  0            
712              
713 4380           k1 += kspan;
  0            
  4380            
  0            
714 4380           k2 -= kspan;
  0            
  4380            
  0            
715 4380           jj = j;
  0            
  4380            
  0            
716 4380           ak = aa;
  0            
  4380            
  0            
717 4380           bk = bb;
  0            
  4380            
  0            
718 4380           k = 1;
  0            
  4380            
  0            
719             do {
720 31620           ak += Rtmp [k] * Cos [jj - 1];
  0            
  31620            
  0            
721 31620           bk += Itmp [k] * Cos [jj - 1];
  0            
  31620            
  0            
722 31620           k++;
  0            
  31620            
  0            
723 31620           aj += Rtmp [k] * Sin [jj - 1];
  0            
  31620            
  0            
724 31620           bj += Itmp [k] * Sin [jj - 1];
  0            
  31620            
  0            
725 31620           k++;
  0            
  31620            
  0            
726 31620           jj += j;
  0            
  31620            
  0            
727 31620 0         if (jj > jf)
  0 100          
  31620 0          
  0            
728 7680           jj -= jf;
  0            
  7680            
  0            
729 31620 0         } while (k < jf);
  0 100          
  31620 0          
  0            
730 4380           k = jf - j;
  0            
  4380            
  0            
731 4380           Re_Data (k1) = ak - bj;
  0            
  4380            
  0            
732 4380           Im_Data (k1) = bk + aj;
  0            
  4380            
  0            
733 4380           Re_Data (k2) = ak + bj;
  0            
  4380            
  0            
734 4380           Im_Data (k2) = bk - aj;
  0            
  4380            
  0            
735 4380           j++;
  0            
  4380            
  0            
736 4380 0         } while (j < k);
  0 100          
  4380 0          
  0            
737 900           kk += ispan;
  0            
  900            
  0            
738 900 0         } while (kk <= nn);
  0 100          
  900 0          
  0            
739 208           kk -= nn;
  0            
  208            
  0            
740 208 0         } while (kk <= kspan);
  0 50          
  208 0          
  0            
741 208           break;
  0            
  208            
  0            
742             }
743             /* multiply by rotation factor (except for factors of 2 and 4) */
744 11020 50         if (ii == nFactor)
  2304 100          
  8716 0          
  0            
745 828           goto Permute_Results; /* exit infinite loop */
  0            
  828            
  0            
746 10192           kk = jc + 1;
  2304            
  7888            
  0            
747             do {
748 10192           c2 = 1.0 - cd;
  2304            
  7888            
  0            
749 10192           s1 = sd;
  2304            
  7888            
  0            
750             do {
751 72256           c1 = c2;
  16128            
  56128            
  0            
752 72256           s2 = s1;
  16128            
  56128            
  0            
753 72256           kk += kspan;
  16128            
  56128            
  0            
754             do {
755             REALFIX tmp;
756             do {
757             REALFIX ak;
758 2242808           ak = Re_Data (kk);
  516096            
  1726712            
  0            
759 2242808           Re_Data (kk) = c2 * ak - s2 * Im_Data (kk);
  516096            
  1726712            
  0            
760 2242808           Im_Data (kk) = s2 * ak + c2 * Im_Data (kk);
  516096            
  1726712            
  0            
761 2242808           kk += ispan;
  516096            
  1726712            
  0            
762 2242808 100         } while (kk <= nt);
  516096 100          
  1726712 0          
  0            
763 146168           tmp = s1 * s2;
  32256            
  113912            
  0            
764 146168           s2 = s1 * c2 + c1 * s2;
  32256            
  113912            
  0            
765 146168           c2 = c1 * c2 - tmp;
  32256            
  113912            
  0            
766 146168           kk = kk - nt + kspan;
  32256            
  113912            
  0            
767 146168 100         } while (kk <= ispan);
  32256 100          
  113912 0          
  0            
768 72256           c2 = c1 - (cd * c1 + sd * s1);
  16128            
  56128            
  0            
769 72256           s1 += sd * c1 - cd * s1;
  16128            
  56128            
  0            
770 72256           c1 = 2.0 - (c2 * c2 + s1 * s1);
  16128            
  56128            
  0            
771 72256           s1 *= c1;
  16128            
  56128            
  0            
772 72256           c2 *= c1;
  16128            
  56128            
  0            
773 72256           kk = kk - ispan + jc;
  16128            
  56128            
  0            
774 72256 100         } while (kk <= kspan);
  16128 100          
  56128 0          
  0            
775 10192           kk = kk - kspan + jc + inc;
  2304            
  7888            
  0            
776 10192 50         } while (kk <= jc + jc);
  2304 50          
  7888 0          
  0            
777 10192           break;
  2304            
  7888            
  0            
778             #endif /* FFT_RADIX4 */
779             }
780             }
781              
782             /* permute the results to normal order -- done in two stages */
783             /* permutation for square factors of n */
784 10964           Permute_Results:
  2308            
  8656            
  0            
785 10964           Perm [0] = ns;
  2308            
  8656            
  0            
786 10964 100         if (kt)
  2308 100          
  8656 0          
  0            
787             {
788             int k2;
789              
790 10128           k = kt + kt + 1;
  2304            
  7824            
  0            
791 10128 50         if (k > nFactor)
  2304 50          
  7824 0          
  0            
792 0           k--;
  0            
  0            
  0            
793 10128           Perm [k] = jc;
  2304            
  7824            
  0            
794 10128           j = 1;
  2304            
  7824            
  0            
795             do {
796 20112           Perm [j] = Perm [j - 1] / factor [j - 1];
  4608            
  15504            
  0            
797 20112           Perm [k - 1] = Perm [k] * factor [j - 1];
  4608            
  15504            
  0            
798 20112           j++;
  4608            
  15504            
  0            
799 20112           k--;
  4608            
  15504            
  0            
800 20112 100         } while (j < k);
  4608 100          
  15504 0          
  0            
801 10128           k3 = Perm [k];
  2304            
  7824            
  0            
802 10128           kspan = Perm [1];
  2304            
  7824            
  0            
803 10128           kk = jc + 1;
  2304            
  7824            
  0            
804 10128           k2 = kspan + 1;
  2304            
  7824            
  0            
805 10128           j = 1;
  2304            
  7824            
  0            
806 10128 50         if (nPass != nTotal)
  2304 50          
  7824 0          
  0            
807             {
808             /* permutation for multivariate transform */
809 0           Permute_Multi:
  0            
  0            
  0            
810             do {
811             do {
812 0           k = kk + jc;
  0            
  0            
  0            
813             do {
814             /* swap
815             * Re_Data (kk) <> Re_Data (k2)
816             * Im_Data (kk) <> Im_Data (k2)
817             */
818             REALFIX tmp;
819 0           tmp = Re_Data (kk); Re_Data (kk) = Re_Data (k2); Re_Data (k2) = tmp;
  0            
  0            
  0            
820 0           tmp = Im_Data (kk); Im_Data (kk) = Im_Data (k2); Im_Data (k2) = tmp;
  0            
  0            
  0            
821 0           kk += inc;
  0            
  0            
  0            
822 0           k2 += inc;
  0            
  0            
  0            
823 0 0         } while (kk < k);
  0 0          
  0 0          
  0            
824 0           kk += (ns - jc);
  0            
  0            
  0            
825 0           k2 += (ns - jc);
  0            
  0            
  0            
826 0 0         } while (kk < nt);
  0 0          
  0 0          
  0            
827 0           k2 = k2 - nt + kspan;
  0            
  0            
  0            
828 0           kk = kk - nt + jc;
  0            
  0            
  0            
829 0 0         } while (k2 < ns);
  0 0          
  0 0          
  0            
830             do {
831             do {
832 0           k2 -= Perm [j - 1];
  0            
  0            
  0            
833 0           j++;
  0            
  0            
  0            
834 0           k2 = Perm [j] + k2;
  0            
  0            
  0            
835 0 0         } while (k2 > Perm [j - 1]);
  0 0          
  0 0          
  0            
836 0           j = 1;
  0            
  0            
  0            
837             do {
838 0 0         if (kk < k2)
  0 0          
  0 0          
  0            
839 0           goto Permute_Multi;
  0            
  0            
  0            
840 0           kk += jc;
  0            
  0            
  0            
841 0           k2 += kspan;
  0            
  0            
  0            
842 0 0         } while (k2 < ns);
  0 0          
  0 0          
  0            
843 0 0         } while (kk < ns);
  0 0          
  0 0          
  0            
844             }
845             else
846             {
847             /* permutation for single-variate transform (optional code) */
848 789168           Permute_Single:
  182016            
  607152            
  0            
849             do {
850             /* swap
851             * Re_Data (kk) <> Re_Data (k2)
852             * Im_Data (kk) <> Im_Data (k2)
853             */
854             REALFIX t;
855 1677600           t = Re_Data (kk); Re_Data (kk) = Re_Data (k2); Re_Data (k2) = t;
  387072            
  1290528            
  0            
856 1677600           t = Im_Data (kk); Im_Data (kk) = Im_Data (k2); Im_Data (k2) = t;
  387072            
  1290528            
  0            
857 1677600           kk += inc;
  387072            
  1290528            
  0            
858 1677600           k2 += kspan;
  387072            
  1290528            
  0            
859 1677600 100         } while (k2 < ns);
  387072 100          
  1290528 0          
  0            
860             do {
861             do {
862 1518144           k2 -= Perm [j - 1];
  350208            
  1167936            
  0            
863 1518144           j++;
  350208            
  1167936            
  0            
864 1518144           k2 = Perm [j] + k2;
  350208            
  1167936            
  0            
865 1518144 100         } while (k2 > Perm [j - 1]);
  350208 100          
  1167936 0          
  0            
866 948912           j = 1;
  218880            
  730032            
  0            
867             do {
868 2906064 100         if (kk < k2)
  670464 100          
  2235600 0          
  0            
869 768912           goto Permute_Single;
  177408            
  591504            
  0            
870 2137152           kk += inc;
  493056            
  1644096            
  0            
871 2137152           k2 += kspan;
  493056            
  1644096            
  0            
872 2137152 100         } while (k2 < ns);
  493056 100          
  1644096 0          
  0            
873 180000 100         } while (kk < ns);
  41472 100          
  138528 0          
  0            
874             }
875 10128           jc = k3;
  2304            
  7824            
  0            
876             }
877              
878 10964 100         if ((kt << 1) + 1 >= nFactor)
  2308 100          
  8656 0          
  0            
879 152 50         FFTRADIX_RETURN(0);
  4 50          
  148 50          
  0 50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
880 10812           ispan = Perm [kt];
  2304            
  8508            
  0            
881              
882             /* permutation for square-free factors of n */
883 10812           j = nFactor - kt;
  2304            
  8508            
  0            
884 10812           factor [j] = 1;
  2304            
  8508            
  0            
885             do {
886 21624           factor [j - 1] *= factor [j];
  4608            
  17016            
  0            
887 21624           j--;
  4608            
  17016            
  0            
888 21624 100         } while (j != kt);
  4608 100          
  17016 0          
  0            
889 10812           nn = factor [kt] - 1;
  2304            
  8508            
  0            
890 10812           kt++;
  2304            
  8508            
  0            
891 10812 50         if (nn > maxPerm)
  2304 50          
  8508 0          
  0            
892 0           goto Memory_Error;
  0            
  0            
  0            
893              
894 10812           j = jj = 0;
  2304            
  8508            
  0            
895 64952           for (;;) {
  11520            
  53432            
  0            
896             int k2;
897              
898 75764           k = kt + 1;
  13824            
  61940            
  0            
899 75764           k2 = factor [kt - 1];
  13824            
  61940            
  0            
900 75764           kk = factor [k - 1];
  13824            
  61940            
  0            
901 75764           j++;
  13824            
  61940            
  0            
902 75764 100         if (j > nn)
  13824 100          
  61940 0          
  0            
903 10812           break; /* exit infinite loop */
  2304            
  8508            
  0            
904 64952           jj += kk;
  11520            
  53432            
  0            
905 89768 100         while (jj >= k2)
  16128 100          
  73640 0          
  0            
906             {
907 24816           jj -= k2;
  4608            
  20208            
  0            
908 24816           k2 = kk;
  4608            
  20208            
  0            
909 24816           kk = factor [k++];
  4608            
  20208            
  0            
910 24816           jj += kk;
  4608            
  20208            
  0            
911             }
912 64952           Perm [j - 1] = jj;
  11520            
  53432            
  0            
913             }
914             /* determine the permutation cycles of length greater than 1 */
915 10812           j = 0;
  2304            
  8508            
  0            
916 12058           for (;;) {
  2304            
  9754            
  0            
917             do {
918 64952           kk = Perm [j++];
  11520            
  53432            
  0            
919 64952 100         } while (kk < 0);
  11520 100          
  53432 0          
  0            
920 22870 100         if (kk != j)
  4608 100          
  18262 0          
  0            
921             {
922             do {
923 42082           k = kk;
  6912            
  35170            
  0            
924 42082           kk = Perm [k - 1];
  6912            
  35170            
  0            
925 42082           Perm [k - 1] = -kk;
  6912            
  35170            
  0            
926 42082 100         } while (kk != j);
  6912 100          
  35170 0          
  0            
927 11850           k3 = kk;
  2304            
  9546            
  0            
928             }
929             else
930             {
931 11020           Perm [j - 1] = -j;
  2304            
  8716            
  0            
932 11020 50         if (j == nn)
  2304 100          
  8716 0          
  0            
933 10812           break; /* exit infinite loop */
  2304            
  8508            
  0            
934             }
935             }
936              
937 10812           maxFactors *= inc;
  2304            
  8508            
  0            
938              
939             /* reorder a and b, following the permutation cycles */
940             for (;;) {
941 91512           j = k3 + 1;
  20736            
  70776            
  0            
942 91512           nt -= ispan;
  20736            
  70776            
  0            
943 91512           ii = nt - inc + 1;
  20736            
  70776            
  0            
944 91512 100         if (nt < 0)
  20736 100          
  70776 0          
  0            
945 10812           break; /* exit infinite loop */
  2304            
  8508            
  0            
946             do {
947             do {
948 83198           j--;
  18432            
  64766            
  0            
949 83198 50         } while (Perm [j - 1] < 0);
  18432 100          
  64766 0          
  0            
950 81738           jj = jc;
  18432            
  63306            
  0            
951             do {
952             int k2;
953              
954 81738 50         if (jj < maxFactors) kspan = jj; else kspan = maxFactors;
  18432 50          
  63306 0          
  0            
955              
956 81738           jj -= kspan;
  18432            
  63306            
  0            
957 81738           k = Perm [j - 1];
  18432            
  63306            
  0            
958 81738           kk = jc * k + ii + jj;
  18432            
  63306            
  0            
959              
960 81738           k1 = kk + kspan;
  18432            
  63306            
  0            
961 81738           k2 = 0;
  18432            
  63306            
  0            
962             do {
963 640842           Rtmp [k2] = Re_Data (k1);
  147456            
  493386            
  0            
964 640842           Itmp [k2] = Im_Data (k1);
  147456            
  493386            
  0            
965 640842           k2++;
  147456            
  493386            
  0            
966 640842           k1 -= inc;
  147456            
  493386            
  0            
967 640842 100         } while (k1 != kk);
  147456 100          
  493386 0          
  0            
968              
969             do {
970 251746           k1 = kk + kspan;
  55296            
  196450            
  0            
971 251746           k2 = k1 - jc * (k + Perm [k - 1]);
  55296            
  196450            
  0            
972 251746           k = -Perm [k - 1];
  55296            
  196450            
  0            
973             do {
974 1929058           Re_Data (k1) = Re_Data (k2);
  442368            
  1486690            
  0            
975 1929058           Im_Data (k1) = Im_Data (k2);
  442368            
  1486690            
  0            
976 1929058           k1 -= inc;
  442368            
  1486690            
  0            
977 1929058           k2 -= inc;
  442368            
  1486690            
  0            
978 1929058 100         } while (k1 != kk);
  442368 100          
  1486690 0          
  0            
979 251746           kk = k2;
  55296            
  196450            
  0            
980 251746 100         } while (k != j);
  55296 100          
  196450 0          
  0            
981              
982 81738           k1 = kk + kspan;
  18432            
  63306            
  0            
983 81738           k2 = 0;
  18432            
  63306            
  0            
984             do {
985 640842           Re_Data (k1) = Rtmp [k2];
  147456            
  493386            
  0            
986 640842           Im_Data (k1) = Itmp [k2];
  147456            
  493386            
  0            
987 640842           k2++;
  147456            
  493386            
  0            
988 640842           k1 -= inc;
  147456            
  493386            
  0            
989 640842 100         } while (k1 != kk);
  147456 100          
  493386 0          
  0            
990 81738 50         } while (jj);
  18432 50          
  63306 0          
  0            
991 81738 50         } while (j != 1);
  18432 100          
  63306 0          
  0            
992             }
993 10812 50         FFTRADIX_RETURN(0); /* exit point here */
  2304 50          
  8508 50          
  0 50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
994              
995             /* alloc or other problem, do some clean-up */
996 0           Memory_Error:
  0            
  0            
  0            
997 0           fprintf (stderr, "Error: " FFTRADIXS "() - insufficient memory.\n");
  0            
  0            
  0            
998 0 0         FFTRADIX_RETURN(-1);
  0 0          
  0 0          
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
999             #undef FFTRADIX_RETURN
1000             #undef FFTRADIX_MALLOC
1001             }
1002              
1003             /*
1004             *
1005             */
1006             int
1007 10964           FFTN (size_t ndim,
1008             const size_t dims [],
1009             REAL Re [],
1010             REAL Im [],
1011             int iSign,
1012             REAL scaling)
1013             {
1014             size_t nTotal;
1015             int maxFactors, maxPerm;
1016              
1017             /*
1018             * tally the number of elements in the data array
1019             * and determine the number of dimensions
1020             */
1021 10964           nTotal = 1;
1022 10964           if (ndim)
1023             {
1024 10964           if (dims != NULL)
1025             {
1026             int i;
1027             /* number of dimensions was specified */
1028 0           for (i = 0; i < ndim; i++)
1029             {
1030 0           if (dims [i] <= 0) goto Dimension_Error;
1031 0           nTotal *= dims [i];
1032             }
1033             }
1034             else
1035 10964           nTotal *= ndim;
1036             }
1037             else
1038             {
1039             int i;
1040             /* determine # of dimensions from zero-terminated list */
1041 0           if (dims == NULL) goto Dimension_Error;
1042 0           for (ndim = i = 0; dims [i]; i++)
1043             {
1044 0           if (dims [i] <= 0)
1045 0           goto Dimension_Error;
1046 0           nTotal *= dims [i];
1047 0           ndim++;
1048             }
1049             }
1050              
1051             /* determine maximum number of factors and permuations */
1052             #if 1
1053             /*
1054             * follow John Beale's example, just use the largest dimension and don't
1055             * worry about excess allocation. May be someone else will do it?
1056             */
1057 10964           if (dims != NULL)
1058             {
1059             int i;
1060 0           for (maxFactors = maxPerm = 1, i = 0; i < ndim; i++)
1061             {
1062 0           if (dims [i] > maxFactors) maxFactors = dims [i];
1063 0           if (dims [i] > maxPerm) maxPerm = dims [i];
1064             }
1065             }
1066             else
1067             {
1068 10964           maxFactors = maxPerm = nTotal;
1069             }
1070             #else
1071             /* use the constants used in the original Fortran code */
1072             maxFactors = 23;
1073             maxPerm = 209;
1074             #endif
1075             /* loop over the dimensions: */
1076 10964           if (dims != NULL)
1077             {
1078 0           size_t nSpan = 1;
1079             int i;
1080              
1081 0           for (i = 0; i < ndim; i++)
1082             {
1083             int ret;
1084 0           nSpan *= dims [i];
1085 0           ret = FFTRADIX (Re, Im, nTotal, dims [i], nSpan, iSign,
1086             maxFactors, maxPerm);
1087             /* exit, clean-up already done */
1088 0           if (ret)
1089 0           return ret;
1090             }
1091             }
1092             else
1093             {
1094             int ret;
1095 10964           ret = FFTRADIX (Re, Im, nTotal, nTotal, nTotal, iSign,
1096             maxFactors, maxPerm);
1097             /* exit, clean-up already done */
1098 10964           if (ret)
1099 0           return ret;
1100             }
1101              
1102             /* Divide through by the normalizing constant: */
1103 10964           if (scaling && scaling != 1.0)
1104             {
1105             int i;
1106              
1107 4380           if (iSign < 0) iSign = -iSign;
1108 4380           if (scaling < 0.0)
1109 4380           scaling = (scaling < -1.0) ? sqrt (nTotal) : nTotal;
1110              
1111 4380           scaling = 1.0 / scaling; /* multiply is often faster */
1112 1631626           for (i = 0; i < nTotal; i += iSign)
1113             {
1114 1627246           Re_Data (i) *= scaling;
1115 1627246           Im_Data (i) *= scaling;
1116             }
1117             }
1118 10964           return 0;
1119              
1120 0           Dimension_Error:
1121 0           fprintf (stderr, "Error: " FFTNS "() - dimension error\n");
1122 0           return -1;
1123             }
1124             #endif /* _FFTN_C */
1125             /*----------------------- end-of-file (C source) -----------------------*/