NFFT 3.5.3alpha
nfsoft.c
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#include "config.h"
20
21#include <stdio.h>
22#include <math.h>
23#include <string.h>
24#include <stdlib.h>
25#ifdef HAVE_COMPLEX_H
26#include <complex.h>
27#endif
28#include "nfft3.h"
29#include "infft.h"
30#include "wigner.h"
31#include "../fpt/fpt.h"
32
33#ifdef _OPENMP
34#include <omp.h>
35#endif
36
37#define DEFAULT_NFFT_CUTOFF 6
38#define FPT_THRESHOLD 1000
39
40#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)))
41
42static fpt_set* SO3_fpt_init(int l, unsigned int flags, int kappa, int nthreads);
43static int posN(int n, int m, int B);
44
45void nfsoft_init(nfsoft_plan *plan, int N, int M)
46{
47 nfsoft_init_advanced(plan, N, M, NFSOFT_MALLOC_X | NFSOFT_MALLOC_F
49}
50
51void nfsoft_init_advanced(nfsoft_plan *plan, int N, int M,
52 unsigned int nfsoft_flags)
53{
54 nfsoft_init_guru(plan, N, M, nfsoft_flags, PRE_PHI_HUT | PRE_PSI | MALLOC_X | NFFT_OMP_BLOCKWISE_ADJOINT
56 DEFAULT_NFFT_CUTOFF, FPT_THRESHOLD);
57}
58
59void nfsoft_init_guru(nfsoft_plan *plan, int B, int M,
60 unsigned int nfsoft_flags, unsigned int nfft_flags, int nfft_cutoff,
61 int fpt_kappa)
62{
63 nfsoft_init_guru_advanced(plan, B, M, nfsoft_flags, nfft_flags, nfft_cutoff, fpt_kappa, 8* B);
64}
65
66void nfsoft_init_guru_advanced(nfsoft_plan *plan, int B, int M,
67 unsigned int nfsoft_flags, unsigned int nfft_flags, int nfft_cutoff,
68 int fpt_kappa, int nn_oversampled)
69{
70 int N[3];
71 int n[3];
72
73 N[0] = 2* B + 2;
74 N[1] = 2* B + 2;
75 N[2] = 2* B + 2;
76
77 n[0] = nn_oversampled ;
78 n[1] = nn_oversampled ;
79 n[2] = nn_oversampled ;
80
81 nfft_init_guru(&plan->p_nfft, 3, N, M, n, nfft_cutoff, nfft_flags,
82 FFTW_ESTIMATE | FFTW_DESTROY_INPUT);
83
84 if ((plan->p_nfft).flags & PRE_LIN_PSI)
85 {
86 nfft_precompute_lin_psi(&(plan->p_nfft));
87 }
88
89 plan->N_total = B;
90 plan->M_total = M;
91 plan->flags = nfsoft_flags;
92
93 if (plan->flags & NFSOFT_MALLOC_F_HAT)
94 {
95 plan->f_hat = (C*) nfft_malloc((B + 1) * (4* (B +1)*(B+1)-1)/3*sizeof(C));
96 if (plan->f_hat == NULL ) printf("Allocation failed!\n");
97 }
98
99 if (plan->flags & NFSOFT_MALLOC_X)
100 {
101 plan->x = (R*) nfft_malloc(plan->M_total*3*sizeof(R));
102 if (plan->x == NULL ) printf("Allocation failed!\n");
103 }
104 if (plan->flags & NFSOFT_MALLOC_F)
105 {
106 plan->f = (C*) nfft_malloc(plan->M_total*sizeof(C));
107 if (plan->f == NULL ) printf("Allocation failed!\n");
108 }
109
110 plan->wig_coeffs = NULL;
111 plan->cheby = NULL;
112 plan->aux = NULL;
113
114 plan->mv_trafo = (void (*) (void* ))nfsoft_trafo;
115 plan->mv_adjoint = (void (*) (void* ))nfsoft_adjoint;
116
117 plan->nthreads = Y(get_num_threads)();
118
119 plan->internal_fpt_set = SO3_fpt_init(plan->N_total, plan->flags, fpt_kappa, plan->nthreads);
120
121}
122
123static void c2e(nfsoft_plan *my_plan, int even, C* wig_coeffs, int k, int m)
124{
125 int j, N;
126
128 N = 2* (my_plan ->N_total+1);
129
131 C cheby[2*my_plan->N_total + 2];
132 cheby[my_plan->N_total+1] = wig_coeffs[0];
133 cheby[0]=0.0;
134
135 for (j=1;j<my_plan->N_total+1;j++)
136 {
137 cheby[my_plan->N_total+1+j]=0.5* wig_coeffs[j];
138 cheby[my_plan->N_total+1-j]=0.5* wig_coeffs[j];
139 }
140
141 C aux[N+2];
142
143 for(j=1;j<N;j++)
144 aux[j]=cheby[j];
145
146 aux[0]=0.;
147 aux[N]=0.;
148
149 if (even>0)
150 {
151 cheby[0]=(C) (-1.)/(2.*_Complex_I) * aux[1];
152 for (j=1;j<N;j++)
153 {
154 cheby[j]=(1./(2.*_Complex_I)*(aux[j+1]-aux[j-1]));
155 }
156
157 }
158
159 for (int i = 1; i <= 2* my_plan ->N_total + 2; i++)
160 {
161 my_plan->p_nfft.f_hat[NFSOFT_INDEX(k, m, i - my_plan->N_total - 1, my_plan->N_total) - 1]
162 = cheby[i - 1];
163 }
164
165}
166
167
168static fpt_set* SO3_fpt_init(int l, unsigned int flags, int kappa, int nthreads)
169{
170 fpt_set *set = (fpt_set*)nfft_malloc(nthreads * sizeof(fpt_set));
171 int N, t, k_start, k, m;
172
174 if (flags & NFSOFT_USE_DPT)
175 {
176 if (l < 2)
177 N = 2;
178 else
179 N = l;
180
181 t = (int) log2(X(next_power_of_2)(N));
182
183 }
184 else
185 {
187 if (l < 2)
188 N = 2;
189 else
190 N = X(next_power_of_2)(l);
191
192 t = (int) log2(N);
193 }
194
196 unsigned int fptflags = 0U
199/*#ifdef _OPENMP
200 #pragma omp parallel default(shared) num_threads(nthreads)
201 {
202 int threadid = omp_get_thread_num();
203
204 if (threadid == 0)
205 set[threadid] = fpt_init((2* N + 1) * (2* N + 1), t, fptflags);
206 else
207 set[threadid] = fpt_init((2* N + 1) * (2* N + 1), t, fptflags | FPT_NO_INIT_FPT_DATA);
208
209 #pragma omp barrier
210
211 if (threadid != 0)
212 set[threadid]->dpt = set[0]->dpt;
213 }
214
215#else*/
216 set[0] = fpt_init((2* N + 1) * (2* N + 1), t, fptflags);
217 for (int i=1; i<nthreads; i++)
218 {
219 set[i] = fpt_init((2* N + 1) * (2* N + 1), t, fptflags | FPT_NO_INIT_FPT_DATA);
220 set[i]->dpt = set[0]->dpt;
221 }
222//#endif
223
224#ifdef _OPENMP
225 for (k = -N; k <= N; k++)
226 for (m = -N; m <= N; m++)
227 {
229 k_start = (ABS(k) >= ABS(m)) ? ABS(k) : ABS(m);
230
231 fpt_precompute_1(set[0], (k+N)*(2*N+1) + m+N,k_start);
232 }
233 #pragma omp parallel for default(shared) private(k,m,k_start) schedule(dynamic) num_threads(nthreads)
234#endif
235 for (k = -N; k <= N; k++)
236 for (m = -N; m <= N; m++)
237 {
239 k_start = (ABS(k) >= ABS(m)) ? ABS(k) : ABS(m);
240 // k_end = N;
241
242 R alpha[N+2], beta[N+2], gamma[N+2];
243 SO3_alpha_row(alpha, N, k, m);
244 SO3_beta_row(beta, N, k, m);
245 SO3_gamma_row(gamma, N, k, m);
246
247#ifdef _OPENMP
248 fpt_precompute_2(set[omp_get_thread_num()], (k+N)*(2*N+1) + m+N, alpha, beta, gamma, k_start, kappa);
249#else
250 fpt_precompute(set[0], (k+N)*(2*N+1) + m+N, alpha, beta, gamma, k_start, kappa);
251#endif
252 }
253
254 return set;
255}
256
257static void SO3_fpt(C *coeffs, fpt_set set, int l, int k, int m, unsigned int flags)
258{
259 int N;
260 int trafo_nr;
261 int k_start, k_end, j;
262 int function_values = 0;
263
265 if (flags & NFSOFT_USE_DPT)
266 {
267 N = l;
268 if (l < 2)
269 N = 2;
270 }
271 else
272 {
273 if (l < 2)
274 N = 2;
275 else
276 N = X(next_power_of_2)(l);
277 }
278
280 k_start = (ABS(k) >= ABS(m)) ? ABS(k) : ABS(m);
281 k_end = N;
282 trafo_nr = (N + k) * (2* N + 1) + (m + N);
283
285 C x[k_end + 1];
286
287 for (j = 0; j <= k_end; j++)
288 x[j] = K(0.0);
289
290
291 for (j = 0; j <= l - k_start; j++)
292 {
293 x[j + k_start] = coeffs[j];
294 }
295 for (j = l - k_start + 1; j <= k_end - k_start; j++)
296 {
297 x[j + k_start] = K(0.0);
298 }
299
301 C y[k_end + 1];
302
303 if (flags & NFSOFT_USE_DPT)
304 {
305 fpt_trafo_direct(set, trafo_nr, &x[k_start], y, k_end, 0U
306 | (function_values ? FPT_FUNCTION_VALUES : 0U));
307 }
308 else
309 {
310 fpt_trafo(set, trafo_nr, &x[k_start], y, k_end, 0U
311 | (function_values ? FPT_FUNCTION_VALUES : 0U));
312 }
313
315 for (j = 0; j <= l; j++)
316 {
317 coeffs[j] = y[j];
318 }
319
320}
321
322static void SO3_fpt_transposed(C *coeffs, fpt_set set, int l, int k, int m,
323 unsigned int flags)
324{
325 int N, k_start, k_end, j;
326 int trafo_nr;
327 int function_values = 0;
328
331 if (flags & NFSOFT_USE_DPT)
332 {
333 N = l;
334 if (l < 2)
335 N = 2;
336 }
337 else
338 {
339 if (l < 2)
340 N = 2;
341 else
342 N = X(next_power_of_2)(l);
343 }
344
346 k_start = (ABS(k) >= ABS(m)) ? ABS(k) : ABS(m);
347 k_end = N;
348 trafo_nr = (N + k) * (2* N + 1) + (m + N);
349
351 C y[k_end + 1];
353 C x[k_end + 1];
354
355 for (j = 0; j <= l; j++)
356 {
357 y[j] = coeffs[j];
358 }
359 for (j = l + 1; j <= k_end; j++)
360 {
361 y[j] = K(0.0);
362 }
363
364 if (flags & NFSOFT_USE_DPT)
365 {
366 fpt_transposed_direct(set, trafo_nr, &x[k_start], y, k_end, 0U
367 | (function_values ? FPT_FUNCTION_VALUES : 0U));
368 }
369 else
370 {
371 fpt_transposed(set, trafo_nr, &x[k_start], y, k_end, 0U
372 | (function_values ? FPT_FUNCTION_VALUES : 0U));
373 }
374
375 for (j = 0; j <= l; j++)
376 {
377 coeffs[j] = x[j];
378 }
379
380}
381
382void nfsoft_precompute(nfsoft_plan *plan3D)
383{
384 int j;
385 int M = plan3D->M_total;
386
389 if (plan3D->x != plan3D->p_nfft.x)
390 {
391 for (j = 0; j < M; j++)
392 {
393 plan3D->p_nfft.x[3* j ] = plan3D->x[3* j + 2];
394 plan3D->p_nfft.x[3* j + 1] = plan3D->x[3* j ];
395 plan3D->p_nfft.x[3* j + 2] = plan3D->x[3* j + 1];
396 }
397
398 for (j = 0; j < 3* plan3D ->p_nfft.M_total; j++)
399 {
400 plan3D->p_nfft.x[j] = plan3D->p_nfft.x[j] * (1 / (2* KPI ));
401 }
402 }
403
404
405 if ((plan3D->p_nfft).flags & FG_PSI)
406 {
407 nfft_precompute_one_psi(&(plan3D->p_nfft));
408 }
409 if ((plan3D->p_nfft).flags & PRE_PSI)
410 {
411 nfft_precompute_one_psi(&(plan3D->p_nfft));
412 }
413
414}
415
416void nfsoft_trafo(nfsoft_plan *plan3D)
417{
418 // glo1 = 0;
419
420 int N = plan3D->N_total;
421 int M = plan3D->M_total;
422
424 if (N == 0)
425 {
426 for (int j = 0; j < M; j++)
427 plan3D->f[j] = plan3D->f_hat[0];
428 return;
429 }
430
431 for (int j = 0; j < plan3D->p_nfft.N_total; j++)
432 plan3D->p_nfft.f_hat[j] = 0.0;
433
434#ifdef _OPENMP
435 #pragma omp parallel for default(shared) num_threads(plan3D->nthreads)
436#endif
437 for (int k = -N; k <= N; k++)
438 {
439 C wig_coeffs[(X(next_power_of_2)(N)+1)];
440#ifdef _OPENMP
441 int threadid = omp_get_thread_num();
442#else
443 int threadid = 0;
444#endif
445
446 for (int m = -N; m <= N; m++)
447 {
448
449 int max = (ABS(m) > ABS(k) ? ABS(m) : ABS(k));
450
451 int glo0 = NFSOFT_INDEX_TWO(k,m,max,N);
452
453 for (int j = 0; j <= N - max; j++)
454 {
455 wig_coeffs[j] = plan3D->f_hat[glo0 + j];
456
457 if ((plan3D->flags & NFSOFT_NORMALIZED))
458 {
459 wig_coeffs[j] = wig_coeffs[j] * (1. / (2. * KPI))
460 * SQRT(0.5 * (2. * (max + j) + 1.));
461 }
462
463 if ((plan3D->flags & NFSOFT_REPRESENT))
464 {
465 if ((k < 0) && (k % 2))
466 {
467 wig_coeffs[j] = wig_coeffs[j] * (-1);
468 }
469 if ((m < 0) && (m % 2))
470 wig_coeffs[j] = wig_coeffs[j] * (-1);
471
472 if ((m + k) % 2)
473 wig_coeffs[j] = wig_coeffs[j] * (-1);
474
475 }
476
477 // glo1++;
478 }
479
480 for (int j = N - max + 1; j < X(next_power_of_2)(N) + 1; j++)
481 wig_coeffs[j] = 0.0;
482 //fprintf(stdout,"\n k= %d, m= %d \n",k,m);
483 SO3_fpt(wig_coeffs, plan3D->internal_fpt_set[threadid], N, k, m, plan3D->flags);
484
485 c2e(plan3D, ABS((k + m) % 2), wig_coeffs, k, m);
486 }
487
488 }
489
490 if (plan3D->flags & NFSOFT_USE_NDFT)
491 {
492 nfft_trafo_direct(&(plan3D->p_nfft));
493 }
494 else
495 {
496 nfft_trafo(&(plan3D->p_nfft));
497 }
498
499 if (plan3D->f != plan3D->p_nfft.f)
500 for (int j = 0; j < plan3D->M_total; j++)
501 plan3D->f[j] = plan3D->p_nfft.f[j];
502
503}
504
505static void e2c(nfsoft_plan *my_plan, int even, C* wig_coeffs, C* cheby)
506{
507 int N;
508 int j;
509
511 N = 2* (my_plan ->N_total+1);
512 //nfft_vpr_complex(my_plan->cheby,N+1,"chebychev");
513
514 C aux[N];
515
516 if (even>0)
517 {
518 //my_plan->aux[N-1]= -1/(2*I)* my_plan->cheby[N-2];
519 aux[0]= 1/(2*_Complex_I)*cheby[1];
520
521 for(j=1;j<N-1;j++)
522 {
523 aux[j]=1/(2*_Complex_I)*(cheby[j+1]-cheby[j-1]);
524 }
525 aux[N-1]=1/(2*_Complex_I)*(-cheby[j-1]);
526
527
528 for(j=0;j<N;j++)
529 {
530 cheby[j]= aux[j];
531 }
532 }
533
534 wig_coeffs[0]=cheby[my_plan->N_total+1];
535
536 for(j=1;j<=my_plan->N_total;j++)
537 {
538 wig_coeffs[j]=0.5*(cheby[my_plan->N_total+j+1]+cheby[my_plan->N_total+1-j]);
539 }
540
541//nfft_vpr_complex(my_plan->wig_coeffs,my_plan->N_total,"chebychev ");
542
543}
544
545void nfsoft_adjoint(nfsoft_plan *plan3D)
546{
547 //int glo1 = 0;
548
549 int N = plan3D->N_total;
550 int M = plan3D->M_total;
551
552 //nothing much to be done for polynomial degree 0
553 if (N == 0)
554 {
555 plan3D->f_hat[0]=0;
556 for (int j = 0; j < M; j++)
557 plan3D->f_hat[0] += plan3D->f[j];
558 return;
559 }
560
561 if (plan3D->p_nfft.f != plan3D->f)
562 for (int j = 0; j < M; j++)
563 {
564 plan3D->p_nfft.f[j] = plan3D->f[j];
565 }
566
567 if (plan3D->flags & NFSOFT_USE_NDFT)
568 {
569 nfft_adjoint_direct(&(plan3D->p_nfft));
570 }
571 else
572 {
573 nfft_adjoint(&(plan3D->p_nfft));
574 }
575
576 //nfft_vpr_complex(plan3D->nfft_plan.f_hat,plan3D->nfft_plan.N_total,"all results");
577
578#ifdef _OPENMP
579 #pragma omp parallel for default(shared) num_threads(plan3D->nthreads)
580#endif
581 for (int k = -N; k <= N; k++)
582 {
583#ifdef _OPENMP
584 int threadid = omp_get_thread_num();
585#else
586 int threadid = 0;
587#endif
588 for (int m = -N; m <= N; m++)
589 {
590 C wig_coeffs[(X(next_power_of_2)(N)+1)];
591 C cheby[2*plan3D->N_total + 2];
592
593 int max = (ABS(m) > ABS(k) ? ABS(m) : ABS(k));
594
595 for (int i = 1; i < 2* plan3D ->N_total + 3; i++)
596 {
597 cheby[i - 1] = plan3D->p_nfft.f_hat[NFSOFT_INDEX(k, m, i - N
598 - 1, N) - 1];
599 }
600
601 //fprintf(stdout,"k=%d,m=%d \n",k,m);
602 //nfft_vpr_complex(plan3D->cheby,2*plan3D->N_total+2,"euler");
603
604 e2c(plan3D, ABS((k + m) % 2), wig_coeffs, cheby);
605
606 //nfft_vpr_complex(plan3D->wig_coeffs,plan3D->N_total+1,"chebys");
607 SO3_fpt_transposed(wig_coeffs, plan3D->internal_fpt_set[threadid], N, k, m,
608 plan3D->flags);
609 //nfft_vpr_complex(plan3D->wig_coeffs,plan3D->N_total+1,"wigners");
610 // SO3_fpt_transposed(plan3D->wig_coeffs,N,k,m,plan3D->flags,plan3D->fpt_kappa);
611
612 int glo0 = NFSOFT_INDEX_TWO(k,m,0,N);
613
614 for (int j = max; j <= N; j++)
615 {
616 if ((plan3D->flags & NFSOFT_REPRESENT))
617 {
618 if ((k < 0) && (k % 2))
619 {
620 wig_coeffs[j] = -wig_coeffs[j];
621 }
622 if ((m < 0) && (m % 2))
623 wig_coeffs[j] = -wig_coeffs[j];
624
625 if ((m + k) % 2)
626 wig_coeffs[j] = wig_coeffs[j] * (-1);
627
628 }
629
630 plan3D->f_hat[glo0+j] = wig_coeffs[j];
631
632 if ((plan3D->flags & NFSOFT_NORMALIZED))
633 {
634 plan3D->f_hat[glo0+j] = plan3D->f_hat[glo0+j] * (1 / (2. * KPI)) * SQRT(
635 0.5 * (2. * (j) + 1.));
636 }
637
638 //glo1++;
639 }
640
641 }
642 }
643}
644
645void nfsoft_finalize(nfsoft_plan *plan)
646{
647 /* Finalise the nfft plan. */
648 nfft_finalize(&plan->p_nfft);
649
650 for (int i=0; i<plan->nthreads; i++)
651 fpt_finalize(plan->internal_fpt_set[i]);
653 plan->internal_fpt_set = NULL;
654
655 if (plan->flags & NFSOFT_MALLOC_F_HAT)
656 {
657 //fprintf(stderr,"deallocating f_hat\n");
658 nfft_free(plan->f_hat);
659 }
660
661 /* De-allocate memory for samples, if necessary. */
662 if (plan->flags & NFSOFT_MALLOC_F)
663 {
664 //fprintf(stderr,"deallocating f\n");
665 nfft_free(plan->f);
666 }
667
668 /* De-allocate memory for nodes, if necessary. */
669 if (plan->flags & NFSOFT_MALLOC_X)
670 {
671 //fprintf(stderr,"deallocating x\n");
672 nfft_free(plan->x);
673 }
674}
675
676static int posN(int n, int m, int B)
677{
678 int pos;
679
680 if (n > -B)
681 pos = posN(n - 1, m, B) + B + 1 - MAX(ABS(m), ABS(n - 1));
682 else
683 pos = 0;
684 //(n > -B? pos=posN(n-1,m,B)+B+1-MAX(ABS(m),ABS(n-1)): pos= 0)
685 return pos;
686}
687
#define FPT_NO_FAST_ALGORITHM
If set, TODO complete comment.
Definition nfft3.h:644
#define FPT_NO_STABILIZATION
If set, no stabilization will be used.
Definition nfft3.h:643
#define FPT_FUNCTION_VALUES
If set, the output are function values at Chebyshev nodes rather than Chebyshev coefficients.
Definition nfft3.h:650
#define FPT_NO_DIRECT_ALGORITHM
If set, TODO complete comment.
Definition nfft3.h:645
#define FG_PSI
Definition nfft3.h:188
#define MALLOC_F_HAT
Definition nfft3.h:194
#define MALLOC_X
Definition nfft3.h:193
#define PRE_PSI
Definition nfft3.h:191
#define MALLOC_F
Definition nfft3.h:195
#define PRE_LIN_PSI
Definition nfft3.h:189
#define FFTW_INIT
Definition nfft3.h:197
#define PRE_PHI_HUT
Definition nfft3.h:187
#define NFSOFT_USE_NDFT
Definition nfft3.h:704
#define NFSOFT_REPRESENT
Definition nfft3.h:707
#define NFSOFT_USE_DPT
Definition nfft3.h:705
#define NFSOFT_INDEX(m, n, l, B)
Definition nfft3.h:724
#define NFSOFT_MALLOC_F_HAT
Definition nfft3.h:708
#define NFSOFT_NORMALIZED
Definition nfft3.h:703
#define NFSOFT_MALLOC_X
Definition nfft3.h:706
#define NFSOFT_MALLOC_F
Definition nfft3.h:709
#define NFSOFT_NO_STABILIZATION
Definition nfft3.h:718
Internal header file for auxiliary definitions and functions.
Header file for the nfft3 library.
void * nfft_malloc(size_t n)
void nfft_free(void *p)
Holds data for a set of cascade summations.
Definition fpt.h:66
fpt_data * dpt
The DPT transform data
Definition fpt.h:72
nfft_plan p_nfft
the internal NFFT plan
Definition nfft3.h:699
NFFT_INT N_total
Total number of Fourier coefficients.
Definition nfft3.h:699
fftw_complex * f
Samples.
Definition nfft3.h:699
void(* mv_trafo)(void *)
Transform.
Definition nfft3.h:699
int nthreads
the number of threads
Definition nfft3.h:699
fftw_complex * cheby
deprecated variable
Definition nfft3.h:699
fpt_set * internal_fpt_set
the internal FPT plan
Definition nfft3.h:699
void(* mv_adjoint)(void *)
Adjoint transform.
Definition nfft3.h:699
fftw_complex * f_hat
Fourier coefficients.
Definition nfft3.h:699
unsigned int flags
the planner flags
Definition nfft3.h:699
NFFT_INT M_total
Total number of samples.
Definition nfft3.h:699
fftw_complex * aux
deprecated variable
Definition nfft3.h:699
double * x
input nodes
Definition nfft3.h:699
fftw_complex * wig_coeffs
deprecated variable
Definition nfft3.h:699
Header file for functions related to Wigner-d/D functions.