44#define X(name) NFFT(name)
47static inline INT intprod(
const INT *vec,
const INT a,
const INT d)
52 for (t = 0; t < d; t++)
59#define BASE(x) CEXP(x)
75static inline void sort0(
const INT d,
const INT *n,
const INT m,
76 const INT local_x_num,
const R *local_x, INT *ar_x)
78 INT u_j[d], i, j, help, rhigh;
82 for (i = 0; i < local_x_num; i++)
86 for (j = 0; j < d; j++)
88 help = (INT) LRINT(FLOOR((R)(n[j]) * local_x[d * i + j] - (R)(m)));
89 u_j[j] = (help % n[j] + n[j]) % n[j];
91 ar_x[2 * i] += u_j[j];
93 ar_x[2 * i] *= n[j + 1];
97 for (j = 0, nprod = 1; j < d; j++)
100 rhigh = (INT) LRINT(CEIL(LOG2((R)nprod))) - 1;
102 ar_x_temp = (INT*) Y(malloc)(2 * (size_t)(local_x_num) *
sizeof(INT));
103 Y(sort_node_indices_radix_lsdf)(local_x_num, ar_x, ar_x_temp, rhigh);
105 for (i = 1; i < local_x_num; i++)
106 assert(ar_x[2 * (i - 1)] <= ar_x[2 * i]);
119static inline void sort(
const X(plan) *ths)
121 if (ths->flags & NFFT_SORT_NODES)
122 sort0(ths->d, ths->n, ths->m, ths->M_total, ths->x, ths->index_x);
145void X(trafo_direct)(
const X(plan) *ths)
147 C *f_hat = (C*)ths->f_hat, *f = (C*)ths->f;
154 #pragma omp parallel for default(shared) private(j)
156 for (j = 0; j < ths->M_total; j++)
160 for (k_L = 0; k_L < ths->N_total; k_L++)
162 R omega = K2PI * ((R)(k_L - ths->N_total/2)) * ths->x[j];
163 v += f_hat[k_L] * (COS(omega) - II * SIN(omega));
174 #pragma omp parallel for default(shared) private(j)
176 for (j = 0; j < ths->M_total; j++)
179 R x[ths->d], omega, Omega[ths->d + 1];
180 INT t, t2, k_L, k[ths->d];
182 for (t = 0; t < ths->d; t++)
185 x[t] = K2PI * ths->x[j * ths->d + t];
186 Omega[t+1] = ((R)k[t]) * x[t] + Omega[t];
188 omega = Omega[ths->d];
190 for (k_L = 0; k_L < ths->N_total; k_L++)
192 v += f_hat[k_L] * (COS(omega) - II * SIN(omega));
194 for (t = ths->d - 1; (t >= 1) && (k[t] == ths->N[t]/2 - 1); t--)
199 for (t2 = t; t2 < ths->d; t2++)
200 Omega[t2+1] = ((R)k[t2]) * x[t2] + Omega[t2];
202 omega = Omega[ths->d];
211void X(adjoint_direct)(
const X(plan) *ths)
213 C *f_hat = (C*)ths->f_hat, *f = (C*)ths->f;
215 memset(f_hat, 0, (
size_t)(ths->N_total) *
sizeof(C));
222 #pragma omp parallel for default(shared) private(k_L)
223 for (k_L = 0; k_L < ths->N_total; k_L++)
226 for (j = 0; j < ths->M_total; j++)
228 R omega = K2PI * ((R)(k_L - (ths->N_total/2))) * ths->x[j];
229 f_hat[k_L] += f[j] * (COS(omega) + II * SIN(omega));
234 for (j = 0; j < ths->M_total; j++)
237 for (k_L = 0; k_L < ths->N_total; k_L++)
239 R omega = K2PI * ((R)(k_L - ths->N_total / 2)) * ths->x[j];
240 f_hat[k_L] += f[j] * (COS(omega) + II * SIN(omega));
250 #pragma omp parallel for default(shared) private(j, k_L)
251 for (k_L = 0; k_L < ths->N_total; k_L++)
253 INT k[ths->d], k_temp, t;
257 for (t = ths->d - 1; t >= 0; t--)
259 k[t] = k_temp % ths->N[t] - ths->N[t]/2;
263 for (j = 0; j < ths->M_total; j++)
266 for (t = 0; t < ths->d; t++)
267 omega += k[t] * K2PI * ths->x[j * ths->d + t];
268 f_hat[k_L] += f[j] * (COS(omega) + II * SIN(omega));
272 for (j = 0; j < ths->M_total; j++)
274 R x[ths->d], omega, Omega[ths->d+1];
275 INT t, t2, k[ths->d];
277 for (t = 0; t < ths->d; t++)
280 x[t] = K2PI * ths->x[j * ths->d + t];
281 Omega[t+1] = ((R)k[t]) * x[t] + Omega[t];
283 omega = Omega[ths->d];
284 for (k_L = 0; k_L < ths->N_total; k_L++)
286 f_hat[k_L] += f[j] * (COS(omega) + II * SIN(omega));
288 for (t = ths->d-1; (t >= 1) && (k[t] == ths->N[t]/2-1); t--)
293 for (t2 = t; t2 < ths->d; t2++)
294 Omega[t2+1] = ((R)k[t2]) * x[t2] + Omega[t2];
296 omega = Omega[ths->d];
328static inline void uo(
const X(plan) *ths,
const INT j, INT *up, INT *op,
331 const R xj = ths->x[j * ths->d + act_dim];
332 INT c = LRINT(FLOOR(xj * (R)(ths->n[act_dim])));
334 (*up) = c - (ths->m);
335 (*op) = c + 1 + (ths->m);
338static inline void uo2(INT *u, INT *o,
const R x,
const INT n,
const INT m)
340 INT c = LRINT(FLOOR(x * (R)(n)));
342 *u = (c - m + n) % n;
343 *o = (c + 1 + m + n) % n;
346#define MACRO_D_compute_A \
348 g_hat[k_plain[ths->d]] = f_hat[ks_plain[ths->d]] * c_phi_inv_k[ths->d]; \
351#define MACRO_D_compute_T \
353 f_hat[ks_plain[ths->d]] = g_hat[k_plain[ths->d]] * c_phi_inv_k[ths->d]; \
356#define MACRO_D_init_result_A memset(g_hat, 0, (size_t)(ths->n_total) * sizeof(C));
358#define MACRO_D_init_result_T memset(f_hat, 0, (size_t)(ths->N_total) * sizeof(C));
360#define MACRO_with_PRE_PHI_HUT * ths->c_phi_inv[t2][ks[t2]];
362#define MACRO_without_PRE_PHI_HUT / (PHI_HUT(ths->n[t2],ks[t2]-(ths->N[t2]/2),t2));
364#define MACRO_init_k_ks \
366 for (t = ths->d-1; 0 <= t; t--) \
369 ks[t] = ths->N[t]/2; \
374#define MACRO_update_c_phi_inv_k(which_one) \
376 for (t2 = t; t2 < ths->d; t2++) \
378 c_phi_inv_k[t2+1] = c_phi_inv_k[t2] MACRO_ ##which_one; \
379 ks_plain[t2+1] = ks_plain[t2]*ths->N[t2] + ks[t2]; \
380 k_plain[t2+1] = k_plain[t2]*ths->n[t2] + k[t2]; \
384#define MACRO_count_k_ks \
386 for (t = ths->d-1; (t > 0) && (kp[t] == ths->N[t]-1); t--) \
389 ks[t]= ths->N[t]/2; \
392 kp[t]++; k[t]++; ks[t]++; \
393 if(kp[t] == ths->N[t]/2) \
395 k[t] = ths->n[t] - ths->N[t]/2; \
401#define MACRO_D(which_one) \
402static inline void D_serial_ ## which_one (X(plan) *ths) \
405 R c_phi_inv_k[ths->d+1]; \
411 INT k_plain[ths->d+1]; \
412 INT ks_plain[ths->d+1]; \
414 f_hat = (C*)ths->f_hat; g_hat = (C*)ths->g_hat; \
415 MACRO_D_init_result_ ## which_one; \
417 c_phi_inv_k[0] = K(1.0); \
423 if (ths->flags & PRE_PHI_HUT) \
425 for (k_L = 0; k_L < ths->N_total; k_L++) \
427 MACRO_update_c_phi_inv_k(with_PRE_PHI_HUT); \
428 MACRO_D_compute_ ## which_one; \
434 for (k_L = 0; k_L < ths->N_total; k_L++) \
436 MACRO_update_c_phi_inv_k(without_PRE_PHI_HUT); \
437 MACRO_D_compute_ ## which_one; \
444static inline void D_openmp_A(X(plan) *ths)
449 f_hat = (C*)ths->f_hat; g_hat = (C*)ths->g_hat;
450 memset(g_hat, 0, ths->n_total *
sizeof(C));
454 #pragma omp parallel for default(shared) private(k_L)
455 for (k_L = 0; k_L < ths->N_total; k_L++)
460 R c_phi_inv_k_val = K(1.0);
462 INT ks_plain_val = 0;
466 for (t = ths->d-1; t >= 0; t--)
468 kp[t] = k_temp % ths->N[t];
469 if (kp[t] >= ths->N[t]/2)
470 k[t] = ths->n[t] - ths->N[t] + kp[t];
473 ks[t] = (kp[t] + ths->N[t]/2) % ths->N[t];
477 for (t = 0; t < ths->d; t++)
479 c_phi_inv_k_val *= ths->c_phi_inv[t][ks[t]];
480 ks_plain_val = ks_plain_val*ths->N[t] + ks[t];
481 k_plain_val = k_plain_val*ths->n[t] + k[t];
484 g_hat[k_plain_val] = f_hat[ks_plain_val] * c_phi_inv_k_val;
489 #pragma omp parallel for default(shared) private(k_L)
490 for (k_L = 0; k_L < ths->N_total; k_L++)
495 R c_phi_inv_k_val = K(1.0);
497 INT ks_plain_val = 0;
501 for (t = ths->d-1; t >= 0; t--)
503 kp[t] = k_temp % ths->N[t];
504 if (kp[t] >= ths->N[t]/2)
505 k[t] = ths->n[t] - ths->N[t] + kp[t];
508 ks[t] = (kp[t] + ths->N[t]/2) % ths->N[t];
512 for (t = 0; t < ths->d; t++)
514 c_phi_inv_k_val /= (PHI_HUT(ths->n[t],ks[t]-(ths->N[t]/2),t));
515 ks_plain_val = ks_plain_val*ths->N[t] + ks[t];
516 k_plain_val = k_plain_val*ths->n[t] + k[t];
519 g_hat[k_plain_val] = f_hat[ks_plain_val] * c_phi_inv_k_val;
529static inline void D_A(X(plan) *ths)
539static void D_openmp_T(X(plan) *ths)
544 f_hat = (C*)ths->f_hat; g_hat = (C*)ths->g_hat;
545 memset(f_hat, 0, ths->N_total *
sizeof(C));
549 #pragma omp parallel for default(shared) private(k_L)
550 for (k_L = 0; k_L < ths->N_total; k_L++)
555 R c_phi_inv_k_val = K(1.0);
557 INT ks_plain_val = 0;
561 for (t = ths->d - 1; t >= 0; t--)
563 kp[t] = k_temp % ths->N[t];
564 if (kp[t] >= ths->N[t]/2)
565 k[t] = ths->n[t] - ths->N[t] + kp[t];
568 ks[t] = (kp[t] + ths->N[t]/2) % ths->N[t];
572 for (t = 0; t < ths->d; t++)
574 c_phi_inv_k_val *= ths->c_phi_inv[t][ks[t]];
575 ks_plain_val = ks_plain_val*ths->N[t] + ks[t];
576 k_plain_val = k_plain_val*ths->n[t] + k[t];
579 f_hat[ks_plain_val] = g_hat[k_plain_val] * c_phi_inv_k_val;
584 #pragma omp parallel for default(shared) private(k_L)
585 for (k_L = 0; k_L < ths->N_total; k_L++)
590 R c_phi_inv_k_val = K(1.0);
592 INT ks_plain_val = 0;
596 for (t = ths->d-1; t >= 0; t--)
598 kp[t] = k_temp % ths->N[t];
599 if (kp[t] >= ths->N[t]/2)
600 k[t] = ths->n[t] - ths->N[t] + kp[t];
603 ks[t] = (kp[t] + ths->N[t]/2) % ths->N[t];
607 for (t = 0; t < ths->d; t++)
609 c_phi_inv_k_val /= (PHI_HUT(ths->n[t],ks[t]-(ths->N[t]/2),t));
610 ks_plain_val = ks_plain_val*ths->N[t] + ks[t];
611 k_plain_val = k_plain_val*ths->n[t] + k[t];
614 f_hat[ks_plain_val] = g_hat[k_plain_val] * c_phi_inv_k_val;
624static void D_T(X(plan) *ths)
634#define MACRO_B_init_result_A memset(ths->f, 0, (size_t)(ths->M_total) * sizeof(C));
635#define MACRO_B_init_result_T memset(ths->g, 0, (size_t)(ths->n_total) * sizeof(C));
637#define MACRO_B_PRE_FULL_PSI_compute_A \
639 (*fj) += ths->psi[ix] * g[ths->psi_index_g[ix]]; \
642#define MACRO_B_PRE_FULL_PSI_compute_T \
644 g[ths->psi_index_g[ix]] += ths->psi[ix] * (*fj); \
647#define MACRO_B_compute_A \
649 ths->f[j] += phi_prod[ths->d] * ths->g[ll_plain[ths->d]]; \
652#define MACRO_B_compute_T \
654 ths->g[ll_plain[ths->d]] += phi_prod[ths->d] * ths->f[j]; \
657#define MACRO_with_FG_PSI fg_psi[t2][lj[t2]]
659#define MACRO_with_PRE_PSI ths->psi[(j*ths->d+t2) * (2*ths->m+2)+lj[t2]]
661#define MACRO_without_PRE_PSI_improved psij_const[t2 * (2*ths->m+2) + lj[t2]]
663#define MACRO_without_PRE_PSI PHI(ths->n[t2], ths->x[j*ths->d+t2] \
664 - ((R) (lj[t2]+u[t2]))/((R)ths->n[t2]), t2)
666#define MACRO_init_uo_l_lj_t \
667INT l_all[ths->d*(2*ths->m+2)]; \
669 for (t = ths->d-1; t >= 0; t--) \
671 uo(ths,j,&u[t],&o[t],t); \
673 for (lj_t = 0; lj_t < 2*ths->m+2; lj_t++) \
674 l_all[t*(2*ths->m+2) + lj_t] = (u[t] + lj_t + ths->n[t]) % ths->n[t]; \
680#define MACRO_update_phi_prod_ll_plain(which_one) { \
681 for (t2 = t; t2 < ths->d; t2++) \
683 phi_prod[t2+1] = phi_prod[t2] * MACRO_ ## which_one; \
684 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
688#define MACRO_count_uo_l_lj_t \
690 for (t = ths->d-1; (t > 0) && (lj[t] == o[t]-u[t]); t--) \
698#define MACRO_COMPUTE_with_PRE_PSI MACRO_with_PRE_PSI
699#define MACRO_COMPUTE_with_PRE_FG_PSI MACRO_with_FG_PSI
700#define MACRO_COMPUTE_with_FG_PSI MACRO_with_FG_PSI
701#define MACRO_COMPUTE_with_PRE_LIN_PSI MACRO_with_FG_PSI
702#define MACRO_COMPUTE_without_PRE_PSI MACRO_without_PRE_PSI_improved
703#define MACRO_COMPUTE_without_PRE_PSI_improved MACRO_without_PRE_PSI_improved
705#define MACRO_B_COMPUTE_ONE_NODE(whichone_AT,whichone_FLAGS) \
708 INT l0, l1, l2, l3; \
709 for (l0 = 0; l0 < 2*ths->m+2; l0++) \
713 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
714 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
715 for (l1 = 0; l1 < 2*ths->m+2; l1++) \
719 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
720 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
721 for (l2 = 0; l2 < 2*ths->m+2; l2++) \
725 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
726 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
727 for (l3 = 0; l3 < 2*ths->m+2; l3++) \
731 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
732 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
734 MACRO_B_compute_ ## whichone_AT; \
740 else if (ths->d == 5) \
742 INT l0, l1, l2, l3, l4; \
743 for (l0 = 0; l0 < 2*ths->m+2; l0++) \
747 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
748 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
749 for (l1 = 0; l1 < 2*ths->m+2; l1++) \
753 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
754 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
755 for (l2 = 0; l2 < 2*ths->m+2; l2++) \
759 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
760 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
761 for (l3 = 0; l3 < 2*ths->m+2; l3++) \
765 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
766 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
767 for (l4 = 0; l4 < 2*ths->m+2; l4++) \
771 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone_FLAGS; \
772 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
774 MACRO_B_compute_ ## whichone_AT; \
782 for (l_L = 0; l_L < lprod; l_L++) \
784 MACRO_update_phi_prod_ll_plain(whichone_FLAGS); \
786 MACRO_B_compute_ ## whichone_AT; \
788 MACRO_count_uo_l_lj_t; \
792#define MACRO_B(which_one) \
793static inline void B_serial_ ## which_one (X(plan) *ths) \
796 INT u[ths->d], o[ths->d]; \
801 INT ll_plain[ths->d+1]; \
802 R phi_prod[ths->d+1]; \
804 R fg_psi[ths->d][2*ths->m+2]; \
805 R fg_exp_l[ths->d][2*ths->m+2+1]; \
807 R tmpEXP1, tmpEXP2, tmpEXP2sq, tmp1, tmp2, tmp3; \
810 INT ip_s = ths->K/(ths->m+2); \
812 MACRO_B_init_result_ ## which_one; \
814 if (ths->flags & PRE_FULL_PSI) \
819 f = (C*)ths->f; g = (C*)ths->g; \
821 for (ix = 0, j = 0, fj = f; j < ths->M_total; j++, fj++) \
823 for (l_L = 0; l_L < ths->psi_index_f[j]; l_L++, ix++) \
825 MACRO_B_PRE_FULL_PSI_compute_ ## which_one; \
831 phi_prod[0] = K(1.0); \
834 for (t = 0, lprod = 1; t < ths->d; t++) \
835 lprod *= (2 * ths->m + 2); \
837 if (ths->flags & PRE_PSI) \
841 for (k = 0; k < ths->M_total; k++) \
843 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k; \
845 MACRO_init_uo_l_lj_t; \
847 MACRO_B_COMPUTE_ONE_NODE(which_one,with_PRE_PSI); \
852 if (ths->flags & PRE_FG_PSI) \
856 for(t2 = 0; t2 < ths->d; t2++) \
858 tmpEXP2 = EXP(K(-1.0) / ths->b[t2]); \
859 tmpEXP2sq = tmpEXP2*tmpEXP2; \
862 fg_exp_l[t2][0] = K(1.0); \
863 for (lj_fg = 1; lj_fg <= (2 * ths->m + 2); lj_fg++) \
865 tmp3 = tmp2*tmpEXP2; \
867 fg_exp_l[t2][lj_fg] = fg_exp_l[t2][lj_fg-1] * tmp3; \
870 for (k = 0; k < ths->M_total; k++) \
872 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k; \
874 MACRO_init_uo_l_lj_t; \
876 for (t2 = 0; t2 < ths->d; t2++) \
878 fg_psi[t2][0] = ths->psi[2*(j*ths->d+t2)]; \
879 tmpEXP1 = ths->psi[2*(j*ths->d+t2)+1]; \
881 for (l_fg = u[t2]+1, lj_fg = 1; l_fg <= o[t2]; l_fg++, lj_fg++) \
884 fg_psi[t2][lj_fg] = fg_psi[t2][0]*tmp1*fg_exp_l[t2][lj_fg]; \
888 MACRO_B_COMPUTE_ONE_NODE(which_one,with_FG_PSI); \
893 if (ths->flags & FG_PSI) \
897 for (t2 = 0; t2 < ths->d; t2++) \
899 tmpEXP2 = EXP(K(-1.0)/ths->b[t2]); \
900 tmpEXP2sq = tmpEXP2*tmpEXP2; \
903 fg_exp_l[t2][0] = K(1.0); \
904 for (lj_fg = 1; lj_fg <= (2*ths->m+2); lj_fg++) \
906 tmp3 = tmp2*tmpEXP2; \
908 fg_exp_l[t2][lj_fg] = fg_exp_l[t2][lj_fg-1]*tmp3; \
911 for (k = 0; k < ths->M_total; k++) \
913 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k; \
915 MACRO_init_uo_l_lj_t; \
917 for (t2 = 0; t2 < ths->d; t2++) \
919 fg_psi[t2][0] = (PHI(ths->n[t2], (ths->x[j*ths->d+t2] - ((R)u[t2])/((R)(ths->n[t2]))), t2));\
921 tmpEXP1 = EXP(K(2.0) * ((R)(ths->n[t2]) * ths->x[j * ths->d + t2] - (R)(u[t2])) \
924 for (l_fg = u[t2] + 1, lj_fg = 1; l_fg <= o[t2]; l_fg++, lj_fg++) \
927 fg_psi[t2][lj_fg] = fg_psi[t2][0]*tmp1*fg_exp_l[t2][lj_fg]; \
931 MACRO_B_COMPUTE_ONE_NODE(which_one,with_FG_PSI); \
936 if (ths->flags & PRE_LIN_PSI) \
940 for (k = 0; k<ths->M_total; k++) \
942 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k; \
944 MACRO_init_uo_l_lj_t; \
946 for (t2 = 0; t2 < ths->d; t2++) \
948 y[t2] = (((R)(ths->n[t2]) * ths->x[j * ths->d + t2] - (R)(u[t2])) \
949 * ((R)(ths->K))) / (R)(ths->m + 2); \
950 ip_u = LRINT(FLOOR(y[t2])); \
952 for (l_fg = u[t2], lj_fg = 0; l_fg <= o[t2]; l_fg++, lj_fg++) \
954 fg_psi[t2][lj_fg] = ths->psi[(ths->K+1)*t2 + ABS(ip_u-lj_fg*ip_s)] \
955 * (1-ip_w) + ths->psi[(ths->K+1)*t2 + ABS(ip_u-lj_fg*ip_s+1)] \
960 MACRO_B_COMPUTE_ONE_NODE(which_one,with_FG_PSI); \
968 for (k = 0; k < ths->M_total; k++) \
970 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k; \
972 R psij_const[ths->d * (2*ths->m+2)]; \
974 MACRO_init_uo_l_lj_t; \
976 for (t2 = 0; t2 < ths->d; t2++) \
979 for (lj_t = 0; lj_t < 2*ths->m+2; lj_t++) \
980 psij_const[t2 * (2*ths->m+2) + lj_t] = PHI(ths->n[t2], ths->x[j*ths->d+t2] \
981 - ((R) (lj_t+u[t2]))/((R)ths->n[t2]), t2); \
984 MACRO_B_COMPUTE_ONE_NODE(which_one,without_PRE_PSI_improved); \
993#define MACRO_B_openmp_A_COMPUTE_BEFORE_LOOP_with_PRE_PSI
994#define MACRO_B_openmp_A_COMPUTE_UPDATE_with_PRE_PSI \
995 MACRO_update_phi_prod_ll_plain(with_PRE_PSI);
997#define MACRO_B_openmp_A_COMPUTE_INIT_FG_PSI \
998 for (t2 = 0; t2 < ths->d; t2++) \
1001 R tmpEXP2 = EXP(K(-1.0)/ths->b[t2]); \
1002 R tmpEXP2sq = tmpEXP2*tmpEXP2; \
1005 fg_exp_l[t2][0] = K(1.0); \
1006 for(lj_fg = 1; lj_fg <= (2*ths->m+2); lj_fg++) \
1008 tmp3 = tmp2*tmpEXP2; \
1009 tmp2 *= tmpEXP2sq; \
1010 fg_exp_l[t2][lj_fg] = fg_exp_l[t2][lj_fg-1]*tmp3; \
1013#define MACRO_B_openmp_A_COMPUTE_BEFORE_LOOP_with_PRE_FG_PSI \
1014 for (t2 = 0; t2 < ths->d; t2++) \
1016 fg_psi[t2][0] = ths->psi[2*(j*ths->d+t2)]; \
1017 tmpEXP1 = ths->psi[2*(j*ths->d+t2)+1]; \
1019 for (l_fg = u[t2]+1, lj_fg = 1; l_fg <= o[t2]; l_fg++, lj_fg++) \
1022 fg_psi[t2][lj_fg] = fg_psi[t2][0]*tmp1*fg_exp_l[t2][lj_fg]; \
1025#define MACRO_B_openmp_A_COMPUTE_UPDATE_with_PRE_FG_PSI \
1026 MACRO_update_phi_prod_ll_plain(with_FG_PSI);
1028#define MACRO_B_openmp_A_COMPUTE_BEFORE_LOOP_with_FG_PSI \
1029 for (t2 = 0; t2 < ths->d; t2++) \
1031 fg_psi[t2][0] = (PHI(ths->n[t2],(ths->x[j*ths->d+t2]-((R)u[t2])/((R)ths->n[t2])),t2)); \
1033 tmpEXP1 = EXP(K(2.0)*(ths->n[t2]*ths->x[j*ths->d+t2] - u[t2]) \
1036 for (l_fg = u[t2] + 1, lj_fg = 1; l_fg <= o[t2]; l_fg++, lj_fg++) \
1039 fg_psi[t2][lj_fg] = fg_psi[t2][0]*tmp1*fg_exp_l[t2][lj_fg]; \
1042#define MACRO_B_openmp_A_COMPUTE_UPDATE_with_FG_PSI \
1043 MACRO_update_phi_prod_ll_plain(with_FG_PSI);
1045#define MACRO_B_openmp_A_COMPUTE_BEFORE_LOOP_with_PRE_LIN_PSI \
1046 for (t2 = 0; t2 < ths->d; t2++) \
1048 y[t2] = ((ths->n[t2]*ths->x[j*ths->d+t2]-(R)u[t2]) \
1049 * ((R)ths->K))/(ths->m+2); \
1050 ip_u = LRINT(FLOOR(y[t2])); \
1051 ip_w = y[t2]-ip_u; \
1052 for (l_fg = u[t2], lj_fg = 0; l_fg <= o[t2]; l_fg++, lj_fg++) \
1054 fg_psi[t2][lj_fg] = ths->psi[(ths->K+1)*t2 + ABS(ip_u-lj_fg*ip_s)] \
1055 * (1-ip_w) + ths->psi[(ths->K+1)*t2 + ABS(ip_u-lj_fg*ip_s+1)] \
1059#define MACRO_B_openmp_A_COMPUTE_UPDATE_with_PRE_LIN_PSI \
1060 MACRO_update_phi_prod_ll_plain(with_FG_PSI);
1062#define MACRO_B_openmp_A_COMPUTE_BEFORE_LOOP_without_PRE_PSI \
1063 for (t2 = 0; t2 < ths->d; t2++) \
1066 for (lj_t = 0; lj_t < 2*ths->m+2; lj_t++) \
1067 psij_const[t2 * (2*ths->m+2) + lj_t] = PHI(ths->n[t2], ths->x[j*ths->d+t2] \
1068 - ((R) (lj_t+u[t2]))/((R)ths->n[t2]), t2); \
1070#define MACRO_B_openmp_A_COMPUTE_UPDATE_without_PRE_PSI \
1071 MACRO_update_phi_prod_ll_plain(without_PRE_PSI_improved);
1073#define MACRO_B_openmp_A_COMPUTE(whichone) \
1075 INT u[ths->d], o[ths->d]; \
1078 INT ll_plain[ths->d+1]; \
1079 R phi_prod[ths->d+1]; \
1080 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k; \
1082 phi_prod[0] = K(1.0); \
1085 MACRO_init_uo_l_lj_t; \
1087 MACRO_B_openmp_A_COMPUTE_BEFORE_LOOP_ ##whichone \
1091 INT l0, l1, l2, l3; \
1092 for (l0 = 0; l0 < 2*ths->m+2; l0++) \
1096 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1097 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1098 for (l1 = 0; l1 < 2*ths->m+2; l1++) \
1102 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1103 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1104 for (l2 = 0; l2 < 2*ths->m+2; l2++) \
1108 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1109 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1110 for (l3 = 0; l3 < 2*ths->m+2; l3++) \
1114 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1115 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1117 ths->f[j] += phi_prod[ths->d] * ths->g[ll_plain[ths->d]]; \
1123 else if (ths->d == 5) \
1125 INT l0, l1, l2, l3, l4; \
1126 for (l0 = 0; l0 < 2*ths->m+2; l0++) \
1130 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1131 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1132 for (l1 = 0; l1 < 2*ths->m+2; l1++) \
1136 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1137 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1138 for (l2 = 0; l2 < 2*ths->m+2; l2++) \
1142 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1143 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1144 for (l3 = 0; l3 < 2*ths->m+2; l3++) \
1148 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1149 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1150 for (l4 = 0; l4 < 2*ths->m+2; l4++) \
1154 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1155 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1157 ths->f[j] += phi_prod[ths->d] * ths->g[ll_plain[ths->d]]; \
1165 for (l_L = 0; l_L < lprod; l_L++) \
1167 MACRO_B_openmp_A_COMPUTE_UPDATE_ ##whichone \
1169 ths->f[j] += phi_prod[ths->d] * ths->g[ll_plain[ths->d]]; \
1171 MACRO_count_uo_l_lj_t; \
1176static inline void B_openmp_A (X(plan) *ths)
1181 memset(ths->f, 0, ths->M_total *
sizeof(C));
1183 for (k = 0, lprod = 1; k < ths->d; k++)
1184 lprod *= (2*ths->m+2);
1188 #pragma omp parallel for default(shared) private(k)
1189 for (k = 0; k < ths->M_total; k++)
1192 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
1194 for (l = 0; l < lprod; l++)
1195 ths->f[j] += ths->psi[j*lprod+l] * ths->g[ths->psi_index_g[j*lprod+l]];
1202 #pragma omp parallel for default(shared) private(k)
1203 for (k = 0; k < ths->M_total; k++)
1206 MACRO_B_openmp_A_COMPUTE(with_PRE_PSI);
1214 R fg_exp_l[ths->d][2*ths->m+2+1];
1216 MACRO_B_openmp_A_COMPUTE_INIT_FG_PSI
1218 #pragma omp parallel for default(shared) private(k,t,t2)
1219 for (k = 0; k < ths->M_total; k++)
1221 R fg_psi[ths->d][2*ths->m+2];
1225 MACRO_B_openmp_A_COMPUTE(with_PRE_FG_PSI);
1233 R fg_exp_l[ths->d][2*ths->m+2+1];
1237 MACRO_B_openmp_A_COMPUTE_INIT_FG_PSI
1239 #pragma omp parallel for default(shared) private(k,t,t2)
1240 for (k = 0; k < ths->M_total; k++)
1242 R fg_psi[ths->d][2*ths->m+2];
1246 MACRO_B_openmp_A_COMPUTE(with_FG_PSI);
1255 #pragma omp parallel for default(shared) private(k)
1256 for (k = 0; k<ths->M_total; k++)
1260 R fg_psi[ths->d][2*ths->m+2];
1264 INT ip_s = ths->K/(ths->m+2);
1266 MACRO_B_openmp_A_COMPUTE(with_PRE_LIN_PSI);
1274 #pragma omp parallel for default(shared) private(k)
1275 for (k = 0; k < ths->M_total; k++)
1278 R psij_const[ths->d * (2*ths->m+2)];
1280 MACRO_B_openmp_A_COMPUTE(without_PRE_PSI);
1285static void B_A(X(plan) *ths)
1310static inline INT index_x_binary_search(
const INT *ar_x,
const INT len,
const INT key)
1312 INT left = 0, right = len - 1;
1317 while (left < right - 1)
1319 INT i = (left + right) / 2;
1320 if (ar_x[2*i] >= key)
1322 else if (ar_x[2*i] < key)
1326 if (ar_x[2*left] < key && left != len-1)
1349static void nfft_adjoint_B_omp_blockwise_init(INT *my_u0, INT *my_o0,
1350 INT *min_u_a, INT *max_u_a, INT *min_u_b, INT *max_u_b,
const INT d,
1351 const INT *n,
const INT m)
1353 const INT n0 = n[0];
1355 INT nthreads = omp_get_num_threads();
1356 INT nthreads_used = MIN(nthreads, n0);
1357 INT size_per_thread = n0 / nthreads_used;
1358 INT size_left = n0 - size_per_thread * nthreads_used;
1359 INT size_g[nthreads_used];
1360 INT offset_g[nthreads_used];
1361 INT my_id = omp_get_thread_num();
1362 INT n_prod_rest = 1;
1364 for (k = 1; k < d; k++)
1365 n_prod_rest *= n[k];
1374 if (my_id < nthreads_used)
1376 const INT m22 = 2 * m + 2;
1379 for (k = 0; k < nthreads_used; k++)
1382 offset_g[k] = offset_g[k-1] + size_g[k-1];
1383 size_g[k] = size_per_thread;
1391 *my_u0 = offset_g[my_id];
1392 *my_o0 = offset_g[my_id] + size_g[my_id] - 1;
1394 if (nthreads_used > 1)
1396 *max_u_a = n_prod_rest*(offset_g[my_id] + size_g[my_id]) - 1;
1397 *min_u_a = n_prod_rest*(offset_g[my_id] - m22 + 1);
1402 *max_u_a = n_prod_rest * n0 - 1;
1407 *min_u_b = n_prod_rest * (offset_g[my_id] - m22 + 1 + n0);
1408 *max_u_b = n_prod_rest * n0 - 1;
1412 if (*min_u_b != -1 && *min_u_b <= *max_u_a)
1414 *max_u_a = *max_u_b;
1419 assert(*min_u_a <= *max_u_a);
1420 assert(*min_u_b <= *max_u_b);
1421 assert(*min_u_b == -1 || *max_u_a < *min_u_b);
1435static void nfft_adjoint_B_compute_full_psi(C *g,
const INT *psi_index_g,
1436 const R *psi,
const C *f,
const INT M,
const INT d,
const INT *n,
1437 const INT m,
const unsigned flags,
const INT *index_x)
1449 for(t = 0, lprod = 1; t < d; t++)
1453 lprod_m1 = lprod / (2 * m + 2);
1457 if (flags & NFFT_OMP_BLOCKWISE_ADJOINT)
1459 #pragma omp parallel private(k)
1461 INT my_u0, my_o0, min_u_a, max_u_a, min_u_b, max_u_b;
1462 const INT *ar_x = index_x;
1463 INT n_prod_rest = 1;
1465 for (k = 1; k < d; k++)
1466 n_prod_rest *= n[k];
1468 nfft_adjoint_B_omp_blockwise_init(&my_u0, &my_o0, &min_u_a, &max_u_a, &min_u_b, &max_u_b, d, n, m);
1472 k = index_x_binary_search(ar_x, M, min_u_a);
1474 assert(ar_x[2*k] >= min_u_a || k == M-1);
1476 assert(ar_x[2*k-2] < min_u_a);
1481 INT u_prod = ar_x[2*k];
1482 INT j = ar_x[2*k+1];
1484 if (u_prod < min_u_a || u_prod > max_u_a)
1487 for (l0 = 0; l0 < 2 * m + 2; l0++)
1489 const INT start_index = psi_index_g[j * lprod + l0 * lprod_m1];
1491 if (start_index < my_u0 * n_prod_rest || start_index > (my_o0+1) * n_prod_rest - 1)
1494 for (lrest = 0; lrest < lprod_m1; lrest++)
1496 const INT l = l0 * lprod_m1 + lrest;
1497 g[psi_index_g[j * lprod + l]] += psi[j * lprod + l] * f[j];
1507 k = index_x_binary_search(ar_x, M, min_u_b);
1509 assert(ar_x[2*k] >= min_u_b || k == M-1);
1511 assert(ar_x[2*k-2] < min_u_b);
1516 INT u_prod = ar_x[2*k];
1517 INT j = ar_x[2*k+1];
1519 if (u_prod < min_u_b || u_prod > max_u_b)
1522 for (l0 = 0; l0 < 2 * m + 2; l0++)
1524 const INT start_index = psi_index_g[j * lprod + l0 * lprod_m1];
1526 if (start_index < my_u0 * n_prod_rest || start_index > (my_o0+1) * n_prod_rest - 1)
1528 for (lrest = 0; lrest < lprod_m1; lrest++)
1530 const INT l = l0 * lprod_m1 + lrest;
1531 g[psi_index_g[j * lprod + l]] += psi[j * lprod + l] * f[j];
1544 #pragma omp parallel for default(shared) private(k)
1546 for (k = 0; k < M; k++)
1549 INT j = (flags & NFFT_SORT_NODES) ? index_x[2*k+1] : k;
1551 for (l = 0; l < lprod; l++)
1554 C val = psi[j * lprod + l] * f[j];
1555 C *gref = g + psi_index_g[j * lprod + l];
1556 R *gref_real = (R*) gref;
1559 gref_real[0] += CREAL(val);
1562 gref_real[1] += CIMAG(val);
1564 g[psi_index_g[j * lprod + l]] += psi[j * lprod + l] * f[j];
1578#define MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_A \
1580 assert(ar_x[2*k] >= min_u_a || k == M-1); \
1582 assert(ar_x[2*k-2] < min_u_a); \
1585#define MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_A
1589#define MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_B \
1591 assert(ar_x[2*k] >= min_u_b || k == M-1); \
1593 assert(ar_x[2*k-2] < min_u_b); \
1596#define MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_B
1599#define MACRO_adjoint_nd_B_OMP_COMPUTE_BEFORE_LOOP_with_PRE_PSI
1600#define MACRO_adjoint_nd_B_OMP_COMPUTE_UPDATE_with_PRE_PSI \
1601 MACRO_update_phi_prod_ll_plain(with_PRE_PSI);
1603#define MACRO_adjoint_nd_B_OMP_COMPUTE_BEFORE_LOOP_with_PRE_FG_PSI \
1604 R fg_psi[ths->d][2*ths->m+2]; \
1607 for (t2 = 0; t2 < ths->d; t2++) \
1609 fg_psi[t2][0] = ths->psi[2*(j*ths->d+t2)]; \
1610 tmpEXP1 = ths->psi[2*(j*ths->d+t2)+1]; \
1612 for (l_fg = u[t2]+1, lj_fg = 1; l_fg <= o[t2]; l_fg++, lj_fg++) \
1615 fg_psi[t2][lj_fg] = fg_psi[t2][0]*tmp1*fg_exp_l[t2][lj_fg]; \
1618#define MACRO_adjoint_nd_B_OMP_COMPUTE_UPDATE_with_PRE_FG_PSI \
1619 MACRO_update_phi_prod_ll_plain(with_FG_PSI);
1621#define MACRO_adjoint_nd_B_OMP_COMPUTE_BEFORE_LOOP_with_FG_PSI \
1622 R fg_psi[ths->d][2*ths->m+2]; \
1625 for (t2 = 0; t2 < ths->d; t2++) \
1627 fg_psi[t2][0] = (PHI(ths->n[t2],(ths->x[j*ths->d+t2]-((R)u[t2])/((R)ths->n[t2])),t2)); \
1629 tmpEXP1 = EXP(K(2.0)*((R)ths->n[t2]*ths->x[j*ths->d+t2] - (R)u[t2]) \
1632 for (l_fg = u[t2] + 1, lj_fg = 1; l_fg <= o[t2]; l_fg++, lj_fg++) \
1635 fg_psi[t2][lj_fg] = fg_psi[t2][0]*tmp1*fg_exp_l[t2][lj_fg]; \
1638#define MACRO_adjoint_nd_B_OMP_COMPUTE_UPDATE_with_FG_PSI \
1639 MACRO_update_phi_prod_ll_plain(with_FG_PSI);
1641#define MACRO_adjoint_nd_B_OMP_COMPUTE_BEFORE_LOOP_with_PRE_LIN_PSI \
1643 R fg_psi[ths->d][2*ths->m+2]; \
1647 INT ip_s = ths->K/(ths->m+2); \
1648 for (t2 = 0; t2 < ths->d; t2++) \
1650 y[t2] = ((((R)ths->n[t2])*ths->x[j*ths->d+t2]-(R)u[t2]) \
1651 * ((R)ths->K))/((R)ths->m+2); \
1652 ip_u = LRINT(FLOOR(y[t2])); \
1653 ip_w = y[t2]-ip_u; \
1654 for (l_fg = u[t2], lj_fg = 0; l_fg <= o[t2]; l_fg++, lj_fg++) \
1656 fg_psi[t2][lj_fg] = ths->psi[(ths->K+1)*t2 + ABS(ip_u-lj_fg*ip_s)] \
1657 * (1-ip_w) + ths->psi[(ths->K+1)*t2 + ABS(ip_u-lj_fg*ip_s+1)] \
1661#define MACRO_adjoint_nd_B_OMP_COMPUTE_UPDATE_with_PRE_LIN_PSI \
1662 MACRO_update_phi_prod_ll_plain(with_FG_PSI);
1664#define MACRO_adjoint_nd_B_OMP_COMPUTE_BEFORE_LOOP_without_PRE_PSI \
1665 R psij_const[ths->d * (2*ths->m+2)]; \
1666 for (t2 = 0; t2 < ths->d; t2++) \
1669 for (lj_t = 0; lj_t < 2*ths->m+2; lj_t++) \
1670 psij_const[t2 * (2*ths->m+2) + lj_t] = PHI(ths->n[t2], ths->x[j*ths->d+t2] \
1671 - ((R) (lj_t+u[t2]))/((R)ths->n[t2]), t2); \
1673#define MACRO_adjoint_nd_B_OMP_COMPUTE_UPDATE_without_PRE_PSI \
1674 MACRO_update_phi_prod_ll_plain(without_PRE_PSI_improved);
1676#define MACRO_adjoint_nd_B_OMP_BLOCKWISE_COMPUTE(whichone) \
1678 INT u[ths->d], o[ths->d]; \
1682 INT ll_plain[ths->d+1]; \
1683 R phi_prod[ths->d+1]; \
1685 phi_prod[0] = K(1.0); \
1688 MACRO_init_uo_l_lj_t; \
1690 MACRO_adjoint_nd_B_OMP_COMPUTE_BEFORE_LOOP_ ##whichone \
1694 INT l0, l1, l2, l3; \
1695 for (l0 = 0; l0 < 2*ths->m+2; l0++) \
1699 if (l_all[lj[0]] < my_u0 || l_all[lj[0]] > my_o0) \
1701 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1702 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1703 for (l1 = 0; l1 < 2*ths->m+2; l1++) \
1707 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1708 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1709 for (l2 = 0; l2 < 2*ths->m+2; l2++) \
1713 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1714 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1715 for (l3 = 0; l3 < 2*ths->m+2; l3++) \
1719 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1720 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1722 ths->g[ll_plain[ths->d]] += phi_prod[ths->d] * ths->f[j]; \
1728 else if (ths->d == 5) \
1730 INT l0, l1, l2, l3, l4; \
1731 for (l0 = 0; l0 < 2*ths->m+2; l0++) \
1735 if (l_all[lj[0]] < my_u0 || l_all[lj[0]] > my_o0) \
1737 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1738 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1739 for (l1 = 0; l1 < 2*ths->m+2; l1++) \
1743 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1744 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1745 for (l2 = 0; l2 < 2*ths->m+2; l2++) \
1749 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1750 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1751 for (l3 = 0; l3 < 2*ths->m+2; l3++) \
1755 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1756 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1757 for (l4 = 0; l4 < 2*ths->m+2; l4++) \
1761 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1762 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1764 ths->g[ll_plain[ths->d]] += phi_prod[ths->d] * ths->f[j]; \
1773 while (l_L < lprod) \
1775 if (t == 0 && (l_all[lj[0]] < my_u0 || l_all[lj[0]] > my_o0)) \
1781 MACRO_adjoint_nd_B_OMP_COMPUTE_UPDATE_ ##whichone \
1782 ths->g[ll_plain[ths->d]] += phi_prod[ths->d] * ths->f[j]; \
1783 MACRO_count_uo_l_lj_t; \
1789#define MACRO_adjoint_nd_B_OMP_BLOCKWISE(whichone) \
1791 if (ths->flags & NFFT_OMP_BLOCKWISE_ADJOINT) \
1793 INT lprodrest = 1; \
1794 for (k = 1; k < ths->d; k++) \
1795 lprodrest *= (2*ths->m+2); \
1796 _Pragma("omp parallel private(k)") \
1798 INT my_u0, my_o0, min_u_a, max_u_a, min_u_b, max_u_b; \
1799 INT *ar_x = ths->index_x; \
1801 nfft_adjoint_B_omp_blockwise_init(&my_u0, &my_o0, &min_u_a, &max_u_a, \
1802 &min_u_b, &max_u_b, ths->d, ths->n, ths->m); \
1804 if (min_u_a != -1) \
1806 k = index_x_binary_search(ar_x, ths->M_total, min_u_a); \
1808 MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_A \
1810 while (k < ths->M_total) \
1812 INT u_prod = ar_x[2*k]; \
1813 INT j = ar_x[2*k+1]; \
1815 if (u_prod < min_u_a || u_prod > max_u_a) \
1818 MACRO_adjoint_nd_B_OMP_BLOCKWISE_COMPUTE(whichone) \
1824 if (min_u_b != -1) \
1826 INT k = index_x_binary_search(ar_x, ths->M_total, min_u_b); \
1828 MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_B \
1830 while (k < ths->M_total) \
1832 INT u_prod = ar_x[2*k]; \
1833 INT j = ar_x[2*k+1]; \
1835 if (u_prod < min_u_b || u_prod > max_u_b) \
1838 MACRO_adjoint_nd_B_OMP_BLOCKWISE_COMPUTE(whichone) \
1848#define MACRO_adjoint_nd_B_OMP_COMPUTE(whichone) \
1850 INT u[ths->d], o[ths->d]; \
1853 INT ll_plain[ths->d+1]; \
1854 R phi_prod[ths->d+1]; \
1856 phi_prod[0] = K(1.0); \
1859 MACRO_init_uo_l_lj_t; \
1861 MACRO_adjoint_nd_B_OMP_COMPUTE_BEFORE_LOOP_ ## whichone \
1865 INT l0, l1, l2, l3; \
1866 for (l0 = 0; l0 < 2*ths->m+2; l0++) \
1870 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1871 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1872 for (l1 = 0; l1 < 2*ths->m+2; l1++) \
1876 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1877 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1878 for (l2 = 0; l2 < 2*ths->m+2; l2++) \
1882 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1883 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1884 for (l3 = 0; l3 < 2*ths->m+2; l3++) \
1888 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1889 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1891 C *lhs = ths->g + ll_plain[ths->d]; \
1892 R *lhs_real = (R*)lhs; \
1893 C val = phi_prod[ths->d] * ths->f[j]; \
1895 _Pragma("omp atomic") \
1896 lhs_real[0] += CREAL(val); \
1898 _Pragma("omp atomic") \
1899 lhs_real[1] += CIMAG(val); \
1905 else if (ths->d == 5) \
1907 INT l0, l1, l2, l3, l4; \
1908 for (l0 = 0; l0 < 2*ths->m+2; l0++) \
1912 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1913 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1914 for (l1 = 0; l1 < 2*ths->m+2; l1++) \
1918 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1919 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1920 for (l2 = 0; l2 < 2*ths->m+2; l2++) \
1924 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1925 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1926 for (l3 = 0; l3 < 2*ths->m+2; l3++) \
1930 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1931 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1932 for (l4 = 0; l4 < 2*ths->m+2; l4++) \
1936 phi_prod[t2+1] = phi_prod[t2] * MACRO_COMPUTE_ ## whichone; \
1937 ll_plain[t2+1] = ll_plain[t2] * ths->n[t2] + l_all[t2*(2*ths->m+2) + lj[t2]]; \
1939 C *lhs = ths->g + ll_plain[ths->d]; \
1940 R *lhs_real = (R*)lhs; \
1941 C val = phi_prod[ths->d] * ths->f[j]; \
1943 _Pragma("omp atomic") \
1944 lhs_real[0] += CREAL(val); \
1946 _Pragma("omp atomic") \
1947 lhs_real[1] += CIMAG(val); \
1955 for (l_L = 0; l_L < lprod; l_L++) \
1961 MACRO_adjoint_nd_B_OMP_COMPUTE_UPDATE_ ## whichone \
1963 lhs = ths->g + ll_plain[ths->d]; \
1964 lhs_real = (R*)lhs; \
1965 val = phi_prod[ths->d] * ths->f[j]; \
1967 _Pragma("omp atomic") \
1968 lhs_real[0] += CREAL(val); \
1970 _Pragma("omp atomic") \
1971 lhs_real[1] += CIMAG(val); \
1973 MACRO_count_uo_l_lj_t; \
1978static inline void B_openmp_T(X(plan) *ths)
1983 memset(ths->g, 0, (
size_t)(ths->n_total) *
sizeof(C));
1985 for (k = 0, lprod = 1; k < ths->d; k++)
1986 lprod *= (2*ths->m+2);
1990 nfft_adjoint_B_compute_full_psi(ths->g, ths->psi_index_g, ths->psi, ths->f,
1991 ths->M_total, ths->d, ths->n, ths->m, ths->flags, ths->index_x);
1997 MACRO_adjoint_nd_B_OMP_BLOCKWISE(with_PRE_PSI);
1999 #pragma omp parallel for default(shared) private(k)
2000 for (k = 0; k < ths->M_total; k++)
2003 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2004 MACRO_adjoint_nd_B_OMP_COMPUTE(with_PRE_PSI);
2012 R fg_exp_l[ths->d][2*ths->m+2+1];
2013 for(t2 = 0; t2 < ths->d; t2++)
2016 R tmpEXP2 = EXP(K(-1.0)/ths->b[t2]);
2017 R tmpEXP2sq = tmpEXP2*tmpEXP2;
2020 fg_exp_l[t2][0] = K(1.0);
2021 for(lj_fg = 1; lj_fg <= (2*ths->m+2); lj_fg++)
2023 tmp3 = tmp2*tmpEXP2;
2025 fg_exp_l[t2][lj_fg] = fg_exp_l[t2][lj_fg-1]*tmp3;
2029 MACRO_adjoint_nd_B_OMP_BLOCKWISE(with_PRE_FG_PSI);
2031 #pragma omp parallel for default(shared) private(k,t,t2)
2032 for (k = 0; k < ths->M_total; k++)
2034 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2035 MACRO_adjoint_nd_B_OMP_COMPUTE(with_PRE_FG_PSI);
2043 R fg_exp_l[ths->d][2*ths->m+2+1];
2047 for (t2 = 0; t2 < ths->d; t2++)
2050 R tmpEXP2 = EXP(K(-1.0)/ths->b[t2]);
2051 R tmpEXP2sq = tmpEXP2*tmpEXP2;
2054 fg_exp_l[t2][0] = K(1.0);
2055 for (lj_fg = 1; lj_fg <= (2*ths->m+2); lj_fg++)
2057 tmp3 = tmp2*tmpEXP2;
2059 fg_exp_l[t2][lj_fg] = fg_exp_l[t2][lj_fg-1]*tmp3;
2063 MACRO_adjoint_nd_B_OMP_BLOCKWISE(with_FG_PSI);
2065 #pragma omp parallel for default(shared) private(k,t,t2)
2066 for (k = 0; k < ths->M_total; k++)
2068 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2069 MACRO_adjoint_nd_B_OMP_COMPUTE(with_FG_PSI);
2078 MACRO_adjoint_nd_B_OMP_BLOCKWISE(with_PRE_LIN_PSI);
2080 #pragma omp parallel for default(shared) private(k)
2081 for (k = 0; k<ths->M_total; k++)
2084 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2085 MACRO_adjoint_nd_B_OMP_COMPUTE(with_PRE_LIN_PSI);
2093 MACRO_adjoint_nd_B_OMP_BLOCKWISE(without_PRE_PSI);
2095 #pragma omp parallel for default(shared) private(k)
2096 for (k = 0; k < ths->M_total; k++)
2099 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2100 MACRO_adjoint_nd_B_OMP_COMPUTE(without_PRE_PSI);
2105static void B_T(X(plan) *ths)
2116static void nfft_1d_init_fg_exp_l(R *fg_exp_l,
const INT m,
const R b)
2118 const INT tmp2 = 2*m+2;
2120 R fg_exp_b0, fg_exp_b1, fg_exp_b2, fg_exp_b0_sq;
2122 fg_exp_b0 = EXP(K(-1.0)/b);
2123 fg_exp_b0_sq = fg_exp_b0*fg_exp_b0;
2124 fg_exp_b1 = fg_exp_b2 =fg_exp_l[0] = K(1.0);
2126 for (l = 1; l < tmp2; l++)
2128 fg_exp_b2 = fg_exp_b1*fg_exp_b0;
2129 fg_exp_b1 *= fg_exp_b0_sq;
2130 fg_exp_l[l] = fg_exp_l[l-1]*fg_exp_b2;
2135static void nfft_trafo_1d_compute(C *fj,
const C *g,
const R *psij_const,
2136 const R *xj,
const INT n,
const INT m)
2143 uo2(&u, &o, *xj, n, m);
2147 for (l = 1, gj = g + u, (*fj) = (*psij++) * (*gj++); l <= 2*m+1; l++)
2148 (*fj) += (*psij++) * (*gj++);
2152 for (l = 1, gj = g + u, (*fj) = (*psij++) * (*gj++); l < 2*m+1 - o; l++)
2153 (*fj) += (*psij++) * (*gj++);
2154 for (l = 0, gj = g; l <= o; l++)
2155 (*fj) += (*psij++) * (*gj++);
2160static void nfft_adjoint_1d_compute_serial(
const C *fj, C *g,
2161 const R *psij_const,
const R *xj,
const INT n,
const INT m)
2168 uo2(&u,&o,*xj, n, m);
2172 for (l = 0, gj = g+u; l <= 2*m+1; l++)
2173 (*gj++) += (*psij++) * (*fj);
2177 for (l = 0, gj = g+u; l < 2*m+1-o; l++)
2178 (*gj++) += (*psij++) * (*fj);
2179 for (l = 0, gj = g; l <= o; l++)
2180 (*gj++) += (*psij++) * (*fj);
2187static void nfft_adjoint_1d_compute_omp_atomic(
const C f, C *g,
2188 const R *psij_const,
const R *xj,
const INT n,
const INT m)
2192 INT index_temp[2*m+2];
2194 uo2(&u,&o,*xj, n, m);
2196 for (l=0; l<=2*m+1; l++)
2197 index_temp[l] = (l+u)%n;
2199 for (l = 0, gj = g+u; l <= 2*m+1; l++)
2201 INT i = index_temp[l];
2203 R *lhs_real = (R*)lhs;
2204 C val = psij_const[l] * f;
2206 lhs_real[0] += CREAL(val);
2209 lhs_real[1] += CIMAG(val);
2230static void nfft_adjoint_1d_compute_omp_blockwise(
const C f, C *g,
2231 const R *psij_const,
const R *xj,
const INT n,
const INT m,
2232 const INT my_u0,
const INT my_o0)
2236 uo2(&ar_u,&ar_o,*xj, n, m);
2240 INT u = MAX(my_u0,ar_u);
2241 INT o = MIN(my_o0,ar_o);
2242 INT offset_psij = u-ar_u;
2244 assert(offset_psij >= 0);
2245 assert(o-u <= 2*m+1);
2246 assert(offset_psij+o-u <= 2*m+1);
2249 for (l = 0; l <= o-u; l++)
2250 g[u+l] += psij_const[offset_psij+l] * f;
2254 INT u = MAX(my_u0,ar_u);
2256 INT offset_psij = u-ar_u;
2258 assert(offset_psij >= 0);
2259 assert(o-u <= 2*m+1);
2260 assert(offset_psij+o-u <= 2*m+1);
2263 for (l = 0; l <= o-u; l++)
2264 g[u+l] += psij_const[offset_psij+l] * f;
2267 o = MIN(my_o0,ar_o);
2268 offset_psij += my_u0-ar_u+n;
2273 assert(o-u <= 2*m+1);
2274 if (offset_psij+o-u > 2*m+1)
2276 fprintf(stderr,
"ERR: %d %d %d %d %d %d %d\n", ar_u, ar_o, my_u0, my_o0, u, o, offset_psij);
2278 assert(offset_psij+o-u <= 2*m+1);
2281 for (l = 0; l <= o-u; l++)
2282 g[u+l] += psij_const[offset_psij+l] * f;
2290static void nfft_trafo_1d_B(X(plan) *ths)
2292 const INT n = ths->n[0], M = ths->M_total, m = ths->m, m2p2 = 2*m+2;
2293 const C *g = (C*)ths->g;
2299 #pragma omp parallel for default(shared) private(k)
2301 for (k = 0; k < M; k++)
2304 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2306 for (l = 0; l < m2p2; l++)
2307 ths->f[j] += ths->psi[j*m2p2+l] * g[ths->psi_index_g[j*m2p2+l]];
2316 #pragma omp parallel for default(shared) private(k)
2318 for (k = 0; k < M; k++)
2320 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2321 nfft_trafo_1d_compute(&ths->f[j], g, ths->psi + j * (2 * m + 2),
2329 R *fg_exp_l = (R*)Y(malloc)((size_t)(m2p2+1) *
sizeof(R));
2331 nfft_1d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
2334 #pragma omp parallel default(shared)
2338 R *psij_const = (R*)Y(malloc)((size_t)(m2p2) *
sizeof(R));
2342 for (k = 0; k < M; k++)
2344 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2345 const R fg_psij0 = ths->psi[2 * j], fg_psij1 = ths->psi[2 * j + 1];
2346 R fg_psij2 = K(1.0);
2349 psij_const[0] = fg_psij0;
2351 for (l = 1; l < m2p2; l++)
2353 fg_psij2 *= fg_psij1;
2354 psij_const[l] = fg_psij0 * fg_psij2 * fg_exp_l[l];
2357 nfft_trafo_1d_compute(&ths->f[j], g, psij_const, &ths->x[j], n, m);
2359 Y(free)(psij_const);
2368 R *fg_exp_l = (R*)Y(malloc)((size_t)(m2p2+1) *
sizeof(R));
2372 nfft_1d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
2375 #pragma omp parallel default(shared)
2379 R *psij_const = (R*)Y(malloc)((size_t)(m2p2) *
sizeof(R));
2383 for (k = 0; k < M; k++)
2385 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2387 R fg_psij0, fg_psij1, fg_psij2;
2389 uo(ths, (INT)j, &u, &o, (INT)0);
2390 fg_psij0 = (PHI(ths->n[0], ths->x[j] - ((R)(u))/(R)(n), 0));
2391 fg_psij1 = EXP(K(2.0) * ((R)(n) * ths->x[j] - (R)(u)) / ths->b[0]);
2394 psij_const[0] = fg_psij0;
2396 for (l = 1; l < m2p2; l++)
2398 fg_psij2 *= fg_psij1;
2399 psij_const[l] = fg_psij0 * fg_psij2 * fg_exp_l[l];
2402 nfft_trafo_1d_compute(&ths->f[j], g, psij_const, &ths->x[j], n, m);
2404 Y(free)(psij_const);
2413 const INT K = ths->K, ip_s = K / (m + 2);
2418 #pragma omp parallel default(shared)
2422 R *psij_const = (R*)Y(malloc)((size_t)(m2p2) *
sizeof(R));
2426 for (k = 0; k < M; k++)
2431 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2433 uo(ths, (INT)j, &u, &o, (INT)0);
2435 ip_y = FABS((R)(n) * ths->x[j] - (R)(u)) * ((R)ip_s);
2436 ip_u = (INT)(LRINT(FLOOR(ip_y)));
2437 ip_w = ip_y - (R)(ip_u);
2439 for (l = 0; l < m2p2; l++)
2440 psij_const[l] = ths->psi[ABS(ip_u-l*ip_s)] * (K(1.0) - ip_w)
2441 + ths->psi[ABS(ip_u-l*ip_s+1)] * (ip_w);
2443 nfft_trafo_1d_compute(&ths->f[j], g, psij_const, &ths->x[j], n, m);
2445 Y(free)(psij_const);
2456 #pragma omp parallel default(shared)
2460 R *psij_const = (R*)Y(malloc)((size_t)(m2p2) *
sizeof(R));
2464 for (k = 0; k < M; k++)
2467 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2469 uo(ths, (INT)j, &u, &o, (INT)0);
2471 for (l = 0; l < m2p2; l++)
2472 psij_const[l] = (PHI(ths->n[0], ths->x[j] - ((R)((u+l))) / (R)(n), 0));
2474 nfft_trafo_1d_compute(&ths->f[j], g, psij_const, &ths->x[j], n, m);
2476 Y(free)(psij_const);
2482#define MACRO_adjoint_1d_B_OMP_BLOCKWISE_COMPUTE_PRE_PSI \
2484 nfft_adjoint_1d_compute_omp_blockwise(ths->f[j], g, \
2485 ths->psi + j * (2 * m + 2), ths->x + j, n, m, my_u0, my_o0); \
2488#define MACRO_adjoint_1d_B_OMP_BLOCKWISE_COMPUTE_PRE_FG_PSI \
2490 R psij_const[2 * m + 2]; \
2492 R fg_psij0 = ths->psi[2 * j]; \
2493 R fg_psij1 = ths->psi[2 * j + 1]; \
2494 R fg_psij2 = K(1.0); \
2496 psij_const[0] = fg_psij0; \
2497 for (l = 1; l <= 2 * m + 1; l++) \
2499 fg_psij2 *= fg_psij1; \
2500 psij_const[l] = fg_psij0 * fg_psij2 * fg_exp_l[l]; \
2503 nfft_adjoint_1d_compute_omp_blockwise(ths->f[j], g, psij_const, \
2504 ths->x + j, n, m, my_u0, my_o0); \
2507#define MACRO_adjoint_1d_B_OMP_BLOCKWISE_COMPUTE_FG_PSI \
2509 R psij_const[2 * m + 2]; \
2510 R fg_psij0, fg_psij1, fg_psij2; \
2513 uo(ths, j, &u, &o, (INT)0); \
2514 fg_psij0 = (PHI(ths->n[0],ths->x[j]-((R)u)/((R)n),0)); \
2515 fg_psij1 = EXP(K(2.0) * (((R)n) * (ths->x[j]) - (R)u) / ths->b[0]); \
2516 fg_psij2 = K(1.0); \
2517 psij_const[0] = fg_psij0; \
2518 for (l = 1; l <= 2 * m + 1; l++) \
2520 fg_psij2 *= fg_psij1; \
2521 psij_const[l] = fg_psij0 * fg_psij2 * fg_exp_l[l]; \
2524 nfft_adjoint_1d_compute_omp_blockwise(ths->f[j], g, psij_const, \
2525 ths->x + j, n, m, my_u0, my_o0); \
2528#define MACRO_adjoint_1d_B_OMP_BLOCKWISE_COMPUTE_PRE_LIN_PSI \
2530 R psij_const[2 * m + 2]; \
2535 uo(ths, j, &u, &o, (INT)0); \
2537 ip_y = FABS(((R)n) * ths->x[j] - (R)u) * ((R)ip_s); \
2538 ip_u = LRINT(FLOOR(ip_y)); \
2539 ip_w = ip_y - ip_u; \
2540 for (l = 0; l < 2 * m + 2; l++) \
2542 = ths->psi[ABS(ip_u-l*ip_s)] * (K(1.0) - ip_w) \
2543 + ths->psi[ABS(ip_u-l*ip_s+1)] * (ip_w); \
2545 nfft_adjoint_1d_compute_omp_blockwise(ths->f[j], g, psij_const, \
2546 ths->x + j, n, m, my_u0, my_o0); \
2549#define MACRO_adjoint_1d_B_OMP_BLOCKWISE_COMPUTE_NO_PSI \
2551 R psij_const[2 * m + 2]; \
2554 uo(ths, j, &u, &o, (INT)0); \
2556 for (l = 0; l <= 2 * m + 1; l++) \
2557 psij_const[l] = (PHI(ths->n[0],ths->x[j]-((R)((u+l)))/((R)n),0)); \
2559 nfft_adjoint_1d_compute_omp_blockwise(ths->f[j], g, psij_const, \
2560 ths->x + j, n, m, my_u0, my_o0); \
2563#define MACRO_adjoint_1d_B_OMP_BLOCKWISE(whichone) \
2565 if (ths->flags & NFFT_OMP_BLOCKWISE_ADJOINT) \
2567 _Pragma("omp parallel private(k)") \
2569 INT my_u0, my_o0, min_u_a, max_u_a, min_u_b, max_u_b; \
2570 INT *ar_x = ths->index_x; \
2572 nfft_adjoint_B_omp_blockwise_init(&my_u0, &my_o0, &min_u_a, &max_u_a, \
2573 &min_u_b, &max_u_b, 1, &n, m); \
2575 if (min_u_a != -1) \
2577 k = index_x_binary_search(ar_x, M, min_u_a); \
2579 MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_A \
2583 INT u_prod = ar_x[2*k]; \
2584 INT j = ar_x[2*k+1]; \
2586 if (u_prod < min_u_a || u_prod > max_u_a) \
2589 MACRO_adjoint_1d_B_OMP_BLOCKWISE_COMPUTE_ ##whichone \
2595 if (min_u_b != -1) \
2597 k = index_x_binary_search(ar_x, M, min_u_b); \
2599 MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_B \
2603 INT u_prod = ar_x[2*k]; \
2604 INT j = ar_x[2*k+1]; \
2606 if (u_prod < min_u_b || u_prod > max_u_b) \
2609 MACRO_adjoint_1d_B_OMP_BLOCKWISE_COMPUTE_ ##whichone \
2619static void nfft_adjoint_1d_B(X(plan) *ths)
2621 const INT n = ths->n[0], M = ths->M_total, m = ths->m;
2625 memset(g, 0, (
size_t)(ths->n_total) *
sizeof(C));
2629 nfft_adjoint_B_compute_full_psi(g, ths->psi_index_g, ths->psi, ths->f, M,
2630 (INT)1, ths->n, m, ths->flags, ths->index_x);
2637 MACRO_adjoint_1d_B_OMP_BLOCKWISE(
PRE_PSI)
2641 #pragma omp parallel for default(shared) private(k)
2643 for (k = 0; k < M; k++)
2645 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2647 nfft_adjoint_1d_compute_omp_atomic(ths->f[j], g, ths->psi + j * (2 * m + 2), ths->x + j, n, m);
2649 nfft_adjoint_1d_compute_serial(ths->f + j, g, ths->psi + j * (2 * m + 2), ths->x + j, n, m);
2658 R fg_exp_l[2 * m + 2 + 1];
2660 nfft_1d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
2668 #pragma omp parallel for default(shared) private(k)
2670 for (k = 0; k < M; k++)
2672 R psij_const[2 * m + 2];
2673 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2675 R fg_psij0 = ths->psi[2 * j];
2676 R fg_psij1 = ths->psi[2 * j + 1];
2677 R fg_psij2 = K(1.0);
2679 psij_const[0] = fg_psij0;
2680 for (l = 1; l <= 2 * m + 1; l++)
2682 fg_psij2 *= fg_psij1;
2683 psij_const[l] = fg_psij0 * fg_psij2 * fg_exp_l[l];
2687 nfft_adjoint_1d_compute_omp_atomic(ths->f[j], g, psij_const, ths->x + j, n, m);
2689 nfft_adjoint_1d_compute_serial(ths->f + j, g, psij_const, ths->x + j, n, m);
2698 R fg_exp_l[2 * m + 2 + 1];
2700 nfft_1d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
2705 MACRO_adjoint_1d_B_OMP_BLOCKWISE(
FG_PSI)
2709 #pragma omp parallel for default(shared) private(k)
2711 for (k = 0; k < M; k++)
2714 R psij_const[2 * m + 2];
2715 R fg_psij0, fg_psij1, fg_psij2;
2716 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2718 uo(ths, j, &u, &o, (INT)0);
2719 fg_psij0 = (PHI(ths->n[0], ths->x[j] - ((R)u) / (R)(n),0));
2720 fg_psij1 = EXP(K(2.0) * ((R)(n) * (ths->x[j]) - (R)(u)) / ths->b[0]);
2722 psij_const[0] = fg_psij0;
2723 for (l = 1; l <= 2 * m + 1; l++)
2725 fg_psij2 *= fg_psij1;
2726 psij_const[l] = fg_psij0 * fg_psij2 * fg_exp_l[l];
2730 nfft_adjoint_1d_compute_omp_atomic(ths->f[j], g, psij_const, ths->x + j, n, m);
2732 nfft_adjoint_1d_compute_serial(ths->f + j, g, psij_const, ths->x + j, n, m);
2741 const INT K = ths->K;
2742 const INT ip_s = K / (m + 2);
2751 #pragma omp parallel for default(shared) private(k)
2753 for (k = 0; k < M; k++)
2758 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2759 R psij_const[2 * m + 2];
2761 uo(ths, j, &u, &o, (INT)0);
2763 ip_y = FABS((R)(n) * ths->x[j] - (R)(u)) * ((R)ip_s);
2764 ip_u = (INT)(LRINT(FLOOR(ip_y)));
2765 ip_w = ip_y - (R)(ip_u);
2766 for (l = 0; l < 2 * m + 2; l++)
2768 = ths->psi[ABS(ip_u-l*ip_s)] * (K(1.0) - ip_w)
2769 + ths->psi[ABS(ip_u-l*ip_s+1)] * (ip_w);
2772 nfft_adjoint_1d_compute_omp_atomic(ths->f[j], g, psij_const, ths->x + j, n, m);
2774 nfft_adjoint_1d_compute_serial(ths->f + j, g, psij_const, ths->x + j, n, m);
2784 MACRO_adjoint_1d_B_OMP_BLOCKWISE(NO_PSI)
2788 #pragma omp parallel for default(shared) private(k)
2790 for (k = 0; k < M; k++)
2793 R psij_const[2 * m + 2];
2794 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
2796 uo(ths, j, &u, &o, (INT)0);
2798 for (l = 0; l <= 2 * m + 1; l++)
2799 psij_const[l] = (PHI(ths->n[0], ths->x[j] - ((R)((u+l))) / (R)(n),0));
2802 nfft_adjoint_1d_compute_omp_atomic(ths->f[j], g, psij_const, ths->x + j, n, m);
2804 nfft_adjoint_1d_compute_serial(ths->f + j, g, psij_const, ths->x + j, n, m);
2809void X(trafo_1d)(X(plan) *ths)
2811 if((ths->N[0] <= ths->m) || (ths->n[0] <= 2*ths->m+2))
2813 X(trafo_direct)(ths);
2817 const INT N = ths->N[0], N2 = N/2, n = ths->n[0];
2818 C *f_hat1 = (C*)ths->f_hat, *f_hat2 = (C*)&ths->f_hat[N2];
2820 ths->g_hat = ths->g1;
2824 C *g_hat1 = (C*)&ths->g_hat[n-N/2], *g_hat2 = (C*)ths->g_hat;
2825 R *c_phi_inv1, *c_phi_inv2;
2831 #pragma omp parallel for default(shared) private(k)
2832 for (k = 0; k < ths->n_total; k++)
2833 ths->g_hat[k] = 0.0;
2836 memset(ths->g_hat, 0, (
size_t)(ths->n_total) *
sizeof(C));
2841 c_phi_inv1 = ths->c_phi_inv[0];
2842 c_phi_inv2 = &ths->c_phi_inv[0][N2];
2845 #pragma omp parallel for default(shared) private(k)
2847 for (k = 0; k < N2; k++)
2849 g_hat1[k] = f_hat1[k] * c_phi_inv1[k];
2850 g_hat2[k] = f_hat2[k] * c_phi_inv2[k];
2857 #pragma omp parallel for default(shared) private(k)
2859 for (k = 0; k < N2; k++)
2861 g_hat1[k] = f_hat1[k] / (PHI_HUT(ths->n[0],k-N2,0));
2862 g_hat2[k] = f_hat2[k] / (PHI_HUT(ths->n[0],k,0));
2868 FFTW(execute)(ths->my_fftw_plan1);
2872 nfft_trafo_1d_B(ths);
2877void X(adjoint_1d)(X(plan) *ths)
2879 if((ths->N[0] <= ths->m) || (ths->n[0] <= 2*ths->m+2))
2881 X(adjoint_direct)(ths);
2886 C *g_hat1,*g_hat2,*f_hat1,*f_hat2;
2887 R *c_phi_inv1, *c_phi_inv2;
2895 f_hat1=(C*)ths->f_hat;
2896 f_hat2=(C*)&ths->f_hat[N/2];
2897 g_hat1=(C*)&ths->g_hat[n-N/2];
2898 g_hat2=(C*)ths->g_hat;
2901 nfft_adjoint_1d_B(ths);
2905 FFTW(execute)(ths->my_fftw_plan2);
2912 c_phi_inv1=ths->c_phi_inv[0];
2913 c_phi_inv2=&ths->c_phi_inv[0][N/2];
2916 #pragma omp parallel for default(shared) private(k)
2918 for (k = 0; k < N/2; k++)
2920 f_hat1[k] = g_hat1[k] * c_phi_inv1[k];
2921 f_hat2[k] = g_hat2[k] * c_phi_inv2[k];
2929 #pragma omp parallel for default(shared) private(k)
2931 for (k = 0; k < N/2; k++)
2933 f_hat1[k] = g_hat1[k] / (PHI_HUT(ths->n[0],k-N/2,0));
2934 f_hat2[k] = g_hat2[k] / (PHI_HUT(ths->n[0],k,0));
2943static void nfft_2d_init_fg_exp_l(R *fg_exp_l,
const INT m,
const R b)
2946 R fg_exp_b0, fg_exp_b1, fg_exp_b2, fg_exp_b0_sq;
2948 fg_exp_b0 = EXP(K(-1.0)/b);
2949 fg_exp_b0_sq = fg_exp_b0*fg_exp_b0;
2952 fg_exp_l[0] = K(1.0);
2953 for(l=1; l <= 2*m+1; l++)
2955 fg_exp_b2 = fg_exp_b1*fg_exp_b0;
2956 fg_exp_b1 *= fg_exp_b0_sq;
2957 fg_exp_l[l] = fg_exp_l[l-1]*fg_exp_b2;
2961static void nfft_trafo_2d_compute(C *fj,
const C *g,
const R *psij_const0,
2962 const R *psij_const1,
const R *xj0,
const R *xj1,
const INT n0,
2963 const INT n1,
const INT m)
2965 INT u0,o0,l0,u1,o1,l1;
2967 const R *psij0,*psij1;
2972 uo2(&u0,&o0,*xj0, n0, m);
2973 uo2(&u1,&o1,*xj1, n1, m);
2979 for(l0=0; l0<=2*m+1; l0++,psij0++)
2983 for(l1=0; l1<=2*m+1; l1++)
2984 (*fj) += (*psij0) * (*psij1++) * (*gj++);
2987 for(l0=0; l0<=2*m+1; l0++,psij0++)
2991 for(l1=0; l1<2*m+1-o1; l1++)
2992 (*fj) += (*psij0) * (*psij1++) * (*gj++);
2994 for(l1=0; l1<=o1; l1++)
2995 (*fj) += (*psij0) * (*psij1++) * (*gj++);
3000 for(l0=0; l0<2*m+1-o0; l0++,psij0++)
3004 for(l1=0; l1<=2*m+1; l1++)
3005 (*fj) += (*psij0) * (*psij1++) * (*gj++);
3007 for(l0=0; l0<=o0; l0++,psij0++)
3011 for(l1=0; l1<=2*m+1; l1++)
3012 (*fj) += (*psij0) * (*psij1++) * (*gj++);
3017 for(l0=0; l0<2*m+1-o0; l0++,psij0++)
3021 for(l1=0; l1<2*m+1-o1; l1++)
3022 (*fj) += (*psij0) * (*psij1++) * (*gj++);
3024 for(l1=0; l1<=o1; l1++)
3025 (*fj) += (*psij0) * (*psij1++) * (*gj++);
3027 for(l0=0; l0<=o0; l0++,psij0++)
3031 for(l1=0; l1<2*m+1-o1; l1++)
3032 (*fj) += (*psij0) * (*psij1++) * (*gj++);
3034 for(l1=0; l1<=o1; l1++)
3035 (*fj) += (*psij0) * (*psij1++) * (*gj++);
3042static void nfft_adjoint_2d_compute_omp_atomic(
const C f, C *g,
3043 const R *psij_const0,
const R *psij_const1,
const R *xj0,
3044 const R *xj1,
const INT n0,
const INT n1,
const INT m)
3046 INT u0,o0,l0,u1,o1,l1;
3048 INT index_temp0[2*m+2];
3049 INT index_temp1[2*m+2];
3051 uo2(&u0,&o0,*xj0, n0, m);
3052 uo2(&u1,&o1,*xj1, n1, m);
3054 for (l0=0; l0<=2*m+1; l0++)
3055 index_temp0[l0] = (u0+l0)%n0;
3057 for (l1=0; l1<=2*m+1; l1++)
3058 index_temp1[l1] = (u1+l1)%n1;
3060 for(l0=0; l0<=2*m+1; l0++)
3062 for(l1=0; l1<=2*m+1; l1++)
3064 INT i = index_temp0[l0] * n1 + index_temp1[l1];
3066 R *lhs_real = (R*)lhs;
3067 C val = psij_const0[l0] * psij_const1[l1] * f;
3070 lhs_real[0] += CREAL(val);
3073 lhs_real[1] += CIMAG(val);
3098static void nfft_adjoint_2d_compute_omp_blockwise(
const C f, C *g,
3099 const R *psij_const0,
const R *psij_const1,
const R *xj0,
3100 const R *xj1,
const INT n0,
const INT n1,
const INT m,
3101 const INT my_u0,
const INT my_o0)
3103 INT ar_u0,ar_o0,l0,u1,o1,l1;
3104 INT index_temp1[2*m+2];
3106 uo2(&ar_u0,&ar_o0,*xj0, n0, m);
3107 uo2(&u1,&o1,*xj1, n1, m);
3109 for (l1 = 0; l1 <= 2*m+1; l1++)
3110 index_temp1[l1] = (u1+l1)%n1;
3114 INT u0 = MAX(my_u0,ar_u0);
3115 INT o0 = MIN(my_o0,ar_o0);
3116 INT offset_psij = u0-ar_u0;
3118 assert(offset_psij >= 0);
3119 assert(o0-u0 <= 2*m+1);
3120 assert(offset_psij+o0-u0 <= 2*m+1);
3123 for (l0 = 0; l0 <= o0-u0; l0++)
3125 INT i0 = (u0+l0) * n1;
3126 const C val0 = psij_const0[offset_psij+l0];
3128 for(l1=0; l1<=2*m+1; l1++)
3129 g[i0 + index_temp1[l1]] += val0 * psij_const1[l1] * f;
3134 INT u0 = MAX(my_u0,ar_u0);
3136 INT offset_psij = u0-ar_u0;
3138 assert(offset_psij >= 0);
3139 assert(o0-u0 <= 2*m+1);
3140 assert(offset_psij+o0-u0 <= 2*m+1);
3143 for (l0 = 0; l0 <= o0-u0; l0++)
3145 INT i0 = (u0+l0) * n1;
3146 const C val0 = psij_const0[offset_psij+l0];
3148 for(l1=0; l1<=2*m+1; l1++)
3149 g[i0 + index_temp1[l1]] += val0 * psij_const1[l1] * f;
3153 o0 = MIN(my_o0,ar_o0);
3154 offset_psij += my_u0-ar_u0+n0;
3159 assert(o0-u0 <= 2*m+1);
3160 assert(offset_psij+o0-u0 <= 2*m+1);
3164 for (l0 = 0; l0 <= o0-u0; l0++)
3166 INT i0 = (u0+l0) * n1;
3167 const C val0 = psij_const0[offset_psij+l0];
3169 for(l1=0; l1<=2*m+1; l1++)
3170 g[i0 + index_temp1[l1]] += val0 * psij_const1[l1] * f;
3177static void nfft_adjoint_2d_compute_serial(
const C *fj, C *g,
3178 const R *psij_const0,
const R *psij_const1,
const R *xj0,
3179 const R *xj1,
const INT n0,
const INT n1,
const INT m)
3181 INT u0,o0,l0,u1,o1,l1;
3183 const R *psij0,*psij1;
3188 uo2(&u0,&o0,*xj0, n0, m);
3189 uo2(&u1,&o1,*xj1, n1, m);
3193 for(l0=0; l0<=2*m+1; l0++,psij0++)
3197 for(l1=0; l1<=2*m+1; l1++)
3198 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3201 for(l0=0; l0<=2*m+1; l0++,psij0++)
3205 for(l1=0; l1<2*m+1-o1; l1++)
3206 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3208 for(l1=0; l1<=o1; l1++)
3209 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3214 for(l0=0; l0<2*m+1-o0; l0++,psij0++)
3218 for(l1=0; l1<=2*m+1; l1++)
3219 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3221 for(l0=0; l0<=o0; l0++,psij0++)
3225 for(l1=0; l1<=2*m+1; l1++)
3226 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3231 for(l0=0; l0<2*m+1-o0; l0++,psij0++)
3235 for(l1=0; l1<2*m+1-o1; l1++)
3236 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3238 for(l1=0; l1<=o1; l1++)
3239 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3241 for(l0=0; l0<=o0; l0++,psij0++)
3245 for(l1=0; l1<2*m+1-o1; l1++)
3246 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3248 for(l1=0; l1<=o1; l1++)
3249 (*gj++) += (*psij0) * (*psij1++) * (*fj);
3255static void nfft_trafo_2d_B(X(plan) *ths)
3257 const C *g = (C*)ths->g;
3258 const INT n0 = ths->n[0];
3259 const INT n1 = ths->n[1];
3260 const INT M = ths->M_total;
3261 const INT m = ths->m;
3267 const INT lprod = (2*m+2) * (2*m+2);
3269 #pragma omp parallel for default(shared) private(k)
3271 for (k = 0; k < M; k++)
3274 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3276 for (l = 0; l < lprod; l++)
3277 ths->f[j] += ths->psi[j*lprod+l] * g[ths->psi_index_g[j*lprod+l]];
3285 #pragma omp parallel for default(shared) private(k)
3287 for (k = 0; k < M; k++)
3289 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3290 nfft_trafo_2d_compute(ths->f+j, g, ths->psi+j*2*(2*m+2), ths->psi+(j*2+1)*(2*m+2), ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3298 R fg_exp_l[2*(2*m+2+1)];
3300 nfft_2d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
3301 nfft_2d_init_fg_exp_l(fg_exp_l+2*m+2, m, ths->b[1]);
3304 #pragma omp parallel for default(shared) private(k)
3306 for (k = 0; k < M; k++)
3308 R psij_const[2*(2*m+2)];
3309 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3311 R fg_psij0 = ths->psi[2*j*2];
3312 R fg_psij1 = ths->psi[2*j*2+1];
3313 R fg_psij2 = K(1.0);
3315 psij_const[0] = fg_psij0;
3316 for (l = 1; l <= 2*m+1; l++)
3318 fg_psij2 *= fg_psij1;
3319 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l];
3322 fg_psij0 = ths->psi[2*(j*2+1)];
3323 fg_psij1 = ths->psi[2*(j*2+1)+1];
3325 psij_const[2*m+2] = fg_psij0;
3326 for (l = 1; l <= 2*m+1; l++)
3328 fg_psij2 *= fg_psij1;
3329 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l];
3332 nfft_trafo_2d_compute(ths->f+j, g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3340 R fg_exp_l[2*(2*m+2+1)];
3342 nfft_2d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
3343 nfft_2d_init_fg_exp_l(fg_exp_l+2*m+2, m, ths->b[1]);
3348 #pragma omp parallel for default(shared) private(k)
3350 for (k = 0; k < M; k++)
3353 R fg_psij0, fg_psij1, fg_psij2;
3354 R psij_const[2*(2*m+2)];
3355 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3357 uo(ths, j, &u, &o, (INT)0);
3358 fg_psij0 = (PHI(ths->n[0], ths->x[2*j] - ((R)u) / (R)(n0),0));
3359 fg_psij1 = EXP(K(2.0) * ((R)(n0) * (ths->x[2*j]) - (R)(u)) / ths->b[0]);
3361 psij_const[0] = fg_psij0;
3362 for (l = 1; l <= 2*m+1; l++)
3364 fg_psij2 *= fg_psij1;
3365 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l];
3368 uo(ths,j,&u,&o, (INT)1);
3369 fg_psij0 = (PHI(ths->n[1], ths->x[2*j+1] - ((R)u) / (R)(n1),1));
3370 fg_psij1 = EXP(K(2.0) * ((R)(n1) * (ths->x[2*j+1]) - (R)(u)) / ths->b[1]);
3372 psij_const[2*m+2] = fg_psij0;
3373 for(l=1; l<=2*m+1; l++)
3375 fg_psij2 *= fg_psij1;
3376 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l];
3379 nfft_trafo_2d_compute(ths->f+j, g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3387 const INT K = ths->K, ip_s = K / (m + 2);
3392 #pragma omp parallel for default(shared) private(k)
3394 for (k = 0; k < M; k++)
3399 R psij_const[2*(2*m+2)];
3400 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3402 uo(ths,j,&u,&o,(INT)0);
3403 ip_y = FABS((R)(n0) * ths->x[2*j] - (R)(u)) * ((R)ip_s);
3404 ip_u = (INT)LRINT(FLOOR(ip_y));
3405 ip_w = ip_y - (R)(ip_u);
3406 for (l = 0; l < 2*m+2; l++)
3407 psij_const[l] = ths->psi[ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) + ths->psi[ABS(ip_u-l*ip_s+1)]*(ip_w);
3409 uo(ths,j,&u,&o,(INT)1);
3410 ip_y = FABS((R)(n1) * ths->x[2*j+1] - (R)(u)) * ((R)ip_s);
3411 ip_u = (INT)(LRINT(FLOOR(ip_y)));
3412 ip_w = ip_y - (R)(ip_u);
3413 for (l = 0; l < 2*m+2; l++)
3414 psij_const[2*m+2+l] = ths->psi[(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) + ths->psi[(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w);
3416 nfft_trafo_2d_compute(ths->f+j, g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3426 #pragma omp parallel for default(shared) private(k)
3428 for (k = 0; k < M; k++)
3430 R psij_const[2*(2*m+2)];
3432 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3434 uo(ths,j,&u,&o,(INT)0);
3435 for (l = 0; l <= 2*m+1; l++)
3436 psij_const[l]=(PHI(ths->n[0], ths->x[2*j] - ((R)((u+l))) / (R)(n0),0));
3438 uo(ths,j,&u,&o,(INT)1);
3439 for (l = 0; l <= 2*m+1; l++)
3440 psij_const[2*m+2+l] = (PHI(ths->n[1], ths->x[2*j+1] - ((R)((u+l)))/(R)(n1),1));
3442 nfft_trafo_2d_compute(ths->f+j, g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3446#define MACRO_adjoint_2d_B_OMP_BLOCKWISE_COMPUTE_PRE_PSI \
3447 nfft_adjoint_2d_compute_omp_blockwise(ths->f[j], g, \
3448 ths->psi+j*2*(2*m+2), ths->psi+(j*2+1)*(2*m+2), \
3449 ths->x+2*j, ths->x+2*j+1, n0, n1, m, my_u0, my_o0);
3451#define MACRO_adjoint_2d_B_OMP_BLOCKWISE_COMPUTE_PRE_FG_PSI \
3453 R psij_const[2*(2*m+2)]; \
3455 R fg_psij0 = ths->psi[2*j*2]; \
3456 R fg_psij1 = ths->psi[2*j*2+1]; \
3457 R fg_psij2 = K(1.0); \
3459 psij_const[0] = fg_psij0; \
3460 for(l=1; l<=2*m+1; l++) \
3462 fg_psij2 *= fg_psij1; \
3463 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l]; \
3466 fg_psij0 = ths->psi[2*(j*2+1)]; \
3467 fg_psij1 = ths->psi[2*(j*2+1)+1]; \
3468 fg_psij2 = K(1.0); \
3469 psij_const[2*m+2] = fg_psij0; \
3470 for(l=1; l<=2*m+1; l++) \
3472 fg_psij2 *= fg_psij1; \
3473 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l]; \
3476 nfft_adjoint_2d_compute_omp_blockwise(ths->f[j], g, \
3477 psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, \
3478 n0, n1, m, my_u0, my_o0); \
3481#define MACRO_adjoint_2d_B_OMP_BLOCKWISE_COMPUTE_FG_PSI \
3483 R psij_const[2*(2*m+2)]; \
3484 R fg_psij0, fg_psij1, fg_psij2; \
3487 uo(ths,j,&u,&o,(INT)0); \
3488 fg_psij0 = (PHI(ths->n[0],ths->x[2*j]-((R)u)/((R)n0),0)); \
3489 fg_psij1 = EXP(K(2.0)*(((R)n0)*(ths->x[2*j]) - (R)u)/ths->b[0]); \
3490 fg_psij2 = K(1.0); \
3491 psij_const[0] = fg_psij0; \
3492 for(l=1; l<=2*m+1; l++) \
3494 fg_psij2 *= fg_psij1; \
3495 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l]; \
3498 uo(ths,j,&u,&o,(INT)1); \
3499 fg_psij0 = (PHI(ths->n[1],ths->x[2*j+1]-((R)u)/((R)n1),1)); \
3500 fg_psij1 = EXP(K(2.0)*(((R)n1)*(ths->x[2*j+1]) - (R)u)/ths->b[1]); \
3501 fg_psij2 = K(1.0); \
3502 psij_const[2*m+2] = fg_psij0; \
3503 for(l=1; l<=2*m+1; l++) \
3505 fg_psij2 *= fg_psij1; \
3506 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l]; \
3509 nfft_adjoint_2d_compute_omp_blockwise(ths->f[j], g, \
3510 psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, \
3511 n0, n1, m, my_u0, my_o0); \
3514#define MACRO_adjoint_2d_B_OMP_BLOCKWISE_COMPUTE_PRE_LIN_PSI \
3516 R psij_const[2*(2*m+2)]; \
3521 uo(ths,j,&u,&o,(INT)0); \
3522 ip_y = FABS(((R)n0)*(ths->x[2*j]) - (R)u)*((R)ip_s); \
3523 ip_u = LRINT(FLOOR(ip_y)); \
3525 for(l=0; l < 2*m+2; l++) \
3526 psij_const[l] = ths->psi[ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) + \
3527 ths->psi[ABS(ip_u-l*ip_s+1)]*(ip_w); \
3529 uo(ths,j,&u,&o,(INT)1); \
3530 ip_y = FABS(((R)n1)*(ths->x[2*j+1]) - (R)u)*((R)ip_s); \
3531 ip_u = LRINT(FLOOR(ip_y)); \
3533 for(l=0; l < 2*m+2; l++) \
3534 psij_const[2*m+2+l] = ths->psi[(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) + \
3535 ths->psi[(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w); \
3537 nfft_adjoint_2d_compute_omp_blockwise(ths->f[j], g, \
3538 psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, \
3539 n0, n1, m, my_u0, my_o0); \
3542#define MACRO_adjoint_2d_B_OMP_BLOCKWISE_COMPUTE_NO_PSI \
3544 R psij_const[2*(2*m+2)]; \
3547 uo(ths,j,&u,&o,(INT)0); \
3548 for(l=0;l<=2*m+1;l++) \
3549 psij_const[l]=(PHI(ths->n[0],ths->x[2*j]-((R)((u+l)))/((R)n0),0)); \
3551 uo(ths,j,&u,&o,(INT)1); \
3552 for(l=0;l<=2*m+1;l++) \
3553 psij_const[2*m+2+l]=(PHI(ths->n[1],ths->x[2*j+1]-((R)((u+l)))/((R)n1),1)); \
3555 nfft_adjoint_2d_compute_omp_blockwise(ths->f[j], g, \
3556 psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, \
3557 n0, n1, m, my_u0, my_o0); \
3560#define MACRO_adjoint_2d_B_OMP_BLOCKWISE(whichone) \
3562 if (ths->flags & NFFT_OMP_BLOCKWISE_ADJOINT) \
3564 _Pragma("omp parallel private(k)") \
3566 INT my_u0, my_o0, min_u_a, max_u_a, min_u_b, max_u_b; \
3567 INT *ar_x = ths->index_x; \
3569 nfft_adjoint_B_omp_blockwise_init(&my_u0, &my_o0, &min_u_a, &max_u_a, \
3570 &min_u_b, &max_u_b, 2, ths->n, m); \
3572 if (min_u_a != -1) \
3574 k = index_x_binary_search(ar_x, M, min_u_a); \
3576 MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_A \
3580 INT u_prod = ar_x[2*k]; \
3581 INT j = ar_x[2*k+1]; \
3583 if (u_prod < min_u_a || u_prod > max_u_a) \
3586 MACRO_adjoint_2d_B_OMP_BLOCKWISE_COMPUTE_ ##whichone \
3592 if (min_u_b != -1) \
3594 INT k = index_x_binary_search(ar_x, M, min_u_b); \
3596 MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_B \
3600 INT u_prod = ar_x[2*k]; \
3601 INT j = ar_x[2*k+1]; \
3603 if (u_prod < min_u_b || u_prod > max_u_b) \
3606 MACRO_adjoint_2d_B_OMP_BLOCKWISE_COMPUTE_ ##whichone \
3617static void nfft_adjoint_2d_B(X(plan) *ths)
3619 const INT n0 = ths->n[0];
3620 const INT n1 = ths->n[1];
3621 const INT M = ths->M_total;
3622 const INT m = ths->m;
3626 memset(g, 0, (
size_t)(ths->n_total) *
sizeof(C));
3630 nfft_adjoint_B_compute_full_psi(g, ths->psi_index_g, ths->psi, ths->f, M,
3631 (INT)2, ths->n, m, ths->flags, ths->index_x);
3638 MACRO_adjoint_2d_B_OMP_BLOCKWISE(
PRE_PSI)
3642 #pragma omp parallel for default(shared) private(k)
3644 for (k = 0; k < M; k++)
3646 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3648 nfft_adjoint_2d_compute_omp_atomic(ths->f[j], g, ths->psi+j*2*(2*m+2), ths->psi+(j*2+1)*(2*m+2), ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3650 nfft_adjoint_2d_compute_serial(ths->f+j, g, ths->psi+j*2*(2*m+2), ths->psi+(j*2+1)*(2*m+2), ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3658 R fg_exp_l[2*(2*m+2+1)];
3660 nfft_2d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
3661 nfft_2d_init_fg_exp_l(fg_exp_l+2*m+2, m, ths->b[1]);
3669 #pragma omp parallel for default(shared) private(k)
3671 for (k = 0; k < M; k++)
3673 R psij_const[2*(2*m+2)];
3674 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3676 R fg_psij0 = ths->psi[2*j*2];
3677 R fg_psij1 = ths->psi[2*j*2+1];
3678 R fg_psij2 = K(1.0);
3680 psij_const[0] = fg_psij0;
3681 for(l=1; l<=2*m+1; l++)
3683 fg_psij2 *= fg_psij1;
3684 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l];
3687 fg_psij0 = ths->psi[2*(j*2+1)];
3688 fg_psij1 = ths->psi[2*(j*2+1)+1];
3690 psij_const[2*m+2] = fg_psij0;
3691 for(l=1; l<=2*m+1; l++)
3693 fg_psij2 *= fg_psij1;
3694 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l];
3698 nfft_adjoint_2d_compute_omp_atomic(ths->f[j], g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3700 nfft_adjoint_2d_compute_serial(ths->f+j, g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3709 R fg_exp_l[2*(2*m+2+1)];
3711 nfft_2d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
3712 nfft_2d_init_fg_exp_l(fg_exp_l+2*m+2, m, ths->b[1]);
3717 MACRO_adjoint_2d_B_OMP_BLOCKWISE(
FG_PSI)
3721 #pragma omp parallel for default(shared) private(k)
3723 for (k = 0; k < M; k++)
3726 R fg_psij0, fg_psij1, fg_psij2;
3727 R psij_const[2*(2*m+2)];
3728 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3730 uo(ths,j,&u,&o,(INT)0);
3731 fg_psij0 = (PHI(ths->n[0], ths->x[2*j] - ((R)u)/(R)(n0),0));
3732 fg_psij1 = EXP(K(2.0) * ((R)(n0) * (ths->x[2*j]) - (R)(u)) / ths->b[0]);
3734 psij_const[0] = fg_psij0;
3735 for(l=1; l<=2*m+1; l++)
3737 fg_psij2 *= fg_psij1;
3738 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l];
3741 uo(ths,j,&u,&o,(INT)1);
3742 fg_psij0 = (PHI(ths->n[1], ths->x[2*j+1] - ((R)u) / (R)(n1),1));
3743 fg_psij1 = EXP(K(2.0) * ((R)(n1) * (ths->x[2*j+1]) - (R)(u)) / ths->b[1]);
3745 psij_const[2*m+2] = fg_psij0;
3746 for(l=1; l<=2*m+1; l++)
3748 fg_psij2 *= fg_psij1;
3749 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l];
3753 nfft_adjoint_2d_compute_omp_atomic(ths->f[j], g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3755 nfft_adjoint_2d_compute_serial(ths->f+j, g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3764 const INT K = ths->K;
3765 const INT ip_s = K / (m + 2);
3774 #pragma omp parallel for default(shared) private(k)
3776 for (k = 0; k < M; k++)
3781 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3782 R psij_const[2*(2*m+2)];
3784 uo(ths,j,&u,&o,(INT)0);
3785 ip_y = FABS((R)(n0) * (ths->x[2*j]) - (R)(u)) * ((R)ip_s);
3786 ip_u = (INT)(LRINT(FLOOR(ip_y)));
3787 ip_w = ip_y - (R)(ip_u);
3788 for(l=0; l < 2*m+2; l++)
3789 psij_const[l] = ths->psi[ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) +
3790 ths->psi[ABS(ip_u-l*ip_s+1)]*(ip_w);
3792 uo(ths,j,&u,&o,(INT)1);
3793 ip_y = FABS((R)(n1) * (ths->x[2*j+1]) - (R)(u)) * ((R)ip_s);
3794 ip_u = (INT)(LRINT(FLOOR(ip_y)));
3795 ip_w = ip_y - (R)(ip_u);
3796 for(l=0; l < 2*m+2; l++)
3797 psij_const[2*m+2+l] = ths->psi[(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) +
3798 ths->psi[(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w);
3801 nfft_adjoint_2d_compute_omp_atomic(ths->f[j], g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3803 nfft_adjoint_2d_compute_serial(ths->f+j, g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3813 MACRO_adjoint_2d_B_OMP_BLOCKWISE(NO_PSI)
3817 #pragma omp parallel for default(shared) private(k)
3819 for (k = 0; k < M; k++)
3822 R psij_const[2*(2*m+2)];
3823 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
3825 uo(ths,j,&u,&o,(INT)0);
3826 for(l=0;l<=2*m+1;l++)
3827 psij_const[l]=(PHI(ths->n[0], ths->x[2*j] - ((R)((u+l))) / (R)(n0),0));
3829 uo(ths,j,&u,&o,(INT)1);
3830 for(l=0;l<=2*m+1;l++)
3831 psij_const[2*m+2+l]=(PHI(ths->n[1], ths->x[2*j+1] - ((R)((u+l))) / (R)(n1),1));
3834 nfft_adjoint_2d_compute_omp_atomic(ths->f[j], g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3836 nfft_adjoint_2d_compute_serial(ths->f+j, g, psij_const, psij_const+2*m+2, ths->x+2*j, ths->x+2*j+1, n0, n1, m);
3842void X(trafo_2d)(X(plan) *ths)
3844 if((ths->N[0] <= ths->m) || (ths->N[1] <= ths->m) || (ths->n[0] <= 2*ths->m+2) || (ths->n[1] <= 2*ths->m+2))
3846 X(trafo_direct)(ths);
3850 INT k0,k1,n0,n1,N0,N1;
3852 R *c_phi_inv01, *c_phi_inv02, *c_phi_inv11, *c_phi_inv12;
3853 R ck01, ck02, ck11, ck12;
3854 C *g_hat11,*f_hat11,*g_hat21,*f_hat21,*g_hat12,*f_hat12,*g_hat22,*f_hat22;
3864 f_hat=(C*)ths->f_hat;
3865 g_hat=(C*)ths->g_hat;
3869 #pragma omp parallel for default(shared) private(k0)
3870 for (k0 = 0; k0 < ths->n_total; k0++)
3871 ths->g_hat[k0] = 0.0;
3873 memset(ths->g_hat, 0, (
size_t)(ths->n_total) *
sizeof(C));
3877 c_phi_inv01=ths->c_phi_inv[0];
3878 c_phi_inv02=&ths->c_phi_inv[0][N0/2];
3881 #pragma omp parallel for default(shared) private(k0,k1,ck01,ck02,c_phi_inv11,c_phi_inv12,g_hat11,f_hat11,g_hat21,f_hat21,g_hat12,f_hat12,g_hat22,f_hat22,ck11,ck12)
3883 for(k0=0;k0<N0/2;k0++)
3885 ck01=c_phi_inv01[k0];
3886 ck02=c_phi_inv02[k0];
3888 c_phi_inv11=ths->c_phi_inv[1];
3889 c_phi_inv12=&ths->c_phi_inv[1][N1/2];
3891 g_hat11=g_hat + (n0-(N0/2)+k0)*n1+n1-(N1/2);
3892 f_hat11=f_hat + k0*N1;
3893 g_hat21=g_hat + k0*n1+n1-(N1/2);
3894 f_hat21=f_hat + ((N0/2)+k0)*N1;
3895 g_hat12=g_hat + (n0-(N0/2)+k0)*n1;
3896 f_hat12=f_hat + k0*N1+(N1/2);
3897 g_hat22=g_hat + k0*n1;
3898 f_hat22=f_hat + ((N0/2)+k0)*N1+(N1/2);
3900 for(k1=0;k1<N1/2;k1++)
3902 ck11=c_phi_inv11[k1];
3903 ck12=c_phi_inv12[k1];
3905 g_hat11[k1] = f_hat11[k1] * ck01 * ck11;
3906 g_hat21[k1] = f_hat21[k1] * ck02 * ck11;
3907 g_hat12[k1] = f_hat12[k1] * ck01 * ck12;
3908 g_hat22[k1] = f_hat22[k1] * ck02 * ck12;
3914 #pragma omp parallel for default(shared) private(k0,k1,ck01,ck02,ck11,ck12)
3916 for(k0=0;k0<N0/2;k0++)
3918 ck01=K(1.0)/(PHI_HUT(ths->n[0],k0-N0/2,0));
3919 ck02=K(1.0)/(PHI_HUT(ths->n[0],k0,0));
3920 for(k1=0;k1<N1/2;k1++)
3922 ck11=K(1.0)/(PHI_HUT(ths->n[1],k1-N1/2,1));
3923 ck12=K(1.0)/(PHI_HUT(ths->n[1],k1,1));
3924 g_hat[(n0-N0/2+k0)*n1+n1-N1/2+k1] = f_hat[k0*N1+k1] * ck01 * ck11;
3925 g_hat[k0*n1+n1-N1/2+k1] = f_hat[(N0/2+k0)*N1+k1] * ck02 * ck11;
3926 g_hat[(n0-N0/2+k0)*n1+k1] = f_hat[k0*N1+N1/2+k1] * ck01 * ck12;
3927 g_hat[k0*n1+k1] = f_hat[(N0/2+k0)*N1+N1/2+k1] * ck02 * ck12;
3934 FFTW(execute)(ths->my_fftw_plan1);
3938 nfft_trafo_2d_B(ths);
3942void X(adjoint_2d)(X(plan) *ths)
3944 if((ths->N[0] <= ths->m) || (ths->N[1] <= ths->m) || (ths->n[0] <= 2*ths->m+2) || (ths->n[1] <= 2*ths->m+2))
3946 X(adjoint_direct)(ths);
3950 INT k0,k1,n0,n1,N0,N1;
3952 R *c_phi_inv01, *c_phi_inv02, *c_phi_inv11, *c_phi_inv12;
3953 R ck01, ck02, ck11, ck12;
3954 C *g_hat11,*f_hat11,*g_hat21,*f_hat21,*g_hat12,*f_hat12,*g_hat22,*f_hat22;
3964 f_hat=(C*)ths->f_hat;
3965 g_hat=(C*)ths->g_hat;
3968 nfft_adjoint_2d_B(ths);
3972 FFTW(execute)(ths->my_fftw_plan2);
3978 c_phi_inv01=ths->c_phi_inv[0];
3979 c_phi_inv02=&ths->c_phi_inv[0][N0/2];
3982 #pragma omp parallel for default(shared) private(k0,k1,ck01,ck02,c_phi_inv11,c_phi_inv12,g_hat11,f_hat11,g_hat21,f_hat21,g_hat12,f_hat12,g_hat22,f_hat22,ck11,ck12)
3984 for(k0=0;k0<N0/2;k0++)
3986 ck01=c_phi_inv01[k0];
3987 ck02=c_phi_inv02[k0];
3989 c_phi_inv11=ths->c_phi_inv[1];
3990 c_phi_inv12=&ths->c_phi_inv[1][N1/2];
3992 g_hat11=g_hat + (n0-(N0/2)+k0)*n1+n1-(N1/2);
3993 f_hat11=f_hat + k0*N1;
3994 g_hat21=g_hat + k0*n1+n1-(N1/2);
3995 f_hat21=f_hat + ((N0/2)+k0)*N1;
3996 g_hat12=g_hat + (n0-(N0/2)+k0)*n1;
3997 f_hat12=f_hat + k0*N1+(N1/2);
3998 g_hat22=g_hat + k0*n1;
3999 f_hat22=f_hat + ((N0/2)+k0)*N1+(N1/2);
4001 for(k1=0;k1<N1/2;k1++)
4003 ck11=c_phi_inv11[k1];
4004 ck12=c_phi_inv12[k1];
4006 f_hat11[k1] = g_hat11[k1] * ck01 * ck11;
4007 f_hat21[k1] = g_hat21[k1] * ck02 * ck11;
4008 f_hat12[k1] = g_hat12[k1] * ck01 * ck12;
4009 f_hat22[k1] = g_hat22[k1] * ck02 * ck12;
4015 #pragma omp parallel for default(shared) private(k0,k1,ck01,ck02,ck11,ck12)
4017 for(k0=0;k0<N0/2;k0++)
4019 ck01=K(1.0)/(PHI_HUT(ths->n[0],k0-N0/2,0));
4020 ck02=K(1.0)/(PHI_HUT(ths->n[0],k0,0));
4021 for(k1=0;k1<N1/2;k1++)
4023 ck11=K(1.0)/(PHI_HUT(ths->n[1],k1-N1/2,1));
4024 ck12=K(1.0)/(PHI_HUT(ths->n[1],k1,1));
4025 f_hat[k0*N1+k1] = g_hat[(n0-N0/2+k0)*n1+n1-N1/2+k1] * ck01 * ck11;
4026 f_hat[(N0/2+k0)*N1+k1] = g_hat[k0*n1+n1-N1/2+k1] * ck02 * ck11;
4027 f_hat[k0*N1+N1/2+k1] = g_hat[(n0-N0/2+k0)*n1+k1] * ck01 * ck12;
4028 f_hat[(N0/2+k0)*N1+N1/2+k1] = g_hat[k0*n1+k1] * ck02 * ck12;
4036static void nfft_3d_init_fg_exp_l(R *fg_exp_l,
const INT m,
const R b)
4039 R fg_exp_b0, fg_exp_b1, fg_exp_b2, fg_exp_b0_sq;
4041 fg_exp_b0 = EXP(-K(1.0) / b);
4042 fg_exp_b0_sq = fg_exp_b0*fg_exp_b0;
4045 fg_exp_l[0] = K(1.0);
4046 for(l=1; l <= 2*m+1; l++)
4048 fg_exp_b2 = fg_exp_b1*fg_exp_b0;
4049 fg_exp_b1 *= fg_exp_b0_sq;
4050 fg_exp_l[l] = fg_exp_l[l-1]*fg_exp_b2;
4054static void nfft_trafo_3d_compute(C *fj,
const C *g,
const R *psij_const0,
4055 const R *psij_const1,
const R *psij_const2,
const R *xj0,
const R *xj1,
4056 const R *xj2,
const INT n0,
const INT n1,
const INT n2,
const INT m)
4058 INT u0, o0, l0, u1, o1, l1, u2, o2, l2;
4060 const R *psij0, *psij1, *psij2;
4062 psij0 = psij_const0;
4063 psij1 = psij_const1;
4064 psij2 = psij_const2;
4066 uo2(&u0, &o0, *xj0, n0, m);
4067 uo2(&u1, &o1, *xj1, n1, m);
4068 uo2(&u2, &o2, *xj2, n2, m);
4075 for (l0 = 0; l0 <= 2 * m + 1; l0++, psij0++)
4077 psij1 = psij_const1;
4078 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4080 psij2 = psij_const2;
4081 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4082 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4083 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4088 for (l0 = 0; l0 <= 2 * m + 1; l0++, psij0++)
4090 psij1 = psij_const1;
4091 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4093 psij2 = psij_const2;
4094 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4095 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4096 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4097 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2;
4098 for (l2 = 0; l2 <= o2; l2++)
4099 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4104 for (l0 = 0; l0 <= 2 * m + 1; l0++, psij0++)
4106 psij1 = psij_const1;
4107 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4109 psij2 = psij_const2;
4110 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4111 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4112 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4114 for (l1 = 0; l1 <= o1; l1++, psij1++)
4116 psij2 = psij_const2;
4117 gj = g + ((u0 + l0) * n1 + l1) * n2 + u2;
4118 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4119 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4124 for (l0 = 0; l0 <= 2 * m + 1; l0++, psij0++)
4126 psij1 = psij_const1;
4127 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4129 psij2 = psij_const2;
4130 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4131 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4132 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4133 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2;
4134 for (l2 = 0; l2 <= o2; l2++)
4135 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4137 for (l1 = 0; l1 <= o1; l1++, psij1++)
4139 psij2 = psij_const2;
4140 gj = g + ((u0 + l0) * n1 + l1) * n2 + u2;
4141 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4142 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4143 gj = g + ((u0 + l0) * n1 + l1) * n2;
4144 for (l2 = 0; l2 <= o2; l2++)
4145 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4153 for (l0 = 0; l0 < 2 * m + 1 - o0; l0++, psij0++)
4155 psij1 = psij_const1;
4156 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4158 psij2 = psij_const2;
4159 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4160 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4161 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4165 for (l0 = 0; l0 <= o0; l0++, psij0++)
4167 psij1 = psij_const1;
4168 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4170 psij2 = psij_const2;
4171 gj = g + (l0 * n1 + (u1 + l1)) * n2 + u2;
4172 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4173 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4178 for (l0 = 0; l0 < 2 * m + 1 - o0; l0++, psij0++)
4180 psij1 = psij_const1;
4181 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4183 psij2 = psij_const2;
4184 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4185 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4186 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4187 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2;
4188 for (l2 = 0; l2 <= o2; l2++)
4189 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4193 for (l0 = 0; l0 <= o0; l0++, psij0++)
4195 psij1 = psij_const1;
4196 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4198 psij2 = psij_const2;
4199 gj = g + (l0 * n1 + (u1 + l1)) * n2 + u2;
4200 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4201 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4202 gj = g + (l0 * n1 + (u1 + l1)) * n2;
4203 for (l2 = 0; l2 <= o2; l2++)
4204 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4211 for (l0 = 0; l0 < 2 * m + 1 - o0; l0++, psij0++)
4213 psij1 = psij_const1;
4214 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4216 psij2 = psij_const2;
4217 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4218 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4219 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4221 for (l1 = 0; l1 <= o1; l1++, psij1++)
4223 psij2 = psij_const2;
4224 gj = g + ((u0 + l0) * n1 + l1) * n2 + u2;
4225 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4226 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4229 for (l0 = 0; l0 <= o0; l0++, psij0++)
4231 psij1 = psij_const1;
4232 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4234 psij2 = psij_const2;
4235 gj = g + (l0 * n1 + (u1 + l1)) * n2 + u2;
4236 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4237 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4239 for (l1 = 0; l1 <= o1; l1++, psij1++)
4241 psij2 = psij_const2;
4242 gj = g + (l0 * n1 + l1) * n2 + u2;
4243 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4244 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4249 for (l0 = 0; l0 < 2 * m + 1 - o0; l0++, psij0++)
4251 psij1 = psij_const1;
4252 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4254 psij2 = psij_const2;
4255 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4256 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4257 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4258 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2;
4259 for (l2 = 0; l2 <= o2; l2++)
4260 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4262 for (l1 = 0; l1 <= o1; l1++, psij1++)
4264 psij2 = psij_const2;
4265 gj = g + ((u0 + l0) * n1 + l1) * n2 + u2;
4266 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4267 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4268 gj = g + ((u0 + l0) * n1 + l1) * n2;
4269 for (l2 = 0; l2 <= o2; l2++)
4270 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4274 for (l0 = 0; l0 <= o0; l0++, psij0++)
4276 psij1 = psij_const1;
4277 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4279 psij2 = psij_const2;
4280 gj = g + (l0 * n1 + (u1 + l1)) * n2 + u2;
4281 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4282 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4283 gj = g + (l0 * n1 + (u1 + l1)) * n2;
4284 for (l2 = 0; l2 <= o2; l2++)
4285 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4287 for (l1 = 0; l1 <= o1; l1++, psij1++)
4289 psij2 = psij_const2;
4290 gj = g + (l0 * n1 + l1) * n2 + u2;
4291 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4292 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4293 gj = g + (l0 * n1 + l1) * n2;
4294 for (l2 = 0; l2 <= o2; l2++)
4295 (*fj) += (*psij0) * (*psij1) * (*psij2++) * (*gj++);
4323static void nfft_adjoint_3d_compute_omp_blockwise(
const C f, C *g,
4324 const R *psij_const0,
const R *psij_const1,
const R *psij_const2,
4325 const R *xj0,
const R *xj1,
const R *xj2,
4326 const INT n0,
const INT n1,
const INT n2,
const INT m,
4327 const INT my_u0,
const INT my_o0)
4329 INT ar_u0,ar_o0,l0,u1,o1,l1,u2,o2,l2;
4331 INT index_temp1[2*m+2];
4332 INT index_temp2[2*m+2];
4334 uo2(&ar_u0,&ar_o0,*xj0, n0, m);
4335 uo2(&u1,&o1,*xj1, n1, m);
4336 uo2(&u2,&o2,*xj2, n2, m);
4338 for (l1=0; l1<=2*m+1; l1++)
4339 index_temp1[l1] = (u1+l1)%n1;
4341 for (l2=0; l2<=2*m+1; l2++)
4342 index_temp2[l2] = (u2+l2)%n2;
4346 INT u0 = MAX(my_u0,ar_u0);
4347 INT o0 = MIN(my_o0,ar_o0);
4348 INT offset_psij = u0-ar_u0;
4350 assert(offset_psij >= 0);
4351 assert(o0-u0 <= 2*m+1);
4352 assert(offset_psij+o0-u0 <= 2*m+1);
4355 for (l0 = 0; l0 <= o0-u0; l0++)
4357 const INT i0 = (u0+l0) * n1;
4358 const C val0 = psij_const0[offset_psij+l0];
4360 for(l1=0; l1<=2*m+1; l1++)
4362 const INT i1 = (i0 + index_temp1[l1]) * n2;
4363 const C val1 = psij_const1[l1];
4365 for(l2=0; l2<=2*m+1; l2++)
4366 g[i1 + index_temp2[l2]] += val0 * val1 * psij_const2[l2] * f;
4372 INT u0 = MAX(my_u0,ar_u0);
4374 INT offset_psij = u0-ar_u0;
4376 assert(offset_psij >= 0);
4377 assert(o0-u0 <= 2*m+1);
4378 assert(offset_psij+o0-u0 <= 2*m+1);
4381 for (l0 = 0; l0 <= o0-u0; l0++)
4383 INT i0 = (u0+l0) * n1;
4384 const C val0 = psij_const0[offset_psij+l0];
4386 for(l1=0; l1<=2*m+1; l1++)
4388 const INT i1 = (i0 + index_temp1[l1]) * n2;
4389 const C val1 = psij_const1[l1];
4391 for(l2=0; l2<=2*m+1; l2++)
4392 g[i1 + index_temp2[l2]] += val0 * val1 * psij_const2[l2] * f;
4397 o0 = MIN(my_o0,ar_o0);
4398 offset_psij += my_u0-ar_u0+n0;
4403 assert(o0-u0 <= 2*m+1);
4404 assert(offset_psij+o0-u0 <= 2*m+1);
4407 for (l0 = 0; l0 <= o0-u0; l0++)
4409 INT i0 = (u0+l0) * n1;
4410 const C val0 = psij_const0[offset_psij+l0];
4412 for(l1=0; l1<=2*m+1; l1++)
4414 const INT i1 = (i0 + index_temp1[l1]) * n2;
4415 const C val1 = psij_const1[l1];
4417 for(l2=0; l2<=2*m+1; l2++)
4418 g[i1 + index_temp2[l2]] += val0 * val1 * psij_const2[l2] * f;
4427static void nfft_adjoint_3d_compute_omp_atomic(
const C f, C *g,
4428 const R *psij_const0,
const R *psij_const1,
const R *psij_const2,
4429 const R *xj0,
const R *xj1,
const R *xj2,
4430 const INT n0,
const INT n1,
const INT n2,
const INT m)
4432 INT u0,o0,l0,u1,o1,l1,u2,o2,l2;
4434 INT index_temp0[2*m+2];
4435 INT index_temp1[2*m+2];
4436 INT index_temp2[2*m+2];
4438 uo2(&u0,&o0,*xj0, n0, m);
4439 uo2(&u1,&o1,*xj1, n1, m);
4440 uo2(&u2,&o2,*xj2, n2, m);
4442 for (l0=0; l0<=2*m+1; l0++)
4443 index_temp0[l0] = (u0+l0)%n0;
4445 for (l1=0; l1<=2*m+1; l1++)
4446 index_temp1[l1] = (u1+l1)%n1;
4448 for (l2=0; l2<=2*m+1; l2++)
4449 index_temp2[l2] = (u2+l2)%n2;
4451 for(l0=0; l0<=2*m+1; l0++)
4453 for(l1=0; l1<=2*m+1; l1++)
4455 for(l2=0; l2<=2*m+1; l2++)
4457 INT i = (index_temp0[l0] * n1 + index_temp1[l1]) * n2 + index_temp2[l2];
4459 R *lhs_real = (R*)lhs;
4460 C val = psij_const0[l0] * psij_const1[l1] * psij_const2[l2] * f;
4463 lhs_real[0] += CREAL(val);
4466 lhs_real[1] += CIMAG(val);
4474static void nfft_adjoint_3d_compute_serial(
const C *fj, C *g,
4475 const R *psij_const0,
const R *psij_const1,
const R *psij_const2,
const R *xj0,
4476 const R *xj1,
const R *xj2,
const INT n0,
const INT n1,
const INT n2,
4479 INT u0, o0, l0, u1, o1, l1, u2, o2, l2;
4481 const R *psij0, *psij1, *psij2;
4483 psij0 = psij_const0;
4484 psij1 = psij_const1;
4485 psij2 = psij_const2;
4487 uo2(&u0, &o0, *xj0, n0, m);
4488 uo2(&u1, &o1, *xj1, n1, m);
4489 uo2(&u2, &o2, *xj2, n2, m);
4494 for (l0 = 0; l0 <= 2 * m + 1; l0++, psij0++)
4496 psij1 = psij_const1;
4497 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4499 psij2 = psij_const2;
4500 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4501 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4502 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4507 for (l0 = 0; l0 <= 2 * m + 1; l0++, psij0++)
4509 psij1 = psij_const1;
4510 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4512 psij2 = psij_const2;
4513 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4514 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4515 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4516 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2;
4517 for (l2 = 0; l2 <= o2; l2++)
4518 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4523 for (l0 = 0; l0 <= 2 * m + 1; l0++, psij0++)
4525 psij1 = psij_const1;
4526 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4528 psij2 = psij_const2;
4529 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4530 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4531 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4533 for (l1 = 0; l1 <= o1; l1++, psij1++)
4535 psij2 = psij_const2;
4536 gj = g + ((u0 + l0) * n1 + l1) * n2 + u2;
4537 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4538 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4543 for (l0 = 0; l0 <= 2 * m + 1; l0++, psij0++)
4545 psij1 = psij_const1;
4546 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4548 psij2 = psij_const2;
4549 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4550 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4551 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4552 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2;
4553 for (l2 = 0; l2 <= o2; l2++)
4554 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4556 for (l1 = 0; l1 <= o1; l1++, psij1++)
4558 psij2 = psij_const2;
4559 gj = g + ((u0 + l0) * n1 + l1) * n2 + u2;
4560 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4561 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4562 gj = g + ((u0 + l0) * n1 + l1) * n2;
4563 for (l2 = 0; l2 <= o2; l2++)
4564 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4572 for (l0 = 0; l0 < 2 * m + 1 - o0; l0++, psij0++)
4574 psij1 = psij_const1;
4575 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4577 psij2 = psij_const2;
4578 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4579 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4580 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4584 for (l0 = 0; l0 <= o0; l0++, psij0++)
4586 psij1 = psij_const1;
4587 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4589 psij2 = psij_const2;
4590 gj = g + (l0 * n1 + (u1 + l1)) * n2 + u2;
4591 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4592 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4597 for (l0 = 0; l0 < 2 * m + 1 - o0; l0++, psij0++)
4599 psij1 = psij_const1;
4600 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4602 psij2 = psij_const2;
4603 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4604 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4605 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4606 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2;
4607 for (l2 = 0; l2 <= o2; l2++)
4608 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4612 for (l0 = 0; l0 <= o0; l0++, psij0++)
4614 psij1 = psij_const1;
4615 for (l1 = 0; l1 <= 2 * m + 1; l1++, psij1++)
4617 psij2 = psij_const2;
4618 gj = g + (l0 * n1 + (u1 + l1)) * n2 + u2;
4619 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4620 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4621 gj = g + (l0 * n1 + (u1 + l1)) * n2;
4622 for (l2 = 0; l2 <= o2; l2++)
4623 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4630 for (l0 = 0; l0 < 2 * m + 1 - o0; l0++, psij0++)
4632 psij1 = psij_const1;
4633 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4635 psij2 = psij_const2;
4636 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4637 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4638 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4640 for (l1 = 0; l1 <= o1; l1++, psij1++)
4642 psij2 = psij_const2;
4643 gj = g + ((u0 + l0) * n1 + l1) * n2 + u2;
4644 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4645 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4648 for (l0 = 0; l0 <= o0; l0++, psij0++)
4650 psij1 = psij_const1;
4651 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4653 psij2 = psij_const2;
4654 gj = g + (l0 * n1 + (u1 + l1)) * n2 + u2;
4655 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4656 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4658 for (l1 = 0; l1 <= o1; l1++, psij1++)
4660 psij2 = psij_const2;
4661 gj = g + (l0 * n1 + l1) * n2 + u2;
4662 for (l2 = 0; l2 <= 2 * m + 1; l2++)
4663 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4668 for (l0 = 0; l0 < 2 * m + 1 - o0; l0++, psij0++)
4670 psij1 = psij_const1;
4671 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4673 psij2 = psij_const2;
4674 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2 + u2;
4675 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4676 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4677 gj = g + ((u0 + l0) * n1 + (u1 + l1)) * n2;
4678 for (l2 = 0; l2 <= o2; l2++)
4679 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4681 for (l1 = 0; l1 <= o1; l1++, psij1++)
4683 psij2 = psij_const2;
4684 gj = g + ((u0 + l0) * n1 + l1) * n2 + u2;
4685 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4686 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4687 gj = g + ((u0 + l0) * n1 + l1) * n2;
4688 for (l2 = 0; l2 <= o2; l2++)
4689 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4693 for (l0 = 0; l0 <= o0; l0++, psij0++)
4695 psij1 = psij_const1;
4696 for (l1 = 0; l1 < 2 * m + 1 - o1; l1++, psij1++)
4698 psij2 = psij_const2;
4699 gj = g + (l0 * n1 + (u1 + l1)) * n2 + u2;
4700 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4701 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4702 gj = g + (l0 * n1 + (u1 + l1)) * n2;
4703 for (l2 = 0; l2 <= o2; l2++)
4704 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4706 for (l1 = 0; l1 <= o1; l1++, psij1++)
4708 psij2 = psij_const2;
4709 gj = g + (l0 * n1 + l1) * n2 + u2;
4710 for (l2 = 0; l2 < 2 * m + 1 - o2; l2++)
4711 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4712 gj = g + (l0 * n1 + l1) * n2;
4713 for (l2 = 0; l2 <= o2; l2++)
4714 (*gj++) += (*psij0) * (*psij1) * (*psij2++) * (*fj);
4721static void nfft_trafo_3d_B(X(plan) *ths)
4723 const INT n0 = ths->n[0];
4724 const INT n1 = ths->n[1];
4725 const INT n2 = ths->n[2];
4726 const INT M = ths->M_total;
4727 const INT m = ths->m;
4729 const C* g = (C*) ths->g;
4735 const INT lprod = (2*m+2) * (2*m+2) * (2*m+2);
4737 #pragma omp parallel for default(shared) private(k)
4739 for (k = 0; k < M; k++)
4742 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
4744 for (l = 0; l < lprod; l++)
4745 ths->f[j] += ths->psi[j*lprod+l] * g[ths->psi_index_g[j*lprod+l]];
4753 #pragma omp parallel for default(shared) private(k)
4755 for (k = 0; k < M; k++)
4757 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
4758 nfft_trafo_3d_compute(ths->f+j, g, ths->psi+j*3*(2*m+2), ths->psi+(j*3+1)*(2*m+2), ths->psi+(j*3+2)*(2*m+2), ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
4765 R fg_exp_l[3*(2*m+2+1)];
4767 nfft_3d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
4768 nfft_3d_init_fg_exp_l(fg_exp_l+2*m+2, m, ths->b[1]);
4769 nfft_3d_init_fg_exp_l(fg_exp_l+2*(2*m+2), m, ths->b[2]);
4772 #pragma omp parallel for default(shared) private(k)
4774 for (k = 0; k < M; k++)
4776 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
4778 R psij_const[3*(2*m+2)];
4779 R fg_psij0 = ths->psi[2*j*3];
4780 R fg_psij1 = ths->psi[2*j*3+1];
4781 R fg_psij2 = K(1.0);
4783 psij_const[0] = fg_psij0;
4784 for(l=1; l<=2*m+1; l++)
4786 fg_psij2 *= fg_psij1;
4787 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l];
4790 fg_psij0 = ths->psi[2*(j*3+1)];
4791 fg_psij1 = ths->psi[2*(j*3+1)+1];
4793 psij_const[2*m+2] = fg_psij0;
4794 for(l=1; l<=2*m+1; l++)
4796 fg_psij2 *= fg_psij1;
4797 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l];
4800 fg_psij0 = ths->psi[2*(j*3+2)];
4801 fg_psij1 = ths->psi[2*(j*3+2)+1];
4803 psij_const[2*(2*m+2)] = fg_psij0;
4804 for(l=1; l<=2*m+1; l++)
4806 fg_psij2 *= fg_psij1;
4807 psij_const[2*(2*m+2)+l] = fg_psij0*fg_psij2*fg_exp_l[2*(2*m+2)+l];
4810 nfft_trafo_3d_compute(ths->f+j, g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
4818 R fg_exp_l[3*(2*m+2+1)];
4820 nfft_3d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
4821 nfft_3d_init_fg_exp_l(fg_exp_l+2*m+2, m, ths->b[1]);
4822 nfft_3d_init_fg_exp_l(fg_exp_l+2*(2*m+2), m, ths->b[2]);
4827 #pragma omp parallel for default(shared) private(k)
4829 for (k = 0; k < M; k++)
4831 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
4833 R psij_const[3*(2*m+2)];
4834 R fg_psij0, fg_psij1, fg_psij2;
4836 uo(ths,j,&u,&o,(INT)0);
4837 fg_psij0 = (PHI(ths->n[0], ths->x[3*j] - ((R)u) / (R)(n0),0));
4838 fg_psij1 = EXP(K(2.0) * ((R)(n0) * (ths->x[3*j]) - (R)(u)) / ths->b[0]);
4840 psij_const[0] = fg_psij0;
4841 for(l=1; l<=2*m+1; l++)
4843 fg_psij2 *= fg_psij1;
4844 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l];
4847 uo(ths,j,&u,&o,(INT)1);
4848 fg_psij0 = (PHI(ths->n[1], ths->x[3*j+1] - ((R)u) / (R)(n1),1));
4849 fg_psij1 = EXP(K(2.0) * ((R)(n1) * (ths->x[3*j+1]) - (R)(u)) / ths->b[1]);
4851 psij_const[2*m+2] = fg_psij0;
4852 for(l=1; l<=2*m+1; l++)
4854 fg_psij2 *= fg_psij1;
4855 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l];
4858 uo(ths,j,&u,&o,(INT)2);
4859 fg_psij0 = (PHI(ths->n[2], ths->x[3*j+2] - ((R)u) / (R)(n2),2));
4860 fg_psij1 = EXP(K(2.0) * ((R)(n2) * (ths->x[3*j+2]) - (R)(u)) / ths->b[2]);
4862 psij_const[2*(2*m+2)] = fg_psij0;
4863 for(l=1; l<=2*m+1; l++)
4865 fg_psij2 *= fg_psij1;
4866 psij_const[2*(2*m+2)+l] = fg_psij0*fg_psij2*fg_exp_l[2*(2*m+2)+l];
4869 nfft_trafo_3d_compute(ths->f+j, g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
4877 const INT K = ths->K, ip_s = K / (m + 2);
4882 #pragma omp parallel for default(shared) private(k)
4884 for (k = 0; k < M; k++)
4889 R psij_const[3*(2*m+2)];
4890 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
4892 uo(ths,j,&u,&o,(INT)0);
4893 ip_y = FABS((R)(n0) * ths->x[3*j+0] - (R)(u)) * ((R)ip_s);
4894 ip_u = (INT)(LRINT(FLOOR(ip_y)));
4895 ip_w = ip_y - (R)(ip_u);
4896 for(l=0; l < 2*m+2; l++)
4897 psij_const[l] = ths->psi[ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) +
4898 ths->psi[ABS(ip_u-l*ip_s+1)]*(ip_w);
4900 uo(ths,j,&u,&o,(INT)1);
4901 ip_y = FABS((R)(n1) * ths->x[3*j+1] - (R)(u)) * ((R)ip_s);
4902 ip_u = (INT)(LRINT(FLOOR(ip_y)));
4903 ip_w = ip_y - (R)(ip_u);
4904 for(l=0; l < 2*m+2; l++)
4905 psij_const[2*m+2+l] = ths->psi[(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) +
4906 ths->psi[(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w);
4908 uo(ths,j,&u,&o,(INT)2);
4909 ip_y = FABS((R)(n2) * ths->x[3*j+2] - (R)(u)) * ((R)ip_s);
4910 ip_u = (INT)(LRINT(FLOOR(ip_y)));
4911 ip_w = ip_y - (R)(ip_u);
4912 for(l=0; l < 2*m+2; l++)
4913 psij_const[2*(2*m+2)+l] = ths->psi[2*(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) +
4914 ths->psi[2*(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w);
4916 nfft_trafo_3d_compute(ths->f+j, g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
4926 #pragma omp parallel for default(shared) private(k)
4928 for (k = 0; k < M; k++)
4930 R psij_const[3*(2*m+2)];
4932 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
4934 uo(ths,j,&u,&o,(INT)0);
4935 for(l=0;l<=2*m+1;l++)
4936 psij_const[l]=(PHI(ths->n[0], ths->x[3*j] - ((R)((u+l))) / (R)(n0),0));
4938 uo(ths,j,&u,&o,(INT)1);
4939 for(l=0;l<=2*m+1;l++)
4940 psij_const[2*m+2+l]=(PHI(ths->n[1], ths->x[3*j+1] - ((R)((u+l))) / (R)(n1),1));
4942 uo(ths,j,&u,&o,(INT)2);
4943 for(l=0;l<=2*m+1;l++)
4944 psij_const[2*(2*m+2)+l]=(PHI(ths->n[2], ths->x[3*j+2] - ((R)((u+l))) / (R)(n2),2));
4946 nfft_trafo_3d_compute(ths->f+j, g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
4950#define MACRO_adjoint_3d_B_OMP_BLOCKWISE_COMPUTE_PRE_PSI \
4951 nfft_adjoint_3d_compute_omp_blockwise(ths->f[j], g, \
4952 ths->psi+j*3*(2*m+2), \
4953 ths->psi+(j*3+1)*(2*m+2), \
4954 ths->psi+(j*3+2)*(2*m+2), \
4955 ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, \
4956 n0, n1, n2, m, my_u0, my_o0);
4958#define MACRO_adjoint_3d_B_OMP_BLOCKWISE_COMPUTE_PRE_FG_PSI \
4961 R psij_const[3*(2*m+2)]; \
4962 R fg_psij0 = ths->psi[2*j*3]; \
4963 R fg_psij1 = ths->psi[2*j*3+1]; \
4964 R fg_psij2 = K(1.0); \
4966 psij_const[0] = fg_psij0; \
4967 for(l=1; l<=2*m+1; l++) \
4969 fg_psij2 *= fg_psij1; \
4970 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l]; \
4973 fg_psij0 = ths->psi[2*(j*3+1)]; \
4974 fg_psij1 = ths->psi[2*(j*3+1)+1]; \
4975 fg_psij2 = K(1.0); \
4976 psij_const[2*m+2] = fg_psij0; \
4977 for(l=1; l<=2*m+1; l++) \
4979 fg_psij2 *= fg_psij1; \
4980 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l]; \
4983 fg_psij0 = ths->psi[2*(j*3+2)]; \
4984 fg_psij1 = ths->psi[2*(j*3+2)+1]; \
4985 fg_psij2 = K(1.0); \
4986 psij_const[2*(2*m+2)] = fg_psij0; \
4987 for(l=1; l<=2*m+1; l++) \
4989 fg_psij2 *= fg_psij1; \
4990 psij_const[2*(2*m+2)+l] = fg_psij0*fg_psij2*fg_exp_l[2*(2*m+2)+l]; \
4993 nfft_adjoint_3d_compute_omp_blockwise(ths->f[j], g, \
4994 psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, \
4995 ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, \
4996 n0, n1, n2, m, my_u0, my_o0); \
4999#define MACRO_adjoint_3d_B_OMP_BLOCKWISE_COMPUTE_FG_PSI \
5002 R psij_const[3*(2*m+2)]; \
5003 R fg_psij0, fg_psij1, fg_psij2; \
5005 uo(ths,j,&u,&o,(INT)0); \
5006 fg_psij0 = (PHI(ths->n[0],ths->x[3*j]-((R)u)/((R)n0),0)); \
5007 fg_psij1 = EXP(K(2.0)*(((R)n0)*(ths->x[3*j]) - (R)u)/ths->b[0]); \
5008 fg_psij2 = K(1.0); \
5009 psij_const[0] = fg_psij0; \
5010 for(l=1; l<=2*m+1; l++) \
5012 fg_psij2 *= fg_psij1; \
5013 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l]; \
5016 uo(ths,j,&u,&o,(INT)1); \
5017 fg_psij0 = (PHI(ths->n[1],ths->x[3*j+1]-((R)u)/((R)n1),1)); \
5018 fg_psij1 = EXP(K(2.0)*(((R)n1)*(ths->x[3*j+1]) - (R)u)/ths->b[1]); \
5019 fg_psij2 = K(1.0); \
5020 psij_const[2*m+2] = fg_psij0; \
5021 for(l=1; l<=2*m+1; l++) \
5023 fg_psij2 *= fg_psij1; \
5024 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l]; \
5027 uo(ths,j,&u,&o,(INT)2); \
5028 fg_psij0 = (PHI(ths->n[2],ths->x[3*j+2]-((R)u)/((R)n2),2)); \
5029 fg_psij1 = EXP(K(2.0)*(((R)n2)*(ths->x[3*j+2]) - (R)u)/ths->b[2]); \
5030 fg_psij2 = K(1.0); \
5031 psij_const[2*(2*m+2)] = fg_psij0; \
5032 for(l=1; l<=2*m+1; l++) \
5034 fg_psij2 *= fg_psij1; \
5035 psij_const[2*(2*m+2)+l] = fg_psij0*fg_psij2*fg_exp_l[2*(2*m+2)+l]; \
5038 nfft_adjoint_3d_compute_omp_blockwise(ths->f[j], g, \
5039 psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, \
5040 ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, \
5041 n0, n1, n2, m, my_u0, my_o0); \
5044#define MACRO_adjoint_3d_B_OMP_BLOCKWISE_COMPUTE_PRE_LIN_PSI \
5047 R psij_const[3*(2*m+2)]; \
5051 uo(ths,j,&u,&o,(INT)0); \
5052 ip_y = FABS(((R)n0)*ths->x[3*j+0] - (R)u)*((R)ip_s); \
5053 ip_u = LRINT(FLOOR(ip_y)); \
5055 for(l=0; l < 2*m+2; l++) \
5056 psij_const[l] = ths->psi[ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) + \
5057 ths->psi[ABS(ip_u-l*ip_s+1)]*(ip_w); \
5059 uo(ths,j,&u,&o,(INT)1); \
5060 ip_y = FABS(((R)n1)*ths->x[3*j+1] - (R)u)*((R)ip_s); \
5061 ip_u = LRINT(FLOOR(ip_y)); \
5063 for(l=0; l < 2*m+2; l++) \
5064 psij_const[2*m+2+l] = ths->psi[(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) + \
5065 ths->psi[(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w); \
5067 uo(ths,j,&u,&o,(INT)2); \
5068 ip_y = FABS(((R)n2)*ths->x[3*j+2] - (R)u)*((R)ip_s); \
5069 ip_u = LRINT(FLOOR(ip_y)); \
5071 for(l=0; l < 2*m+2; l++) \
5072 psij_const[2*(2*m+2)+l] = ths->psi[2*(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) + \
5073 ths->psi[2*(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w); \
5075 nfft_adjoint_3d_compute_omp_blockwise(ths->f[j], g, \
5076 psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, \
5077 ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, \
5078 n0, n1, n2, m, my_u0, my_o0); \
5081#define MACRO_adjoint_3d_B_OMP_BLOCKWISE_COMPUTE_NO_PSI \
5084 R psij_const[3*(2*m+2)]; \
5086 uo(ths,j,&u,&o,(INT)0); \
5087 for(l=0;l<=2*m+1;l++) \
5088 psij_const[l]=(PHI(ths->n[0],ths->x[3*j]-((R)((u+l)))/((R) n0),0)); \
5090 uo(ths,j,&u,&o,(INT)1); \
5091 for(l=0;l<=2*m+1;l++) \
5092 psij_const[2*m+2+l]=(PHI(ths->n[1],ths->x[3*j+1]-((R)((u+l)))/((R) n1),1)); \
5094 uo(ths,j,&u,&o,(INT)2); \
5095 for(l=0;l<=2*m+1;l++) \
5096 psij_const[2*(2*m+2)+l]=(PHI(ths->n[2],ths->x[3*j+2]-((R)((u+l)))/((R) n2),2)); \
5098 nfft_adjoint_3d_compute_omp_blockwise(ths->f[j], g, \
5099 psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, \
5100 ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, \
5101 n0, n1, n2, m, my_u0, my_o0); \
5104#define MACRO_adjoint_3d_B_OMP_BLOCKWISE(whichone) \
5106 if (ths->flags & NFFT_OMP_BLOCKWISE_ADJOINT) \
5108 _Pragma("omp parallel private(k)") \
5110 INT my_u0, my_o0, min_u_a, max_u_a, min_u_b, max_u_b; \
5111 INT *ar_x = ths->index_x; \
5113 nfft_adjoint_B_omp_blockwise_init(&my_u0, &my_o0, &min_u_a, &max_u_a, \
5114 &min_u_b, &max_u_b, 3, ths->n, m); \
5116 if (min_u_a != -1) \
5118 k = index_x_binary_search(ar_x, M, min_u_a); \
5120 MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_A \
5124 INT u_prod = ar_x[2*k]; \
5125 INT j = ar_x[2*k+1]; \
5127 if (u_prod < min_u_a || u_prod > max_u_a) \
5130 MACRO_adjoint_3d_B_OMP_BLOCKWISE_COMPUTE_ ##whichone \
5136 if (min_u_b != -1) \
5138 INT k = index_x_binary_search(ar_x, M, min_u_b); \
5140 MACRO_adjoint_nd_B_OMP_BLOCKWISE_ASSERT_B \
5144 INT u_prod = ar_x[2*k]; \
5145 INT j = ar_x[2*k+1]; \
5147 if (u_prod < min_u_b || u_prod > max_u_b) \
5150 MACRO_adjoint_3d_B_OMP_BLOCKWISE_COMPUTE_ ##whichone \
5160static void nfft_adjoint_3d_B(X(plan) *ths)
5163 const INT n0 = ths->n[0];
5164 const INT n1 = ths->n[1];
5165 const INT n2 = ths->n[2];
5166 const INT M = ths->M_total;
5167 const INT m = ths->m;
5171 memset(g, 0, (
size_t)(ths->n_total) *
sizeof(C));
5175 nfft_adjoint_B_compute_full_psi(g, ths->psi_index_g, ths->psi, ths->f, M,
5176 (INT)3, ths->n, m, ths->flags, ths->index_x);
5183 MACRO_adjoint_3d_B_OMP_BLOCKWISE(
PRE_PSI)
5187 #pragma omp parallel for default(shared) private(k)
5189 for (k = 0; k < M; k++)
5191 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
5193 nfft_adjoint_3d_compute_omp_atomic(ths->f[j], g, ths->psi+j*3*(2*m+2), ths->psi+(j*3+1)*(2*m+2), ths->psi+(j*3+2)*(2*m+2), ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5195 nfft_adjoint_3d_compute_serial(ths->f+j, g, ths->psi+j*3*(2*m+2), ths->psi+(j*3+1)*(2*m+2), ths->psi+(j*3+2)*(2*m+2), ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5203 R fg_exp_l[3*(2*m+2+1)];
5205 nfft_3d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
5206 nfft_3d_init_fg_exp_l(fg_exp_l+2*m+2, m, ths->b[1]);
5207 nfft_3d_init_fg_exp_l(fg_exp_l+2*(2*m+2), m, ths->b[2]);
5214 #pragma omp parallel for default(shared) private(k)
5216 for (k = 0; k < M; k++)
5218 R psij_const[3*(2*m+2)];
5219 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
5221 R fg_psij0 = ths->psi[2*j*3];
5222 R fg_psij1 = ths->psi[2*j*3+1];
5223 R fg_psij2 = K(1.0);
5225 psij_const[0] = fg_psij0;
5226 for(l=1; l<=2*m+1; l++)
5228 fg_psij2 *= fg_psij1;
5229 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l];
5232 fg_psij0 = ths->psi[2*(j*3+1)];
5233 fg_psij1 = ths->psi[2*(j*3+1)+1];
5235 psij_const[2*m+2] = fg_psij0;
5236 for(l=1; l<=2*m+1; l++)
5238 fg_psij2 *= fg_psij1;
5239 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l];
5242 fg_psij0 = ths->psi[2*(j*3+2)];
5243 fg_psij1 = ths->psi[2*(j*3+2)+1];
5245 psij_const[2*(2*m+2)] = fg_psij0;
5246 for(l=1; l<=2*m+1; l++)
5248 fg_psij2 *= fg_psij1;
5249 psij_const[2*(2*m+2)+l] = fg_psij0*fg_psij2*fg_exp_l[2*(2*m+2)+l];
5253 nfft_adjoint_3d_compute_omp_atomic(ths->f[j], g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5255 nfft_adjoint_3d_compute_serial(ths->f+j, g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5264 R fg_exp_l[3*(2*m+2+1)];
5266 nfft_3d_init_fg_exp_l(fg_exp_l, m, ths->b[0]);
5267 nfft_3d_init_fg_exp_l(fg_exp_l+2*m+2, m, ths->b[1]);
5268 nfft_3d_init_fg_exp_l(fg_exp_l+2*(2*m+2), m, ths->b[2]);
5273 MACRO_adjoint_3d_B_OMP_BLOCKWISE(
FG_PSI)
5277 #pragma omp parallel for default(shared) private(k)
5279 for (k = 0; k < M; k++)
5282 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
5283 R psij_const[3*(2*m+2)];
5284 R fg_psij0, fg_psij1, fg_psij2;
5286 uo(ths,j,&u,&o,(INT)0);
5287 fg_psij0 = (PHI(ths->n[0], ths->x[3*j] - ((R)u) / (R)(n0),0));
5288 fg_psij1 = EXP(K(2.0) * ((R)(n0) * (ths->x[3*j]) - (R)(u))/ths->b[0]);
5290 psij_const[0] = fg_psij0;
5291 for(l=1; l<=2*m+1; l++)
5293 fg_psij2 *= fg_psij1;
5294 psij_const[l] = fg_psij0*fg_psij2*fg_exp_l[l];
5297 uo(ths,j,&u,&o,(INT)1);
5298 fg_psij0 = (PHI(ths->n[1], ths->x[3*j+1] - ((R)u) / (R)(n1),1));
5299 fg_psij1 = EXP(K(2.0) * ((R)(n1) * (ths->x[3*j+1]) - (R)(u))/ths->b[1]);
5301 psij_const[2*m+2] = fg_psij0;
5302 for(l=1; l<=2*m+1; l++)
5304 fg_psij2 *= fg_psij1;
5305 psij_const[2*m+2+l] = fg_psij0*fg_psij2*fg_exp_l[2*m+2+l];
5308 uo(ths,j,&u,&o,(INT)2);
5309 fg_psij0 = (PHI(ths->n[2], ths->x[3*j+2] - ((R)u) / (R)(n2),2));
5310 fg_psij1 = EXP(K(2.0) * ((R)(n2) * (ths->x[3*j+2]) - (R)(u))/ths->b[2]);
5312 psij_const[2*(2*m+2)] = fg_psij0;
5313 for(l=1; l<=2*m+1; l++)
5315 fg_psij2 *= fg_psij1;
5316 psij_const[2*(2*m+2)+l] = fg_psij0*fg_psij2*fg_exp_l[2*(2*m+2)+l];
5320 nfft_adjoint_3d_compute_omp_atomic(ths->f[j], g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5322 nfft_adjoint_3d_compute_serial(ths->f+j, g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5331 const INT K = ths->K;
5332 const INT ip_s = K / (m + 2);
5341 #pragma omp parallel for default(shared) private(k)
5343 for (k = 0; k < M; k++)
5348 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
5349 R psij_const[3*(2*m+2)];
5351 uo(ths,j,&u,&o,(INT)0);
5352 ip_y = FABS((R)(n0) * ths->x[3*j+0] - (R)(u)) * ((R)ip_s);
5353 ip_u = (INT)(LRINT(FLOOR(ip_y)));
5354 ip_w = ip_y - (R)(ip_u);
5355 for(l=0; l < 2*m+2; l++)
5356 psij_const[l] = ths->psi[ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) +
5357 ths->psi[ABS(ip_u-l*ip_s+1)]*(ip_w);
5359 uo(ths,j,&u,&o,(INT)1);
5360 ip_y = FABS((R)(n1) * ths->x[3*j+1] - (R)(u)) * ((R)ip_s);
5361 ip_u = (INT)(LRINT(FLOOR(ip_y)));
5362 ip_w = ip_y - (R)(ip_u);
5363 for(l=0; l < 2*m+2; l++)
5364 psij_const[2*m+2+l] = ths->psi[(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) +
5365 ths->psi[(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w);
5367 uo(ths,j,&u,&o,(INT)2);
5368 ip_y = FABS((R)(n2) * ths->x[3*j+2] - (R)(u))*((R)ip_s);
5369 ip_u = (INT)(LRINT(FLOOR(ip_y)));
5370 ip_w = ip_y - (R)(ip_u);
5371 for(l=0; l < 2*m+2; l++)
5372 psij_const[2*(2*m+2)+l] = ths->psi[2*(K+1)+ABS(ip_u-l*ip_s)]*(K(1.0)-ip_w) +
5373 ths->psi[2*(K+1)+ABS(ip_u-l*ip_s+1)]*(ip_w);
5376 nfft_adjoint_3d_compute_omp_atomic(ths->f[j], g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5378 nfft_adjoint_3d_compute_serial(ths->f+j, g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5388 MACRO_adjoint_3d_B_OMP_BLOCKWISE(NO_PSI)
5392 #pragma omp parallel for default(shared) private(k)
5394 for (k = 0; k < M; k++)
5397 R psij_const[3*(2*m+2)];
5398 INT j = (ths->flags & NFFT_SORT_NODES) ? ths->index_x[2*k+1] : k;
5400 uo(ths,j,&u,&o,(INT)0);
5401 for(l=0;l<=2*m+1;l++)
5402 psij_const[l]=(PHI(ths->n[0], ths->x[3*j] - ((R)((u+l))) / (R)(n0),0));
5404 uo(ths,j,&u,&o,(INT)1);
5405 for(l=0;l<=2*m+1;l++)
5406 psij_const[2*m+2+l]=(PHI(ths->n[1], ths->x[3*j+1] - ((R)((u+l))) / (R)(n1),1));
5408 uo(ths,j,&u,&o,(INT)2);
5409 for(l=0;l<=2*m+1;l++)
5410 psij_const[2*(2*m+2)+l]=(PHI(ths->n[2], ths->x[3*j+2] - ((R)((u+l))) / (R)(n2),2));
5413 nfft_adjoint_3d_compute_omp_atomic(ths->f[j], g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5415 nfft_adjoint_3d_compute_serial(ths->f+j, g, psij_const, psij_const+2*m+2, psij_const+(2*m+2)*2, ths->x+3*j, ths->x+3*j+1, ths->x+3*j+2, n0, n1, n2, m);
5421void X(trafo_3d)(X(plan) *ths)
5423 if((ths->N[0] <= ths->m) || (ths->N[1] <= ths->m) || (ths->N[2] <= ths->m) || (ths->n[0] <= 2*ths->m+2) || (ths->n[1] <= 2*ths->m+2) || (ths->n[2] <= 2*ths->m+2))
5425 X(trafo_direct)(ths);
5429 INT k0,k1,k2,n0,n1,n2,N0,N1,N2;
5431 R *c_phi_inv01, *c_phi_inv02, *c_phi_inv11, *c_phi_inv12, *c_phi_inv21, *c_phi_inv22;
5432 R ck01, ck02, ck11, ck12, ck21, ck22;
5433 C *g_hat111,*f_hat111,*g_hat211,*f_hat211,*g_hat121,*f_hat121,*g_hat221,*f_hat221;
5434 C *g_hat112,*f_hat112,*g_hat212,*f_hat212,*g_hat122,*f_hat122,*g_hat222,*f_hat222;
5446 f_hat=(C*)ths->f_hat;
5447 g_hat=(C*)ths->g_hat;
5451 #pragma omp parallel for default(shared) private(k0)
5452 for (k0 = 0; k0 < ths->n_total; k0++)
5453 ths->g_hat[k0] = 0.0;
5455 memset(ths->g_hat, 0, (
size_t)(ths->n_total) *
sizeof(C));
5460 c_phi_inv01=ths->c_phi_inv[0];
5461 c_phi_inv02=&ths->c_phi_inv[0][N0/2];
5464 #pragma omp parallel for default(shared) private(k0,k1,k2,ck01,ck02,c_phi_inv11,c_phi_inv12,ck11,ck12,c_phi_inv21,c_phi_inv22,g_hat111,f_hat111,g_hat211,f_hat211,g_hat121,f_hat121,g_hat221,f_hat221,g_hat112,f_hat112,g_hat212,f_hat212,g_hat122,f_hat122,g_hat222,f_hat222,ck21,ck22)
5466 for(k0=0;k0<N0/2;k0++)
5468 ck01=c_phi_inv01[k0];
5469 ck02=c_phi_inv02[k0];
5470 c_phi_inv11=ths->c_phi_inv[1];
5471 c_phi_inv12=&ths->c_phi_inv[1][N1/2];
5473 for(k1=0;k1<N1/2;k1++)
5475 ck11=c_phi_inv11[k1];
5476 ck12=c_phi_inv12[k1];
5477 c_phi_inv21=ths->c_phi_inv[2];
5478 c_phi_inv22=&ths->c_phi_inv[2][N2/2];
5480 g_hat111=g_hat + ((n0-(N0/2)+k0)*n1+n1-(N1/2)+k1)*n2+n2-(N2/2);
5481 f_hat111=f_hat + (k0*N1+k1)*N2;
5482 g_hat211=g_hat + (k0*n1+n1-(N1/2)+k1)*n2+n2-(N2/2);
5483 f_hat211=f_hat + (((N0/2)+k0)*N1+k1)*N2;
5484 g_hat121=g_hat + ((n0-(N0/2)+k0)*n1+k1)*n2+n2-(N2/2);
5485 f_hat121=f_hat + (k0*N1+(N1/2)+k1)*N2;
5486 g_hat221=g_hat + (k0*n1+k1)*n2+n2-(N2/2);
5487 f_hat221=f_hat + (((N0/2)+k0)*N1+(N1/2)+k1)*N2;
5489 g_hat112=g_hat + ((n0-(N0/2)+k0)*n1+n1-(N1/2)+k1)*n2;
5490 f_hat112=f_hat + (k0*N1+k1)*N2+(N2/2);
5491 g_hat212=g_hat + (k0*n1+n1-(N1/2)+k1)*n2;
5492 f_hat212=f_hat + (((N0/2)+k0)*N1+k1)*N2+(N2/2);
5493 g_hat122=g_hat + ((n0-(N0/2)+k0)*n1+k1)*n2;
5494 f_hat122=f_hat + (k0*N1+N1/2+k1)*N2+(N2/2);
5495 g_hat222=g_hat + (k0*n1+k1)*n2;
5496 f_hat222=f_hat + (((N0/2)+k0)*N1+(N1/2)+k1)*N2+(N2/2);
5498 for(k2=0;k2<N2/2;k2++)
5500 ck21=c_phi_inv21[k2];
5501 ck22=c_phi_inv22[k2];
5503 g_hat111[k2] = f_hat111[k2] * ck01 * ck11 * ck21;
5504 g_hat211[k2] = f_hat211[k2] * ck02 * ck11 * ck21;
5505 g_hat121[k2] = f_hat121[k2] * ck01 * ck12 * ck21;
5506 g_hat221[k2] = f_hat221[k2] * ck02 * ck12 * ck21;
5508 g_hat112[k2] = f_hat112[k2] * ck01 * ck11 * ck22;
5509 g_hat212[k2] = f_hat212[k2] * ck02 * ck11 * ck22;
5510 g_hat122[k2] = f_hat122[k2] * ck01 * ck12 * ck22;
5511 g_hat222[k2] = f_hat222[k2] * ck02 * ck12 * ck22;
5518 #pragma omp parallel for default(shared) private(k0,k1,k2,ck01,ck02,ck11,ck12,ck21,ck22)
5520 for(k0=0;k0<N0/2;k0++)
5522 ck01=K(1.0)/(PHI_HUT(ths->n[0],k0-N0/2,0));
5523 ck02=K(1.0)/(PHI_HUT(ths->n[0],k0,0));
5524 for(k1=0;k1<N1/2;k1++)
5526 ck11=K(1.0)/(PHI_HUT(ths->n[1],k1-N1/2,1));
5527 ck12=K(1.0)/(PHI_HUT(ths->n[1],k1,1));
5529 for(k2=0;k2<N2/2;k2++)
5531 ck21=K(1.0)/(PHI_HUT(ths->n[2],k2-N2/2,2));
5532 ck22=K(1.0)/(PHI_HUT(ths->n[2],k2,2));
5534 g_hat[((n0-N0/2+k0)*n1+n1-N1/2+k1)*n2+n2-N2/2+k2] = f_hat[(k0*N1+k1)*N2+k2] * ck01 * ck11 * ck21;
5535 g_hat[(k0*n1+n1-N1/2+k1)*n2+n2-N2/2+k2] = f_hat[((N0/2+k0)*N1+k1)*N2+k2] * ck02 * ck11 * ck21;
5536 g_hat[((n0-N0/2+k0)*n1+k1)*n2+n2-N2/2+k2] = f_hat[(k0*N1+N1/2+k1)*N2+k2] * ck01 * ck12 * ck21;
5537 g_hat[(k0*n1+k1)*n2+n2-N2/2+k2] = f_hat[((N0/2+k0)*N1+N1/2+k1)*N2+k2] * ck02 * ck12 * ck21;
5539 g_hat[((n0-N0/2+k0)*n1+n1-N1/2+k1)*n2+k2] = f_hat[(k0*N1+k1)*N2+N2/2+k2] * ck01 * ck11 * ck22;
5540 g_hat[(k0*n1+n1-N1/2+k1)*n2+k2] = f_hat[((N0/2+k0)*N1+k1)*N2+N2/2+k2] * ck02 * ck11 * ck22;
5541 g_hat[((n0-N0/2+k0)*n1+k1)*n2+k2] = f_hat[(k0*N1+N1/2+k1)*N2+N2/2+k2] * ck01 * ck12 * ck22;
5542 g_hat[(k0*n1+k1)*n2+k2] = f_hat[((N0/2+k0)*N1+N1/2+k1)*N2+N2/2+k2] * ck02 * ck12 * ck22;
5550 FFTW(execute)(ths->my_fftw_plan1);
5554 nfft_trafo_3d_B(ths);
5558void X(adjoint_3d)(X(plan) *ths)
5560 if((ths->N[0] <= ths->m) || (ths->N[1] <= ths->m) || (ths->N[2] <= ths->m) || (ths->n[0] <= 2*ths->m+2) || (ths->n[1] <= 2*ths->m+2) || (ths->n[2] <= 2*ths->m+2))
5562 X(adjoint_direct)(ths);
5566 INT k0,k1,k2,n0,n1,n2,N0,N1,N2;
5568 R *c_phi_inv01, *c_phi_inv02, *c_phi_inv11, *c_phi_inv12, *c_phi_inv21, *c_phi_inv22;
5569 R ck01, ck02, ck11, ck12, ck21, ck22;
5570 C *g_hat111,*f_hat111,*g_hat211,*f_hat211,*g_hat121,*f_hat121,*g_hat221,*f_hat221;
5571 C *g_hat112,*f_hat112,*g_hat212,*f_hat212,*g_hat122,*f_hat122,*g_hat222,*f_hat222;
5583 f_hat=(C*)ths->f_hat;
5584 g_hat=(C*)ths->g_hat;
5587 nfft_adjoint_3d_B(ths);
5591 FFTW(execute)(ths->my_fftw_plan2);
5597 c_phi_inv01=ths->c_phi_inv[0];
5598 c_phi_inv02=&ths->c_phi_inv[0][N0/2];
5601 #pragma omp parallel for default(shared) private(k0,k1,k2,ck01,ck02,c_phi_inv11,c_phi_inv12,ck11,ck12,c_phi_inv21,c_phi_inv22,g_hat111,f_hat111,g_hat211,f_hat211,g_hat121,f_hat121,g_hat221,f_hat221,g_hat112,f_hat112,g_hat212,f_hat212,g_hat122,f_hat122,g_hat222,f_hat222,ck21,ck22)
5603 for(k0=0;k0<N0/2;k0++)
5605 ck01=c_phi_inv01[k0];
5606 ck02=c_phi_inv02[k0];
5607 c_phi_inv11=ths->c_phi_inv[1];
5608 c_phi_inv12=&ths->c_phi_inv[1][N1/2];
5610 for(k1=0;k1<N1/2;k1++)
5612 ck11=c_phi_inv11[k1];
5613 ck12=c_phi_inv12[k1];
5614 c_phi_inv21=ths->c_phi_inv[2];
5615 c_phi_inv22=&ths->c_phi_inv[2][N2/2];
5617 g_hat111=g_hat + ((n0-(N0/2)+k0)*n1+n1-(N1/2)+k1)*n2+n2-(N2/2);
5618 f_hat111=f_hat + (k0*N1+k1)*N2;
5619 g_hat211=g_hat + (k0*n1+n1-(N1/2)+k1)*n2+n2-(N2/2);
5620 f_hat211=f_hat + (((N0/2)+k0)*N1+k1)*N2;
5621 g_hat121=g_hat + ((n0-(N0/2)+k0)*n1+k1)*n2+n2-(N2/2);
5622 f_hat121=f_hat + (k0*N1+(N1/2)+k1)*N2;
5623 g_hat221=g_hat + (k0*n1+k1)*n2+n2-(N2/2);
5624 f_hat221=f_hat + (((N0/2)+k0)*N1+(N1/2)+k1)*N2;
5626 g_hat112=g_hat + ((n0-(N0/2)+k0)*n1+n1-(N1/2)+k1)*n2;
5627 f_hat112=f_hat + (k0*N1+k1)*N2+(N2/2);
5628 g_hat212=g_hat + (k0*n1+n1-(N1/2)+k1)*n2;
5629 f_hat212=f_hat + (((N0/2)+k0)*N1+k1)*N2+(N2/2);
5630 g_hat122=g_hat + ((n0-(N0/2)+k0)*n1+k1)*n2;
5631 f_hat122=f_hat + (k0*N1+(N1/2)+k1)*N2+(N2/2);
5632 g_hat222=g_hat + (k0*n1+k1)*n2;
5633 f_hat222=f_hat + (((N0/2)+k0)*N1+(N1/2)+k1)*N2+(N2/2);
5635 for(k2=0;k2<N2/2;k2++)
5637 ck21=c_phi_inv21[k2];
5638 ck22=c_phi_inv22[k2];
5640 f_hat111[k2] = g_hat111[k2] * ck01 * ck11 * ck21;
5641 f_hat211[k2] = g_hat211[k2] * ck02 * ck11 * ck21;
5642 f_hat121[k2] = g_hat121[k2] * ck01 * ck12 * ck21;
5643 f_hat221[k2] = g_hat221[k2] * ck02 * ck12 * ck21;
5645 f_hat112[k2] = g_hat112[k2] * ck01 * ck11 * ck22;
5646 f_hat212[k2] = g_hat212[k2] * ck02 * ck11 * ck22;
5647 f_hat122[k2] = g_hat122[k2] * ck01 * ck12 * ck22;
5648 f_hat222[k2] = g_hat222[k2] * ck02 * ck12 * ck22;
5655 #pragma omp parallel for default(shared) private(k0,k1,k2,ck01,ck02,ck11,ck12,ck21,ck22)
5657 for(k0=0;k0<N0/2;k0++)
5659 ck01=K(1.0)/(PHI_HUT(ths->n[0],k0-N0/2,0));
5660 ck02=K(1.0)/(PHI_HUT(ths->n[0],k0,0));
5661 for(k1=0;k1<N1/2;k1++)
5663 ck11=K(1.0)/(PHI_HUT(ths->n[1],k1-N1/2,1));
5664 ck12=K(1.0)/(PHI_HUT(ths->n[1],k1,1));
5666 for(k2=0;k2<N2/2;k2++)
5668 ck21=K(1.0)/(PHI_HUT(ths->n[2],k2-N2/2,2));
5669 ck22=K(1.0)/(PHI_HUT(ths->n[2],k2,2));
5671 f_hat[(k0*N1+k1)*N2+k2] = g_hat[((n0-N0/2+k0)*n1+n1-N1/2+k1)*n2+n2-N2/2+k2] * ck01 * ck11 * ck21;
5672 f_hat[((N0/2+k0)*N1+k1)*N2+k2] = g_hat[(k0*n1+n1-N1/2+k1)*n2+n2-N2/2+k2] * ck02 * ck11 * ck21;
5673 f_hat[(k0*N1+N1/2+k1)*N2+k2] = g_hat[((n0-N0/2+k0)*n1+k1)*n2+n2-N2/2+k2] * ck01 * ck12 * ck21;
5674 f_hat[((N0/2+k0)*N1+N1/2+k1)*N2+k2] = g_hat[(k0*n1+k1)*n2+n2-N2/2+k2] * ck02 * ck12 * ck21;
5676 f_hat[(k0*N1+k1)*N2+N2/2+k2] = g_hat[((n0-N0/2+k0)*n1+n1-N1/2+k1)*n2+k2] * ck01 * ck11 * ck22;
5677 f_hat[((N0/2+k0)*N1+k1)*N2+N2/2+k2] = g_hat[(k0*n1+n1-N1/2+k1)*n2+k2] * ck02 * ck11 * ck22;
5678 f_hat[(k0*N1+N1/2+k1)*N2+N2/2+k2] = g_hat[((n0-N0/2+k0)*n1+k1)*n2+k2] * ck01 * ck12 * ck22;
5679 f_hat[((N0/2+k0)*N1+N1/2+k1)*N2+N2/2+k2] = g_hat[(k0*n1+k1)*n2+k2] * ck02 * ck12 * ck22;
5689void X(trafo)(X(plan) *ths)
5692 for (
int j = 0; j < ths->d; j++)
5694 if((ths->N[j] <= ths->m) || (ths->n[j] <= 2*ths->m+2))
5696 X(trafo_direct)(ths);
5703 case 1: X(trafo_1d)(ths);
break;
5704 case 2: X(trafo_2d)(ths);
break;
5705 case 3: X(trafo_3d)(ths);
break;
5709 ths->g_hat = ths->g1;
5724 FFTW(execute)(ths->my_fftw_plan1);
5737void X(adjoint)(X(plan) *ths)
5740 for (
int j = 0; j < ths->d; j++)
5742 if((ths->N[j] <= ths->m) || (ths->n[j] <= 2*ths->m+2))
5744 X(adjoint_direct)(ths);
5751 case 1: X(adjoint_1d)(ths);
break;
5752 case 2: X(adjoint_2d)(ths);
break;
5753 case 3: X(adjoint_3d)(ths);
break;
5772 FFTW(execute)(ths->my_fftw_plan2);
5788static
void precompute_phi_hut(X(plan) *ths)
5793 ths->c_phi_inv = (R**) Y(malloc)((size_t)(ths->d) *
sizeof(R*));
5795 for (t = 0; t < ths->d; t++)
5797 ths->c_phi_inv[t] = (R*)Y(malloc)((size_t)(ths->N[t]) *
sizeof(R));
5799 for (ks[t] = 0; ks[t] < ths->N[t]; ks[t]++)
5801 ths->c_phi_inv[t][ks[t]]= K(1.0) / (PHI_HUT(ths->n[t], ks[t] - ths->N[t] / 2,t));
5810void X(precompute_lin_psi)(X(plan) *ths)
5816 for (t=0; t<ths->d; t++)
5818 step = ((R)(ths->m+2)) / ((R)(ths->K * ths->n[t]));
5819 for(j = 0;j <= ths->K; j++)
5821 ths->psi[(ths->K+1)*t + j] = PHI(ths->n[t], (R)(j) * step,t);
5826void X(precompute_fg_psi)(X(plan) *ths)
5833 for (t=0; t<ths->d; t++)
5837 #pragma omp parallel for default(shared) private(j,u,o)
5839 for (j = 0; j < ths->M_total; j++)
5843 ths->psi[2*(j*ths->d+t)]=
5844 (PHI(ths->n[t] ,(ths->x[j*ths->d+t] - ((R)u) / (R)(ths->n[t])),t));
5846 ths->psi[2*(j*ths->d+t)+1]=
5847 EXP(K(2.0) * ((R)(ths->n[t]) * ths->x[j*ths->d+t] - (R)(u)) / ths->b[t]);
5853void X(precompute_psi)(X(plan) *ths)
5862 for (t=0; t<ths->d; t++)
5866 #pragma omp parallel for default(shared) private(j,l,lj,u,o)
5868 for (j = 0; j < ths->M_total; j++)
5872 for(l = u, lj = 0; l <= o; l++, lj++)
5873 ths->psi[(j * ths->d + t) * (2 * ths->m + 2) + lj] =
5874 (PHI(ths->n[t], (ths->x[j*ths->d+t] - ((R)l) / (R)(ths->n[t])), t));
5881static void nfft_precompute_full_psi_omp(X(plan) *ths)
5888 for(t=0,lprod = 1; t<ths->d; t++)
5889 lprod *= 2*ths->m+2;
5892 #pragma omp parallel for default(shared) private(j)
5893 for(j=0; j<ths->M_total; j++)
5898 INT ll_plain[ths->d+1];
5900 INT u[ths->d], o[ths->d];
5902 R phi_prod[ths->d+1];
5908 MACRO_init_uo_l_lj_t;
5910 for(l_L=0; l_L<lprod; l_L++, ix++)
5912 MACRO_update_phi_prod_ll_plain(without_PRE_PSI);
5914 ths->psi_index_g[ix]=ll_plain[ths->d];
5915 ths->psi[ix]=phi_prod[ths->d];
5917 MACRO_count_uo_l_lj_t;
5920 ths->psi_index_f[j]=lprod;
5925void X(precompute_full_psi)(X(plan) *ths)
5930 nfft_precompute_full_psi_omp(ths);
5936 INT ll_plain[ths->d+1];
5938 INT u[ths->d], o[ths->d];
5940 R phi_prod[ths->d+1];
5946 phi_prod[0] = K(1.0);
5949 for (t = 0, lprod = 1; t < ths->d; t++)
5950 lprod *= 2 * ths->m + 2;
5952 for (j = 0, ix = 0, ix_old = 0; j < ths->M_total; j++)
5954 MACRO_init_uo_l_lj_t;
5956 for (l_L = 0; l_L < lprod; l_L++, ix++)
5958 MACRO_update_phi_prod_ll_plain(without_PRE_PSI);
5960 ths->psi_index_g[ix] = ll_plain[ths->d];
5961 ths->psi[ix] = phi_prod[ths->d];
5963 MACRO_count_uo_l_lj_t;
5966 ths->psi_index_f[j] = ix - ix_old;
5972void X(precompute_one_psi)(X(plan) *ths)
5975 X(precompute_lin_psi)(ths);
5977 X(precompute_fg_psi)(ths);
5979 X(precompute_psi)(ths);
5981 X(precompute_full_psi)(ths);
5984static void init_help(X(plan) *ths)
5989 if (ths->flags & NFFT_OMP_BLOCKWISE_ADJOINT)
5990 ths->flags |= NFFT_SORT_NODES;
5992 ths->N_total = intprod(ths->N, 0, ths->d);
5993 ths->n_total = intprod(ths->n, 0, ths->d);
5995 ths->sigma = (R*) Y(malloc)((size_t)(ths->d) *
sizeof(R));
5997 for(t = 0;t < ths->d; t++)
5998 ths->sigma[t] = ((R)ths->n[t]) / (R)(ths->N[t]);
6003 ths->x = (R*)Y(malloc)((size_t)(ths->d * ths->M_total) *
sizeof(R));
6006 ths->f_hat = (C*)Y(malloc)((size_t)(ths->N_total) *
sizeof(C));
6009 ths->f = (C*)Y(malloc)((size_t)(ths->M_total) *
sizeof(C));
6012 precompute_phi_hut(ths);
6018 ths->K = Y(m2K)(ths->m);
6020 ths->psi = (R*) Y(malloc)((size_t)((ths->K+1) * ths->d) *
sizeof(R));
6024 ths->psi = (R*) Y(malloc)((size_t)(ths->M_total * ths->d * 2) *
sizeof(R));
6027 ths->psi = (R*) Y(malloc)((size_t)(ths->M_total * ths->d * (2 * ths->m + 2)) *
sizeof(R));
6031 for (t = 0, lprod = 1; t < ths->d; t++)
6032 lprod *= 2 * ths->m + 2;
6034 ths->psi = (R*) Y(malloc)((size_t)(ths->M_total * lprod) *
sizeof(R));
6036 ths->psi_index_f = (INT*) Y(malloc)((size_t)(ths->M_total) *
sizeof(INT));
6037 ths->psi_index_g = (INT*) Y(malloc)((size_t)(ths->M_total * lprod) *
sizeof(INT));
6043 INT nthreads = Y(get_num_threads)();
6046 ths->g1 = (C*)Y(malloc)((size_t)(ths->n_total) *
sizeof(C));
6049 ths->g2 = (C*) Y(malloc)((size_t)(ths->n_total) *
sizeof(C));
6053#if defined(_OPENMP) && defined(HAVE_FFTW_THREADS)
6054#pragma omp critical (nfft_omp_critical_fftw_plan)
6056 FFTW(plan_with_nthreads)(nthreads);
6059 int *_n = Y(malloc)((size_t)(ths->d) *
sizeof(int));
6061 for (t = 0; t < ths->d; t++)
6062 _n[t] = (
int)(ths->n[t]);
6064 ths->my_fftw_plan1 = FFTW(plan_dft)((int)ths->d, _n, ths->g1, ths->g2, FFTW_FORWARD, ths->fftw_flags);
6065 ths->my_fftw_plan2 = FFTW(plan_dft)((int)ths->d, _n, ths->g2, ths->g1, FFTW_BACKWARD, ths->fftw_flags);
6068#if defined(_OPENMP) && defined(HAVE_FFTW_THREADS)
6073 if(ths->flags & NFFT_SORT_NODES)
6074 ths->index_x = (INT*) Y(malloc)(
sizeof(INT) * 2U * (
size_t)(ths->M_total));
6076 ths->index_x = NULL;
6078 ths->mv_trafo = (void (*) (
void* ))X(trafo);
6079 ths->mv_adjoint = (void (*) (
void* ))X(adjoint);
6082void X(init)(X(plan) *ths,
int d,
int *N,
int M_total)
6088 ths->N = (INT*) Y(malloc)((size_t)(d) *
sizeof(INT));
6090 for (t = 0; t < d; t++)
6091 ths->N[t] = (INT)N[t];
6093 ths->M_total = (INT)M_total;
6095 ths->n = (INT*) Y(malloc)((size_t)(d) *
sizeof(INT));
6097 for (t = 0; t < d; t++)
6098 ths->n[t] = 2 * (Y(next_power_of_2)(ths->N[t]));
6100 ths->m = WINDOW_HELP_ESTIMATE_m;
6107 NFFT_OMP_BLOCKWISE_ADJOINT;
6117 ths->fftw_flags= FFTW_ESTIMATE| FFTW_DESTROY_INPUT;
6123void X(init_guru)(X(plan) *ths,
int d,
int *N,
int M_total,
int *n,
int m,
6124 unsigned flags,
unsigned fftw_flags)
6129 ths->M_total = (INT)M_total;
6130 ths->N = (INT*)Y(malloc)((size_t)(ths->d) *
sizeof(INT));
6132 for (t = 0; t < d; t++)
6133 ths->N[t] = (INT)N[t];
6135 ths->n = (INT*)Y(malloc)((size_t)(ths->d) *
sizeof(INT));
6137 for (t = 0; t < d; t++)
6138 ths->n[t] = (INT)n[t];
6143 ths->fftw_flags = fftw_flags;
6149void X(init_lin)(X(plan) *ths,
int d,
int *N,
int M_total,
int *n,
int m,
int K,
6150 unsigned flags,
unsigned fftw_flags)
6155 ths->M_total = (INT)M_total;
6156 ths->N = (INT*)Y(malloc)((size_t)(ths->d) *
sizeof(INT));
6158 for (t = 0; t < d; t++)
6159 ths->N[t] = (INT)N[t];
6161 ths->n = (INT*)Y(malloc)((size_t)(ths->d) *
sizeof(INT));
6163 for (t = 0; t < d; t++)
6164 ths->n[t] = (INT)n[t];
6169 ths->fftw_flags = fftw_flags;
6175void X(init_1d)(X(plan) *ths,
int N1,
int M_total)
6181 X(init)(ths, 1, N, M_total);
6184void X(init_2d)(X(plan) *ths,
int N1,
int N2,
int M_total)
6190 X(init)(ths, 2, N, M_total);
6193void X(init_3d)(X(plan) *ths,
int N1,
int N2,
int N3,
int M_total)
6200 X(init)(ths, 3, N, M_total);
6203const char* X(check)(X(plan) *ths)
6208 return "Member f not initialized.";
6211 return "Member x not initialized.";
6214 return "Member f_hat not initialized.";
6216 if ((ths->flags &
PRE_LIN_PSI) && ths->K < ths->M_total)
6217 return "Number of nodes too small to use PRE_LIN_PSI.";
6219 for (j = 0; j < ths->M_total * ths->d; j++)
6221 if ((ths->x[j]<-K(0.5)) || (ths->x[j]>= K(0.5)))
6223 return "ths->x out of range [-0.5,0.5)";
6227 for (j = 0; j < ths->d; j++)
6229 if (ths->sigma[j] <= 1)
6230 return "Oversampling factor too small";
6237 if(ths->N[j]%2 == 1)
6238 return "polynomial degree N has to be even";
6243void X(finalize)(X(plan) *ths)
6247 if(ths->flags & NFFT_SORT_NODES)
6248 Y(free)(ths->index_x);
6253 #pragma omp critical (nfft_omp_critical_fftw_plan)
6255 FFTW(destroy_plan)(ths->my_fftw_plan2);
6257 #pragma omp critical (nfft_omp_critical_fftw_plan)
6259 FFTW(destroy_plan)(ths->my_fftw_plan1);
6269 Y(free)(ths->psi_index_g);
6270 Y(free)(ths->psi_index_f);
6285 for (t = 0; t < ths->d; t++)
6286 Y(free)(ths->c_phi_inv[t]);
6287 Y(free)(ths->c_phi_inv);
6294 Y(free)(ths->f_hat);
6299 WINDOW_HELP_FINALIZE;
6301 Y(free)(ths->sigma);
#define TIC(a)
Timing, method works since the inaccurate timer is updated mostly in the measured function.
#define UNUSED(x)
Dummy use of unused parameters to silence compiler warnings.
Internal header file for auxiliary definitions and functions.
Header file for the nfft3 library.