xref: /aosp_15_r20/external/pffft/pffft_double.h (revision 3f1979aa0d7ad34fcf3763de7b7b8f8cd67e5bdd)
1*3f1979aaSAndroid Build Coastguard Worker /* Copyright (c) 2013  Julien Pommier ( [email protected] )
2*3f1979aaSAndroid Build Coastguard Worker 
3*3f1979aaSAndroid Build Coastguard Worker    Based on original fortran 77 code from FFTPACKv4 from NETLIB,
4*3f1979aaSAndroid Build Coastguard Worker    authored by Dr Paul Swarztrauber of NCAR, in 1985.
5*3f1979aaSAndroid Build Coastguard Worker 
6*3f1979aaSAndroid Build Coastguard Worker    As confirmed by the NCAR fftpack software curators, the following
7*3f1979aaSAndroid Build Coastguard Worker    FFTPACKv5 license applies to FFTPACKv4 sources. My changes are
8*3f1979aaSAndroid Build Coastguard Worker    released under the same terms.
9*3f1979aaSAndroid Build Coastguard Worker 
10*3f1979aaSAndroid Build Coastguard Worker    FFTPACK license:
11*3f1979aaSAndroid Build Coastguard Worker 
12*3f1979aaSAndroid Build Coastguard Worker    http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html
13*3f1979aaSAndroid Build Coastguard Worker 
14*3f1979aaSAndroid Build Coastguard Worker    Copyright (c) 2004 the University Corporation for Atmospheric
15*3f1979aaSAndroid Build Coastguard Worker    Research ("UCAR"). All rights reserved. Developed by NCAR's
16*3f1979aaSAndroid Build Coastguard Worker    Computational and Information Systems Laboratory, UCAR,
17*3f1979aaSAndroid Build Coastguard Worker    www.cisl.ucar.edu.
18*3f1979aaSAndroid Build Coastguard Worker 
19*3f1979aaSAndroid Build Coastguard Worker    Redistribution and use of the Software in source and binary forms,
20*3f1979aaSAndroid Build Coastguard Worker    with or without modification, is permitted provided that the
21*3f1979aaSAndroid Build Coastguard Worker    following conditions are met:
22*3f1979aaSAndroid Build Coastguard Worker 
23*3f1979aaSAndroid Build Coastguard Worker    - Neither the names of NCAR's Computational and Information Systems
24*3f1979aaSAndroid Build Coastguard Worker    Laboratory, the University Corporation for Atmospheric Research,
25*3f1979aaSAndroid Build Coastguard Worker    nor the names of its sponsors or contributors may be used to
26*3f1979aaSAndroid Build Coastguard Worker    endorse or promote products derived from this Software without
27*3f1979aaSAndroid Build Coastguard Worker    specific prior written permission.
28*3f1979aaSAndroid Build Coastguard Worker 
29*3f1979aaSAndroid Build Coastguard Worker    - Redistributions of source code must retain the above copyright
30*3f1979aaSAndroid Build Coastguard Worker    notices, this list of conditions, and the disclaimer below.
31*3f1979aaSAndroid Build Coastguard Worker 
32*3f1979aaSAndroid Build Coastguard Worker    - Redistributions in binary form must reproduce the above copyright
33*3f1979aaSAndroid Build Coastguard Worker    notice, this list of conditions, and the disclaimer below in the
34*3f1979aaSAndroid Build Coastguard Worker    documentation and/or other materials provided with the
35*3f1979aaSAndroid Build Coastguard Worker    distribution.
36*3f1979aaSAndroid Build Coastguard Worker 
37*3f1979aaSAndroid Build Coastguard Worker    THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38*3f1979aaSAndroid Build Coastguard Worker    EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF
39*3f1979aaSAndroid Build Coastguard Worker    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
40*3f1979aaSAndroid Build Coastguard Worker    NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
41*3f1979aaSAndroid Build Coastguard Worker    HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL,
42*3f1979aaSAndroid Build Coastguard Worker    EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN
43*3f1979aaSAndroid Build Coastguard Worker    ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
44*3f1979aaSAndroid Build Coastguard Worker    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
45*3f1979aaSAndroid Build Coastguard Worker    SOFTWARE.
46*3f1979aaSAndroid Build Coastguard Worker */
47*3f1979aaSAndroid Build Coastguard Worker /*
48*3f1979aaSAndroid Build Coastguard Worker    NOTE: This file is adapted from Julien Pommier's original PFFFT,
49*3f1979aaSAndroid Build Coastguard Worker    which works on 32 bit floating point precision using SSE instructions,
50*3f1979aaSAndroid Build Coastguard Worker    to work with 64 bit floating point precision using AVX instructions.
51*3f1979aaSAndroid Build Coastguard Worker    Author: Dario Mambro @ https://github.com/unevens/pffft
52*3f1979aaSAndroid Build Coastguard Worker */
53*3f1979aaSAndroid Build Coastguard Worker /*
54*3f1979aaSAndroid Build Coastguard Worker    PFFFT : a Pretty Fast FFT.
55*3f1979aaSAndroid Build Coastguard Worker 
56*3f1979aaSAndroid Build Coastguard Worker    This is basically an adaptation of the single precision fftpack
57*3f1979aaSAndroid Build Coastguard Worker    (v4) as found on netlib taking advantage of SIMD instruction found
58*3f1979aaSAndroid Build Coastguard Worker    on cpus such as intel x86 (SSE1), powerpc (Altivec), and arm (NEON).
59*3f1979aaSAndroid Build Coastguard Worker 
60*3f1979aaSAndroid Build Coastguard Worker    For architectures where no SIMD instruction is available, the code
61*3f1979aaSAndroid Build Coastguard Worker    falls back to a scalar version.
62*3f1979aaSAndroid Build Coastguard Worker 
63*3f1979aaSAndroid Build Coastguard Worker    Restrictions:
64*3f1979aaSAndroid Build Coastguard Worker 
65*3f1979aaSAndroid Build Coastguard Worker    - 1D transforms only, with 64-bit double precision.
66*3f1979aaSAndroid Build Coastguard Worker 
67*3f1979aaSAndroid Build Coastguard Worker    - supports only transforms for inputs of length N of the form
68*3f1979aaSAndroid Build Coastguard Worker    N=(2^a)*(3^b)*(5^c), a >= 5, b >=0, c >= 0 (32, 48, 64, 96, 128,
69*3f1979aaSAndroid Build Coastguard Worker    144, 160, etc are all acceptable lengths). Performance is best for
70*3f1979aaSAndroid Build Coastguard Worker    128<=N<=8192.
71*3f1979aaSAndroid Build Coastguard Worker 
72*3f1979aaSAndroid Build Coastguard Worker    - all (double*) pointers in the functions below are expected to
73*3f1979aaSAndroid Build Coastguard Worker    have an "simd-compatible" alignment, that is 32 bytes on x86 and
74*3f1979aaSAndroid Build Coastguard Worker    powerpc CPUs.
75*3f1979aaSAndroid Build Coastguard Worker 
76*3f1979aaSAndroid Build Coastguard Worker    You can allocate such buffers with the functions
77*3f1979aaSAndroid Build Coastguard Worker    pffft_aligned_malloc / pffft_aligned_free (or with stuff like
78*3f1979aaSAndroid Build Coastguard Worker    posix_memalign..)
79*3f1979aaSAndroid Build Coastguard Worker 
80*3f1979aaSAndroid Build Coastguard Worker */
81*3f1979aaSAndroid Build Coastguard Worker 
82*3f1979aaSAndroid Build Coastguard Worker #ifndef PFFFT_DOUBLE_H
83*3f1979aaSAndroid Build Coastguard Worker #define PFFFT_DOUBLE_H
84*3f1979aaSAndroid Build Coastguard Worker 
85*3f1979aaSAndroid Build Coastguard Worker #include <stddef.h> /* for size_t */
86*3f1979aaSAndroid Build Coastguard Worker 
87*3f1979aaSAndroid Build Coastguard Worker #ifdef __cplusplus
88*3f1979aaSAndroid Build Coastguard Worker extern "C" {
89*3f1979aaSAndroid Build Coastguard Worker #endif
90*3f1979aaSAndroid Build Coastguard Worker 
91*3f1979aaSAndroid Build Coastguard Worker   /* opaque struct holding internal stuff (precomputed twiddle factors)
92*3f1979aaSAndroid Build Coastguard Worker      this struct can be shared by many threads as it contains only
93*3f1979aaSAndroid Build Coastguard Worker      read-only data.
94*3f1979aaSAndroid Build Coastguard Worker   */
95*3f1979aaSAndroid Build Coastguard Worker   typedef struct PFFFTD_Setup PFFFTD_Setup;
96*3f1979aaSAndroid Build Coastguard Worker 
97*3f1979aaSAndroid Build Coastguard Worker #ifndef PFFFT_COMMON_ENUMS
98*3f1979aaSAndroid Build Coastguard Worker #define PFFFT_COMMON_ENUMS
99*3f1979aaSAndroid Build Coastguard Worker 
100*3f1979aaSAndroid Build Coastguard Worker   /* direction of the transform */
101*3f1979aaSAndroid Build Coastguard Worker   typedef enum { PFFFT_FORWARD, PFFFT_BACKWARD } pffft_direction_t;
102*3f1979aaSAndroid Build Coastguard Worker 
103*3f1979aaSAndroid Build Coastguard Worker   /* type of transform */
104*3f1979aaSAndroid Build Coastguard Worker   typedef enum { PFFFT_REAL, PFFFT_COMPLEX } pffft_transform_t;
105*3f1979aaSAndroid Build Coastguard Worker 
106*3f1979aaSAndroid Build Coastguard Worker #endif
107*3f1979aaSAndroid Build Coastguard Worker 
108*3f1979aaSAndroid Build Coastguard Worker   /*
109*3f1979aaSAndroid Build Coastguard Worker     prepare for performing transforms of size N -- the returned
110*3f1979aaSAndroid Build Coastguard Worker     PFFFTD_Setup structure is read-only so it can safely be shared by
111*3f1979aaSAndroid Build Coastguard Worker     multiple concurrent threads.
112*3f1979aaSAndroid Build Coastguard Worker   */
113*3f1979aaSAndroid Build Coastguard Worker   PFFFTD_Setup *pffftd_new_setup(int N, pffft_transform_t transform);
114*3f1979aaSAndroid Build Coastguard Worker   void pffftd_destroy_setup(PFFFTD_Setup *);
115*3f1979aaSAndroid Build Coastguard Worker   /*
116*3f1979aaSAndroid Build Coastguard Worker      Perform a Fourier transform , The z-domain data is stored in the
117*3f1979aaSAndroid Build Coastguard Worker      most efficient order for transforming it back, or using it for
118*3f1979aaSAndroid Build Coastguard Worker      convolution. If you need to have its content sorted in the
119*3f1979aaSAndroid Build Coastguard Worker      "usual" way, that is as an array of interleaved complex numbers,
120*3f1979aaSAndroid Build Coastguard Worker      either use pffft_transform_ordered , or call pffft_zreorder after
121*3f1979aaSAndroid Build Coastguard Worker      the forward fft, and before the backward fft.
122*3f1979aaSAndroid Build Coastguard Worker 
123*3f1979aaSAndroid Build Coastguard Worker      Transforms are not scaled: PFFFT_BACKWARD(PFFFT_FORWARD(x)) = N*x.
124*3f1979aaSAndroid Build Coastguard Worker      Typically you will want to scale the backward transform by 1/N.
125*3f1979aaSAndroid Build Coastguard Worker 
126*3f1979aaSAndroid Build Coastguard Worker      The 'work' pointer should point to an area of N (2*N for complex
127*3f1979aaSAndroid Build Coastguard Worker      fft) doubles, properly aligned. If 'work' is NULL, then stack will
128*3f1979aaSAndroid Build Coastguard Worker      be used instead (this is probably the best strategy for small
129*3f1979aaSAndroid Build Coastguard Worker      FFTs, say for N < 16384). Threads usually have a small stack, that
130*3f1979aaSAndroid Build Coastguard Worker      there's no sufficient amount of memory, usually leading to a crash!
131*3f1979aaSAndroid Build Coastguard Worker      Use the heap with pffft_aligned_malloc() in this case.
132*3f1979aaSAndroid Build Coastguard Worker 
133*3f1979aaSAndroid Build Coastguard Worker      input and output may alias.
134*3f1979aaSAndroid Build Coastguard Worker   */
135*3f1979aaSAndroid Build Coastguard Worker   void pffftd_transform(PFFFTD_Setup *setup, const double *input, double *output, double *work, pffft_direction_t direction);
136*3f1979aaSAndroid Build Coastguard Worker 
137*3f1979aaSAndroid Build Coastguard Worker   /*
138*3f1979aaSAndroid Build Coastguard Worker      Similar to pffft_transform, but makes sure that the output is
139*3f1979aaSAndroid Build Coastguard Worker      ordered as expected (interleaved complex numbers).  This is
140*3f1979aaSAndroid Build Coastguard Worker      similar to calling pffft_transform and then pffft_zreorder.
141*3f1979aaSAndroid Build Coastguard Worker 
142*3f1979aaSAndroid Build Coastguard Worker      input and output may alias.
143*3f1979aaSAndroid Build Coastguard Worker   */
144*3f1979aaSAndroid Build Coastguard Worker   void pffftd_transform_ordered(PFFFTD_Setup *setup, const double *input, double *output, double *work, pffft_direction_t direction);
145*3f1979aaSAndroid Build Coastguard Worker 
146*3f1979aaSAndroid Build Coastguard Worker   /*
147*3f1979aaSAndroid Build Coastguard Worker      call pffft_zreorder(.., PFFFT_FORWARD) after pffft_transform(...,
148*3f1979aaSAndroid Build Coastguard Worker      PFFFT_FORWARD) if you want to have the frequency components in
149*3f1979aaSAndroid Build Coastguard Worker      the correct "canonical" order, as interleaved complex numbers.
150*3f1979aaSAndroid Build Coastguard Worker 
151*3f1979aaSAndroid Build Coastguard Worker      (for real transforms, both 0-frequency and half frequency
152*3f1979aaSAndroid Build Coastguard Worker      components, which are real, are assembled in the first entry as
153*3f1979aaSAndroid Build Coastguard Worker      F(0)+i*F(n/2+1). Note that the original fftpack did place
154*3f1979aaSAndroid Build Coastguard Worker      F(n/2+1) at the end of the arrays).
155*3f1979aaSAndroid Build Coastguard Worker 
156*3f1979aaSAndroid Build Coastguard Worker      input and output should not alias.
157*3f1979aaSAndroid Build Coastguard Worker   */
158*3f1979aaSAndroid Build Coastguard Worker   void pffftd_zreorder(PFFFTD_Setup *setup, const double *input, double *output, pffft_direction_t direction);
159*3f1979aaSAndroid Build Coastguard Worker 
160*3f1979aaSAndroid Build Coastguard Worker   /*
161*3f1979aaSAndroid Build Coastguard Worker      Perform a multiplication of the frequency components of dft_a and
162*3f1979aaSAndroid Build Coastguard Worker      dft_b and accumulate them into dft_ab. The arrays should have
163*3f1979aaSAndroid Build Coastguard Worker      been obtained with pffft_transform(.., PFFFT_FORWARD) and should
164*3f1979aaSAndroid Build Coastguard Worker      *not* have been reordered with pffft_zreorder (otherwise just
165*3f1979aaSAndroid Build Coastguard Worker      perform the operation yourself as the dft coefs are stored as
166*3f1979aaSAndroid Build Coastguard Worker      interleaved complex numbers).
167*3f1979aaSAndroid Build Coastguard Worker 
168*3f1979aaSAndroid Build Coastguard Worker      the operation performed is: dft_ab += (dft_a * fdt_b)*scaling
169*3f1979aaSAndroid Build Coastguard Worker 
170*3f1979aaSAndroid Build Coastguard Worker      The dft_a, dft_b and dft_ab pointers may alias.
171*3f1979aaSAndroid Build Coastguard Worker   */
172*3f1979aaSAndroid Build Coastguard Worker   void pffftd_zconvolve_accumulate(PFFFTD_Setup *setup, const double *dft_a, const double *dft_b, double *dft_ab, double scaling);
173*3f1979aaSAndroid Build Coastguard Worker 
174*3f1979aaSAndroid Build Coastguard Worker   /*
175*3f1979aaSAndroid Build Coastguard Worker      Perform a multiplication of the frequency components of dft_a and
176*3f1979aaSAndroid Build Coastguard Worker      dft_b and put result in dft_ab. The arrays should have
177*3f1979aaSAndroid Build Coastguard Worker      been obtained with pffft_transform(.., PFFFT_FORWARD) and should
178*3f1979aaSAndroid Build Coastguard Worker      *not* have been reordered with pffft_zreorder (otherwise just
179*3f1979aaSAndroid Build Coastguard Worker      perform the operation yourself as the dft coefs are stored as
180*3f1979aaSAndroid Build Coastguard Worker      interleaved complex numbers).
181*3f1979aaSAndroid Build Coastguard Worker 
182*3f1979aaSAndroid Build Coastguard Worker      the operation performed is: dft_ab = (dft_a * fdt_b)*scaling
183*3f1979aaSAndroid Build Coastguard Worker 
184*3f1979aaSAndroid Build Coastguard Worker      The dft_a, dft_b and dft_ab pointers may alias.
185*3f1979aaSAndroid Build Coastguard Worker   */
186*3f1979aaSAndroid Build Coastguard Worker   void pffftd_zconvolve_no_accu(PFFFTD_Setup *setup, const double *dft_a, const double *dft_b, double*dft_ab, double scaling);
187*3f1979aaSAndroid Build Coastguard Worker 
188*3f1979aaSAndroid Build Coastguard Worker   /* return 4 or 1 wether support AVX instructions was enabled when building pffft-double.c */
189*3f1979aaSAndroid Build Coastguard Worker   int pffftd_simd_size();
190*3f1979aaSAndroid Build Coastguard Worker 
191*3f1979aaSAndroid Build Coastguard Worker   /* return string identifier of used architecture (AVX/..) */
192*3f1979aaSAndroid Build Coastguard Worker   const char * pffftd_simd_arch();
193*3f1979aaSAndroid Build Coastguard Worker 
194*3f1979aaSAndroid Build Coastguard Worker 
195*3f1979aaSAndroid Build Coastguard Worker   /* following functions are identical to the pffft_ functions */
196*3f1979aaSAndroid Build Coastguard Worker 
197*3f1979aaSAndroid Build Coastguard Worker   /* simple helper to get minimum possible fft size */
198*3f1979aaSAndroid Build Coastguard Worker   int pffftd_min_fft_size(pffft_transform_t transform);
199*3f1979aaSAndroid Build Coastguard Worker 
200*3f1979aaSAndroid Build Coastguard Worker   /* simple helper to determine next power of 2
201*3f1979aaSAndroid Build Coastguard Worker      - without inexact/rounding floating point operations
202*3f1979aaSAndroid Build Coastguard Worker   */
203*3f1979aaSAndroid Build Coastguard Worker   int pffftd_next_power_of_two(int N);
204*3f1979aaSAndroid Build Coastguard Worker 
205*3f1979aaSAndroid Build Coastguard Worker   /* simple helper to determine if power of 2 - returns bool */
206*3f1979aaSAndroid Build Coastguard Worker   int pffftd_is_power_of_two(int N);
207*3f1979aaSAndroid Build Coastguard Worker 
208*3f1979aaSAndroid Build Coastguard Worker   /*
209*3f1979aaSAndroid Build Coastguard Worker     the double buffers must have the correct alignment (32-byte boundary
210*3f1979aaSAndroid Build Coastguard Worker     on intel and powerpc). This function may be used to obtain such
211*3f1979aaSAndroid Build Coastguard Worker     correctly aligned buffers.
212*3f1979aaSAndroid Build Coastguard Worker   */
213*3f1979aaSAndroid Build Coastguard Worker   void *pffftd_aligned_malloc(size_t nb_bytes);
214*3f1979aaSAndroid Build Coastguard Worker   void pffftd_aligned_free(void *);
215*3f1979aaSAndroid Build Coastguard Worker 
216*3f1979aaSAndroid Build Coastguard Worker #ifdef __cplusplus
217*3f1979aaSAndroid Build Coastguard Worker }
218*3f1979aaSAndroid Build Coastguard Worker #endif
219*3f1979aaSAndroid Build Coastguard Worker 
220*3f1979aaSAndroid Build Coastguard Worker #endif /* PFFFT_DOUBLE_H */
221*3f1979aaSAndroid Build Coastguard Worker 
222