NFFT  3.3.0
nfft3.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002, 2015 Jens Keiner, Stefan Kunis, Daniel Potts
3  *
4  * This program is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 /* $Id$ */
20 
21 #ifndef __NFFT3_H__
22 #define __NFFT3_H__
23 
24 /* fftw_complex */
25 #include <fftw3.h>
26 
27 #ifdef __cplusplus
28 extern "C"
29 {
30 #endif /* __cplusplus */
31 
32 #define NFFT_CONCAT(prefix, name) prefix ## name
33 
34 /* IMPORTANT: for Windows compilers, you should add a line
35  * #define FFTW_DLL
36  * here and in kernel/infft.h if you are compiling/using NFFT as a DLL, in order
37  * to do the proper importing/exporting, or alternatively compile with
38  * -DNFFT_DLL or the equivalent command-line flag. This is not necessary under
39  * MinGW/Cygwin, where libtool does the imports/exports automatically. */
40 #if defined(NFFT_DLL) && (defined(_WIN32) || defined(__WIN32__))
41  /* annoying Windows syntax for shared-library declarations */
42 # if defined(COMPILING_NFFT) /* defined in api.h when compiling NFFT */
43 # define NFFT_EXTERN extern __declspec(dllexport)
44 # else /* user is calling NFFT; import symbol */
45 # define NFFT_EXTERN extern __declspec(dllimport)
46 # endif
47 #else
48 # define NFFT_EXTERN extern
49 #endif
50 
51 /* Integral type large enough to contain a stride (what ``int'' should have been
52  * in the first place) */
53 typedef ptrdiff_t NFFT_INT;
54 
55 /* Members inherited by all plans. */
56 #define MACRO_MV_PLAN(RC) \
57  NFFT_INT N_total; \
58  NFFT_INT M_total; \
59  RC *f_hat; \
60  RC *f; \
61  void (*mv_trafo)(void*); \
62  void (*mv_adjoint)(void*);
64 /* nfft */
65 
66 /* Name mangling macros. */
67 #define NFFT_MANGLE_DOUBLE(name) NFFT_CONCAT(nfft_, name)
68 #define NFFT_MANGLE_FLOAT(name) NFFT_CONCAT(nfftf_, name)
69 #define NFFT_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(nfftl_, name)
70 
71 #define NFFT_DEFINE_MALLOC_API(X) \
72 /* our own memory allocation and exit functions */ \
73 NFFT_EXTERN void *X(malloc)(size_t n); \
74 NFFT_EXTERN void X(free)(void *p); \
75 NFFT_EXTERN void X(die)(const char *s); \
76 \
77 /* You can replace the hooks with your own functions, if necessary. We */ \
78 /* need this for the Matlab interface. */ \
79 typedef void *(*X(malloc_type_function)) (size_t n); \
80 typedef void (*X(free_type_function)) (void *p); \
81 typedef void (*X(die_type_function)) (const char *errString); \
82 NFFT_EXTERN X(malloc_type_function) X(malloc_hook); \
83 NFFT_EXTERN X(free_type_function) X(free_hook); \
84 NFFT_EXTERN X(die_type_function) X(die_hook);
85 
86 /* Nfft module API. */
87 NFFT_DEFINE_MALLOC_API(NFFT_MANGLE_FLOAT)
88 NFFT_DEFINE_MALLOC_API(NFFT_MANGLE_DOUBLE)
89 NFFT_DEFINE_MALLOC_API(NFFT_MANGLE_LONG_DOUBLE)
90 
91 /* Macro to define prototypes for all NFFT API functions.
92  * We expand this macro for each supported precision.
93  * X: NFFT name-mangling macro
94  * Y: FFTW name-mangling macro
95  * R: Real float type
96  * C: Complex float type
97  */
98 #define NFFT_DEFINE_API(X,Y,R,C) \
99 \
100 typedef struct \
101 { \
102  MACRO_MV_PLAN(C) \
103 } X(mv_plan_complex); \
104 \
105 typedef struct \
106 { \
107  MACRO_MV_PLAN(R) \
108 } X(mv_plan_double); \
109 \
110  \
111 typedef struct\
112 {\
113  MACRO_MV_PLAN(C)\
114 \
115  NFFT_INT d; \
116  NFFT_INT *N; \
117  R *sigma; \
118  NFFT_INT *n; \
120  NFFT_INT n_total; \
121  NFFT_INT m; \
127  R *b; \
128  NFFT_INT K; \
130 \
131  unsigned flags; \
135 \
136  unsigned fftw_flags; \
138 \
139  R *x; \
140 \
141  R MEASURE_TIME_t[3]; \
143 \
144  /* internal use only */\
145  Y(plan) my_fftw_plan1; \
146  Y(plan) my_fftw_plan2; \
147 \
148  R **c_phi_inv; \
150  R *psi; \
152  NFFT_INT *psi_index_g; \
153  NFFT_INT *psi_index_f; \
154 \
155  C *g; \
156  C *g_hat; \
157  C *g1; \
158  C *g2; \
159 \
160  R *spline_coeffs; \
161 \
162  NFFT_INT *index_x; \
163 } X(plan); \
164 \
165 NFFT_EXTERN void X(trafo_direct)(const X(plan) *ths);\
166 NFFT_EXTERN void X(adjoint_direct)(const X(plan) *ths);\
167 NFFT_EXTERN void X(trafo)(X(plan) *ths);\
168 NFFT_EXTERN void X(trafo_1d)(X(plan) *ths);\
169 NFFT_EXTERN void X(trafo_2d)(X(plan) *ths);\
170 NFFT_EXTERN void X(trafo_3d)(X(plan) *ths);\
171 NFFT_EXTERN void X(adjoint)(X(plan) *ths);\
172 NFFT_EXTERN void X(adjoint_1d)(X(plan) *ths);\
173 NFFT_EXTERN void X(adjoint_2d)(X(plan) *ths);\
174 NFFT_EXTERN void X(adjoint_3d)(X(plan) *ths);\
175 NFFT_EXTERN void X(init_1d)(X(plan) *ths, int N1, int M);\
176 NFFT_EXTERN void X(init_2d)(X(plan) *ths, int N1, int N2, int M);\
177 NFFT_EXTERN void X(init_3d)(X(plan) *ths, int N1, int N2, int N3, int M);\
178 NFFT_EXTERN void X(init)(X(plan) *ths, int d, int *N, int M);\
179 NFFT_EXTERN void X(init_guru)(X(plan) *ths, int d, int *N, int M, int *n, \
180  int m, unsigned flags, unsigned fftw_flags);\
181 NFFT_EXTERN void X(init_lin)(X(plan) *ths, int d, int *N, int M, int *n, \
182  int m, int K, unsigned flags, unsigned fftw_flags); \
183 NFFT_EXTERN void X(precompute_one_psi)(X(plan) *ths);\
184 NFFT_EXTERN void X(precompute_psi)(X(plan) *ths);\
185 NFFT_EXTERN void X(precompute_full_psi)(X(plan) *ths);\
186 NFFT_EXTERN void X(precompute_fg_psi)(X(plan) *ths); \
187 NFFT_EXTERN void X(precompute_lin_psi)(X(plan) *ths);\
188 NFFT_EXTERN const char* X(check)(X(plan) *ths);\
189 NFFT_EXTERN void X(finalize)(X(plan) *ths);
190 
191 /* Nfft module API. */
192 NFFT_DEFINE_API(NFFT_MANGLE_FLOAT,FFTW_MANGLE_FLOAT,float,fftwf_complex)
193 NFFT_DEFINE_API(NFFT_MANGLE_DOUBLE,FFTW_MANGLE_DOUBLE,double,fftw_complex)
194 NFFT_DEFINE_API(NFFT_MANGLE_LONG_DOUBLE,FFTW_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
195 
196 /* Flags for init routines. */
197 #define PRE_PHI_HUT (1U<<0)
198 #define FG_PSI (1U<<1)
199 #define PRE_LIN_PSI (1U<<2)
200 #define PRE_FG_PSI (1U<<3)
201 #define PRE_PSI (1U<<4)
202 #define PRE_FULL_PSI (1U<<5)
203 #define MALLOC_X (1U<<6)
204 #define MALLOC_F_HAT (1U<<7)
205 #define MALLOC_F (1U<<8)
206 #define FFT_OUT_OF_PLACE (1U<<9)
207 #define FFTW_INIT (1U<<10)
208 #define NFFT_SORT_NODES (1U<<11)
209 #define NFFT_OMP_BLOCKWISE_ADJOINT (1U<<12)
210 #define PRE_ONE_PSI (PRE_LIN_PSI| PRE_FG_PSI| PRE_PSI| PRE_FULL_PSI)
211 
212 /* nfct */
213 
214 /* name mangling macros */
215 #define NFCT_MANGLE_DOUBLE(name) NFFT_CONCAT(nfct_, name)
216 #define NFCT_MANGLE_FLOAT(name) NFFT_CONCAT(nfctf_, name)
217 #define NFCT_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(nfctl_, name)
218 
219 /* huge second-order macro that defines prototypes for all nfct API functions.
220  * We expand this macro for each supported precision.
221  * X: nfct name-mangling macro
222  * Y: fftw name-mangling macro
223  * R: real data type
224  * C: complex data type
225  */
226 #define NFCT_DEFINE_API(X,Y,R,C) \
227  \
228 typedef struct\
229 {\
230  /* api */\
231  MACRO_MV_PLAN(R)\
232 \
233  NFFT_INT d; \
234  NFFT_INT *N; \
235  NFFT_INT *n; \
236  NFFT_INT n_total; \
237  R *sigma; \
238  NFFT_INT m; \
239 \
240  R *b; \
241  NFFT_INT K; \
243 \
244  unsigned flags; \
245  unsigned fftw_flags; \
246 \
247  R *x; \
248 \
249  double MEASURE_TIME_t[3]; \
250 \
251  /* internal use only */\
252  Y(plan) my_fftw_r2r_plan; \
253  Y(r2r_kind) *r2r_kind; \
254 \
255  R **c_phi_inv; \
256  R *psi; \
257  NFFT_INT size_psi; \
258  NFFT_INT *psi_index_g; \
259  NFFT_INT *psi_index_f; \
260 \
261  R *g;\
262  R *g_hat;\
263  R *g1; \
264  R *g2; \
265 \
266  R *spline_coeffs; \
267 } X(plan);\
268 \
269 NFFT_EXTERN void X(init_1d)(X(plan) *ths_plan, int N0, int M_total); \
270 NFFT_EXTERN void X(init_2d)(X(plan) *ths_plan, int N0, int N1, int M_total); \
271 NFFT_EXTERN void X(init_3d)(X(plan) *ths_plan, int N0, int N1, int N2, int M_total); \
272 NFFT_EXTERN void X(init)(X(plan) *ths_plan, int d, int *N, int M_total); \
273 NFFT_EXTERN void X(init_guru)(X(plan) *ths_plan, int d, int *N, int M_total, int *n, \
274  int m, unsigned flags, unsigned fftw_flags); \
275 NFFT_EXTERN void X(precompute_one_psi)(X(plan) *ths);\
276 NFFT_EXTERN void X(precompute_psi)(X(plan) *ths);\
277 NFFT_EXTERN void X(precompute_full_psi)(X(plan) *ths);\
278 NFFT_EXTERN void X(precompute_fg_psi)(X(plan) *ths); \
279 NFFT_EXTERN void X(precompute_lin_psi)(X(plan) *ths);\
280 NFFT_EXTERN void X(trafo)(X(plan) *ths_plan); \
281 NFFT_EXTERN void X(trafo_direct)(const X(plan) *ths_plan); \
282 NFFT_EXTERN void X(adjoint)(X(plan) *ths_plan); \
283 NFFT_EXTERN void X(adjoint_direct)(const X(plan) *ths_plan); \
284 NFFT_EXTERN const char* X(check)(X(plan) *ths);\
285 NFFT_EXTERN void X(finalize)(X(plan) *ths_plan); \
287 /* nfct api */
288 NFCT_DEFINE_API(NFCT_MANGLE_FLOAT,FFTW_MANGLE_FLOAT,float,fftwf_complex)
289 NFCT_DEFINE_API(NFCT_MANGLE_DOUBLE,FFTW_MANGLE_DOUBLE,double,fftw_complex)
290 NFCT_DEFINE_API(NFCT_MANGLE_LONG_DOUBLE,FFTW_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
291 
292 /* nfst */
293 
294 /* name mangling macros */
295 #define NFST_MANGLE_DOUBLE(name) NFFT_CONCAT(nfst_, name)
296 #define NFST_MANGLE_FLOAT(name) NFFT_CONCAT(nfstf_, name)
297 #define NFST_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(nfstl_, name)
298 
299 /* huge second-order macro that defines prototypes for all nfct API functions.
300  * We expand this macro for each supported precision.
301  * X: nfst name-mangling macro
302  * Y: fftw name-mangling macro
303  * R: real data type
304  * C: complex data type
305  */
306 #define NFST_DEFINE_API(X,Y,R,C) \
307  \
308 typedef struct\
309 {\
310  /* api */\
311  MACRO_MV_PLAN(R)\
312 \
313  NFFT_INT d; \
314  NFFT_INT *N; \
315  NFFT_INT *n; \
316  NFFT_INT n_total; \
317  R *sigma; \
318  NFFT_INT m; \
319 \
320  R *b; \
321  NFFT_INT K; \
323 \
324  unsigned flags; \
325  unsigned fftw_flags; \
326 \
327  R *x; \
328 \
329  double MEASURE_TIME_t[3]; \
330 \
331  /* internal use only */\
332  Y(plan) my_fftw_r2r_plan; \
333  Y(r2r_kind) *r2r_kind; \
334 \
335  R **c_phi_inv; \
336  R *psi; \
337  NFFT_INT size_psi; \
338  NFFT_INT *psi_index_g; \
339  NFFT_INT *psi_index_f; \
340 \
341  R *g;\
342  R *g_hat;\
343  R *g1; \
344  R *g2; \
345 \
346  R *spline_coeffs; \
347 \
348  R X(full_psi_eps);\
349 } X(plan);\
350 \
351 NFFT_EXTERN void X(init_1d)(X(plan) *ths_plan, int N0, int M_total); \
352 NFFT_EXTERN void X(init_2d)(X(plan) *ths_plan, int N0, int N1, int M_total); \
353 NFFT_EXTERN void X(init_3d)(X(plan) *ths_plan, int N0, int N1, int N2, int M_total); \
354 NFFT_EXTERN void X(init)(X(plan) *ths_plan, int d, int *N, int M_total); \
355 NFFT_EXTERN void X(init_guru)(X(plan) *ths_plan, int d, int *N, int M_total, int *n, \
356  int m, unsigned flags, unsigned fftw_flags); \
357 NFFT_EXTERN void X(precompute_one_psi)(X(plan) *ths);\
358 NFFT_EXTERN void X(precompute_psi)(X(plan) *ths);\
359 NFFT_EXTERN void X(precompute_full_psi)(X(plan) *ths);\
360 NFFT_EXTERN void X(precompute_fg_psi)(X(plan) *ths); \
361 NFFT_EXTERN void X(precompute_lin_psi)(X(plan) *ths);\
362 NFFT_EXTERN void X(trafo)(X(plan) *ths_plan); \
363 NFFT_EXTERN void X(trafo_direct)(const X(plan) *ths_plan); \
364 NFFT_EXTERN void X(adjoint)(X(plan) *ths_plan); \
365 NFFT_EXTERN void X(adjoint_direct)(const X(plan) *ths_plan); \
366 NFFT_EXTERN const char* X(check)(X(plan) *ths);\
367 NFFT_EXTERN void X(finalize)(X(plan) *ths_plan); \
368 
369 /* nfst api */
370 NFST_DEFINE_API(NFST_MANGLE_FLOAT,FFTW_MANGLE_FLOAT,float,fftwf_complex)
371 NFST_DEFINE_API(NFST_MANGLE_DOUBLE,FFTW_MANGLE_DOUBLE,double,fftw_complex)
372 NFST_DEFINE_API(NFST_MANGLE_LONG_DOUBLE,FFTW_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
373 
374 /* nnfft */
375 
376 /* name mangling macros */
377 #define NNFFT_MANGLE_DOUBLE(name) NFFT_CONCAT(nnfft_, name)
378 #define NNFFT_MANGLE_FLOAT(name) NFFT_CONCAT(nnfftf_, name)
379 #define NNFFT_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(nnfftl_, name)
380 
381 /* huge second-order macro that defines prototypes for all nfst API functions.
382  * We expand this macro for each supported precision.
383  * X: nnfft name-mangling macro
384  * Y: fftw name-mangling macro
385  * Z: nfft name mangling macro
386  * R: real data type
387  * C: complex data type
388  */
389 #define NNFFT_DEFINE_API(X,Y,Z,R,C) \
390  \
391 typedef struct\
392 {\
393  /* api */\
394  MACRO_MV_PLAN(C)\
395 \
396  int d; \
397  R *sigma; \
398  R *a; \
399  int *N; \
400  int *N1; \
401  int *aN1; \
402  int m; \
403  R *b; \
404  int K; \
405  int aN1_total; \
406  Z(plan) *direct_plan; \
407  unsigned nnfft_flags; \
408  int *n; \
409  R *x; \
410  R *v; \
411  R *c_phi_inv; \
412  R *psi; \
413  int size_psi; \
414  int *psi_index_g; \
415  int *psi_index_f; \
416  C *F;\
417  R *spline_coeffs; \
418 } X(plan);\
419 \
420 NFFT_EXTERN void X(init)(X(plan) *ths_plan, int d, int N_total, int M_total, int *N); \
421 NFFT_EXTERN void X(init_1d)(X(plan) *ths_plan, int N, int M_total); \
422 NFFT_EXTERN void X(init_guru)(X(plan) *ths_plan, int d, int N_total, int M_total, \
423  int *N, int *N1, int m, unsigned nnfft_flags); \
424 NFFT_EXTERN void X(trafo_direct)(X(plan) *ths_plan); \
425 NFFT_EXTERN void X(adjoint_direct)(X(plan) *ths_plan); \
426 NFFT_EXTERN void X(trafo)(X(plan) *ths_plan); \
427 NFFT_EXTERN void X(adjoint)(X(plan) *ths_plan); \
428 NFFT_EXTERN void X(precompute_lin_psi)(X(plan) *ths_plan); \
429 NFFT_EXTERN void X(precompute_psi)(X(plan) *ths_plan); \
430 NFFT_EXTERN void X(precompute_full_psi)(X(plan) *ths_plan); \
431 NFFT_EXTERN void X(precompute_phi_hut)(X(plan) *ths_plan); \
432 NFFT_EXTERN void X(precompute_one_psi)(X(plan) *ths);\
433 NFFT_EXTERN void X(finalize)(X(plan) *ths_plan);
434 
435 /* nnfft api */
436 NNFFT_DEFINE_API(NNFFT_MANGLE_FLOAT,FFTW_MANGLE_FLOAT,NFFT_MANGLE_FLOAT,float,fftwf_complex)
437 NNFFT_DEFINE_API(NNFFT_MANGLE_DOUBLE,FFTW_MANGLE_DOUBLE,NFFT_MANGLE_DOUBLE,double,fftw_complex)
438 NNFFT_DEFINE_API(NNFFT_MANGLE_LONG_DOUBLE,FFTW_MANGLE_LONG_DOUBLE,NFFT_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
439 
440 /* additional init flags */
441 #define MALLOC_V (1U<< 11)
442 
443 /* nsfft */
444 
445 #define NSFFT_MANGLE_DOUBLE(name) NFFT_CONCAT(nsfft_, name)
446 #define NSFFT_MANGLE_FLOAT(name) NFFT_CONCAT(nsfftf_, name)
447 #define NSFFT_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(nsfftl_, name)
448 
449 /* huge second-order macro that defines prototypes for all nnfft API functions.
450  * We expand this macro for each supported precision.
451  * X: nnfft name-mangling macro
452  * Y: fftw name-mangling macro
453  * Z: nfft name mangling macro
454  * R: real data type
455  * C: complex data type
456  */
457 #define NSFFT_DEFINE_API(X,Y,Z,R,C) \
458  \
459 typedef struct\
460 {\
461  MACRO_MV_PLAN(C)\
462 \
463  int d; \
464  int J; \
467  int sigma; \
468  unsigned flags; \
469  int *index_sparse_to_full; \
470  int r_act_nfft_plan; \
471  Z(plan) *act_nfft_plan; \
472  Z(plan) *center_nfft_plan; \
473  Y(plan) *set_fftw_plan1; \
474  Y(plan) *set_fftw_plan2; \
475  Z(plan) *set_nfft_plan_1d; \
476  Z(plan) *set_nfft_plan_2d; \
477  R *x_transposed; \
478  R *x_102,*x_201,*x_120,*x_021; \
479 } X(plan);\
480 \
481 NFFT_EXTERN void X(trafo_direct)(X(plan) *ths); \
482 NFFT_EXTERN void X(adjoint_direct)(X(plan) *ths); \
483 NFFT_EXTERN void X(trafo)(X(plan) *ths); \
484 NFFT_EXTERN void X(adjoint)(X(plan) *ths); \
485 NFFT_EXTERN void X(cp)(X(plan) *ths, Z(plan) *ths_nfft); \
486 NFFT_EXTERN void X(init_random_nodes_coeffs)(X(plan) *ths); \
487 NFFT_EXTERN void X(init)(X(plan) *ths, int d, int J, int M, int m, unsigned flags); \
488 NFFT_EXTERN void X(finalize)(X(plan) *ths);
489 
490 /* nsfft api */
491 NSFFT_DEFINE_API(NSFFT_MANGLE_FLOAT,FFTW_MANGLE_FLOAT,NFFT_MANGLE_FLOAT,float,fftwf_complex)
492 NSFFT_DEFINE_API(NSFFT_MANGLE_DOUBLE,FFTW_MANGLE_DOUBLE,NFFT_MANGLE_DOUBLE,double,fftw_complex)
493 NSFFT_DEFINE_API(NSFFT_MANGLE_LONG_DOUBLE,FFTW_MANGLE_LONG_DOUBLE,NFFT_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
494 
495 /* additional init flags */
496 #define NSDFT (1U<< 12)
497 
498 /* mri */
499 
500 /* name mangling macros */
501 #define MRI_MANGLE_DOUBLE(name) NFFT_CONCAT(mri_, name)
502 #define MRI_MANGLE_FLOAT(name) NFFT_CONCAT(mrif_, name)
503 #define MRI_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(mril_, name)
504 
505 /* huge second-order macro that defines prototypes for all mri API functions.
506  * We expand this macro for each supported precision.
507  * X: mri name-mangling macro
508  * Z: nfft name mangling macro
509  * R: real data type
510  * C: complex data type
511  */
512 #define MRI_DEFINE_API(X,Z,R,C) \
513 typedef struct\
514 {\
515  MACRO_MV_PLAN(C)\
516  Z(plan) plan;\
517  int N3;\
518  R sigma3;\
519  R *t;\
520  R *w;\
521 } X(inh_2d1d_plan);\
522 \
523 typedef struct\
524 {\
525  MACRO_MV_PLAN(C)\
526  Z(plan) plan;\
527  int N3;\
528  R sigma3;\
529  R *t;\
530  R *w;\
531 } X(inh_3d_plan);\
532 \
533 void X(inh_2d1d_trafo)(X(inh_2d1d_plan) *ths); \
534 void X(inh_2d1d_adjoint)(X(inh_2d1d_plan) *ths); \
535 void X(inh_2d1d_init_guru)(X(inh_2d1d_plan) *ths, int *N, int M, int *n, \
536  int m, R sigma, unsigned nfft_flags, unsigned fftw_flags); \
537 void X(inh_2d1d_finalize)(X(inh_2d1d_plan) *ths); \
538 void X(inh_3d_trafo)(X(inh_3d_plan) *ths); \
539 void X(inh_3d_adjoint)(X(inh_3d_plan) *ths); \
540 void X(inh_3d_init_guru)(X(inh_3d_plan) *ths, int *N, int M, int *n, \
541  int m, R sigma, unsigned nfft_flags, unsigned fftw_flags); \
542 void X(inh_3d_finalize)(X(inh_3d_plan) *ths);
543 
544  /* mri api */
545 MRI_DEFINE_API(MRI_MANGLE_FLOAT,NFFT_MANGLE_FLOAT,float,fftwf_complex)
546 MRI_DEFINE_API(MRI_MANGLE_DOUBLE,NFFT_MANGLE_DOUBLE,double,fftw_complex)
547 MRI_DEFINE_API(MRI_MANGLE_LONG_DOUBLE,NFFT_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
548 
549 /* nfsft */
550 
551 /* name mangling macros */
552 #define NFSFT_MANGLE_DOUBLE(name) NFFT_CONCAT(nfsft_, name)
553 #define NFSFT_MANGLE_FLOAT(name) NFFT_CONCAT(nfsftf_, name)
554 #define NFSFT_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(nfsftl_, name)
555 
556 /* huge second-order macro that defines prototypes for all nfsft API functions.
557  * We expand this macro for each supported precision.
558  * X: nfsft name-mangling macro
559  * Z: nfft name mangling macro
560  * R: real data type
561  * C: complex data type
562  */
563 #define NFSFT_DEFINE_API(X,Z,R,C) \
564  \
565 typedef struct\
566 {\
567  MACRO_MV_PLAN(C)\
568  int N; \
569  R *x; \
572  /* internal use only */\
573  int t; \
574  unsigned int flags; \
575  Z(plan) plan_nfft; \
576  C *f_hat_intern; \
578  double MEASURE_TIME_t[3]; \
580 } X(plan);\
581 \
582 NFFT_EXTERN void X(init)(X(plan) *plan, int N, int M); \
583 NFFT_EXTERN void X(init_advanced)(X(plan)* plan, int N, int M, unsigned int \
584  nfsft_flags); \
585 NFFT_EXTERN void X(init_guru)(X(plan) *plan, int N, int M, \
586  unsigned int nfsft_flags, unsigned int nfft_flags, int nfft_cutoff); \
587 NFFT_EXTERN void X(precompute)(int N, R kappa, unsigned int nfsft_flags, \
588  unsigned int fpt_flags); \
589 NFFT_EXTERN void X(forget)(void); \
590 NFFT_EXTERN void X(trafo_direct)(X(plan)* plan); \
591 NFFT_EXTERN void X(adjoint_direct)(X(plan)* plan); \
592 NFFT_EXTERN void X(trafo)(X(plan)* plan); \
593 NFFT_EXTERN void X(adjoint)(X(plan)* plan); \
594 NFFT_EXTERN void X(finalize)(X(plan) *plan); \
595 NFFT_EXTERN void X(precompute_x)(X(plan) *plan);
596 
597 /* nfsft api */
598 NFSFT_DEFINE_API(NFSFT_MANGLE_FLOAT,NFFT_MANGLE_FLOAT,float,fftwf_complex)
599 NFSFT_DEFINE_API(NFSFT_MANGLE_DOUBLE,NFFT_MANGLE_DOUBLE,double,fftw_complex)
600 NFSFT_DEFINE_API(NFSFT_MANGLE_LONG_DOUBLE,NFFT_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
601 
602 /* init flags */
603 #define NFSFT_NORMALIZED (1U << 0)
604 #define NFSFT_USE_NDFT (1U << 1)
605 #define NFSFT_USE_DPT (1U << 2)
606 #define NFSFT_MALLOC_X (1U << 3)
607 #define NFSFT_MALLOC_F_HAT (1U << 5)
608 #define NFSFT_MALLOC_F (1U << 6)
609 #define NFSFT_PRESERVE_F_HAT (1U << 7)
610 #define NFSFT_PRESERVE_X (1U << 8)
611 #define NFSFT_PRESERVE_F (1U << 9)
612 #define NFSFT_DESTROY_F_HAT (1U << 10)
613 #define NFSFT_DESTROY_X (1U << 11)
614 #define NFSFT_DESTROY_F (1U << 12)
615 
616 /* precompute flags */
617 #define NFSFT_NO_DIRECT_ALGORITHM (1U << 13)
618 #define NFSFT_NO_FAST_ALGORITHM (1U << 14)
619 #define NFSFT_ZERO_F_HAT (1U << 16)
620 
621 /* helper macros */
622 #define NFSFT_INDEX(k,n,plan) ((2*(plan)->N+2)*((plan)->N-n+1)+(plan)->N+k+1)
623 #define NFSFT_F_HAT_SIZE(N) ((2*N+2)*(2*N+2))
624 
625 /* fpt */
626 
627 /* name mangling macros */
628 #define FPT_MANGLE_DOUBLE(name) NFFT_CONCAT(fpt_, name)
629 #define FPT_MANGLE_FLOAT(name) NFFT_CONCAT(fptf_, name)
630 #define FPT_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(fptl_, name)
631 
632 /* huge second-order macro that defines prototypes for all fpt API functions.
633  * We expand this macro for each supported precision.
634  * X: fpt name-mangling macro
635  * R: real data type
636  * C: complex data type
637  */
638 #define FPT_DEFINE_API(X,Y,R,C) \
639 typedef struct X(set_s_) *X(set); \
641 \
642 NFFT_EXTERN X(set) X(init)(const int M, const int t, const unsigned int flags); \
643 NFFT_EXTERN void X(precompute)(X(set) set, const int m, R *alpha, R *beta, \
644  R *gam, int k_start, const R threshold); \
645 NFFT_EXTERN void X(trafo_direct)(X(set) set, const int m, const C *x, C *y, \
646  const int k_end, const unsigned int flags); \
647 NFFT_EXTERN void X(trafo)(X(set) set, const int m, const C *x, C *y, \
648  const int k_end, const unsigned int flags); \
649 NFFT_EXTERN void X(transposed_direct)(X(set) set, const int m, C *x, \
650  C *y, const int k_end, const unsigned int flags); \
651 NFFT_EXTERN void X(transposed)(X(set) set, const int m, C *x, \
652  C *y, const int k_end, const unsigned int flags); \
653 NFFT_EXTERN void X(finalize)(X(set) set);
654 
655 /* fpt api */
656 FPT_DEFINE_API(FPT_MANGLE_FLOAT,FFTW_MANGLE_FLOAT,float,fftwf_complex)
657 FPT_DEFINE_API(FPT_MANGLE_DOUBLE,FFTW_MANGLE_DOUBLE,double,fftw_complex)
658 FPT_DEFINE_API(FPT_MANGLE_LONG_DOUBLE,FFTW_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
659 
660 /* init flags */
661 #define FPT_NO_STABILIZATION (1U << 0)
662 #define FPT_NO_FAST_ALGORITHM (1U << 2)
663 #define FPT_NO_DIRECT_ALGORITHM (1U << 3)
664 #define FPT_PERSISTENT_DATA (1U << 4)
665 
666 /* transform flags */
667 #define FPT_FUNCTION_VALUES (1U << 5)
668 #define FPT_AL_SYMMETRY (1U << 6)
669 
670 /* nfsoft*/
671 
672 /* name mangling macros */
673 #define NFSOFT_MANGLE_DOUBLE(name) NFFT_CONCAT(nfsoft_, name)
674 #define NFSOFT_MANGLE_FLOAT(name) NFFT_CONCAT(nfsoftf_, name)
675 #define NFSOFT_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(nfsoftl_, name)
676 
677 /* huge second-order macro that defines prototypes for all nfsoft API functions.
678  * We expand this macro for each supported precision.
679  * X: nfsoft name-mangling macro
680  * Y: nfft name-mangling macro
681  * Z: fpt name-mangling macro
682  * R: real data type
683  * C: complex data type
684  */
685 #define NFSOFT_DEFINE_API(X,Y,Z,R,C) \
686 typedef struct X(plan_)\
687 {\
688  MACRO_MV_PLAN(C) \
689  R *x; \
690  C *wig_coeffs; \
692  C *cheby; \
694  C *aux; \
695  /* internal use only */\
696  int t; \
697  unsigned int flags; \
698  Y(plan) p_nfft; \
699  Z(set) internal_fpt_set; \
700  int fpt_kappa; \
701 } X(plan);\
702 \
703 NFFT_EXTERN void X(precompute)(X(plan) *plan); \
704 NFFT_EXTERN Z(set) X(SO3_single_fpt_init)(int l, int k, int m, unsigned int flags, int kappa); \
705 NFFT_EXTERN void X(SO3_fpt)(C *coeffs, Z(set) set, int l, int k, int m, unsigned int nfsoft_flags); \
706 NFFT_EXTERN void X(SO3_fpt_transposed)(C *coeffs, Z(set) set,int l, int k, int m,unsigned int nfsoft_flags); \
707 NFFT_EXTERN void X(init)(X(plan) *plan, int N, int M); \
708 NFFT_EXTERN void X(init_advanced)(X(plan) *plan, int N, int M,unsigned int nfsoft_flags); \
709 NFFT_EXTERN void X(init_guru)(X(plan) *plan, int N, int M,unsigned int nfsoft_flags,unsigned int nfft_flags,int nfft_cutoff,int fpt_kappa); \
710 NFFT_EXTERN void X(trafo)(X(plan) *plan_nfsoft); \
711 NFFT_EXTERN void X(adjoint)(X(plan) *plan_nfsoft); \
712 NFFT_EXTERN void X(finalize)(X(plan) *plan); \
713 NFFT_EXTERN int X(posN)(int n,int m, int B);
714 
715 /* nfsoft api */
716 NFSOFT_DEFINE_API(NFSOFT_MANGLE_FLOAT,NFFT_MANGLE_FLOAT,FPT_MANGLE_FLOAT,float,fftwf_complex)
717 NFSOFT_DEFINE_API(NFSOFT_MANGLE_DOUBLE,NFFT_MANGLE_DOUBLE,FPT_MANGLE_DOUBLE,double,fftw_complex)
718 NFSOFT_DEFINE_API(NFSOFT_MANGLE_LONG_DOUBLE,NFFT_MANGLE_LONG_DOUBLE,FPT_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
719 
720 /* init flags */
721 #define NFSOFT_NORMALIZED (1U << 0)
722 #define NFSOFT_USE_NDFT (1U << 1)
723 #define NFSOFT_USE_DPT (1U << 2)
724 #define NFSOFT_MALLOC_X (1U << 3)
725 #define NFSOFT_REPRESENT (1U << 4)
726 #define NFSOFT_MALLOC_F_HAT (1U << 5)
727 #define NFSOFT_MALLOC_F (1U << 6)
728 #define NFSOFT_PRESERVE_F_HAT (1U << 7)
729 #define NFSOFT_PRESERVE_X (1U << 8)
730 #define NFSOFT_PRESERVE_F (1U << 9)
731 #define NFSOFT_DESTROY_F_HAT (1U << 10)
732 #define NFSOFT_DESTROY_X (1U << 11)
733 #define NFSOFT_DESTROY_F (1U << 12)
734 
735 /* precompute flags */
736 #define NFSOFT_NO_STABILIZATION (1U << 13)
737 #define NFSOFT_CHOOSE_DPT (1U << 14)
738 #define NFSOFT_SOFT (1U << 15)
739 #define NFSOFT_ZERO_F_HAT (1U << 16)
740 
741 /* helper macros */
742 #define NFSOFT_INDEX(m,n,l,B) (((l)+((B)+1))+(2*(B)+2)*(((n)+((B)+1))+(2*(B)+2)*((m)+((B)+1))))
743 #define NFSOFT_INDEX_TWO(m,n,l,B) ((B+1)*(B+1)+(B+1)*(B+1)*(m+B)-((m-1)*m*(2*m-1)+(B+1)*(B+2)*(2*B+3))/6)+(posN(n,m,B))+(l-MAX(ABS(m),ABS(n)))
744 #define NFSOFT_F_HAT_SIZE(B) (((B)+1)*(4*((B)+1)*((B)+1)-1)/3)
745 
746 /* solver */
747 
748 /* name mangling macros */
749 #define SOLVER_MANGLE_DOUBLE(name) NFFT_CONCAT(solver_, name)
750 #define SOLVER_MANGLE_FLOAT(name) NFFT_CONCAT(solverf_, name)
751 #define SOLVER_MANGLE_LONG_DOUBLE(name) NFFT_CONCAT(solverl_, name)
752 
753 /* huge second-order macro that defines prototypes for all nfsoft API functions.
754  * We expand this macro for each supported precision.
755  * X: nfsoft name-mangling macro
756  * Y: nfft name-mangling macro
757  * R: real data type
758  * C: complex data type
759  */
760 #define SOLVER_DEFINE_API(X,Y,R,C)\
761  \
762 typedef struct\
763 {\
764  Y(mv_plan_complex) *mv; \
765  unsigned flags; \
766  R *w; \
767  R *w_hat; \
768  C *y; \
769  C *f_hat_iter; \
770  C *r_iter; \
771  C *z_hat_iter; \
772  C *p_hat_iter; \
773  C *v_iter; \
774  R alpha_iter; \
775  R beta_iter; \
776  R dot_r_iter; \
777  R dot_r_iter_old; \
778  R dot_z_hat_iter; \
779  R dot_z_hat_iter_old; \
780  R dot_p_hat_iter; \
781  R dot_v_iter; \
782 } X(plan_complex);\
783 \
784 NFFT_EXTERN void X(init_advanced_complex)(X(plan_complex)* ths, Y(mv_plan_complex) *mv, unsigned flags);\
785 NFFT_EXTERN void X(init_complex)(X(plan_complex)* ths, Y(mv_plan_complex) *mv);\
786 NFFT_EXTERN void X(before_loop_complex)(X(plan_complex)* ths);\
787 NFFT_EXTERN void X(loop_one_step_complex)(X(plan_complex) *ths);\
788 NFFT_EXTERN void X(finalize_complex)(X(plan_complex) *ths);\
789 \
790  \
791 typedef struct\
792 {\
793  Y(mv_plan_double) *mv; \
794  unsigned flags; \
795  R *w; \
796  R *w_hat; \
797  R *y; \
798  R *f_hat_iter; \
799  R *r_iter; \
800  R *z_hat_iter; \
801  R *p_hat_iter; \
802  R *v_iter; \
803  R alpha_iter; \
804  R beta_iter; \
805  R dot_r_iter; \
806  R dot_r_iter_old; \
807  R dot_z_hat_iter; \
808  R dot_z_hat_iter_old; \
809  R dot_p_hat_iter; \
810  R dot_v_iter; \
811 } X(plan_double);\
812 \
813 NFFT_EXTERN void X(init_advanced_double)(X(plan_double)* ths, Y(mv_plan_double) *mv, unsigned flags);\
814 NFFT_EXTERN void X(init_double)(X(plan_double)* ths, Y(mv_plan_double) *mv);\
815 NFFT_EXTERN void X(before_loop_double)(X(plan_double)* ths);\
816 NFFT_EXTERN void X(loop_one_step_double)(X(plan_double) *ths);\
817 NFFT_EXTERN void X(finalize_double)(X(plan_double) *ths);
818 
819 /* solver api */
820 SOLVER_DEFINE_API(SOLVER_MANGLE_FLOAT,NFFT_MANGLE_FLOAT,float,fftwf_complex)
821 SOLVER_DEFINE_API(SOLVER_MANGLE_DOUBLE,NFFT_MANGLE_DOUBLE,double,fftw_complex)
822 SOLVER_DEFINE_API(SOLVER_MANGLE_LONG_DOUBLE,NFFT_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
823 
824 /* init flags */
825 #define LANDWEBER (1U<< 0)
826 #define STEEPEST_DESCENT (1U<< 1)
827 #define CGNR (1U<< 2)
828 #define CGNE (1U<< 3)
829 #define NORMS_FOR_LANDWEBER (1U<< 4)
830 #define PRECOMPUTE_WEIGHT (1U<< 5)
831 #define PRECOMPUTE_DAMP (1U<< 6)
832 
833 /* util */
834 
835 /* huge second-order macro that defines prototypes for all utility API functions.
836  * We expand this macro for each supported precision.
837  * Y: nfft name-mangling macro
838  * R: real data type
839  * C: complex data type
840  */
841 #define NFFT_DEFINE_UTIL_API(Y,R,C) \
842 /* rand.c */ \
843 R Y(drand48)(void); \
844 void Y(srand48)(long int seed); \
845 \
846  \
848 void Y(vrand_unit_complex)(C *x, const NFFT_INT n); \
849 \
850  \
852 void Y(vrand_shifted_unit_double)(R *x, const NFFT_INT n); \
853 \
854 void Y(vrand_real)(R *x, const NFFT_INT n, const R a, const R b); \
855 \
856 /* print.c */ \
857  \
858 void Y(vpr_double)(R *x, const NFFT_INT n, const char *text); \
859 \
860  \
861 void Y(vpr_complex)(C *x, const NFFT_INT n, const char *text); \
862 /* thread.c */ \
863 NFFT_INT Y(get_num_threads)(void); \
864 /* time.c */ \
865 R Y(clock_gettime_seconds)(void); \
866 /* error.c: */ \
867 R Y(error_l_infty_complex)(const C *x, const C *y, const NFFT_INT n); \
868 R Y(error_l_infty_1_complex)(const C *x, const C *y, const NFFT_INT n, \
869  const C *z, const NFFT_INT m); \
870 /* int.c: */ \
871 NFFT_INT Y(exp2i)(const NFFT_INT a); \
872 NFFT_INT Y(next_power_of_2)(const NFFT_INT N); \
873 /* vector1.c */ \
874  \
875 R Y(dot_complex)(C *x, NFFT_INT n); \
876 /* vector3.c */ \
877  \
878 void Y(upd_axpy_complex)(C *x, R a, C *y, NFFT_INT n); \
879  \
880 void Y(fftshift_complex)(C *x, NFFT_INT d, NFFT_INT* N); \
881 void Y(fftshift_complex_int)(C *x, int d, int* N);
882 
883 
884 NFFT_DEFINE_UTIL_API(NFFT_MANGLE_FLOAT,float,fftwf_complex)
885 NFFT_DEFINE_UTIL_API(NFFT_MANGLE_DOUBLE,double,fftw_complex)
886 NFFT_DEFINE_UTIL_API(NFFT_MANGLE_LONG_DOUBLE,long double,fftwl_complex)
887 
888 #ifdef __cplusplus
889 } /* extern "C" */
890 #endif /* __cplusplus */
891 
892 #endif /* defined(__NFFT3_H__) */