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