NFFT  3.5.0
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 
42 static fpt_set* SO3_fpt_init(int l, unsigned int flags, int kappa, int nthreads);
43 static int posN(int n, int m, int B);
44 
45 void nfsoft_init(nfsoft_plan *plan, int N, int M)
46 {
49 }
50 
51 void 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 
59 void 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 
66 void 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  {
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 
123 static 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 
168 static 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
197  | IF(flags & NFSOFT_USE_DPT,FPT_NO_FAST_ALGORITHM,IF(t > 1,FPT_NO_DIRECT_ALGORITHM,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 
257 static 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 
322 static 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 
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 
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 
505 static 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 
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 
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 
676 static 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 
static void c2e(nfsft_plan *plan)
Converts coefficients with , from a linear combination of Chebyshev polynomials to coefficients m...
Definition: nfsft.c:115
void nfsoft_init_advanced(nfsoft_plan *plan, int N, int M, unsigned int nfsoft_flags)
Definition: nfsoft.c:51
double * gamma
Precomputed recursion coefficients /f$^n/f$ for /f$k = 0,/ldots, N_{{max}}; n=-k,/ldots,k/f$ of associated Legendre-functions /f$P_k^n/f$.
fftw_complex * f_hat
Fourier coefficients.
Definition: nfft3.h:684
void nfsoft_init_guru_advanced(nfsoft_plan *plan, int B, int M, unsigned int nfsoft_flags, unsigned int nfft_flags, int nfft_cutoff, int fpt_kappa, int nn_oversampled)
Definition: nfsoft.c:66
#define NFSOFT_NO_STABILIZATION
Definition: nfft3.h:700
fftw_complex * aux
deprecated variable
Definition: nfft3.h:684
fftw_complex * f
Samples.
Definition: nfft3.h:684
fftw_complex * f_hat
Fourier coefficients.
Definition: nfft3.h:192
void nfsoft_init(nfsoft_plan *plan, int N, int M)
Definition: nfsoft.c:45
#define MALLOC_X
Definition: nfft3.h:199
#define MALLOC_F_HAT
Definition: nfft3.h:200
#define NFSOFT_NORMALIZED
Definition: nfft3.h:685
void SO3_gamma_row(double *gamma, int N, int m, int n)
Compute three-term-recurrence coefficients of Wigner-d functions for all degrees ...
Definition: wigner.c:104
int nthreads
the number of threads
Definition: nfft3.h:684
void fpt_transposed(fpt_set set, const int m, double _Complex *x, double _Complex *y, const int k_end, const unsigned int flags)
Definition: fpt.c:1740
void nfft_precompute_lin_psi(nfft_plan *ths)
#define NFSOFT_INDEX(m, n, l, B)
Definition: nfft3.h:706
fftw_complex * wig_coeffs
deprecated variable
Definition: nfft3.h:684
#define FG_PSI
Definition: nfft3.h:194
void SO3_beta_row(double *beta, int N, int m, int n)
Compute three-term-recurrence coefficients of Wigner-d functions for all degrees ...
Definition: wigner.c:96
#define NFSOFT_MALLOC_F_HAT
Definition: nfft3.h:690
NFFT_INT M_total
Total number of samples.
Definition: nfft3.h:684
double * x
input nodes
Definition: nfft3.h:684
#define FPT_NO_STABILIZATION
If set, no stabilization will be used.
Definition: nfft3.h:629
#define NFSOFT_USE_NDFT
Definition: nfft3.h:686
void nfft_adjoint(nfft_plan *ths)
void fpt_precompute(fpt_set set, const int m, double *alpha, double *beta, double *gam, int k_start, const double threshold)
Definition: fpt.c:1307
#define NFSOFT_USE_DPT
Definition: nfft3.h:687
#define FPT_FUNCTION_VALUES
If set, the output are function values at Chebyshev nodes rather than Chebyshev coefficients.
Definition: nfft3.h:636
Holds data for a set of cascade summations.
Definition: fpt.h:65
fftw_complex * f
Samples.
Definition: nfft3.h:192
void nfsoft_precompute(nfsoft_plan *plan3D)
Definition: nfsoft.c:382
void(* mv_adjoint)(void *)
Adjoint transform.
Definition: nfft3.h:684
void SO3_alpha_row(double *alpha, int N, int m, int n)
Compute three-term-recurrence coefficients of Wigner-d functions for all degrees ...
Definition: wigner.c:88
void nfft_free(void *p)
NFFT_INT N_total
Total number of Fourier coefficients.
Definition: nfft3.h:684
#define NFSOFT_MALLOC_X
Definition: nfft3.h:688
fftw_complex * cheby
deprecated variable
Definition: nfft3.h:684
#define FFTW_INIT
Definition: nfft3.h:203
NFFT_INT N_total
Total number of Fourier coefficients.
Definition: nfft3.h:192
#define MALLOC_F
Definition: nfft3.h:201
#define FPT_NO_FAST_ALGORITHM
If set, TODO complete comment.
Definition: nfft3.h:630
NFFT_INT M_total
Total number of samples.
Definition: nfft3.h:192
#define X(name)
Include header for C99 complex datatype.
Definition: fastsum.h:57
#define NFSOFT_MALLOC_F
Definition: nfft3.h:691
#define PRE_LIN_PSI
Definition: nfft3.h:195
#define PRE_PSI
Definition: nfft3.h:197
void nfft_trafo(nfft_plan *ths)
void nfsoft_finalize(nfsoft_plan *plan)
Definition: nfsoft.c:645
void * nfft_malloc(size_t n)
double * alpha
Precomputed recursion coefficients /f$^n/f$ for /f$k = 0,/ldots, N_{{max}}; n=-k,/ldots,k/f$ of associated Legendre-functions /f$P_k^n/f$.
void nfft_finalize(nfft_plan *ths)
void nfsoft_trafo(nfsoft_plan *plan3D)
Definition: nfsoft.c:416
void nfft_precompute_one_psi(nfft_plan *ths)
void nfsoft_init_guru(nfsoft_plan *plan, int B, int M, unsigned int nfsoft_flags, unsigned int nfft_flags, int nfft_cutoff, int fpt_kappa)
Definition: nfsoft.c:59
fpt_set fpt_init(const int M, const int t, const unsigned int flags)
Definition: fpt.c:795
void nfsoft_adjoint(nfsoft_plan *plan3D)
Definition: nfsoft.c:545
double * beta
Precomputed recursion coefficients /f$^n/f$ for /f$k = 0,/ldots, N_{{max}}; n=-k,/ldots,k/f$ of associated Legendre-functions /f$P_k^n/f$.
Header file for functions related to Wigner-d/D functions.
void(* mv_trafo)(void *)
Transform.
Definition: nfft3.h:684
Header file for the nfft3 library.
fpt_set * internal_fpt_set
the internal FPT plan
Definition: nfft3.h:684
double * x
Nodes in time/spatial domain, size is doubles.
Definition: nfft3.h:192
#define PRE_PHI_HUT
Definition: nfft3.h:193
#define FPT_NO_DIRECT_ALGORITHM
If set, TODO complete comment.
Definition: nfft3.h:631
#define NFSOFT_REPRESENT
Definition: nfft3.h:689
nfft_plan p_nfft
the internal NFFT plan
Definition: nfft3.h:684
unsigned int flags
the planner flags
Definition: nfft3.h:684