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