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