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