1# Copyright 2014 Knowledge Economy Developments Ltd
2#
3# Henry Gomersall
4# heng@kedevelopments.co.uk
5#
6# All rights reserved.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions are met:
10#
11# * Redistributions of source code must retain the above copyright notice, this
12# list of conditions and the following disclaimer.
13#
14# * Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17#
18# * Neither the name of the copyright holder nor the names of its contributors
19# may be used to endorse or promote products derived from this software without
20# specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32# POSSIBILITY OF SUCH DAMAGE.
33#
34
35cimport numpy as np
36from libc.stdint cimport int64_t
37
38ctypedef struct _fftw_iodim:
39    int _n
40    int _is
41    int _os
42
43cdef extern from 'pyfftw_complex.h':
44
45    ctypedef float cfloat[2]
46    ctypedef double cdouble[2]
47    ctypedef long double clongdouble[2]
48
49cdef extern from 'fftw3.h':
50
51    # Double precision plans
52    ctypedef struct fftw_plan_struct:
53        pass
54
55    ctypedef fftw_plan_struct *fftw_plan
56
57    # Single precision plans
58    ctypedef struct fftwf_plan_struct:
59        pass
60
61    ctypedef fftwf_plan_struct *fftwf_plan
62
63    # Long double precision plans
64    ctypedef struct fftwl_plan_struct:
65        pass
66
67    ctypedef fftwl_plan_struct *fftwl_plan
68
69    # The stride info structure. I think that strictly
70    # speaking, this should be defined with a type suffix
71    # on fftw (ie fftw, fftwf or fftwl), but since the
72    # definition is transparent and is defined as _fftw_iodim,
73    # we ignore the distinction in order to simplify the code.
74    ctypedef struct fftw_iodim:
75        pass
76
77    # Double precision complex planner
78    fftw_plan fftw_plan_guru_dft(
79            int rank, fftw_iodim *dims,
80            int howmany_rank, fftw_iodim *howmany_dims,
81            cdouble *_in, cdouble *_out,
82            int sign, unsigned flags) nogil
83
84    # Single precision complex planner
85    fftwf_plan fftwf_plan_guru_dft(
86            int rank, fftw_iodim *dims,
87            int howmany_rank, fftw_iodim *howmany_dims,
88            cfloat *_in, cfloat *_out,
89            int sign, unsigned flags) nogil
90
91    # Single precision complex planner
92    fftwl_plan fftwl_plan_guru_dft(
93            int rank, fftw_iodim *dims,
94            int howmany_rank, fftw_iodim *howmany_dims,
95            clongdouble *_in, clongdouble *_out,
96            int sign, unsigned flags) nogil
97
98    # Double precision real to complex planner
99    fftw_plan fftw_plan_guru_dft_r2c(
100            int rank, fftw_iodim *dims,
101            int howmany_rank, fftw_iodim *howmany_dims,
102            double *_in, cdouble *_out,
103            unsigned flags) nogil
104
105    # Single precision real to complex planner
106    fftwf_plan fftwf_plan_guru_dft_r2c(
107            int rank, fftw_iodim *dims,
108            int howmany_rank, fftw_iodim *howmany_dims,
109            float *_in, cfloat *_out,
110            unsigned flags) nogil
111
112    # Single precision real to complex planner
113    fftwl_plan fftwl_plan_guru_dft_r2c(
114            int rank, fftw_iodim *dims,
115            int howmany_rank, fftw_iodim *howmany_dims,
116            long double *_in, clongdouble *_out,
117            unsigned flags) nogil
118
119    # Double precision complex to real planner
120    fftw_plan fftw_plan_guru_dft_c2r(
121            int rank, fftw_iodim *dims,
122            int howmany_rank, fftw_iodim *howmany_dims,
123            cdouble *_in, double *_out,
124            unsigned flags) nogil
125
126    # Single precision complex to real planner
127    fftwf_plan fftwf_plan_guru_dft_c2r(
128            int rank, fftw_iodim *dims,
129            int howmany_rank, fftw_iodim *howmany_dims,
130            cfloat *_in, float *_out,
131            unsigned flags) nogil
132
133    # Single precision complex to real planner
134    fftwl_plan fftwl_plan_guru_dft_c2r(
135            int rank, fftw_iodim *dims,
136            int howmany_rank, fftw_iodim *howmany_dims,
137            clongdouble *_in, long double *_out,
138            unsigned flags) nogil
139
140    # Double precision real planner
141    fftw_plan fftw_plan_guru_r2r(
142            int rank, fftw_iodim *dims,
143            int howmany_rank, fftw_iodim *howmany_dims,
144            double *_in, double *_out,
145            int *kind, unsigned flags)
146
147    # Single precision real planner
148    fftwf_plan fftwf_plan_guru_r2r(
149            int rank, fftw_iodim *dims,
150            int howmany_rank, fftw_iodim *howmany_dims,
151            float *_in, float *_out,
152            int *kind, unsigned flags)
153
154    # Long double precision real planner
155    fftwl_plan fftwl_plan_guru_r2r(
156            int rank, fftw_iodim *dims,
157            int howmany_rank, fftw_iodim *howmany_dims,
158            long double *_in, long double *_out,
159            int *kind, unsigned flags)
160
161    # Double precision complex new array execute
162    void fftw_execute_dft(fftw_plan,
163          cdouble *_in, cdouble *_out) nogil
164
165    # Single precision complex new array execute
166    void fftwf_execute_dft(fftwf_plan,
167          cfloat *_in, cfloat *_out) nogil
168
169    # Long double precision complex new array execute
170    void fftwl_execute_dft(fftwl_plan,
171          clongdouble *_in, clongdouble *_out) nogil
172
173    # Double precision real to complex new array execute
174    void fftw_execute_dft_r2c(fftw_plan,
175          double *_in, cdouble *_out) nogil
176
177    # Single precision real to complex new array execute
178    void fftwf_execute_dft_r2c(fftwf_plan,
179          float *_in, cfloat *_out) nogil
180
181    # Long double precision real to complex new array execute
182    void fftwl_execute_dft_r2c(fftwl_plan,
183          long double *_in, clongdouble *_out) nogil
184
185    # Double precision complex to real new array execute
186    void fftw_execute_dft_c2r(fftw_plan,
187          cdouble *_in, double *_out) nogil
188
189    # Single precision complex to real new array execute
190    void fftwf_execute_dft_c2r(fftwf_plan,
191          cfloat *_in, float *_out) nogil
192
193    # Long double precision complex to real new array execute
194    void fftwl_execute_dft_c2r(fftwl_plan,
195          clongdouble *_in, long double *_out) nogil
196
197    # Double precision real new array execute
198    void fftw_execute_r2r(fftw_plan,
199          double *_in, double *_out) nogil
200
201    # Single precision real new array execute
202    void fftwf_execute_r2r(fftwf_plan,
203          float *_in, float *_out) nogil
204
205    # Long double precision real new array execute
206    void fftwl_execute_r2r(fftwl_plan,
207          long double *_in, long double *_out) nogil
208
209    # Double precision plan destroyer
210    void fftw_destroy_plan(fftw_plan)
211
212    # Single precision plan destroyer
213    void fftwf_destroy_plan(fftwf_plan)
214
215    # Long double precision plan destroyer
216    void fftwl_destroy_plan(fftwl_plan)
217
218    # Double precision set timelimit
219    void fftw_set_timelimit(double seconds)
220
221    # Single precision set timelimit
222    void fftwf_set_timelimit(double seconds)
223
224    # Long double precision set timelimit
225    void fftwl_set_timelimit(double seconds)
226
227    # Threading routines
228    # Double precision
229    void fftw_init_threads()
230    void fftw_plan_with_nthreads(int n)
231
232    # Single precision
233    void fftwf_init_threads()
234    void fftwf_plan_with_nthreads(int n)
235
236    # Long double precision
237    void fftwl_init_threads()
238    void fftwl_plan_with_nthreads(int n)
239
240    # cleanup routines
241    void fftw_cleanup()
242    void fftwf_cleanup()
243    void fftwl_cleanup()
244    void fftw_cleanup_threads()
245    void fftwf_cleanup_threads()
246    void fftwl_cleanup_threads()
247
248    # wisdom functions
249    void fftw_export_wisdom(void (*write_char)(char c, void *), void *data)
250    void fftwf_export_wisdom(void (*write_char)(char c, void *), void *data)
251    void fftwl_export_wisdom(void (*write_char)(char c, void *), void *data)
252
253    int fftw_import_wisdom_from_string(char *input_string)
254    int fftwf_import_wisdom_from_string(char *input_string)
255    int fftwl_import_wisdom_from_string(char *input_string)
256
257    #int fftw_export_wisdom_to_filename(char *filename)
258    #int fftwf_export_wisdom_to_filename(char *filename)
259    #int fftwl_export_wisdom_to_filename(char *filename)
260    #
261    #int fftw_import_wisdom_from_filename(char *filename)
262    #int fftwf_import_wisdom_from_filename(char *filename)
263    #int fftwl_import_wisdom_from_filename(char *filename)
264
265    void fftw_forget_wisdom()
266    void fftwf_forget_wisdom()
267    void fftwl_forget_wisdom()
268
269    double FFTW_NO_TIMELIMIT
270
271# Define function pointers that can act as a placeholder
272# for whichever dtype is used (the problem being that fftw
273# has different function names and signatures for all the
274# different precisions and dft types).
275ctypedef void * (*fftw_generic_plan_guru)(
276        int rank, fftw_iodim *dims,
277        int howmany_rank, fftw_iodim *howmany_dims,
278        void *_in, void *_out,
279        int *directions, unsigned flags) nogil
280
281ctypedef void (*fftw_generic_execute)(void *_plan, void *_in, void *_out) nogil
282
283ctypedef void (*fftw_generic_destroy_plan)(void *_plan)
284
285ctypedef void (*fftw_generic_init_threads)()
286
287ctypedef void (*fftw_generic_plan_with_nthreads)(int n)
288
289ctypedef void (*fftw_generic_set_timelimit)(double seconds)
290
291ctypedef bint (*validator)(np.ndarray input_array,
292        np.ndarray output_array, int64_t *axes, int64_t *not_axes,
293        int64_t axes_length)
294
295# Direction enum
296cdef enum:
297    FFTW_FORWARD = -1
298    FFTW_BACKWARD = 1
299    # from fftw3.f 3.3.3; may not be valid for different versions of FFTW.
300    FFTW_REDFT00  = 3
301    FFTW_REDFT01  = 4
302    FFTW_REDFT10  = 5
303    FFTW_REDFT11  = 6
304    FFTW_RODFT00  = 7
305    FFTW_RODFT01  = 8
306    FFTW_RODFT10  = 9
307    FFTW_RODFT11  = 10
308
309# Documented flags
310cdef enum:
311    FFTW_MEASURE = 0
312    FFTW_DESTROY_INPUT = 1
313    FFTW_UNALIGNED = 2
314    FFTW_CONSERVE_MEMORY = 4
315    FFTW_EXHAUSTIVE = 8
316    FFTW_PRESERVE_INPUT = 16
317    FFTW_PATIENT = 32
318    FFTW_ESTIMATE = 64
319    FFTW_WISDOM_ONLY = 2097152
320