casacore
Loading...
Searching...
No Matches
SCSL.h
Go to the documentation of this file.
1// # extern_fft.h: C++ wrapper functions for FORTRAN FFT code
2// # Copyright (C) 1993,1994,1995,1997,1999,2000
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef SCIMATH_SCSL_H
27#define SCIMATH_SCSL_H
28
29#include <casacore/casa/aips.h>
30#include <casacore/casa/BasicSL/Complex.h>
31
32namespace casacore { // # NAMESPACE CASACORE - BEGIN
33
34// <summary>C++ Interface to the Sgi/Cray Scientific Library (SCSL)</summary>
35// <synopsis>
36// These are C++ wrapper functions for the transform routines in the SGI/Cray
37// Scientific Library (SCSL). The purpose of these definitions is to overload
38// the functions so that C++ users can access the functions in SCSL with
39// identical function names.
40//
41// <note role=warning>
42// Currently, the SCSL is available only on SGI machines.
43// </note>
44// </synopsis>
45
46class SCSL {
47 public:
48 // These routines compute the Fast Fourier Transform (FFT) of the complex
49 // vector x, and store the result in vector y. <src>ccfft</src> does the
50 // complex-to-complex transform and <src>zzfft</src> does the same for double
51 // precision arrays.
52 //
53 // In FFT applications, it is customary to use zero-based subscripts; the
54 // formulas are simpler that way. Suppose that the arrays are
55 // dimensioned as follows:
56 //
57 // <srcblock>
58 // COMPLEX X(0:N-1), Y(0:N-1)
59 // </srcblock>
60 //
61 // The output array is the FFT of the input array, using the following
62 // formula for the FFT:
63 //
64 // <srcblock>
65 // n-1
66 // Y(k) = scale * Sum [ X(j)*w**(isign*j*k) ] for k = 0, ..., n-1
67 // j=0
68 //
69 // where:
70 // w = exp(2*pi*i/n),
71 // i = + sqrt(-1),
72 // pi = 3.14159...,
73 // isign = +1 or -1
74 // </srcblock>
75 //
76 // Different authors use different conventions for which of the
77 // transforms, isign = +1 or isign = -1, is the forward or inverse
78 // transform, and what the scale factor should be in either case. You
79 // can make this routine compute any of the various possible definitions,
80 // however, by choosing the appropriate values for isign and scale.
81 //
82 // The relevant fact from FFT theory is this: If you take the FFT with
83 // any particular values of isign and scale, the mathematical inverse
84 // function is computed by taking the FFT with -isign and 1/(n*scale).
85 // In particular, if you use isign = +1 and scale = 1.0 you can compute
86 // the inverse FFT by using isign = -1 and scale = 1.0/n.
87 //
88 // The output array may be the same as the input array.
89 //
90 // <h3>Initialization</h3>
91 // The table array stores the trigonometric tables used in calculation of
92 // the FFT. You must initialize table by calling the routine with isign
93 // = 0 prior to doing the transforms. If the value of the problem size,
94 // n, does not change, table does not have to be reinitialized.
95 //
96 // <h3>Dimensions</h3>
97 // In the preceding description, it is assumed that array subscripts were
98 // zero-based, as is customary in FFT applications. Thus, the input and
99 // output arrays are declared as follows:
100 //
101 // <srcblock>
102 // COMPLEX X(0:N-1)
103 // COMPLEX Y(0:N-1)
104 // </srcblock>
105 //
106 // However, if you prefer to use the more customary FORTRAN style with
107 // subscripts starting at 1 you do not have to change the calling
108 // sequence, as in the following (assuming N > 0):
109 //
110 // <srcblock>
111 // COMPLEX X(N)
112 // COMPLEX Y(N)
113 // </srcblock>
114 //
115 // <example>
116 // These examples use the table and workspace sizes appropriate to the
117 // Origin series.
118 //
119 // Example 1: Initialize the complex array table in preparation for
120 // doing an FFT of size 1024. Only the isign, n, and table arguments are
121 // used in this case. You can use dummy arguments or zeros for the other
122 // arguments in the subroutine call.
123 //
124 // <srcblock>
125 // REAL TABLE(30 + 2048)
126 // CALL CCFFT(0, 1024, 0.0, DUMMY, DUMMY, TABLE, DUMMY, 0)
127 // </srcblock>
128 //
129 // Example 2: x and y are complex arrays of dimension (0:1023). Take
130 // the FFT of x and store the results in y. Before taking the FFT,
131 // initialize the table array, as in example 1.
132 //
133 // <srcblock>
134 // COMPLEX X(0:1023), Y(0:1023)
135 // REAL TABLE(30 + 2048)
136 // REAL WORK(2048)
137 // CALL CCFFT(0, 1024, 1.0, X, Y, TABLE, WORK, 0)
138 // CALL CCFFT(1, 1024, 1.0, X, Y, TABLE, WORK, 0)
139 // </srcblock>
140 //
141 // Example 3: Using the same x and y as in example 2, take the inverse
142 // FFT of y and store it back in x. The scale factor 1/1024 is used.
143 // Assume that the table array is already initialized.
144 //
145 // <srcblock>
146 // CALL CCFFT(-1, 1024, 1.0/1024.0, Y, X, TABLE, WORK, 0)
147 // </srcblock>
148 //
149 // Example 4: Perform the same computation as in example 2, but assume
150 // that the lower bound of each array is 1, rather than 0. No change was
151 // needed in the subroutine calls.
152 //
153 // <srcblock>
154 // COMPLEX X(1024), Y(1024)
155 // CALL CCFFT(0, 1024, 1.0, X, Y, TABLE, WORK, 0)
156 // CALL CCFFT(1, 1024, 1.0, X, Y, TABLE, WORK, 0)
157 // </srcblock>
158 //
159 // Example 5: Do the same computation as in example 4, but put the
160 // output back in array x to save storage space. Assume that table is
161 // already initialized.
162 //
163 // <srcblock>
164 // COMPLEX X(1024)
165 // CALL CCFFT(1, 1024, 1.0, X, X, TABLE, WORK, 0)
166 // </srcblock>
167 // </example>
168 //
169 // Input parameters:
170 // <dl compact>
171 // <dt><b>isign</b>
172 // <dd> Integer.
173 // Specifies whether to initialize the table array or to do the
174 // forward or inverse Fourier transform, as follows:
175 //
176 // If isign = 0, the routine initializes the table array and
177 // returns. In this case, the only arguments used or checked
178 // are isign, n, and table.
179 //
180 // If isign = +1 or -1, the value of isign is the sign of the
181 // exponent used in the FFT formula.
182 // <dt><b>n</b>
183 // <dd> Integer. Size of the transform (the number of values in
184 // the input array). n >= 1.
185 // <dt><b>scale</b>
186 // <dd> Scale factor.
187 // <src>ccfft</src>: real.
188 // <src>zzfft</src>: double precision.
189 // Each element of the output array is multiplied by scale
190 // after taking the Fourier transform, as defined by the previous
191 // formula.
192 // <dt><b>x</b>
193 // <dd> Array of dimension (0:n-1).
194 // <src>ccfft</src>: complex array.
195 // <src>zzfft</src>: double complex array.
196 //
197 // Input array of values to be transformed.
198 // <dt><b>isys</b>
199 // <dd> Integer.
200 // Algorithm used; value dependent on hardware system. Currently, no
201 // special options are supported; therefore, you must always specify
202 // an isys argument as constant 0.
203 // </dl>
204 // Output parameters:
205 // <dl compact>
206 // <dt><b>y</b>
207 // <dd> Array of dimension (0:n-1).
208 // <src>ccfft</src>: complex array.
209 // <src>zzfft</src>: double complex array.
210 // Output array of transformed values. The output array may be
211 // the same as the input array. In that case, the transform is
212 // done in place and the input array is overwritten with the
213 // transformed values.
214 // <dt><b>table</b>
215 // <dd> Real array; dimension 2*n+30.
216 //
217 // Table of factors and trigonometric functions.
218 //
219 // If isign = 0, the routine initializes table (table is output
220 // only).
221 //
222 // If isign = +1 or -1, the values in table are assumed to be
223 // initialized already by a prior call with isign = 0 (table is
224 // input only).
225 // <dt><b>work</b>
226 // <dd> Real array; dimension 2*n.
227 //
228 // Work array. This is a scratch array used for intermediate
229 // calculations. Its address space must be different address
230 // space from that of the input and output arrays.
231 // </dl>
232 // <group>
233 static void ccfft(Int isign, Int n, Float scale, Complex* x, Complex* y, Float* table,
234 Float* work, Int isys);
235 static void ccfft(Int isign, Int n, Double scale, DComplex* x, DComplex* y, Double* table,
236 Double* work, Int isys);
237 static void zzfft(Int isign, Int n, Double scale, DComplex* x, DComplex* y, Double* table,
238 Double* work, Int isys);
239 // </group>
240
241 // <src>scfft/dzfft</src> computes the FFT of the real array x, and it stores
242 // the results in the complex array y. <src>csfft/zdfft</src> computes the
243 // corresponding inverse complex-to-real transform.
244 //
245 // It is customary in FFT applications to use zero-based subscripts; the
246 // formulas are simpler that way. For these routines, suppose that the
247 // arrays are dimensioned as follows:
248 //
249 // <srcblock>
250 // REAL X(0:n-1)
251 // COMPLEX Y(0:n/2)
252 // </srcblock>
253 //
254 // Then the output array is the FFT of the input array, using the
255 // following formula for the FFT:
256 //
257 // <srcblock>
258 // n-1
259 // Y(k) = scale * Sum [ X(j)*w**(isign*j*k) ] for k = 0, ..., n/2
260 // j=0
261 //
262 // where:
263 // w = exp(2*pi*i/n),
264 // i = + sqrt(-1),
265 // pi = 3.14159...,
266 // isign = +1 or -1.
267 // </srcblock>
268 //
269 // Different authors use different conventions for which of the
270 // transforms, isign = +1 or isign = -1, is the forward or inverse
271 // transform, and what the scale factor should be in either case. You
272 // can make these routines compute any of the various possible
273 // definitions, however, by choosing the appropriate values for isign and
274 // scale.
275 //
276 // The relevant fact from FFT theory is this: If you call <src>scfft</src>
277 // with any particular values of isign and scale, the mathematical inverse
278 // function is computed by calling <src>csfft</src> with -isign and
279 // 1/(n*scale). In particular, if you use isign = +1 and scale = 1.0 in
280 // <src>scfft</src> for the forward FFT, you can compute the inverse FFT by
281 // using <src>ccfft</src> with isign = -1 and scale = 1.0/n.
282 //
283 // <h3>Real-to-complex FFTs</h3>
284 // Notice in the preceding formula that there are n real input values,
285 // and n/2 + 1 complex output values. This property is characteristic of
286 // real-to-complex FFTs.
287 //
288 // The mathematical definition of the Fourier transform takes a sequence
289 // of n complex values and transforms it to another sequence of n complex
290 // values. A complex-to-complex FFT routine, such as <src>ccfft</src>, will
291 // take n complex input values, and produce n complex output values. In
292 // fact, one easy way to compute a real-to-complex FFT is to store the
293 // input data in a complex array, then call routine <src>ccfft</src> to
294 // compute the FFT. You get the same answer when using the <src>scfft</src>
295 // routine.
296 //
297 // The reason for having a separate real-to-complex FFT routine is
298 // efficiency. Because the input data is real, you can make use of this
299 // fact to save almost half of the computational work. The theory of
300 // Fourier transforms tells us that for real input data, you have to
301 // compute only the first n/2 + 1 complex output values, because the
302 // remaining values can be computed from the first half of the values by
303 // the simple formula:
304 //
305 // <srcblock>
306 // Y(k) = conjg(Y(n-k)) for n/2 <= k <= n-1
307 // </srcblock>
308 //
309 // where the notation conjgY represents the complex conjugate of y.
310 //
311 // In fact, in many applications, the second half of the complex output
312 // data is never explicitly computed or stored. Likewise, as explained
313 // later, only the first half of the complex data has to be supplied for
314 // the complex-to-real FFT.
315 //
316 // Another implication of FFT theory is that, for real input data, the
317 // first output value, Y(0), will always be a real number; therefore, the
318 // imaginary part will always be 0. If n is an even number, Y(n/2) will
319 // also be real and thus, have zero imaginary parts.
320 //
321 // <h3>Complex-to-real FFTs</h3>
322 // Consider the complex-to-real case. The effect of the computation is
323 // given by the preceding formula, but with X complex and Y real.
324 //
325 // Generally, the FFT transforms a complex sequence into a complex
326 // sequence. However, in a certain application we may know the output
327 // sequence is real. Often, this is the case because the complex input
328 // sequence was the transform of a real sequence. In this case, you can
329 // save about half of the computational work.
330 //
331 // According to the theory of Fourier transforms, for the output
332 // sequence, Y, to be a real sequence, the following identity on the
333 // input sequence, X, must be true:
334 //
335 // <srcblock>
336 // X(k) = conjg(X(n-k)) for n/2 <= k <= n-1
337 // </srcblock>
338 //
339 // And, in fact, the input values X(k) for k > n/2 need not be supplied;
340 // they can be inferred from the first half of the input.
341 //
342 // Thus, in the complex-to-real routine, <src>csfft</src>, the arrays can be
343 // dimensioned as follows:
344 //
345 // <srcblock>
346 // COMPLEX X(0:n/2)
347 // REAL Y(0:n-1)
348 // </srcblock>
349 //
350 // There are n/2 + 1 complex input values and n real output values. Even
351 // though only n/2 + 1 input values are supplied, the size of the
352 // transform is still n in this case, because implicitly you are using
353 // the FFT formula for a sequence of length n.
354 //
355 // Another implication of the theory is that X(0) must be a real number
356 // (that is, it must have zero imaginary part). Also, if n is even,
357 // X(n/2) must also be real. Routine <src>CSFFT</src> assumes that these
358 // values are real; if you specify a nonzero imaginary part, it is ignored.
359 //
360 // <h3>Table Initialization</h3>
361 // The table array stores the trigonometric tables used in calculation of
362 // the FFT. This table must be initialized by calling the routine with
363 // isign = 0 prior to doing the transforms. The table does not have to
364 // be reinitialized if the value of the problem size, n, does not change.
365 // Because <src>scfft</src> and <src>csfft</src> use the same format for
366 // table, either can be used to initialize it (note that CCFFT uses a
367 // different table format).
368 //
369 // <h3>Dimensions</h3>
370 // In the preceding description, it is assumed that array subscripts were
371 // zero-based, as is customary in FFT applications. Thus, the input and
372 // output arrays are declared (assuming n > 0):
373 //
374 // <srcblock>
375 // REAL X(0:n-1)
376 // COMPLEX Y(0:n/2)
377 // </srcblock>
378 //
379 // No change is needed in the calling sequence; however, if you prefer
380 // you can use the more customary Fortran style with subscripts starting
381 // at 1, as in the following:
382 //
383 // <srcblock>
384 // REAL X(n)
385 // COMPLEX Y(n/2 + 1)
386 // </srcblock>
387 //
388 // <example>
389 // These examples use the table and workspace sizes appropriate to Origin
390 // series.
391 //
392 // Example 1: Initialize the complex array TABLE in preparation for
393 // doing an FFT of size 1024. In this case only the arguments isign, n,
394 // and table are used. You can use dummy arguments or zeros for the other
395 // arguments in the subroutine call.
396 //
397 // <srcblock>
398 // REAL TABLE(15 + 1024)
399 // CALL SCFFT(0, 1024, 0.0, DUMMY, DUMMY, TABLE, DUMMY, 0)
400 // </srcblock>
401 //
402 // Example 2: X is a real array of dimension (0:1023), and Y is a
403 // complex array of dimension (0:512). Take the FFT of X and store the
404 // results in Y. Before taking the FFT, initialize the TABLE array, as
405 // in example 1.
406 //
407 // <srcblock>
408 // REAL X(0:1023)
409 // COMPLEX Y(0:512)
410 // REAL TABLE(15 + 1024)
411 // REAL WORK(1024)
412 // CALL SCFFT(0, 1024, 1.0, X, Y, TABLE, WORK, 0)
413 // CALL SCFFT(1, 1024, 1.0, X, Y, TABLE, WORK, 0)
414 // </srcblock>
415 //
416 // Example 3: With X and Y as in example 2, take the inverse FFT of Y
417 // and store it back in X. The scale factor 1/1024 is used. Assume that
418 // the TABLE array is initialized already.
419 //
420 // <srcblock>
421 // CALL CSFFT(-1, 1024, 1.0/1024.0, Y, X, TABLE, WORK, 0)
422 // </srcblock>
423 //
424 // Example 4: Perform the same computation as in example 2, but assume
425 // that the lower bound of each array is 1, rather than 0. The
426 // subroutine calls are not changed.
427 //
428 // <srcblock>
429 // REAL X(1024)
430 // COMPLEX Y(513)
431 // CALL SCFFT(0, 1024, 1.0, X, Y, TABLE, WORK, 0)
432 // CALL SCFFT(1, 1024, 1.0, X, Y, TABLE, WORK, 0)
433 // </srcblock>
434 //
435 // Example 5: Perform the same computation as in example 4, but
436 // equivalence the input and output arrays to save storage space. Assume
437 // that the TABLE array is initialized already.
438 //
439 // <srcblock>
440 // REAL X(1024)
441 // COMPLEX Y(513)
442 // EQUIVALENCE ( X(1), Y(1) )
443 // CALL SCFFT(1, 1024, 1.0, X, Y, TABLE, WORK, 0)
444 // </srcblock>
445 // </example>
446 //
447 // Input parameters:
448 // <dl compact>
449 // <dt><b>isign</b>
450 // <dd> Integer.
451 // Specifies whether to initialize the table array or to do the
452 // forward or inverse Fourier transform, as follows:
453 //
454 // If isign = 0, the routine initializes the table array and
455 // returns. In this case, the only arguments used or checked
456 // are isign, n, and table.
457 //
458 // If isign = +1 or -1, the value of isign is the sign of the
459 // exponent used in the FFT formula.
460 // <dt><b>n</b>
461 // <dd> Integer.
462 // Size of transform. If n <= 2, <src>scfft/dzfft</src>
463 // returns without calculating the transform.
464 // <dt><b>scale</b>
465 // <dd> Scale factor.
466 // <src>scfft</src>: real.
467 // <src>dzfft</src>: double precision.
468 // <src>csfft</src>: real.
469 // <src>zdfft</src>: double precision.
470 // Each element of the output array is multiplied by scale
471 // after taking the Fourier transform, as defined by the previous
472 // formula.
473 // <dt><b>x</b>
474 // <dd> Input array of values to be transformed.
475 // <src>scfft</src>: real array of dimension (0:n-1).
476 // <src>dzfft</src>: double precision array of dimension (0:n-1).
477 // <src>csfft</src>: complex array of dimension (0:n/2).
478 // <src>zdfft</src>: double complex array of dimension (0:n/2).
479 // <dt><b>isys</b>
480 // <dd> Integer array of dimension (0:isys(0)).
481 // Use isys to specify certain processor-specific parameters or
482 // options. The first element of the array specifies how many
483 // more elements are in the array.
484 //
485 // If isys(0) = 0, the default values of such parameters are
486 // used. In this case, you can specify the argument value as
487 // the scalar integer constant 0. If isys(0) > 0, isys(0)
488 // gives the upper bound of the isys array; that is, if
489 // il = isys(0), user-specified parameters are expected in
490 // isys(1) through isys(il).
491 // </dl>
492 // Output parameters:
493 // <dl compact>
494 // <dt><b>y</b>
495 // <dd> Output array of transformed values.
496 // <src>scfft</src>: complex array of dimension (0:n/2).
497 // <src>dzfft</src>: double complex array of dimension (0:n/2).
498 // <src>csfft</src>: real array of dimension (0:n-1).
499 // <src>zdfft</src>: double precision array of dimension (0:n-1).
500 //
501 // The output array, y, is the FFT of the the input array, x,
502 // computed according to the preceding formula. The output
503 // array may be equivalenced to the input array in the calling
504 // program. Be careful when dimensioning the arrays, in this
505 // case, to allow for the fact that the complex array contains
506 // two (real) words more than the real array.
507 // <dt><b>table</b>
508 // <dd> Real array; dimension n+15.
509 //
510 // Table of factors and trigonometric functions.
511 //
512 // If isign = 0, the table array is initialized to contain
513 // trigonometric tables needed to compute an FFT of size n.
514 //
515 // If isign = +1 or -1, the values in table are assumed to be
516 // initialized already by a prior call with isign = 0.
517 // <dt><b>work</b>
518 // <dd> Real array; dimension n.
519 //
520 // Work array used for intermediate calculations. Its address
521 // space must be different from that of the input and output
522 // arrays.
523 // </dl>
524 // <group>
525 static void scfft(Int isign, Int n, Float scale, Float* x, Complex* y, Float* table, Float* work,
526 Int isys);
527 static void scfft(Int isign, Int n, Double scale, Double* x, DComplex* y, Double* table,
528 Double* work, Int isys);
529 static void dzfft(Int isign, Int n, Double scale, Double* x, DComplex* y, Double* table,
530 Double* work, Int isys);
531 static void csfft(Int isign, Int n, Float scale, Complex* x, Float* y, Float* table, Float* work,
532 Int isys);
533 static void csfft(Int isign, Int n, Double scale, DComplex* x, Double* y, Double* table,
534 Double* work, Int isys);
535 static void zdfft(Int isign, Int n, Double scale, DComplex* x, Double* y, Double* table,
536 Double* work, Int isys);
537 // </group>
538
539 // <src>ccfftm/zzfftm</src> computes the FFT of each column of the
540 // complex matrix x, and stores the results in the columns of complex
541 // matrix y.
542 //
543 // Suppose the arrays are dimensioned as follows:
544 //
545 // <srcblock>
546 // COMPLEX X(0:ldx-1, 0:lot-1)
547 // COMPLEX Y(0:ldy-1, 0:lot-1)
548 //
549 // where ldx >= n, ldy >= n.
550 // </srcblock>
551 //
552 // Then column L of the output array is the FFT of column L of the
553 // input array, using the following formula for the FFT:
554 //
555 // <srcblock>
556 // n-1
557 // Y(k, L) = scale * Sum [ X(j)*w**(isign*j*k) ]
558 // j=0
559 // for k = 0, ..., n-1
560 // L = 0, ..., lot-1
561 // where:
562 // w = exp(2*pi*i/n),
563 // i = + sqrt(-1),
564 // pi = 3.14159...,
565 // isign = +1 or -1
566 // lot = the number of columns to transform
567 // </srcblock>
568 //
569 // Different authors use different conventions for which of the
570 // transforms, isign = +1 or isign = -1, is the forward or inverse
571 // transform, and what the scale factor should be in either case. You
572 // can make this routine compute any of the various possible definitions,
573 // however, by choosing the appropriate values for isign and scale.
574 //
575 // The relevant fact from FFT theory is this: If you take the FFT with
576 // any particular values of isign and scale, the mathematical inverse
577 // function is computed by taking the FFT with -isign and 1/(n * scale).
578 // In particular, if you use isign = +1 and scale = 1.0 for the forward
579 // FFT, you can compute the inverse FFT by using the following: isign =
580 // -1 and scale = 1.0/n.
581 //
582 // This section contains information about the algorithm for these
583 // routines, the initialization of the table array, the declaration of
584 // dimensions for x and y arrays, some performance tips, and some
585 // implementation-dependent details.
586 //
587 // <h3>Algorithm</h3>
588 // These routines use decimation-in-frequency type FFT. It takes the FFT
589 // of the columns and vectorizes the operations along the rows of the
590 // matrix. Thus, the vector length in the calculations depends on the
591 // row size, and the strides for vector loads and stores are the leading
592 // dimensions, ldx and ldy.
593 //
594 // <h3>Initialization</h3>
595 // The table array stores the trigonometric tables used in calculation of
596 // the FFT. You must initialize the table array by calling the routine
597 // with isign = 0 prior to doing the transforms. If the value of the
598 // problem size, n, does not change, table does not have to be
599 // reinitialized.
600 //
601 // <h3>Dimensions</h3>
602 // In the preceding description, it is assumed that array subscripts were
603 // zero-based, as is customary in FFT applications. Thus, the input and
604 // output arrays are declared as follows:
605 //
606 // <srcblock>
607 // COMPLEX X(0:ldx-1, 0:lot-1)
608 // COMPLEX Y(0:ldy-1, 0:lot-1)
609 // </srcblock>
610 //
611 // The calling sequence does not have to change, however, if you prefer
612 // to use the more customary Fortran style with subscripts starting at 1.
613 // The same values of ldx and ldy would be passed to the subroutine even
614 // if the input and output arrays were dimensioned as follows:
615 //
616 // <srcblock>
617 // COMPLEX X(ldx, lot)
618 // COMPLEX Y(ldy, lot)
619 // </srcblock>
620 //
621 // <example>
622 // Example 1: Initialize the TABLE array in preparation for doing an FFT
623 // of size 128. Only the isign, n, and table arguments are used in this
624 // case. You can use dummy arguments or zeros for the other arguments in
625 // the subroutine call.
626 //
627 // <srcblock>
628 // REAL TABLE(30 + 256)
629 // CALL CCFFTM(0, 128, 0, 0., DUMMY, 1, DUMMY, 1, TABLE, DUMMY, 0)
630 // </srcblock>
631 //
632 // Example 2: X and Y are complex arrays of dimension (0:128) by (0:55).
633 // The first 128 elements of each column contain data. For performance
634 // reasons, the extra element forces the leading dimension to be an odd
635 // number. Take the FFT of the first 50 columns of X and store the
636 // results in the first 50 columns of Y. Before taking the FFT,
637 // initialize the TABLE array, as in example 1.
638 //
639 // <srcblock>
640 // COMPLEX X(0:128, 0:55)
641 // COMPLEX Y(0:128, 0:55)
642 // REAL TABLE(30 + 256)
643 // REAL WORK(256)
644 // ...
645 // CALL CCFFTM(0, 128, 50, 1.0, X, 129, Y, 129, TABLE, WORK, 0)
646 // CALL CCFFTM(1, 128, 50, 1.0, X, 129, Y, 129, TABLE, WORK, 0)
647 // </srcblock>
648 //
649 // Example 3: With X and Y as in example 2, take the inverse FFT of Y
650 // and store it back in X. The scale factor 1/128 is used. Assume that
651 // the TABLE array is already initialized.
652 //
653 // <srcblock>
654 // CALL CCFFTM(-1, 128, 50, 1./128., Y, 129, X, 129, TABLE,WORK,0)
655 // </srcblock>
656 //
657 // Example 4: Perform the same computation as in example 2, but assume
658 // that the lower bound of each array is 1, rather than 0. The
659 // subroutine calls are not changed.
660 //
661 // <srcblock>
662 // COMPLEX X(129, 55)
663 // COMPLEX Y(129, 55)
664 // ...
665 // CALL CCFFTM(0, 128, 50, 1.0, X, 129, Y, 129, TABLE, WORK, 0)
666 // CALL CCFFTM(1, 128, 50, 1.0, X, 129, Y, 129, TABLE, WORK, 0)
667 // </srcblock>
668 //
669 // Example 5: Perform the same computation as in example 4, but put the
670 // output back in array X to save storage space. Assume that the TABLE
671 // array is already initialized.
672 //
673 // <srcblock>
674 // COMPLEX X(129, 55)
675 // ...
676 // CALL CCFFTM(1, 128, 50, 1.0, X, 129, X, 129, TABLE, WORK, 0)
677 // </srcblock>
678 //
679 // </example>
680 //
681 // Input parameters:
682 // <dl compact>
683 // <dt><b>isign</b>
684 // <dd> Integer.
685 // Specifies whether to initialize the table array or to do the
686 // forward or inverse Fourier transform, as follows:
687 //
688 // If isign = 0, the routine initializes the table array and
689 // returns. In this case, the only arguments used or checked
690 // are isign, n, and table.
691 //
692 // If isign = +1 or -1, the value of isign is the sign of the
693 // exponent used in the FFT formula.
694 // <dt><b>n</b>
695 // <dd> Integer.
696 // Size of each transform (the number of elements in each
697 // column of the input and output matrix to be transformed).
698 // Performance depends on the value of n, as explained above.
699 // n >= 0; if n = 0, the routine returns.
700 // <dt><b>lot</b>
701 // <dd> Integer.
702 // The number of transforms to be computed (lot size). This is
703 // the number of elements in each row of the input and output
704 // matrix. lot >= 0. If lot = 0, the routine returns.
705 // <dt><b>scale</b>
706 // <dd> Scale factor.
707 // <src>ccfftm</src>: real.
708 // <src>zzfftm</src>: double precision.
709 // Each element of the output array is multiplied by scale
710 // factor after taking the Fourier transform, as defined
711 // previously.
712 // <dt><b>x</b>
713 // <dd> Array of dimension (0:ldx-1, 0:n2-1).
714 // <src>ccfftm</src>: real array.
715 // <src>zzfftm</src>: double precision array.
716 // Input array of values to be transformed.
717 // <dt><b>ldx</b>
718 // <dd> The number of rows in the x array, as it was declared in the
719 // calling program (the leading dimension of X). ldx >= MAX(n, 1).
720 // <dt><b>ldy</b>
721 // <dd> Integer.
722 // The number of rows in the y array, as it was declared in the
723 // calling program (the leading dimension of y). ldy >= MAX(n,
724 // 1).
725 // <dt><b>isys</b>
726 // <dd> Integer array of dimension (0:isys(0)).
727 // The first element of the array specifies how many more
728 // elements are in the array. Use isys to specify certain
729 // processor-specific parameters or options.
730 //
731 // If isys(0) = 0, the default values of such parameters are
732 // used. In this case, you can specify the argument value as
733 // the scalar integer constant 0.
734 //
735 // If isys(0) > 0, isys(0) gives the upper bound of the isys
736 // array. Therefore, if il = isys(0), user-specified
737 // parameters are expected in isys(1) through isys(il).
738 // </dl>
739 // Output parameters:
740 // <dl compact>
741 // <dt><b>y</b>
742 // <dd> Array of dimension (0:ldy-1, 0:lot-1).
743 // <src>ccfftm</src>: complex array.
744 // <src>zzfftm</src>: double complex array.
745 // Output array of transformed values. Each column of the
746 // output array, y, is the FFT of the corresponding column of
747 // the input array, x, computed according to the preceding
748 // formula.
749 //
750 // The output array may be the same as the input array. In that
751 // case, the transform is done in place. The input array is
752 // overwritten with the transformed values. In this case, it
753 // is necessary that ldx = ldy.
754 // <dt><b>table</b>
755 // <dd> Real array; dimension (30 + 2n).
756 // Table of factors and trigonometric functions.
757 //
758 // If isign = 0, the routine initializes table (table is output
759 // only).
760 //
761 // If isign = +1 or -1, the values in table are assumed to be
762 // initialized already by a prior call with isign = 0 (table is
763 // input only).
764 // <dt><b>work</b>
765 // <dd> Real array; dimension 2n.
766 // Work array. This is a scratch array used for intermediate
767 // calculations. Its address space must be different from that
768 // of the input and output arrays.
769 // </dl>
770 // <group>
771 static void ccfftm(Int isign, Int n, Int lot, Float scale, Complex* x, Int ldx, Complex* y,
772 Int ldy, Float* table, Float* work, Int isys);
773 static void zzfftm(Int isign, Int n, Int lot, Double scale, DComplex* x, Int ldx, DComplex* y,
774 Int ldy, Double* table, Double* work, Int isys);
775 // </group>
776
777 // <src>scfftm/dzfftm</src> computes the FFT of each column of the real matrix
778 // X, and it stores the results in the corresponding column of the complex
779 // matrix Y. <src>csfftm/zdfftm</src> computes the corresponding inverse
780 // transforms.
781 //
782 // In FFT applications, it is customary to use zero-based subscripts; the
783 // formulas are simpler that way. First, the function of <src>scfftm</src> is
784 // described. Suppose that the arrays are dimensioned as follows:
785 //
786 // <srcblock>
787 // REAL X(0:ldx-1, 0:lot-1)
788 // COMPLEX Y(0:ldy-1, 0:lot-1)
789 //
790 // where ldx >= n, ldy >= n/2 + 1.
791 // </srcblock>
792 //
793 // Then column L of the output array is the FFT of column L of the input
794 // array, using the following formula for the FFT:
795 //
796 // <srcblock>
797 // n-1
798 // Y(k, L) = scale * Sum [ X(j, L)*w**(isign*j*k) ]
799 // j=0
800 //
801 // for k = 0, ..., n/2
802 // L = 0, ..., lot-1 where:
803 // w = exp(2*pi*i/n),
804 // i = + sqrt(-1)
805 // pi = 3.14159...,
806 // isign = +1 or -1,
807 // lot = the number of columns to transform
808 // </srcblock>
809 //
810 // Different authors use different conventions for which transform
811 // (isign = +1 or isign = -1) is used in the real-to-complex case, and
812 // what the scale factor should be. Some adopt the convention that isign
813 // = 1 for the real-to-complex transform, and isign = -1 for the
814 // complex-to-real inverse. Others use the opposite convention. You can
815 // make these routines compute any of the various possible definitions,
816 // however, by choosing the appropriate values for isign and scale.
817 //
818 // The relevant fact from FFT theory is this: If you use <src>scfftm</src> to
819 // take the real-to-complex FFT, using any particular values of isign and
820 // scale, the mathematical inverse function is computed by using
821 // <src>csfftm</src> with -isign and 1/ (n*scale). In particular, if you call
822 // <src>scfftm</src> with isign = +1 and scale = 1.0, you can use
823 // <src>csfftm</src> to compute the inverse complex-to-real FFT by using isign
824 // = -1 and scale = 1.0/n.
825 //
826 // <h3>Real-to-complex FFTs</h3>
827 // Notice in the preceding formula that there are n real input values and
828 // (n/2) + 1 complex output values for each column. This property is
829 // characteristic of real-to-complex FFTs.
830 //
831 // The mathematical definition of the Fourier transform takes a sequence
832 // of n complex values and transforms it to another sequence of n complex
833 // values. A complex-to-complex FFT routine, such as <src>ccfftm</src>, will
834 // take n complex input values and produce n complex output values. In fact,
835 // one easy way to compute a real-to-complex FFT is to store the input
836 // data x in a complex array, then call routine <src>ccfftm</src> to compute
837 // the FFT. You get the same answer when using the <src>scfftm</src> routine.
838 //
839 // A separate real-to-complex FFT routine is more efficient than the
840 // equivalent complex-to-complex routine. Because the input data is
841 // real, you can make use of this fact to save almost half of the
842 // computational work. According to the theory of Fourier transforms,
843 // for real input data, you have to compute only the first n/2 + 1
844 // complex output values in each column, because the second half of the
845 // FFT values in each column can be computed from the first half of the
846 // values by the simple formula:
847 //
848 // <srcblock>
849 // Y = conjgY for n/2 <= k <= n-1
850 // k,L n-k, L
851 //
852 // where the notation conjg(z) represents the complex conjugate of z.
853 // </srcblock>
854 //
855 // In fact, in many applications, the second half of the complex output
856 // data is never explicitly computed or stored. Likewise, you must
857 // supply only the first half of the complex data in each column has to
858 // be supplied for the complex-to-real FFT.
859 //
860 // Another implication of FFT theory is that for real input data, the
861 // first output value in each column, Y(0, L), will always be a real
862 // number; therefore, the imaginary part will always be 0. If n is an
863 // even number, Y(n/2, L) will also be real and have 0 imaginary parts.
864 //
865 // <h3>Complex-to-real FFTs</h3>
866 // Consider the complex-to-real case. The effect of the computation is
867 // given by the preceding formula, but with X complex and Y real.
868 //
869 // In general, the FFT transforms a complex sequence into a complex
870 // sequence; however, in a certain application you may know the output
871 // sequence is real, perhaps because the complex input sequence was the
872 // transform of a real sequence. In this case, you can save about half
873 // of the computational work.
874 //
875 // According to the theory of Fourier transforms, for the output
876 // sequence, Y, to be a real sequence, the following identity on the
877 // input sequence, X, must be true:
878 //
879 // <srcblock>
880 // X = conjgX for n/2 <= k <= n-1
881 // k,L n-k,L
882 // And, in fact, the following input values
883 //
884 // X for k > n/2
885 // k,L
886 // do not have to be supplied, because they can be inferred from the
887 // first half of the input.
888 // </srcblock>
889 //
890 // Thus, in the complex-to-real routine, CSFFTM, the arrays can be
891 // dimensioned as follows:
892 //
893 // <srcblock>
894 // COMPLEX X(0:ldx-1, 0:lot-1)
895 // REAL Y(0:ldy-1, 0:lot-1)
896 //
897 // where ldx >= n/2 + 1, ldy >= n.
898 // </srcblock>
899 //
900 // In each column, there are (n/2) + 1 complex input values and n real
901 // output values. Even though only (n/2) + 1 input values are supplied,
902 // the size of the transform is still n in this case, because implicitly
903 // the FFT formula for a sequence of length n is used.
904 //
905 // Another implication of the theory is that X(0, L) must be a real
906 // number (that is, must have zero imaginary part). If n is an even
907 // number, X(n/2, L) must also be real. Routine CSFFTM assumes that each
908 // of these values is real; if a nonzero imaginary part is given, it is
909 // ignored.
910 //
911 // <h3>Table Initialization</h3>
912 // The table array contains the trigonometric tables used in calculation
913 // of the FFT. You must initialize this table by calling the routine
914 // with isign = 0 prior to doing the transforms. table does not have to
915 // be reinitialized if the value of the problem size, n, does not change.
916 //
917 // <h3>Dimensions</h3>
918 // In the preceding description, it is assumed that array subscripts were
919 // zero-based, as is customary in FFT applications. Thus, the input and
920 // output arrays are declared (for SCFFTM):
921 //
922 // <srcblock>
923 // REAL X(0:ldx-1, 0:lot-1)
924 // COMPLEX Y(0:ldy-1, 0:lot-1)
925 // </srcblock>
926 //
927 // No change is made in the calling sequence, however, if you prefer to
928 // use the more customary Fortran style with subscripts starting at 1.
929 // The same values of ldx and ldy would be passed to the subroutine even
930 // if the input and output arrays were dimensioned as follows:
931 //
932 // <srcblock>
933 // REAL X(ldx, lot)
934 // COMPLEX Y(ldy, lot)
935 // </srcblock>
936
937 // </example>
938 // Example 1: Initialize the complex array TABLE in preparation for
939 // doing an FFT of size 128. In this case only the isign, n, and table
940 // arguments are used; you may use dummy arguments or zeros for the other
941 // arguments in the subroutine call.
942 //
943 // <srcblock>
944 // REAL TABLE(15 + 128)
945 // CALL SCFFTM(0, 128, 1, 0.0, DUMMY, 1, DUMMY, 1,
946 // & TABLE, DUMMY, 0)
947 // </srcblock>
948 //
949 // Example 2: X is a real array of dimension (0:128, 0:55), and Y is a
950 // complex array of dimension (0:64, 0:55). The first 128 elements in
951 // each column of X contain data; the extra element forces an odd leading
952 // dimension. Take the FFT of the first 50 columns of X and store the
953 // results in the first 50 columns of Y. Before taking the FFT,
954 // initialize the TABLE array, as in example 1.
955 //
956 // <srcblock>
957 // REAL X(0:128, 0:55)
958 // COMPLEX Y(0:64, 0:55)
959 // REAL TABLE(15 + 128)
960 // REAL WORK((128)
961 // ...
962 // CALL SCFFTM(0, 128, 50, 1.0, X, 129, Y, 65, TABLE, WORK, 0)
963 // CALL SCFFTM(1, 128, 50, 1.0, X, 129, Y, 65, TABLE, WORK, 0)
964 // </srcblock>
965 //
966 // Example 3: With X and Y as in example 2, take the inverse FFT of Y
967 // and store it back in X. The scale factor 1/128 is used. Assume that
968 // the TABLE array is initialized already.
969 //
970 // <srcblock>
971 // CALL CSFFTM(-1, 128, 50, 1.0/128.0, Y, 65, X, 129,
972 // & TABLE, WORK, 0)
973 // </srcblock>
974 //
975 // Example 4: Perform the same computation as in example 2, but assume
976 // that the lower bound of each array is 1, rather than 0. No change is
977 // made in the subroutine calls.
978 //
979 // <srcblock>
980 // REAL X(129, 56)
981 // COMPLEX Y(65, 56)
982 // ...
983 // CALL SCFFTM(0, 128, 50, 1.0, X, 129, Y, 65, TABLE, WORK, 0)
984 // CALL SCFFTM(1, 128, 50, 1.0, X, 129, Y, 65, TABLE, WORK, 0)
985 // </srcblock>
986 //
987 // Example 5: Perform the same computation as in example 4, but
988 // equivalence the input and output arrays to save storage space. In
989 // this case, a row must be added to X, because it is equivalenced to a
990 // complex array. The leading dimension of X is two times an odd number;
991 // therefore, memory bank conflicts are minimal. Assume that TABLE is
992 // initialized already.
993 //
994 // <srcblock>
995 // REAL X(130, 56)
996 // COMPLEX Y(65, 56)
997 // EQUIVALENCE ( X(1, 1), Y(1, 1) )
998 // ...
999 // CALL SCFFTM(1, 128, 50, 1.0, X, 130, Y, 65, TABLE, WORK, 0)
1000 // </srcblock>
1001 // </example>
1002 //
1003 // Input parameters:
1004 // <dl compact>
1005 // <dt><b>isign</b>
1006 // <dd> Integer.
1007 // Specifies whether to initialize the table array or to do the
1008 // forward or inverse Fourier transform, as follows:
1009 //
1010 // If isign = 0, the routine initializes the table array and
1011 // returns. In this case, the only arguments used or checked
1012 // are isign, n, and table.
1013 //
1014 // If isign = +1 or -1, the value of isign is the sign of the
1015 // exponent used in the FFT formula.
1016 // <dt><b>n</b>
1017 // <dd> Integer.
1018 // Size of the transforms (the number of elements in each
1019 // column of the input and output matrix to be transformed).
1020 // If n is not positive, <src>scfftm</src> or <src>csfftm</src> returns
1021 // without computing a transforms.
1022 // <dt><b>lot</b>
1023 // <dd> Integer.
1024 // The number of transforms to be computed (or "lot size").
1025 // This is the number of elements in each row of the input and
1026 // output matrix. If lot is not positive, <src>csfftm</src> or
1027 // <src>scfftm</src> returns without computing a transforms.
1028 // <dt><b>scale</b>
1029 // <dd> Scale factor.
1030 // <src>scfftm</src>: real.
1031 // <src>dzfftm</src>: double precision.
1032 // <src>csfftm</src>: real.
1033 // <src>zdfftm</src>: double precision.
1034 // Each element of the output array is multiplied by scale
1035 // after taking the transform, as defined in the preceding
1036 // formula.
1037 // <dt><b>x</b>
1038 // <dd> Input array of values to be transformed. Dimension (0:ldx-1,
1039 // 0:lot-1).
1040 // <src>scfftm</src>: real array.
1041 // <src>dzfftm</src>: double precision array.
1042 // <src>csfftm</src>: complex array.
1043 // <src>zdfftm</src>: double complex array.
1044 // <dt><b>ldx</b>
1045 // <dd> Integer.
1046 // The number of rows in the x array, as it was declared in the
1047 // calling program. That is, the leading dimension of x.
1048 // <src>scfftm, dzfftm</src>: ldx >= MAX(n, 1).
1049 // <src>csfftm, zdfftm</src>: ldx >= MAX(n/2 + 1, 1).
1050 // <dt><b>ldy</b>
1051 // <dd> Integer.
1052 // The number of rows in the y array, as it was declared in the
1053 // calling program (the leading dimension of y).
1054 // <src>scfftm, dzfftm</src>: ldy >= MAX(n/2 + 1, 1).
1055 // <src>csfftm, zdfftm</src>: ldy >= MAX(n, 1).
1056 // <dt><b>isys</b>
1057 // <dd> Integer array of dimension (0:isys(0)).
1058 // The first element of the array specifies how many more
1059 // elements are in the array. Use isys to specify certain
1060 // processor-specific parameters or options.
1061 //
1062 // If isys(0) = 0, the default values of such parameters are
1063 // used. In this case, you can specify the argument value as
1064 // the scalar integer constant 0.
1065 //
1066 // If isys(0) > 0, isys(0) gives the upper bound of the isys
1067 // array. Therefore, if il = isys(0), user-specified
1068 // parameters are expected in isys(1) through isys(il).
1069 // </dl>
1070 // Output parameters:
1071 // <dl compact>
1072 // <dt><b>y</b>
1073 // <dd> Output array of transformed values. Dimension (0:ldy-1,
1074 // 0:lot-1).
1075 // <src>scfftm</src>: complex array.
1076 // <src>dzfftm</src>: double complex array.
1077 // <src>csfftm</src>: real array.
1078 // <src>zdfftm</src>: double precision array.
1079 //
1080 // Each column of the output array, y, is the FFT of the
1081 // corresponding column of the input array, x, computed
1082 // according to the preceding formula. The output array may be
1083 // equivalenced to the input array. In that case, the transform
1084 // is done in place and the input array is overwritten with the
1085 // transformed values. In this case, the following conditions
1086 // on the leading dimensions must hold:
1087 //
1088 // <src>scfftm, dzfftm</src>: ldx = 2ldy.
1089 // <src>csfftm, zdfftm</src>: ldy = 2ldx.
1090 // <dt><b>table</b>
1091 // <dd> Real array; dimension (15 + n).
1092 // Table of factors and trigonometric functions.
1093 // This array must be initialized by a call to <src>scfftm</src> (or
1094 // <src>csfftm</src>) with isign = 0.
1095 //
1096 // If isign = 0, table is initialized to contain trigonometric
1097 // tables needed to compute an FFT of length n.
1098 // <dt><b>work</b>
1099 // <dd> Real array; dimension n.
1100 // Work array used for intermediate calculations. Its address
1101 // space must be different from that of the input and output
1102 // arrays.
1103 // </dl>
1104 // <group>
1105 static void scfftm(Int isign, Int n, Int lot, Float scale, Float* x, Int ldx, Complex* y, Int ldy,
1106 Float* table, Float* work, Int isys);
1107 static void dzfftm(Int isign, Int n, Int lot, Double scale, Double* x, Int ldx, DComplex* y,
1108 Int ldy, Double* table, Double* work, Int isys);
1109 static void csfftm(Int isign, Int n, Int lot, Float scale, Complex* x, Int ldx, Float* y, Int ldy,
1110 Float* table, Float* work, Int isys);
1111 static void zdfftm(Int isign, Int n, Int lot, Double scale, DComplex* x, Int ldx, Double* y,
1112 Int ldy, Double* table, Double* work, Int isys);
1113 // </group>
1114
1115 // These routines compute the two-dimensional complex Fast Fourier
1116 // Transform (FFT) of the complex matrix x, and store the results in the
1117 // complex matrix y. <src>ccfft2d</src> does the complex-to-complex
1118 // transform and <src>zzfft</src> does the same for double
1119 // precision arrays.
1120 //
1121 // In FFT applications, it is customary to use zero-based subscripts; the
1122 // formulas are simpler that way. Suppose that the arrays are
1123 // dimensioned as follows:
1124 //
1125 // <srcblock>
1126 // COMPLEX X(0:n1-1, 0:n2-1)
1127 // COMPLEX Y(0:n1-1, 0:n2-1)
1128 // </srcblock>
1129 //
1130 // These routines compute the formula:
1131 //
1132 // <srcblock>
1133 // n2-1 n1-1
1134 // Y(k1, k2) = scale * Sum Sum [ X(j1, j2)*w1**(j1*k1)*w2**(j2*k2) ]
1135 // j2=0 j1=0
1136 //
1137 // for k1 = 0, ..., n1-1
1138 // k2 = 0, ..., n2-1
1139 //
1140 // where:
1141 // w1 = exp(isign*2*pi*i/n1)
1142 // w2 = exp(isign*2*pi*i/n2)
1143 // i = + sqrt(-1)
1144 // pi = 3.14159...,
1145 // isign = +1 or -1
1146 // </srcblock>
1147 //
1148 // Different authors use different conventions for which of the
1149 // transforms, isign = +1 or isign = -1, is the forward or inverse
1150 // transform, and what the scale factor should be in either case. You
1151 // can make this routine compute any of the various possible definitions,
1152 // however, by choosing the appropriate values for isign and scale.
1153 //
1154 // The relevant fact from FFT theory is this: If you take the FFT with
1155 // any particular values of isign and scale, the mathematical inverse
1156 // function is computed by taking the FFT with -isign and
1157 // 1/(n1*n2*scale). In particular, if you use isign = +1 and scale = 1.0
1158 // for the forward FFT, you can compute the inverse FFT by using isign =
1159 // -1 and scale = 1.0/(n1*n2).
1160 //
1161 // <h3>Algorithm</h3>
1162 // These routines use a routine very much like <src>ccfftm/zzfftm</src> to do
1163 // multiple FFTs first on all columns in an input matrix and then on all
1164 // of the rows.
1165 //
1166 // <h3>Initialization</h3>
1167 // The table array stores factors of n1 and n2 and also trigonometric
1168 // tables that are used in calculation of the FFT. This table must be
1169 // initialized by calling the routine with isign = 0. If the values of
1170 // the problem sizes, n1 and n2, do not change, the table does not have
1171 // to be reinitialized.
1172 //
1173 // <h3>Dimensions</h3>
1174 // In the preceding description, it is assumed that array subscripts were
1175 // zero-based, as is customary in FFT applications. Thus, the input and
1176 // output arrays are declared as follows:
1177 //
1178 // <srcblock>
1179 // COMPLEX X(0:ldx-1, 0:n2-1)
1180 // COMPLEX Y(0:ldy-1, 0:n2-1)
1181 // </srcblock>
1182 //
1183 // However, the calling sequence does not change if you prefer to use the
1184 // more customary Fortran style with subscripts starting at 1. The same
1185 // values of ldx and ldy would be passed to the subroutine even if the
1186 // input and output arrays were dimensioned as follows:
1187 //
1188 // <srcblock>
1189 // COMPLEX X(ldx, n2)
1190 // COMPLEX Y(ldy, n2)
1191 // </srcblock>
1192 //
1193 // <example>
1194 // All examples here are for Origin series only.
1195 //
1196 // Example 1: Initialize the TABLE array in preparation for doing a
1197 // two-dimensional FFT of size 128 by 256. In this case only the isign,
1198 // n1, n2, and table arguments are used; you can use dummy arguments or
1199 // zeros for other arguments.
1200 //
1201 // <srcblock>
1202 // REAL TABLE ((30 + 256) + (30 + 512))
1203 // CALL CCFFT2D (0, 128, 256, 0.0, DUMMY, 1, DUMMY, 1,
1204 // & TABLE, DUMMY, 0)
1205 // </srcblock>
1206 //
1207 // Example 2: X and Y are complex arrays of dimension (0:128, 0:255).
1208 // The first 128 elements of each column contain data. For performance
1209 // reasons, the extra element forces the leading dimension to be an odd
1210 // number. Take the two-dimensional FFT of X and store it in Y.
1211 // Initialize the TABLE array, as in example 1.
1212 //
1213 // <srcblock>
1214 // COMPLEX X(0:128, 0:255)
1215 // COMPLEX Y(0:128, 0:255)
1216 // REAL TABLE((30 + 256) + (30 + 512))
1217 // REAL WORK(2*128*256)
1218 // ...
1219 // CALL CCFFT2D(0, 128, 256, 1.0, X, 129, Y, 129, TABLE, WORK, 0)
1220 // CALL CCFFT2D(1, 128, 256, 1.0, X, 129, Y, 129, TABLE, WORK, 0)
1221 // </srcblock>
1222 //
1223 // Example 3: With X and Y as in example 2, take the inverse FFT of Y
1224 // and store it back in X. The scale factor 1/(128*256) is used. Assume
1225 // that the TABLE array is already initialized.
1226 //
1227 // <srcblock>
1228 // CALL CCFFT2D(-1, 128, 256, 1.0/(128.0*256.0), Y, 129,
1229 // & X, 129, TABLE, WORK, 0)
1230 // </srcblock>
1231 //
1232 // Example 4: Perform the same computation as in example 2, but assume
1233 // that the lower bound of each array is 1, rather than 0. The
1234 // subroutine calls are not changed.
1235 //
1236 // <srcblock>
1237 // COMPLEX X(129, 256)
1238 // COMPLEX Y(129, 256)
1239 // ...
1240 // CALL CCFFT2D(0, 128, 256, 1.0, X, 129, Y, 129, TABLE, WORK, 0)
1241 // CALL CCFFT2D(1, 128, 256, 1.0, X, 129, Y, 129, TABLE, WORK, 0)
1242 // </srcblock>
1243 //
1244 // Example 5: Perform the same computation as in example 4, but put the
1245 // output back in array X to save storage space. Assume that the TABLE
1246 // array is already initialized.
1247 //
1248 // <srcblock>
1249 // COMPLEX X(129, 256)
1250 // ...
1251 // CALL CCFFT2D(1, 128, 256, 1.0, X, 129, X, 129, TABLE, WORK, 0)
1252 // </srcblock>
1253 // </example>
1254 //
1255 // Input parameters:
1256 // <dl compact>
1257 // <dt><b>isign</b>
1258 // <dd> Integer.
1259 // Specifies whether to initialize the table array or to do the
1260 // forward or inverse transform as follows:
1261 //
1262 // If isign = 0, the routine initializes the table array and
1263 // returns. In this case, the only arguments used or checked
1264 // are isign, n1, n2, table.
1265 //
1266 // If isign = +1 or -1, the value of isign is the sign of the
1267 // exponent used in the FFT formula.
1268 // <dt><b>n1</b>
1269 // <dd> Integer.
1270 // Transform size in the first dimension. If n1 is not
1271 // positive, the routine returns without performing a
1272 // transform.
1273 // <dt><b>n2</b>
1274 // <dd> Integer.
1275 // Transform size in the second dimension. If n2 is not
1276 // positive, the routine returns without performing a
1277 // transform.
1278 // <dt><b>scale</b>
1279 // <dd> Scale factor.
1280 // ccfft2d: real.
1281 // zzfft2d: double precision.
1282 // Each element of the output array is multiplied by scale
1283 // factor after taking the Fourier transform, as defined
1284 // previously.
1285 // <dt><b>x</b>
1286 // <dd> Array of dimension (0:ldx-1, 0:n2-1).
1287 // ccfft2d: complex array.
1288 // zzfft2d: double complex array.
1289 // Input array of values to be transformed.
1290 // <dt><b>ldx</b>
1291 // <dd> Integer.
1292 // The number of rows in the x array, as it was declared in the
1293 // calling program (the leading dimension of x). ldx >=
1294 // MAX(n1, 1).
1295 // <dt><b>ldy</b>
1296 // <dd> Integer.
1297 //
1298 // The number of rows in the y array, as it was declared in the
1299 // calling program (the leading dimension of y). ldy >=
1300 // MAX(n1, 1).
1301 // <dt><b>isys</b>
1302 // <dd> Algorithm used; value dependent on hardware system. Currently, no
1303 // special options are supported; therefore, you must always specify
1304 // an isys argument as constant 0.
1305 // </dl>
1306 // Output parameters:
1307 // <dl compact>
1308 // <dt><b>y</b>
1309 // <dd> Array of dimension (0:ldy-1, 0:n2-1).
1310 // ccfft2d: complex array.
1311 // zzfft2d: double complex array.
1312 // Output array of transformed values. The output array may be
1313 // the same as the input array, in which case, the transform is
1314 // done in place (the input array is overwritten with the
1315 // transformed values). In this case, it is necessary that
1316 // ldx = ldy.
1317 // <dt><b>table</b>
1318 // <dd> Real array; dimension (30+ 2 * n1) + (30 + 2 * n2).
1319 //
1320 // Table of factors and trigonometric functions.
1321 //
1322 // If isign = 0, the routine initializes table (table is output
1323 // only).
1324 //
1325 // If isign = +1 or -1, the values in table are assumed to be
1326 // initialized already by a prior call with isign = 0 (table is
1327 // input only).
1328 // <dt><b>work</b>
1329 // <dd> Real array; dimension 2 * (n1*n2).
1330 //
1331 // Work array. This is a scratch array used for intermediate
1332 // calculations. Its address space must be different from that
1333 // of the input and output arrays.
1334 // </dl>
1335 // <group>
1336 static void ccfft2d(Int isign, Int n1, Int n2, Float scale, Complex* x, Int ldx, Complex* y,
1337 Int ldy, Float* table, Float* work, Int isys);
1338 static void zzfft2d(Int isign, Int n1, Int n2, Double scale, DComplex* x, Int ldx, DComplex* y,
1339 Int ldy, Double* table, Double* work, Int isys);
1340 // </group>
1341
1342 // <src>scfft2d/dzfft2d</src> computes the two-dimensional Fast Fourier
1343 // Transform (FFT) of the real matrix x, and it stores the results in the
1344 // complex matrix y. <src>csfft2d/zdfft2d</src> computes the corresponding
1345 // inverse transform.
1346 //
1347 // In FFT applications, it is customary to use zero-based subscripts; the
1348 // formulas are simpler that way. First the function of <src>scfft2d</src> is
1349 // described. Suppose the arrays are dimensioned as follows:
1350 //
1351 // <srcblock>
1352 // REAL X(0:ldx-1, 0:n2-1)
1353 // COMPLEX Y(0:ldy-1, 0:n2-1)
1354 //
1355 // where ldx >= n1 ldy >= (n1/2) + 1.
1356 // </srcblock>
1357 //
1358 // <src>scfft2d</src> computes the formula:
1359 //
1360 // <srcblock>
1361 // n2-1 n1-1
1362 // Y(k1, k2) = scale * Sum Sum [ X(j1, j2)*w1**(j1*k1)*w2**(j2*k2) ]
1363 // j2=0 j1=0
1364 //
1365 // for k1 = 0, ..., n1/2 + 1
1366 // k2 = 0, ..., n2-1
1367 //
1368 // where:
1369 // w1 = exp(isign*2*pi*i/n1)
1370 // w2 = exp(isign*2*pi*i/n2)
1371 // i = + sqrt(-1)
1372 // pi = 3.14159...,
1373 // isign = +1 or -1
1374 // </srcblock>
1375 //
1376 // Different authors use different conventions for which of the
1377 // transforms, isign = +1 or isign = -1, is the forward or inverse
1378 // transform, and what the scale factor should be in either case. You
1379 // can make these routines compute any of the various possible
1380 // definitions, however, by choosing the appropriate values for isign and
1381 // scale.
1382 //
1383 // The relevant fact from FFT theory is this: If you take the FFT with
1384 // any particular values of isign and scale, the mathematical inverse
1385 // function is computed by taking the FFT with -isign and 1/(n1 * n2 *
1386 // scale). In particular, if you use isign = +1 and scale = 1.0 for the
1387 // forward FFT, you can compute the inverse FFT by using isign = -1 and
1388 // scale = 1.0/(n1 . n2).
1389 //
1390 // <src>scfft2d</src> is very similar in function to <src>ccfft2d</src>, but
1391 // it takes the real-to-complex transform in the first dimension, followed by
1392 // the complex-to-complex transform in the second dimension.
1393 //
1394 // <src>csfft2d</src> does the reverse. It takes the complex-to-complex FFT
1395 // in the second dimension, followed by the complex-to-real FFT in the first
1396 // dimension.
1397 //
1398 // See the <src>scfft</src> man page for more information about real-to-complex
1399 // and complex-to-real FFTs. The two-dimensional analog of the conjugate
1400 // formula is as follows:
1401 //
1402 // <srcblock>
1403 // Y = conjg Y
1404 // k , k n1 - k , n2 - k
1405 // 1 2 1 2
1406 //
1407 // for n1/2 < k <= n1 - 1
1408 // 1
1409 //
1410 // 0 <= k <= n2 - 1
1411 // 2
1412 // where the notation conjg(z) represents the complex conjugate of z.
1413 // </srcblock>
1414 //
1415 // Thus, you have to compute only (slightly more than) half of the output
1416 // values, namely:
1417 //
1418 // <srcblock>
1419 // Y for 0 <= k <= n1/2 0 <= k <= n2 - 1
1420 // k , k 1 2
1421 // 1 2
1422 // </srcblock>
1423 //
1424 // <h3>Algorithm</h3>
1425 // <src>scfft2d</src> uses a routine similar to <src>scfftm</src> to do a
1426 // real-to-complex FFT on the columns, then uses a routine similar to
1427 // <src>ccfftm</src> to do a complex-to-complex FFT on the rows.
1428 //
1429 // <src>csfft2d</src> uses a routine similar to <src>ccfftm</src> to do a
1430 // complex-to-complex FFT on the rows, then uses a routine similar to
1431 // <src>csfftm</src> to do a complex-to-real FFT on the columns.
1432 //
1433 // <h3>Table Initialization</h3>
1434 // The table array stores factors of n1 and n2, and trigonometric tables
1435 // that are used in calculation of the FFT. table must be initialized by
1436 // calling the routine with isign = 0. table does not have to be
1437 // reinitialized if the values of the problem sizes, n1 and n2, do not
1438 // change.
1439 //
1440 // <h3>Dimensions</h3>
1441 // In the preceding description, it is assumed that array subscripts were
1442 // zero-based, as is customary in FFT applications. Thus, the input and
1443 // output arrays are declared:
1444 //
1445 // <srcblock>
1446 // REAL X(0:ldx-1, 0:n2-1)
1447 // COMPLEX Y(0:ldy-1, 0:n2-1)
1448 // </srcblock>
1449 //
1450 // No change is made in the calling sequence, however, if you prefer to
1451 // use the more customary Fortran style with subscripts starting at 1.
1452 // The same values of ldx and ldy would be passed to the subroutine even
1453 // if the input and output arrays were dimensioned as follows:
1454 //
1455 // <srcblock>
1456 // REAL X(ldx, n2)
1457 // COMPLEX Y(ldy, n2)
1458 // </srcblock>
1459 //
1460 // <example>
1461 // The following examples are for Origin series only.
1462 //
1463 // Example 1: Initialize the TABLE array in preparation for doing a
1464 // two-dimensional FFT of size 128 by 256. In this case, only the isign,
1465 // n1, n2, and table arguments are used; you can use dummy arguments or
1466 // zeros for other arguments.
1467 //
1468 // <srcblock>
1469 // REAL TABLE ((15 + 128) + 2(15 + 256))
1470 // CALL SCFFT2D (0, 128, 256, 0.0, DUMMY, 1, DUMMY, 1,
1471 // & TABLE, DUMMY, 0)
1472 // </srcblock>
1473 //
1474 // Example 2: X is a real array of size (0:128, 0: 255), and Y is a
1475 // complex array of dimension (0:64, 0:255). The first 128 elements of
1476 // each column of X contain data; for performance reasons, the extra
1477 // element forces the leading dimension to be an odd number. Take the
1478 // two-dimensional FFT of X and store it in Y. Initialize the TABLE
1479 // array, as in example 1.
1480 //
1481 // <srcblock>
1482 // REAL X(0:128, 0:255)
1483 // COMPLEX Y(0:64, 0:255)
1484 // REAL TABLE ((15 + 128) + 2(15 + 256))
1485 // REAL WORK(128*256)
1486 // ...
1487 // CALL SCFFT2D(0, 128, 256, 1.0, X, 129, Y, 65, TABLE, WORK, 0)
1488 // CALL SCFFT2D(1, 128, 256, 1.0, X, 129, Y, 65, TABLE, WORK, 0)
1489 // </srcblock>
1490 //
1491 // Example 3: With X and Y as in example 2, take the inverse FFT of Y
1492 // and store it back in X. The scale factor 1/(128*256) is used. Assume
1493 // that the TABLE array is initialized already.
1494 //
1495 // <srcblock>
1496 // CALL CSFFT2D(-1, 128, 256, 1.0/(128.0*256.0), Y, 65,
1497 // & X, 130, TABLE, WORK, 0)
1498 // </srcblock>
1499 //
1500 // Example 4: Perform the same computation as in example 2, but assume
1501 // that the lower bound of each array is 1, rather than 0. No change is
1502 // needed in the subroutine calls.
1503 //
1504 // <srcblock>
1505 // REAL X(129, 256)
1506 // COMPLEX Y(65, 256)
1507 // ...
1508 // CALL SCFFT2D(0, 128, 256, 1.0, X, 129, Y, 65, TABLE, WORK, 0)
1509 // CALL SCFFT2D(1, 128, 256, 1.0, X, 129, Y, 65, TABLE, WORK, 0)
1510 // </srcblock>
1511 //
1512 // Example 5: Perform the same computation as in example 4, but
1513 // equivalence the input and output arrays to save storage space. In
1514 // this case, a row must be added to X, because it is equivalenced to a
1515 // complex array. Assume that TABLE is already initialized.
1516 //
1517 // <srcblock>
1518 // REAL X(130, 256)
1519 // COMPLEX Y(65, 256)
1520 // EQUIVALENCE ( X(1, 1), Y(1, 1) )
1521 // ...
1522 // CALL SCFFT2D(1, 128, 256, 1.0, X, 130, Y, 65, TABLE, WORK, 0)
1523 // </srcblock>
1524 // </example>
1525 //
1526 // Input parameters:
1527 // <dl compact>
1528 // <dt><b>isign</b>
1529 // <dd> Integer.
1530 // Specifies whether to initialize the table array or to do the
1531 // forward or inverse Fourier transform, as follows:
1532 //
1533 // If isign = 0, the routine initializes the table array and
1534 // returns. In this case, the only arguments used or checked
1535 // are isign, n, and table.
1536 //
1537 // If isign = +1 or -1, the value of isign is the sign of the
1538 // exponent used in the FFT formula.
1539 // <dt><b>n1</b>
1540 // <dd> Integer.
1541 // Transform size in the first dimension. If n1 is not
1542 // positive, <src>scfft2d</src> returns without calculating a
1543 // transform.
1544 // <dt><b>n2</b>
1545 // <dd> Integer.
1546 // Transform size in the second dimension. If n2 is not
1547 // positive, <src>scfft2d</src> returns without calculating a
1548 // transform.
1549 // <dt><b>scale</b>
1550 // <dd> Scale factor.
1551 // <src>scfft2d</src>: real.
1552 // <src>dzfft2d</src>: double precision.
1553 // <src>csfft2d</src>: real.
1554 // <src>zdfft2d</src>: double precision.
1555 // Each element of the output array is multiplied by scale
1556 // factor after taking the Fourier transform, as defined
1557 // previously.
1558 // <dt><b>x</b>
1559 // <dd> Array of dimension (0:ldx-1, 0:n2-1).
1560 // <src>scfft2d</src>: real array.
1561 // <src>dzfft2d</src>: double precision array.
1562 // <src>csfft2d</src>: complex array.
1563 // <src>zdfft2d</src>: double complex array.
1564 //
1565 // Array of values to be transformed.
1566 // <dt><b>ldx</b>
1567 // <dd> Integer.
1568 // The number of rows in the x array, as it was declared in the
1569 // calling program. That is, the leading dimension of x.
1570 // <src>scfft2d, dzfft2d</src>: ldx >= MAX(n1, 1).
1571 // <src>csfft2d, zdfft2d</src>: ldx >= MAX(n1/2 + 1, 1).
1572 // <dt><b>ldy</b>
1573 // <dd> Integer.
1574 //
1575 // The number of rows in the y array, as it was declared in the
1576 // calling program (the leading dimension of y).
1577 //
1578 // <src>scfft2d, dzfft2d</src>: ldy >= MAX(n1/2 + 1, 1).
1579 // <src>csfft2d, zdfft2d</src>: ldy >= MAX(n1 + 2, 1).
1580 //
1581 // In the complex-to-real routine, two extra elements are in
1582 // the first dimension (ldy >= n1 + 2, rather than just ldy >=
1583 // n1). These elements are needed for intermediate storage
1584 // during the computation. On exit, their value is undefined.
1585 // <dt><b>isys</b>
1586 // <dd> Integer array of dimension (0:isys(0)).
1587 // The first element of the array specifies how many more
1588 // elements are in the array. Use isys to specify certain
1589 // processor-specific parameters or options.
1590 //
1591 // If isys(0) = 0, the default values of such parameters are
1592 // used. In this case, you can specify the argument value as
1593 // the scalar integer constant 0.
1594 //
1595 // If isys(0) > 0, isys(0) gives the upper bound of the isys
1596 // array. Therefore, if il = isys(0), user-specified
1597 // parameters are expected in isys(1) through isys(il).
1598 // <dt><b>isys</b>
1599 // <dd> Algorithm used; value dependent on hardware system. Currently, no
1600 // special options are supported; therefore, you must always specify
1601 // an isys argument as constant 0.
1602 // </dl>
1603 // Output parameters:
1604 // <dl compact>
1605 // <dt><b>y</b>
1606 // <dd> <src>scfft2d</src>: complex array.
1607 // <src>dzfft2d</src>: double complex array.
1608 // <src>csfft2d</src>: real array.
1609 // <src>zdfft2d</src>: double precision array.
1610 //
1611 // Output array of transformed values. The output array can be
1612 // the same as the input array, in which case, the transform is
1613 // done in place and the input array is overwritten with the
1614 // transformed values. In this case, it is necessary that the
1615 // following equalities hold:
1616 //
1617 // <src>scfft2d, dzfft2d</src>: ldx = 2 * ldy.
1618 // <src>csfft2d, zdfft2d</src>: ldy = 2 * ldx.
1619 // <dt><b>table</b>
1620 // <dd> Real array; dimension (15 + n1) + 2(15 + n2).
1621 //
1622 // Table of factors and trigonometric functions.
1623 //
1624 // If isign = 0, the routine initializes table (table is output
1625 // only).
1626 //
1627 // If isign = +1 or -1, the values in table are assumed to be
1628 // initialized already by a prior call with isign = 0 (table is
1629 // input only).
1630 // <dt><b>work</b>
1631 // <dd> Real array; dimension (n1 * n2).
1632 //
1633 // Work array. This is a scratch array used for intermediate
1634 // calculations. Its address space must be different from that
1635 // of the input and output arrays.
1636 // </dl>
1637 // <group>
1638 static void scfft2d(Int isign, Int n1, Int n2, Float scale, Float* x, Int ldx, Complex* y,
1639 Int ldy, Float* table, Float* work, Int isys);
1640 static void dzfft2d(Int isign, Int n1, Int n2, Double scale, Double* x, Int ldx, DComplex* y,
1641 Int ldy, Double* table, Double* work, Int isys);
1642 static void csfft2d(Int isign, Int n1, Int n2, Float scale, Complex* x, Int ldx, Float* y,
1643 Int ldy, Float* table, Float* work, Int isys);
1644 static void zdfft2d(Int isign, Int n1, Int n2, Double scale, DComplex* x, Int ldx, Double* y,
1645 Int ldy, Double* table, Double* work, Int isys);
1646 // </group>
1647
1648 // These routines compute the three-dimensional complex FFT of the
1649 // complex matrix X, and store the results in the complex matrix Y.
1650 //
1651 // In FFT applications, it is customary to use zero-based subscripts; the
1652 // formulas are simpler that way. So suppose the arrays are dimensioned
1653 // as follows:
1654 //
1655 // <srcblock>
1656 // COMPLEX X(0:n1-1, 0:n2-1, 0:n3-1)
1657 // COMPLEX Y(0:n1-1, 0:n2-1, 0:n3-1)
1658 // </srcblock>
1659 //
1660 // These routines compute the formula:
1661 //
1662 // <srcblock>
1663 // Y(k1,k2,k3) =
1664 // n1-1 n2-1 n3-1
1665 // scale * Sum Sum Sum [X(j1,j2,j3)*w1**(j1*k1)*w2**(j2*k2)*w3**(j3*k3)]
1666 // j1=0 j2=0 j3=0
1667 //
1668 // for k1 = 0, ..., n1 - 1,
1669 // k2 = 0, ..., n2 - 1,
1670 // k3 = 0, ..., n3 - 1,
1671 //
1672 // where:
1673 // w1 = exp(isign*2*pi*i/n1),
1674 // w2 = exp(isign*2*pi*i/n2),
1675 // w3 = exp(isign*2*pi*i/n3),
1676 // i = + sqrt(-1)
1677 // pi = 3.14159...
1678 // isign = +1 or -1
1679 // </srcblock>
1680 //
1681 // Different authors use different conventions for which of the
1682 // transforms, isign = +1 or isign = -1, is the forward or inverse
1683 // transform, and what the scale factor should be in either case. You
1684 // can make this routine compute any of the various possible definitions,
1685 // however, by choosing the appropriate values for isign and scale.
1686 //
1687 // The relevant fact from FFT theory is this: If you take the FFT with
1688 // any particular values of isign and scale, the mathematical inverse
1689 // function is computed by taking the FFT with -isign and 1/(n1 * n2 * n3
1690 // * scale). In particular, if you use isign = +1 and scale = 1.0 for
1691 // the forward FFT, you can compute the inverse FFT by using isign = -1
1692 // and scale = 1/(n1 . n2 . n3).
1693 //
1694 // <example>
1695 // The following examples are for Origin series only.
1696 //
1697 // Example 1: Initialize the TABLE array in preparation for doing a
1698 // three-dimensional FFT of size 128 by 128 by 128. In this case, only
1699 // the isign, n1, n2, n3, and table arguments are used; you can use dummy
1700 // arguments or zeros for other arguments.
1701 //
1702 // <srcblock>
1703 // REAL TABLE ((30 + 256) + (30 + 256) + (30 + 256))
1704 // CALL CCFFT3D (0, 128, 128, 128, 0.0, DUMMY, 1, 1, DUMMY, 1, 1,
1705 // & TABLE, DUMMY, 0)
1706 // </srcblock>
1707 //
1708 // Example 2: X and Y are complex arrays of dimension (0:128, 0:128,
1709 // 0:128). The first 128 elements of each dimension contain data; for
1710 // performance reasons, the extra element forces the leading dimensions
1711 // to be odd numbers. Take the three-dimensional FFT of X and store it
1712 // in Y. Initialize the TABLE array, as in example 1.
1713 //
1714 // <srcblock>
1715 // COMPLEX X(0:128, 0:128, 0:128)
1716 // COMPLEX Y(0:128, 0:128, 0:128)
1717 // REAL TABLE ((30+256) + (30 + 256) + (30 + 256))
1718 // REAL WORK 2(128*128*128)
1719 // ...
1720 // CALL CCFFT3D(0, 128, 128, 128, 1.0, DUMMY, 1, 1,
1721 // & DUMMY, 1, 1, TABLE, WORK, 0)
1722 // CALL CCFFT3D(1, 128, 128, 128, 1.0, X, 129, 129,
1723 // & Y, 129, 129, TABLE, WORK, 0)
1724 // </srcblock>
1725 //
1726 // Example 3: With X and Y as in example 2, take the inverse FFT of Y
1727 // and store it back in X. The scale factor 1.0/(128.0**3) is used.
1728 // Assume that the TABLE array is already initialized.
1729 //
1730 // <srcblock>
1731 // CALL CCFFT3D(-1, 128, 128, 128, 1.0/(128.0**3), Y, 129, 129,
1732 // & X, 129, 129, TABLE, WORK, 0)
1733 // </srcblock>
1734 //
1735 // Example 4: Perform the same computation as in example 2, but assume
1736 // that the lower bound of each array is 1, rather than 0. The
1737 // subroutine calls do not change.
1738 //
1739 // <srcblock>
1740 // COMPLEX X(129, 129, 129)
1741 // COMPLEX Y(129, 129, 129)
1742 // ...
1743 // CALL CCFFT3D(0, 128, 128, 128, 1.0, DUMMY, 1, 1,
1744 // & DUMMY, 1, 1, TABLE, WORK, 0)
1745 // CALL CCFFT3D(1, 128, 128, 128, 1.0, X, 129, 129,
1746 // & Y, 129, 129, TABLE, WORK, 0)
1747 // </srcblock>
1748 //
1749 // Example 5: Perform the same computation as in example 4, but put the
1750 // output back in the array X to save storage space. Assume that the
1751 // TABLE array is already initialized.
1752 //
1753 // <srcblock>
1754 // COMPLEX X(129, 129, 129)
1755 // ...
1756 // CALL CCFFT3D(1, 128, 128, 128, 1.0, X, 129, 129,
1757 // & X, 129, 129, TABLE, WORK, 0)
1758 // </srcblock>
1759 // </example>
1760 //
1761 // Input parameters:
1762 // <dl compact>
1763 // <dt><b>isign</b>
1764 // <dd> Integer.
1765 // Specifies whether to initialize the table array or to do the
1766 // forward or inverse Fourier transform, as follows:
1767 //
1768 // If isign = 0, the routine initializes the table array and
1769 // returns. In this case, the only arguments used or checked
1770 // are isign, n1, n2, n3, and table.
1771 //
1772 // If isign = +1 or -1, the value of isign is the sign of the
1773 // exponent used in the FFT formula.
1774 //
1775 // <dt><b>n1</b>
1776 // <dd> Integer.
1777 // Transform size in the first dimension. If n1 is not
1778 // positive, the routine returns without computing a transform.
1779 //
1780 // <dt><b>n2</b>
1781 // <dd> Integer.
1782 // Transform size in the second dimension. If n2 is not
1783 // positive, the routine returns without computing a transform.
1784 //
1785 // <dt><b>n3</b>
1786 // <dd> Integer.
1787 // Transform size in the third dimension. If n3 is not
1788 // positive, the routine returns without computing a transform.
1789 //
1790 // <dt><b>scale</b>
1791 // <dd> Scale factor.
1792 // <src>ccfft3d</src>: real.
1793 // <src>zzfft3d</src>: double precision.
1794 //
1795 // Each element of the output array is multiplied by scale
1796 // after taking the Fourier transform, as defined previously.
1797 //
1798 // <dt><b>x</b>
1799 // <dd> Array of dimension (0:ldx-1, 0:ldx2-1, 0:n3-1).
1800 // <src>ccfft3d</src>: complex array.
1801 // <src>zzfft3d</src>: double complex array.
1802 //
1803 // Input array of values to be transformed.
1804 //
1805 // <dt><b>ldx</b>
1806 // <dd> Integer.
1807 // The first dimension of x, as it was declared in the calling
1808 // program (the leading dimension of x). ldx >= MAX(n1, 1).
1809 //
1810 // <dt><b>ldx2</b>
1811 // <dd> Integer.
1812 // The second dimension of x, as it was declared in the calling
1813 // program. ldx2 >= MAX(n2, 1).
1814 //
1815 // <dt><b>ldy</b>
1816 // <dd> Integer.
1817 // The first dimension of y, as it was declared in the calling
1818 // program (the leading dimension of y). ldy >= MAX(n1, 1).
1819 //
1820 // <dt><b>ldy2</b>
1821 // <dd> Integer.
1822 // The second dimension of y, as it was declared in the calling
1823 // program. ldy2 >= MAX(n2, 1).
1824 //
1825 // <dt><b>isys</b>
1826 // <dd> Algorithm used; value dependent on hardware system. Currently, no
1827 // special options are supported; therefore, you must always specify
1828 // an isys argument as constant 0.
1829 //
1830 // isys = 0 or 1 depending on the amount of workspace the user
1831 // can provide to the routine.
1832 // </dl>
1833 // Output parameters:
1834 // <dl compact>
1835 // <dt><b>y</b>
1836 // <dd> Array of dimension (0:ldy-1, 0:ldy2-1, 0:n3-1).
1837 // <src>ccfft3d</src>: complex array.
1838 // <src>zzfft3d</src>: double complex array.
1839 //
1840 // Output array of transformed values. The output array may be
1841 // the same as the input array, in which case, the transform is
1842 // done in place; that is, the input array is overwritten with
1843 // the transformed values. In this case, it is necessary that
1844 // ldx = ldy, and ldx2 = ldy2.
1845 //
1846 // <dt><b>table</b>
1847 // <dd> Real array; dimension 30 + 2 * n1) + (30 + 2 * n2) + (30 + 2 * n3).
1848 //
1849 // Table of factors and trigonometric functions. If isign = 0,
1850 // the routine initializes table (table is output only). If
1851 // isign = +1 or -1, the values in table are assumed to be
1852 // initialized already by a prior call with isign = 0 (table is
1853 // input only).
1854 //
1855 // <dt><b>work</b>
1856 // <dd> Real array; dimension (n1 * n2 * n3).
1857 //
1858 // Work array. This is a scratch array used for intermediate
1859 // calculations. Its address space must be different from that
1860 // of the input and output arrays.
1861 //
1862 // </dl>
1863 // <group>
1864 static void ccfft3d(Int isign, Int n1, Int n2, Int n3, Float scale, Complex* x, Int ldx, Int ldx2,
1865 Complex* y, Int ldy, Int ldy2, Float* table, Float* work, Int isys);
1866 static void zzfft3d(Int isign, Int n1, Int n2, Int n3, Double scale, DComplex* x, Int ldx,
1867 Int ldx2, DComplex* y, Int ldy, Int ldy2, Double* table, Double* work,
1868 Int isys);
1869 // </group>
1870
1871 // These are C++ wrapper functions for the 3D real-to-complex and
1872 // complex-to-real transform routines in the SGI/Cray Scientific Library
1873 // (SCSL). The purpose of these definitions is to overload the functions so
1874 // that C++ users can access the functions in SCSL with identical function
1875 // names.
1876 //
1877 // <note role=warning>
1878 // Currently, the SCSL is available only on SGI machines.
1879 // </note>
1880 //
1881 // <src>scfft3d/dzfft3d</src> computes the three-dimensional Fast Fourier
1882 // Transform (FFT) of the real matrix X, and it stores the results in the
1883 // complex matrix Y. <src>csfft3d/zdfft3d</src> computes the corresponding
1884 // inverse transform.
1885 //
1886 // In FFT applications, it is customary to use zero-based subscripts; the
1887 // formulas are simpler that way. First, the function of <src>SCFFT3D</src> is
1888 // described. Suppose the arrays are dimensioned as follows:
1889 //
1890 // <srcblock>
1891 // REAL X(0:ldx-1, 0:ldx2-1, 0:n3-1)
1892 // COMPLEX Y(0:ldy-1, 0:ldy2-1, 0:n3-1)
1893 // </srcblock>
1894 //
1895 // <src>scfft3d</src> computes the formula:
1896 //
1897 // <srcblock>
1898 // Y(k1,k2,k3) =
1899 // n1-1 n2-1 n3-1
1900 // scale * Sum Sum Sum [X(j1,j2,j3)*w1**(j1*k1)*w2**(j2*k2)*w3**(j3*k3)]
1901 // j1=0 j2=0 j3=0
1902 //
1903 // for k1 = 0, ..., n1/2,
1904 // k2 = 0, ..., n2 - 1,
1905 // k3 = 0, ..., n3 - 1,
1906 //
1907 // where:
1908 // w1 = exp(isign*2*pi*i/n1),
1909 // w2 = exp(isign*2*pi*i/n2),
1910 // w3 = exp(isign*2*pi*i/n3),
1911 // i = + sqrt(-1)
1912 // pi = 3.14159...
1913 // isign = +1 or -1
1914 // </srcblock>
1915 //
1916 // Different authors use different conventions for which of the
1917 // transforms, isign = +1 or isign = -1, is the forward or inverse
1918 // transform, and what the scale factor should be in either case. You
1919 // can make these routines compute any of the various possible
1920 // definitions, however, by choosing the appropriate values for isign and
1921 // scale.
1922 //
1923 // The relevant fact from FFT theory is this: If you take the FFT with
1924 // any particular values of isign and scale, the mathematical inverse
1925 // function is computed by taking the FFT with -isign and 1/(n1 * n2 * n3
1926 // * scale). In particular, if you use isign = +1 and scale = 1.0 for
1927 // the forward FFT, you can compute the inverse FFT by isign = -1 and
1928 //
1929 // <srcblock>
1930 // scale = 1.0/(n1*n2*n3).
1931 // </srcblock>
1932 //
1933 // <src>scfft3d</src> is very similar in function to <src>ccfft3d</src>, but
1934 // it takes the real-to-complex transform in the first dimension, followed by
1935 // the complex-to-complex transform in the second and third dimensions.
1936 //
1937 // <src>csfft3d</src> does the reverse. It takes the complex-to-complex FFT
1938 // in the third and second dimensions, followed by the complex-to-real FFT in
1939 // the first dimension.
1940 //
1941 // See the <src>scfftm</src> man page for more information about
1942 // real-to-complex and complex-to-real FFTs. The three dimensional analog of
1943 // the conjugate formula is as follows:
1944 //
1945 // <srcblock>
1946 // Y = conjg Y
1947 // k ,k ,k n1 - k , n2 - k , n3 - k
1948 // 1 2 3 1 2 3
1949 //
1950 // for n1/2 < k <= n1 - 1
1951 // 1
1952 //
1953 // 0 <= k <= n2 - 1
1954 // 2
1955 //
1956 // 0 <= k <= n3 - 1
1957 // 3
1958 // where the notation conjg(z) represents the complex conjugate of z.
1959 // </srcblock>
1960 //
1961 // Thus, you have to compute only (slightly more than) half out the
1962 // output values, namely:
1963 //
1964 // <srcblock>
1965 // Y
1966 // k ,k ,k
1967 // 1 2 3
1968 //
1969 // for 0 <= k <= n1/2
1970 // 1
1971 //
1972 // 0 <= k <= n2 - 1
1973 // 2
1974 //
1975 // 0 <= k <= n3 - 1
1976 // </srcblock>
1977 //
1978 // <h3>Algorithm</h3>
1979 // <src>scfft3d</src> uses a routine similar to <src>scfftm</src> to do
1980 // multiple FFTs first on all columns of the input matrix, then uses a routine
1981 // similar to <src>ccfftm</src> on all rows of the result, and then on all
1982 // planes of that result. See <src>scfftm</src> and <src>ccfftm</src> for
1983 // more information about the algorithms used.
1984 //
1985 // </example>
1986 // The following examples are for Origin series only.
1987 //
1988 // Example 1: Initialize the TABLE array in preparation for doing a
1989 // three-dimensional FFT of size 128 by 128 by 128. In this case only
1990 // the isign, n1, n2, n3, and table arguments are used; you can use dummy
1991 // arguments or zeros for other arguments.
1992 //
1993 // <srcblock>
1994 // REAL TABLE ((15 + 128) + 2(15+128) + 2( 15 + 128))
1995 // CALL SCFFT3D (0, 128, 128, 128, 0.0, DUMMY, 1, 1, DUMMY, 1, 1,
1996 // & TABLE, DUMMY, 0)
1997 // </srcblock>
1998 //
1999 // Example 2: X is a real array of size (0:128, 0:128, 0:128). The
2000 // first 128 elements of each dimension contain data; for performance
2001 // reasons, the extra element forces the leading dimensions to be odd
2002 // numbers. Y is a complex array of dimension (0:64, 0:128, 0:128).
2003 // Take the three-dimensional FFT of X and store it in Y. Initialize the
2004 // TABLE array, as in example 1.
2005 //
2006 // <srcblock>
2007 // REAL X(0:128, 0:128, 0:128)
2008 // COMPLEX Y(0:64, 0:128, 0:128)
2009 // REAL TABLE ((15+128) + 2(15 + 128) + 2(15 + 128))
2010 // REAL WORK(128*128*128)
2011 // ...
2012 // CALL SCFFT3D(0, 128, 128, 128, 1.0, X, 129, 129,
2013 // & Y, 65, 129, TABLE, WORK, 0)
2014 // CALL SCFFT3D(1, 128, 128, 128, 1.0, X, 129, 129,
2015 // & Y, 65, 129, TABLE, WORK, 0)
2016 // </srcblock>
2017 //
2018 // Example 3: With X and Y as in example 2, take the inverse FFT of Y
2019 // and store it back in X. The scale factor 1/(128**3) is used. Assume
2020 // that the TABLE array is initialized already.
2021 //
2022 // <srcblock>
2023 // CALL CSFFT3D(-1, 128, 128, 128, 1.0/128.0**3, Y, 65, 129,
2024 // & X, 130, 129, TABLE, WORK, 0)
2025 // </srcblock>
2026 //
2027 // Example 4: Perform the same computation as in example 2, but assume
2028 // that the lower bound of each array is 1, rather than 0. No change is
2029 // made in the subroutine calls.
2030 //
2031 // <srcblock>
2032 // REAL X(129, 129, 129)
2033 // COMPLEX Y(65, 129, 129)
2034 // REAL TABLE ((15+128) + 2(15 + 128) + 2(15 + 128))
2035 // REAL WORK(128*128*128)
2036 // ...
2037 // CALL SCFFT3D(0, 128, 128, 128, 1.0, X, 129, 129,
2038 // & Y, 65, 129, TABLE, WORK, 0)
2039 // CALL SCFFT3D(1, 128, 128, 128, 1.0, X, 129, 129,
2040 // & X, 129, 129, TABLE, WORK, 0)
2041 // </srcblock>
2042 //
2043 // Example 5: Perform the same computation as in example 4, but
2044 // equivalence the input and output arrays to save storage space. Assume
2045 // that the TABLE array is initialized already.
2046 //
2047 // <srcblock>
2048 // REAL X(130, 129, 129)
2049 // COMPLEX Y(65, 129, 129)
2050 // EQUIVALENCE (X(1, 1, 1), Y(1, 1, 1))
2051 // ...
2052 // CALL SCFFT3D(1, 128, 128, 128, 1.0, X, 130, 129,
2053 // & Y, 65, 129, TABLE, WORK, 0)
2054 // </srcblock>
2055 // </example>
2056 //
2057 // Input parameters:
2058 // <dl compact>
2059 // <dt><b>isign</b>
2060 // <dd> Integer.
2061 // Specifies whether to initialize the table array or to do the
2062 // forward or inverse Fourier transform, as follows:
2063 //
2064 // If isign = 0, the routine initializes the table array and
2065 // returns. In this case, the only arguments used or checked
2066 // are isign, n1, n2, n3, and table.
2067 //
2068 // If isign = +1 or -1, the value of isign is the sign of the
2069 // exponent used in the FFT formula.
2070 //
2071 // <dt><b>n1</b>
2072 // <dd> Integer.
2073 // Transform size in the first dimension. If n1 is not
2074 // positive, <src>scfft3d</src> returns without computing a transform.
2075 //
2076 // <dt><b>n2</b>
2077 // <dd> Integer.
2078 // Transform size in the second dimension. If n2 is not
2079 // positive, <src>scfft3d</src> returns without computing a transform.
2080 //
2081 // <dt><b>n3</b>
2082 // <dd> Integer.
2083 // Transform size in the third dimension. If n3 is not
2084 // positive, <src>scfft3d</src> returns without computing a transform.
2085 //
2086 // <dt><b>scale</b>
2087 // <dd> Scale factor.
2088 // <src>scfft3d</src>: real.
2089 // <src>dzfft3d</src>: double precision.
2090 // <src>csfft3d</src>: real.
2091 // <src>zdfft3d</src>: double precision.
2092 // Each element of the output array is multiplied by scale
2093 // after taking the Fourier transform, as defined previously.
2094 //
2095 // <dt><b>x</b>
2096 // <dd> Array of dimension (0:ldx-1, 0:ldx2-1, 0:n3-1).
2097 // <src>scfft3d</src>: real array.
2098 // <src>dzfft3d</src>: double precision array.
2099 // <src>csfft3d</src>: complex array.
2100 // <src>zdfft3d</src>: double complex array.
2101 //
2102 // Array of values to be transformed.
2103 //
2104 // <dt><b>ldx</b>
2105 // <dd> Integer.
2106 // The first dimension of x, as it was declared in the calling
2107 // program (the leading dimension of x).
2108 //
2109 // <src>scfft3d, dzfft3d</src>: ldx >= MAX(n1, 1).
2110 // <src>csfft3d, zdfft3d</src>: ldx >= MAX(n1/2 + 1, 1).
2111 //
2112 // <dt><b>ldx2</b>
2113 // <dd> Integer.
2114 // The second dimension of x, as it was declared in the calling
2115 // program. ldx2 >= MAX(n2, 1).
2116 //
2117 // <dt><b>ldy</b>
2118 // <dd> Integer.
2119 // The first dimension of y, as it was declared in the calling
2120 // program; that is, the leading dimension of y.
2121 //
2122 // <src>scfft3d, dzfft3d</src>: ldy >= MAX(n1/2 + 1, 1).
2123 // <src>csfft3d, zdfft3d</src>: ldy >= MAX(n1 + 2, 1).
2124 //
2125 // In the complex-to-real routine, two extra elements are in
2126 // the first dimension (that is, ldy >= n1 + 2, rather than
2127 // just ldy >= n1). These elements are needed for intermediate
2128 // storage during the computation. On exit, their value is
2129 // undefined.
2130 //
2131 // <dt><b>ldy2</b>
2132 // <dd> Integer.
2133 // The second dimension of y, as it was declared in the calling
2134 // program. ldy2 >= MAX(n2, 1).
2135 //
2136 // <dt><b>isys</b>
2137 // <dd> Algorithm used; value dependent on hardware system. Currently, no
2138 // special options are supported; therefore, you must always specify
2139 // an isys argument as constant 0.
2140 //
2141 // isys = 0 or 1 depending on the amount of workspace the user
2142 // can provide to the routine.
2143 // </dl>
2144 // Output parameters:
2145 // <dl compact>
2146 // <dt><b>y</b>
2147 // <dd> Array of dimension (0:ldy-1, 0:ldy2-1, 0:n3-1).
2148 // <src>scfft3d</src>: complex array.
2149 // <src>dzfft3d</src>: double complex array.
2150 // <src>csfft3d</src>: real array.
2151 // <src>zdfft3d</src>: double precision array.
2152 //
2153 // Output array of transformed values. The output array can be
2154 // the same as the input array, in which case, the transform is
2155 // done in place; that is, the input array is overwritten with
2156 // the transformed values. In this case, it is necessary that
2157 // the following equalities hold:
2158 //
2159 // <src>scfft3d, dzfft3d</src>: ldx = 2 * ldy, and ldx2 = ldy2.
2160 // <src>csfft3d, zdfft3d</src>: ldy = 2 * ldx, and ldx2 = ldy2.
2161 //
2162 // <dt><b>table</b>
2163 // <dd> Real array; dimension (15 + n1) + 2(15 + n2) + 2(15 + n3).
2164 //
2165 // Table of factors and trigonometric functions.
2166 //
2167 // This array must be initialized by a call to <src>scfft3d</src> or
2168 // <src>csfft3d</src> with isign = 0.
2169 //
2170 // If isign = 0, table is initialized to contain trigonometric
2171 // tables needed to compute a three-dimensional FFT of size n1
2172 // by n2 by n3. If isign = +1 or -1, the values in table are
2173 // assumed to be initialized already by a prior call with isign
2174 // = 0.
2175 //
2176 // <dt><b>work</b>
2177 // <dd> Real array; dimension n1 * n2 * n3.
2178 //
2179 // Work array. This is a scratch array used for intermediate
2180 // calculations. Its address space must be different from that
2181 // of the input and output arrays.
2182 //
2183 // </dl>
2184 // <group>
2185 static void scfft3d(Int isign, Int n1, Int n2, Int n3, Float scale, Float* x, Int ldx, Int ldx2,
2186 Complex* y, Int ldy, Int ldy2, Float* table, Float* work, Int isys);
2187 static void dzfft3d(Int isign, Int n1, Int n2, Int n3, Double scale, Double* x, Int ldx, Int ldx2,
2188 DComplex* y, Int ldy, Int ldy2, Double* table, Double* work, Int isys);
2189 static void csfft3d(Int isign, Int n1, Int n2, Int n3, Float scale, Complex* x, Int ldx, Int ldx2,
2190 Float* y, Int ldy, Int ldy2, Float* table, Float* work, Int isys);
2191 static void zdfft3d(Int isign, Int n1, Int n2, Int n3, Double scale, DComplex* x, Int ldx,
2192 Int ldx2, Double* y, Int ldy, Int ldy2, Double* table, Double* work,
2193 Int isys);
2194 // </group>
2195};
2196
2197} // namespace casacore
2198
2199#endif
static void dzfft(Int isign, Int n, Double scale, Double *x, DComplex *y, Double *table, Double *work, Int isys)
static void zzfftm(Int isign, Int n, Int lot, Double scale, DComplex *x, Int ldx, DComplex *y, Int ldy, Double *table, Double *work, Int isys)
static void dzfft3d(Int isign, Int n1, Int n2, Int n3, Double scale, Double *x, Int ldx, Int ldx2, DComplex *y, Int ldy, Int ldy2, Double *table, Double *work, Int isys)
static void scfft(Int isign, Int n, Double scale, Double *x, DComplex *y, Double *table, Double *work, Int isys)
static void zdfft(Int isign, Int n, Double scale, DComplex *x, Double *y, Double *table, Double *work, Int isys)
static void ccfft2d(Int isign, Int n1, Int n2, Float scale, Complex *x, Int ldx, Complex *y, Int ldy, Float *table, Float *work, Int isys)
These routines compute the two-dimensional complex Fast Fourier Transform (FFT) of the complex matrix...
static void zzfft3d(Int isign, Int n1, Int n2, Int n3, Double scale, DComplex *x, Int ldx, Int ldx2, DComplex *y, Int ldy, Int ldy2, Double *table, Double *work, Int isys)
static void zdfft3d(Int isign, Int n1, Int n2, Int n3, Double scale, DComplex *x, Int ldx, Int ldx2, Double *y, Int ldy, Int ldy2, Double *table, Double *work, Int isys)
static void scfft3d(Int isign, Int n1, Int n2, Int n3, Float scale, Float *x, Int ldx, Int ldx2, Complex *y, Int ldy, Int ldy2, Float *table, Float *work, Int isys)
These are C++ wrapper functions for the 3D real-to-complex and complex-to-real transform routines in ...
static void dzfft2d(Int isign, Int n1, Int n2, Double scale, Double *x, Int ldx, DComplex *y, Int ldy, Double *table, Double *work, Int isys)
static void csfftm(Int isign, Int n, Int lot, Float scale, Complex *x, Int ldx, Float *y, Int ldy, Float *table, Float *work, Int isys)
static void scfftm(Int isign, Int n, Int lot, Float scale, Float *x, Int ldx, Complex *y, Int ldy, Float *table, Float *work, Int isys)
scfftm/dzfftm computes the FFT of each column of the real matrix X, and it stores the results in the ...
static void ccfft(Int isign, Int n, Float scale, Complex *x, Complex *y, Float *table, Float *work, Int isys)
These routines compute the Fast Fourier Transform (FFT) of the complex vector x, and store the result...
static void ccfft3d(Int isign, Int n1, Int n2, Int n3, Float scale, Complex *x, Int ldx, Int ldx2, Complex *y, Int ldy, Int ldy2, Float *table, Float *work, Int isys)
These routines compute the three-dimensional complex FFT of the complex matrix X, and store the resul...
static void zdfftm(Int isign, Int n, Int lot, Double scale, DComplex *x, Int ldx, Double *y, Int ldy, Double *table, Double *work, Int isys)
static void zzfft(Int isign, Int n, Double scale, DComplex *x, DComplex *y, Double *table, Double *work, Int isys)
static void scfft2d(Int isign, Int n1, Int n2, Float scale, Float *x, Int ldx, Complex *y, Int ldy, Float *table, Float *work, Int isys)
scfft2d/dzfft2d computes the two-dimensional Fast Fourier Transform (FFT) of the real matrix x,...
static void scfft(Int isign, Int n, Float scale, Float *x, Complex *y, Float *table, Float *work, Int isys)
scfft/dzfft computes the FFT of the real array x, and it stores the results in the complex array y.
static void csfft2d(Int isign, Int n1, Int n2, Float scale, Complex *x, Int ldx, Float *y, Int ldy, Float *table, Float *work, Int isys)
static void zzfft2d(Int isign, Int n1, Int n2, Double scale, DComplex *x, Int ldx, DComplex *y, Int ldy, Double *table, Double *work, Int isys)
static void ccfftm(Int isign, Int n, Int lot, Float scale, Complex *x, Int ldx, Complex *y, Int ldy, Float *table, Float *work, Int isys)
ccfftm/zzfftm computes the FFT of each column of the complex matrix x, and stores the results in the ...
static void csfft3d(Int isign, Int n1, Int n2, Int n3, Float scale, Complex *x, Int ldx, Int ldx2, Float *y, Int ldy, Int ldy2, Float *table, Float *work, Int isys)
static void dzfftm(Int isign, Int n, Int lot, Double scale, Double *x, Int ldx, DComplex *y, Int ldy, Double *table, Double *work, Int isys)
static void ccfft(Int isign, Int n, Double scale, DComplex *x, DComplex *y, Double *table, Double *work, Int isys)
static void zdfft2d(Int isign, Int n1, Int n2, Double scale, DComplex *x, Int ldx, Double *y, Int ldy, Double *table, Double *work, Int isys)
static void csfft(Int isign, Int n, Double scale, DComplex *x, Double *y, Double *table, Double *work, Int isys)
static void csfft(Int isign, Int n, Float scale, Complex *x, Float *y, Float *table, Float *work, Int isys)
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
float Float
Definition aipstype.h:52
int Int
Definition aipstype.h:48
double Double
Definition aipstype.h:53