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