62 #define NFSFT_DEFAULT_NFFT_CUTOFF 6
69 #define NFSFT_DEFAULT_THRESHOLD 1000
76 #define NFSFT_BREAK_EVEN 5
112 double _Complex last;
122 memset(plan->
f_hat_intern,0U,(2*plan->
N+2)*
sizeof(
double _Complex));
125 lowe = -plan->
N + (plan->
N%2);
129 for (n = lowe; n <= upe; n += 2)
135 for(k = 1; k <= plan->
N; k++)
146 low = -plan->
N + (1-plan->
N%2);
151 for (n = low; n <= up; n += 2)
163 *xm = 0.5 * _Complex_I * (0.5*xm[-1]);
165 for (k = plan->
N-1; k > 0; k--)
168 *xm = 0.5 * _Complex_I * (0.5*(xm[-1] - last));
190 double _Complex last;
200 lowe = -plan->
N + (plan->
N%2);
204 for (n = lowe; n <= upe; n += 2)
210 for(k = 1; k <= plan->
N; k++)
218 low = -plan->
N + (1-plan->
N%2);
222 for (n = low; n <= up; n += 2)
228 for(k = 1; k <= plan->
N; k++)
240 for (k = 2; k < plan->
N; k++)
243 *xp = -0.25 * _Complex_I * (xp[1] - last);
247 *xp = 0.25 * _Complex_I * last;
268 void nfsft_init_guru(
nfsft_plan *plan,
int N,
int M,
unsigned int flags,
269 unsigned int nfft_flags,
int nfft_cutoff)
287 plan->
N_total = (2*plan->
N+2)*(2*plan->
N+2);
294 sizeof(
double _Complex));
301 sizeof(
double _Complex));
326 nfft_size[0] = 2*plan->
N+2;
327 nfft_size[1] = 2*plan->
N+2;
328 fftw_size[0] = 4*plan->
N;
329 fftw_size[1] = 4*plan->
N;
333 nfft_cutoff, nfft_flags,
334 FFTW_ESTIMATE | FFTW_DESTROY_INPUT);
358 unsigned int fpt_flags)
369 #pragma omp parallel default(shared)
371 int nthreads = omp_get_num_threads();
372 int threadid = omp_get_thread_num();
375 wisdom.nthreads = nthreads;
381 wisdom.flags = nfsft_flags;
385 X(next_power_of_2_exp_int)(N,&wisdom.
N_MAX,&wisdom.
T_MAX);
420 if (wisdom.
alpha != NULL)
423 #pragma omp parallel default(shared) private(n)
425 int nthreads = omp_get_num_threads();
426 int threadid = omp_get_thread_num();
429 wisdom.nthreads = nthreads;
435 for (n = 0; n <= wisdom.
N_MAX; n++)
437 &wisdom.
beta[ROW(n)], &wisdom.
gamma[ROW(n)],n,kappa);
445 for (n = 0; n <= wisdom.
N_MAX; n++)
451 &wisdom.
gamma[ROW(n)],n,kappa);
458 #pragma omp parallel default(shared) private(n)
461 int nthreads = omp_get_num_threads();
462 int threadid = omp_get_thread_num();
465 wisdom.nthreads = nthreads;
475 for (n = 0; n <= wisdom.
N_MAX; n++)
477 alpha_al_row(alpha,wisdom.
N_MAX,n);
478 beta_al_row(beta,wisdom.
N_MAX,n);
479 gamma_al_row(gamma,wisdom.
N_MAX,n);
497 for (n = 0; n <= wisdom.
N_MAX; n++)
558 for (k = 0; k < wisdom.nthreads; k++)
559 fpt_finalize(wisdom.set_threads[k]);
563 fpt_finalize(wisdom.
set);
624 double _Complex temp;
645 sizeof(
double _Complex));
659 #pragma omp parallel for default(shared) private(k,n)
661 for (k = 0; k <= plan->
N; k++)
663 for (n = -k; n <= k; n++)
667 sqrt((2*k+1)/(4.0*KPI));
678 for (m = 0; m < plan->
M_total; m++)
693 #pragma omp parallel for default(shared) private(m,stheta,sphi,f_m,n,a,n_abs,alpha,gamma,it2,it1,k,temp)
695 for (m = 0; m < plan->
M_total; m++)
698 stheta = cos(2.0*KPI*plan->
x[2*m+1]);
700 sphi = 2.0*KPI*plan->
x[2*m];
709 for (n = -plan->
N; n <= plan->N; n++)
718 alpha = &(wisdom.
alpha[ROW(n_abs)]);
719 gamma = &(wisdom.
gamma[ROW(n_abs)]);
724 for (k = plan->
N; k > n_abs + 1; k--)
726 temp = a[k-2] + it2 * gamma[k];
727 it2 = it1 + it2 * alpha[k] * stheta;
734 it2 = it1 + it2 * wisdom.
alpha[ROWK(n_abs)+1] * stheta;
743 f_m += it2 * wisdom.
gamma[ROW(n_abs)] *
744 pow(1- stheta * stheta, 0.5*n_abs) * cexp(_Complex_I*n*sphi);
767 double _Complex temp;
783 memset(plan->
f_hat,0U,plan->
N_total*
sizeof(
double _Complex));
791 for (m = 0; m < plan->
M_total; m++)
802 #pragma omp parallel for default(shared) private(n,n_abs,alpha,gamma,m,stheta,sphi,it2,it1,k,temp)
803 for (n = -plan->
N; n <= plan->N; n++)
809 alpha = &(wisdom.
alpha[ROW(n_abs)]);
810 gamma = &(wisdom.
gamma[ROW(n_abs)]);
813 for (m = 0; m < plan->
M_total; m++)
816 stheta = cos(2.0*KPI*plan->
x[2*m+1]);
818 sphi = 2.0*KPI*plan->
x[2*m];
823 it1 = plan->
f[m] * wisdom.
gamma[ROW(n_abs)] *
824 pow(1 - stheta * stheta, 0.5*n_abs) * cexp(-_Complex_I*n*sphi);
830 it2 = it1 * wisdom.
alpha[ROWK(n_abs)+1] * stheta;
835 for (k = n_abs+2; k <= plan->
N; k++)
838 it2 = alpha[k] * stheta * it2 + gamma[k] * it1;
846 for (m = 0; m < plan->
M_total; m++)
849 stheta = cos(2.0*KPI*plan->
x[2*m+1]);
851 sphi = 2.0*KPI*plan->
x[2*m];
854 for (n = -plan->
N; n <= plan->N; n++)
860 alpha = &(wisdom.
alpha[ROW(n_abs)]);
861 gamma = &(wisdom.
gamma[ROW(n_abs)]);
866 it1 = plan->
f[m] * wisdom.
gamma[ROW(n_abs)] *
867 pow(1 - stheta * stheta, 0.5*n_abs) * cexp(-_Complex_I*n*sphi);
873 it2 = it1 * wisdom.
alpha[ROWK(n_abs)+1] * stheta;
878 for (k = n_abs+2; k <= plan->
N; k++)
881 it2 = alpha[k] * stheta * it2 + gamma[k] * it1;
897 #pragma omp parallel for default(shared) private(k,n)
899 for (k = 0; k <= plan->
N; k++)
901 for (n = -k; n <= k; n++)
905 sqrt((2*k+1)/(4.0*KPI));
913 for (n = -plan->
N; n <= plan->N+1; n++)
916 (plan->
N+1+abs(n))*
sizeof(
double _Complex));
929 double t, t_pre, t_nfft, t_fpt, t_c2e, t_norm;
960 nfsft_trafo_direct(plan);
964 else if (plan->
N <= wisdom.
N_MAX)
970 sizeof(
double _Complex));
991 #pragma omp parallel for default(shared) private(k,n)
993 for (k = 0; k <= plan->
N; k++)
995 for (n = -k; n <= k; n++)
999 sqrt((2*k+1)/(4.0*KPI));
1011 #pragma omp parallel for default(shared) private(n) num_threads(wisdom.nthreads)
1012 for (n = -plan->
N; n <= plan->N; n++)
1013 fpt_trafo_direct(wisdom.set_threads[omp_get_thread_num()],abs(n),
1019 for (n = -plan->
N; n <= plan->N; n++)
1023 fpt_trafo_direct(wisdom.
set,abs(n),
1033 #pragma omp parallel for default(shared) private(n) num_threads(wisdom.nthreads)
1034 for (n = -plan->
N; n <= plan->N; n++)
1035 fpt_trafo(wisdom.set_threads[omp_get_thread_num()],abs(n),
1041 for (n = -plan->
N; n <= plan->N; n++)
1045 fpt_trafo(wisdom.
set,abs(n),
1122 nfsft_adjoint_direct(plan);
1125 else if (plan->
N <= wisdom.
N_MAX)
1181 #pragma omp parallel for default(shared) private(n) num_threads(wisdom.nthreads)
1182 for (n = -plan->
N; n <= plan->N; n++)
1183 fpt_transposed_direct(wisdom.set_threads[omp_get_thread_num()],abs(n),
1189 for (n = -plan->
N; n <= plan->N; n++)
1193 fpt_transposed_direct(wisdom.
set,abs(n),
1203 #pragma omp parallel for default(shared) private(n) num_threads(wisdom.nthreads)
1204 for (n = -plan->
N; n <= plan->N; n++)
1212 for (n = -plan->
N; n <= plan->N; n++)
1237 #pragma omp parallel for default(shared) private(k,n)
1239 for (k = 0; k <= plan->
N; k++)
1241 for (n = -k; n <= k; n++)
1245 sqrt((2*k+1)/(4.0*KPI));
1255 for (n = -plan->
N; n <= plan->N+1; n++)
1258 (plan->
N+1+abs(n))*
sizeof(
double _Complex));
void nfsft_init_advanced(nfsft_plan *plan, int N, int M, unsigned int flags)
static void c2e(nfsft_plan *plan)
Converts coefficients with , from a linear combination of Chebyshev polynomials to coefficients m...
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$.
#define NFSFT_MALLOC_F_HAT
double * x
the nodes for ,
#define FPT_PERSISTENT_DATA
If set, TODO complete comment.
void(* mv_trafo)(void *)
Transform.
fftw_complex * f_hat
Fourier coefficients.
void nfsft_trafo(nfsft_plan *plan)
#define NFSFT_PRESERVE_F_HAT
void nfsft_adjoint(nfsft_plan *plan)
fftw_complex * f_hat
Fourier coefficients.
R nfft_elapsed_seconds(ticks t1, ticks t0)
Return number of elapsed seconds between two time points.
void fpt_transposed(fpt_set set, const int m, double _Complex *x, double _Complex *y, const int k_end, const unsigned int flags)
void nfsft_precompute(int N, double kappa, unsigned int nfsft_flags, unsigned int fpt_flags)
data structure for an NFSFT (nonequispaced fast spherical Fourier transform) plan with double precisi...
fpt_set set
Structure for discrete polynomial transform (DPT)
#define NFSFT_BREAK_EVEN
The break-even bandwidth .
#define NFSFT_NO_FAST_ALGORITHM
int N_MAX
Stores precomputation flags.
bool initialized
Indicates wether the structure has been initialized.
void fpt_precompute(fpt_set set, const int m, double *alpha, double *beta, double *gam, int k_start, const double threshold)
void alpha_al_all(R *alpha, const int N)
Compute three-term-recurrence coefficients of associated Legendre functions for .
unsigned int flags
the planner flags
void nfsft_init(nfsft_plan *plan, int N, int M)
Holds data for a set of cascade summations.
#define NFSFT_DEFAULT_NFFT_CUTOFF
The default NFFT cutoff parameter.
nfft_plan plan_nfft
the internal NFFT plan
NFFT_INT M_total
Total number of samples.
double MEASURE_TIME_t[3]
Measured time for each step if MEASURE_TIME is set.
#define X(name)
Include header for C99 complex datatype.
#define NFSFT_NO_DIRECT_ALGORITHM
void * nfft_malloc(size_t n)
NFFT_INT N_total
Total number of Fourier coefficients.
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 nfft_precompute_one_psi(nfft_plan *ths)
fpt_set fpt_init(const int M, const int t, const unsigned int flags)
void nfsft_finalize(nfsft_plan *plan)
void(* mv_adjoint)(void *)
Adjoint transform.
void beta_al_all(R *alpha, const int N)
Compute three-term-recurrence coefficients of associated Legendre functions for .
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$.
static void c2e_transposed(nfsft_plan *plan)
Transposed version of the function c2e.
void gamma_al_all(R *alpha, const int N)
Compute three-term-recurrence coefficients of associated Legendre functions for .
Header file for the nfft3 library.
double * x
Nodes in time/spatial domain, size is doubles.
#define FPT_AL_SYMMETRY
If set, TODO complete comment.
static struct nfsft_wisdom wisdom
The global wisdom structure for precomputed data.
unsigned flags
Flags for precomputation, (de)allocation, and FFTW usage, default setting is PRE_PHI_HUT | PRE_PSI | ...
fftw_complex * f_hat_intern
Internally used pointer to spherical Fourier coefficients.
int T_MAX
The logarithm /f$t = N_{{max}}/f$ of the maximum bandwidth.
#define NFSFT_INDEX(k, n, plan)