NFFT Logo 3.2.3
nsfft.c
1 /*
2  * Copyright (c) 2002, 2012 Jens Keiner, Stefan Kunis, Daniel Potts
3  *
4  * This program is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 /* $Id: nsfft.c 3896 2012-10-10 12:19:26Z tovo $ */
20 #include "config.h"
21 
22 #include <stdio.h>
23 #include <math.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #ifdef HAVE_COMPLEX_H
27 #include <complex.h>
28 #endif
29 #include "nfft3util.h"
30 #include "nfft3.h"
31 #include "infft.h"
32 
33 #define NSFTT_DISABLE_TEST
34 
35 /* computes a 2d ndft by 1d nfft along the dimension 1 times
36  1d ndft along dimension 0
37 */
38 static void short_nfft_trafo_2d(nfft_plan* ths, nfft_plan* plan_1d)
39 {
40  int j,k0;
41  double omega;
42 
43  for(j=0;j<ths->M_total;j++)
44  {
45  ths->f[j]= 0;
46  plan_1d->x[j] = ths->x[ths->d * j + 1];
47  }
48 
49  for(k0=0;k0<ths->N[0];k0++) /* for shorties */
50  {
51  plan_1d->f_hat = ths->f_hat + k0*ths->N[1];
52 
53  nfft_trafo(plan_1d);
54 
55  for(j=0;j<ths->M_total;j++)
56  {
57  omega = ((double)(k0 - ths->N[0]/2)) * ths->x[ths->d * j + 0];
58  ths->f[j] += plan_1d->f[j] * cexp( - I*2*PI*omega);
59  }
60  }
61 }
62 
63 static void short_nfft_adjoint_2d(nfft_plan* ths, nfft_plan* plan_1d)
64 {
65  int j,k0;
66  double omega;
67 
68  for(j=0;j<ths->M_total;j++)
69  plan_1d->x[j] = ths->x[ths->d * j + 1];
70 
71  for(k0=0;k0<ths->N[0];k0++) /* for shorties */
72  {
73  for(j=0;j<ths->M_total;j++)
74  {
75  omega = ((double)(k0 - ths->N[0]/2)) * ths->x[ths->d * j + 0];
76  plan_1d->f[j] = ths->f[j] * cexp( + _Complex_I*2*PI*omega);
77  }
78 
79  plan_1d->f_hat = ths->f_hat + k0*ths->N[1];
80 
81  nfft_adjoint(plan_1d);
82  }
83 }
84 
85 /* computes a 3d ndft by 1d nfft along the dimension 2 times
86  2d ndft along dimension 0,1
87 */
88 static void short_nfft_trafo_3d_1(nfft_plan* ths, nfft_plan* plan_1d)
89 {
90  int j,k0,k1;
91  double omega;
92 
93  for(j=0;j<ths->M_total;j++)
94  {
95  ths->f[j] = 0;
96  plan_1d->x[j] = ths->x[ths->d * j + 2];
97  }
98 
99  for(k0=0;k0<ths->N[0];k0++) /* for shorties */
100  for(k1=0;k1<ths->N[1];k1++)
101  {
102  plan_1d->f_hat = ths->f_hat + (k0*ths->N[1]+k1)*ths->N[2];
103 
104  nfft_trafo(plan_1d);
105 
106  for(j=0;j<ths->M_total;j++)
107  {
108  omega = ((double)(k0 - ths->N[0]/2)) * ths->x[ths->d * j + 0]
109  + ((double)(k1 - ths->N[1]/2)) * ths->x[ths->d * j + 1];
110  ths->f[j] += plan_1d->f[j] * cexp( - I*2*PI*omega);
111  }
112  }
113 }
114 
115 static void short_nfft_adjoint_3d_1(nfft_plan* ths, nfft_plan* plan_1d)
116 {
117  int j,k0,k1;
118  double omega;
119 
120  for(j=0;j<ths->M_total;j++)
121  plan_1d->x[j] = ths->x[ths->d * j + 2];
122 
123  for(k0=0;k0<ths->N[0];k0++) /* for shorties */
124  for(k1=0;k1<ths->N[1];k1++)
125  {
126  for(j=0;j<ths->M_total;j++)
127  {
128  omega = ((double)(k0 - ths->N[0]/2)) * ths->x[ths->d * j + 0]
129  + ((double)(k1 - ths->N[1]/2)) * ths->x[ths->d * j + 1];
130  plan_1d->f[j] = ths->f[j] * cexp( + _Complex_I*2*PI*omega);
131  }
132 
133  plan_1d->f_hat = ths->f_hat + (k0*ths->N[1]+k1)*ths->N[2];
134 
135  nfft_adjoint(plan_1d);
136  }
137 }
138 
139 /* computes a 3d ndft by 2d nfft along the dimension 1,2 times
140  1d ndft along dimension 0
141 */
142 static void short_nfft_trafo_3d_2(nfft_plan* ths, nfft_plan* plan_2d)
143 {
144  int j,k0;
145  double omega;
146 
147  for(j=0;j<ths->M_total;j++)
148  {
149  ths->f[j] = 0;
150  plan_2d->x[2*j+0] = ths->x[ths->d * j + 1];
151  plan_2d->x[2*j+1] = ths->x[ths->d * j + 2];
152  }
153 
154  for(k0=0;k0<ths->N[0];k0++) /* for shorties */
155  {
156  plan_2d->f_hat = ths->f_hat + k0*ths->N[1]*ths->N[2];
157 
158  nfft_trafo(plan_2d);
159 
160  for(j=0;j<ths->M_total;j++)
161  {
162  omega = ((double)(k0 - ths->N[0]/2)) * ths->x[ths->d * j + 0];
163  ths->f[j] += plan_2d->f[j] * cexp( - I*2*PI*omega);
164  }
165  }
166 }
167 
168 static void short_nfft_adjoint_3d_2(nfft_plan* ths, nfft_plan* plan_2d)
169 {
170  int j,k0;
171  double omega;
172 
173  for(j=0;j<ths->M_total;j++)
174  {
175  plan_2d->x[2*j+0] = ths->x[ths->d * j + 1];
176  plan_2d->x[2*j+1] = ths->x[ths->d * j + 2];
177  }
178 
179  for(k0=0;k0<ths->N[0];k0++) /* for shorties */
180  {
181  for(j=0;j<ths->M_total;j++)
182  {
183  omega = ((double)(k0 - ths->N[0]/2)) * ths->x[ths->d * j + 0];
184  plan_2d->f[j] = ths->f[j] * cexp( + _Complex_I*2*PI*omega);
185  }
186 
187  plan_2d->f_hat = ths->f_hat + k0*ths->N[1]*ths->N[2];
188 
189  nfft_adjoint(plan_2d);
190  }
191 }
192 
193 /*---------------------------------------------------------------------------*/
194 
195 #ifdef GAUSSIAN
196 static int index_sparse_to_full_direct_2d(int J, int k)
197 {
198  int N=X(exp2i)(J+2); /* number of full coeffs */
199  int N_B=X(exp2i)(J); /* number in each sparse block */
200 
201  int j=k/N_B; /* consecutive number of Block */
202  int r=j/4; /* level of block */
203 
204  int i, o, a, b,s,l,m1,m2;
205  int k1,k2;
206 
207  if (k>=(J+4)*X(exp2i)(J+1))
208  {
209  printf("Fehler!\n");
210  return(-1);
211  }
212  else
213  {
214  if (r>(J+1)/2) /* center block */
215  {
216  i=k-4*((J+1)/2+1)*N_B;
217  a=X(exp2i)(J/2+1);
218  m1=i/a;
219  m2=i%a;
220  k1=N/2-a/2+m1;
221  k2=N/2-a/2+m2;
222  }
223  else /* no center block */
224  {
225  i=k-j*N_B; /* index in specific block */
226  o=j%4; /* kind of specific block */
227  a=X(exp2i)(r);
228  b=X(exp2i)(J-r);
229  l=NFFT_MAX(a,b); /* long dimension of block */
230  s=NFFT_MIN(a,b); /* short dimension of block */
231  m1=i/l;
232  m2=i%l;
233 
234  switch(o)
235  {
236  case 0:
237  {
238  k1=N/2-a/2 ;
239  k2=N/2+ b ;
240 
241  if (b>=a)
242  {
243  k1+=m1;
244  k2+=m2;
245  }
246  else
247  {
248  k1+=m2;
249  k2+=m1;
250  }
251  break;
252  }
253  case 1:
254  {
255  k1=N/2+ b ;
256  k2=N/2-a/2 ;
257 
258  if (b>a)
259  {
260  k1+=m2;
261  k2+=m1;
262  }
263  else
264  {
265  k1+=m1;
266  k2+=m2;
267  }
268  break;
269  }
270  case 2:
271  {
272  k1=N/2-a/2 ;
273  k2=N/2-2*b ;
274 
275  if (b>=a)
276  {
277  k1+=m1;
278  k2+=m2;
279  }
280  else
281  {
282  k1+=m2;
283  k2+=m1;
284  }
285  break;
286  }
287  case 3:
288  {
289  k1=N/2-2*b ;
290  k2=N/2-a/2 ;
291 
292  if (b>a)
293  {
294  k1+=m2;
295  k2+=m1;
296  }
297  else
298  {
299  k1+=m1;
300  k2+=m2;
301  }
302  break;
303  }
304  default:
305  {
306  k1=-1;
307  k2=-1;
308  }
309  }
310  }
311  //printf("m1=%d, m2=%d\n",m1,m2);
312  return(k1*N+k2);
313  }
314 }
315 #endif
316 
317 static inline int index_sparse_to_full_2d(nsfft_plan *ths, int k)
318 {
319  /* only by lookup table */
320  if( k < ths->N_total)
321  return ths->index_sparse_to_full[k];
322  else
323  return -1;
324 }
325 
326 #ifndef NSFTT_DISABLE_TEST
327 static int index_full_to_sparse_2d(int J, int k)
328 {
329  int N=X(exp2i)(J+2); /* number of full coeffs */
330  int N_B=X(exp2i)(J); /* number in each sparse block */
331 
332  int k1=k/N-N/2; /* coordinates in the full grid */
333  int k2=k%N-N/2; /* k1: row, k2: column */
334 
335  int r,a,b;
336 
337  a=X(exp2i)(J/2+1);
338 
339  if ( (k1>=-(a/2)) && (k1<a/2) && (k2>=(-a/2)) && (k2<a/2) )
340  {
341  return(4*((J+1)/2+1)*N_B+(k1+a/2)*a+(k2+a/2));
342  }
343 
344  for (r=0; r<=(J+1)/2; r++)
345  {
346  b=X(exp2i)(r);
347  a=X(exp2i)(J-r);
348  if ( (k1>=-(b/2)) && (k1<(b+1)/2) && (k2>=a) && (k2<2*a) )
349  {
350  if (a>=b)
351  return((4*r+0)*N_B+(k1+b/2)*a+(k2-a));
352  else
353  return((4*r+0)*N_B+(k2-a)*b+(k1+b/2));
354  }
355  else if ( (k1>=a) && (k1<2*a) && (k2>=-(b/2)) && (k2<(b+1)/2) )
356  {
357  if (a>b)
358  return((4*r+1)*N_B+(k2+b/2)*a+(k1-a));
359  else
360  return((4*r+1)*N_B+(k1-a)*b+(k2+b/2));
361  }
362  else if ( (k1>=-(b/2)) && (k1<(b+1)/2) && (k2>=-2*a) && (k2<-a) )
363  {
364  if (a>=b)
365  return((4*r+2)*N_B+(k1+b/2)*a+(k2+2*a));
366  else
367  return((4*r+2)*N_B+(k2+2*a)*b+(k1+b/2));
368  }
369  else if ( (k1>=-2*a) && (k1<-a) && (k2>=-(b/2)) && (k2<(b+1)/2) )
370  {
371  if (a>b)
372  return((4*r+3)*N_B+(k2+b/2)*a+(k1+2*a));
373  else
374  return((4*r+3)*N_B+(k1+2*a)*b+(k2+b/2));
375  }
376  }
377 
378  return(-1);
379 }
380 #endif
381 
382 #ifdef GAUSSIAN
383 static void init_index_sparse_to_full_2d(nsfft_plan *ths)
384 {
385  int k_S;
386 
387  for (k_S=0; k_S<ths->N_total; k_S++)
388  ths->index_sparse_to_full[k_S]=index_sparse_to_full_direct_2d(ths->J, k_S);
389 }
390 #endif
391 
392 #ifdef GAUSSIAN
393 static inline int index_sparse_to_full_3d(nsfft_plan *ths, int k)
394 {
395  /* only by lookup table */
396  if( k < ths->N_total)
397  return ths->index_sparse_to_full[k];
398  else
399  return -1;
400 }
401 #endif
402 
403 #ifndef NSFTT_DISABLE_TEST
404 static int index_full_to_sparse_3d(int J, int k)
405 {
406  int N=X(exp2i)(J+2); /* length of the full grid */
407  int N_B_r; /* size of a sparse block in level r */
408  int sum_N_B_less_r; /* sum N_B_r */
409 
410  int r,a,b;
411 
412  int k3=(k%N)-N/2; /* coordinates in the full grid */
413  int k2=((k/N)%N)-N/2;
414  int k1=k/(N*N)-N/2;
415 
416  a=X(exp2i)(J/2+1); /* length of center block */
417 
418  if((k1>=-(a/2)) && (k1<a/2) && (k2>=(-a/2)) && (k2<a/2) && (k3>=(-a/2)) &&
419  (k3<a/2))
420  {
421  return(6*X(exp2i)(J)*(X(exp2i)((J+1)/2+1)-1)+((k1+a/2)*a+(k2+a/2))*a+
422  (k3+a/2));
423  }
424 
425  sum_N_B_less_r=0;
426  for (r=0; r<=(J+1)/2; r++)
427  {
428  a=X(exp2i)(J-r);
429  b=X(exp2i)(r);
430 
431  N_B_r=a*b*b;
432 
433  /* right - rear - top - left - front - bottom */
434  if ((k1>=a) && (k1<2*a) && (k2>=-(b/2)) && (k2<(b+1)/2) &&
435  (k3>=-(b/2)) && (k3<(b+1)/2)) /* right */
436  {
437  if(a>b)
438  return sum_N_B_less_r+N_B_r*0 + ((k2+b/2)*b+k3+b/2)*a + (k1-a);
439  else
440  return sum_N_B_less_r+N_B_r*0 + ((k1-a)*b+(k2+b/2))*b + (k3+b/2);
441  }
442  else if ((k2>=a) && (k2<2*a) && (k1>=-(b/2)) && (k1<(b+1)/2) &&
443  (k3>=-(b/2)) && (k3<(b+1)/2)) /* rear */
444  {
445  if(a>b)
446  return sum_N_B_less_r+N_B_r*1 + ((k1+b/2)*b+k3+b/2)*a + (k2-a);
447  else if (a==b)
448  return sum_N_B_less_r+N_B_r*1 + ((k1+b/2)*b+(k2-a))*a + (k3+b/2);
449  else
450  return sum_N_B_less_r+N_B_r*1 + ((k2-a)*b+(k1+b/2))*b + (k3+b/2);
451  }
452  else if ((k3>=a) && (k3<2*a) && (k1>=-(b/2)) && (k1<(b+1)/2) &&
453  (k2>=-(b/2)) && (k2<(b+1)/2)) /* top */
454  {
455  if(a>=b)
456  return sum_N_B_less_r+N_B_r*2 + ((k1+b/2)*b+k2+b/2)*a + (k3-a);
457  else
458  return sum_N_B_less_r+N_B_r*2 + ((k3-a)*b+(k1+b/2))*b + (k2+b/2);
459  }
460 
461  else if ((k1>=-2*a) && (k1<-a) && (k2>=-(b/2)) && (k2<(b+1)/2) &&
462  (k3>=-(b/2)) && (k3<(b+1)/2)) /* left */
463  {
464  if(a>b)
465  return sum_N_B_less_r+N_B_r*3 + ((k2+b/2)*b+k3+b/2)*a + (k1+2*a);
466  else
467  return sum_N_B_less_r+N_B_r*3 + ((k1+2*a)*b+(k2+b/2))*b + (k3+b/2);
468  }
469  else if ((k2>=-2*a) && (k2<-a) && (k1>=-(b/2)) && (k1<(b+1)/2) &&
470  (k3>=-(b/2)) && (k3<(b+1)/2)) /* front */
471  {
472  if(a>b)
473  return sum_N_B_less_r+N_B_r*4 + ((k1+b/2)*b+k3+b/2)*a + (k2+2*a);
474  else if (a==b)
475  return sum_N_B_less_r+N_B_r*4 + ((k1+b/2)*b+(k2+2*a))*a + (k3+b/2);
476  else
477  return sum_N_B_less_r+N_B_r*4 + ((k2+2*a)*b+(k1+b/2))*b + (k3+b/2);
478  }
479  else if ((k3>=-2*a) && (k3<-a) && (k1>=-(b/2)) && (k1<(b+1)/2) &&
480  (k2>=-(b/2)) && (k2<(b+1)/2)) /* bottom */
481  {
482  if(a>=b)
483  return sum_N_B_less_r+N_B_r*5 + ((k1+b/2)*b+k2+b/2)*a + (k3+2*a);
484  else
485  return sum_N_B_less_r+N_B_r*5 + ((k3+2*a)*b+(k1+b/2))*b + (k2+b/2);
486  }
487 
488  sum_N_B_less_r+=6*N_B_r;
489  } /* for(r) */
490 
491  return(-1);
492 }
493 #endif
494 
495 #ifdef GAUSSIAN
496 static void init_index_sparse_to_full_3d(nsfft_plan *ths)
497 {
498  int k1,k2,k3,k_s,r;
499  int a,b;
500  int N=X(exp2i)(ths->J+2); /* length of the full grid */
501  int Nc=ths->center_nfft_plan->N[0]; /* length of the center block */
502 
503  for (k_s=0, r=0; r<=(ths->J+1)/2; r++)
504  {
505  a=X(exp2i)(ths->J-r);
506  b=X(exp2i)(r);
507 
508  /* right - rear - top - left - front - bottom */
509 
510  /* right */
511  if(a>b)
512  for(k2=-b/2;k2<(b+1)/2;k2++)
513  for(k3=-b/2;k3<(b+1)/2;k3++)
514  for(k1=a; k1<2*a; k1++,k_s++)
515  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
516  else
517  for(k1=a; k1<2*a; k1++)
518  for(k2=-b/2;k2<(b+1)/2;k2++)
519  for(k3=-b/2;k3<(b+1)/2;k3++,k_s++)
520  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
521 
522  /* rear */
523  if(a>b)
524  for(k1=-b/2;k1<(b+1)/2;k1++)
525  for(k3=-b/2;k3<(b+1)/2;k3++)
526  for(k2=a; k2<2*a; k2++,k_s++)
527  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
528  else if(a==b)
529  for(k1=-b/2;k1<(b+1)/2;k1++)
530  for(k2=a; k2<2*a; k2++)
531  for(k3=-b/2;k3<(b+1)/2;k3++,k_s++)
532  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
533  else
534  for(k2=a; k2<2*a; k2++)
535  for(k1=-b/2;k1<(b+1)/2;k1++)
536  for(k3=-b/2;k3<(b+1)/2;k3++,k_s++)
537  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
538 
539  /* top */
540  if(a>=b)
541  for(k1=-b/2;k1<(b+1)/2;k1++)
542  for(k2=-b/2;k2<(b+1)/2;k2++)
543  for(k3=a; k3<2*a; k3++,k_s++)
544  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
545  else
546  for(k3=a; k3<2*a; k3++)
547  for(k1=-b/2;k1<(b+1)/2;k1++)
548  for(k2=-b/2;k2<(b+1)/2;k2++,k_s++)
549  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
550 
551  /* left */
552  if(a>b)
553  for(k2=-b/2;k2<(b+1)/2;k2++)
554  for(k3=-b/2;k3<(b+1)/2;k3++)
555  for(k1=-2*a; k1<-a; k1++,k_s++)
556  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
557  else
558  for(k1=-2*a; k1<-a; k1++)
559  for(k2=-b/2;k2<(b+1)/2;k2++)
560  for(k3=-b/2;k3<(b+1)/2;k3++,k_s++)
561  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
562 
563  /* front */
564  if(a>b)
565  for(k1=-b/2;k1<(b+1)/2;k1++)
566  for(k3=-b/2;k3<(b+1)/2;k3++)
567  for(k2=-2*a; k2<-a; k2++,k_s++)
568  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
569  else if(a==b)
570  for(k1=-b/2;k1<(b+1)/2;k1++)
571  for(k2=-2*a; k2<-a; k2++)
572  for(k3=-b/2;k3<(b+1)/2;k3++,k_s++)
573  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
574  else
575  for(k2=-2*a; k2<-a; k2++)
576  for(k1=-b/2;k1<(b+1)/2;k1++)
577  for(k3=-b/2;k3<(b+1)/2;k3++,k_s++)
578  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
579 
580  /* top */
581  if(a>=b)
582  for(k1=-b/2;k1<(b+1)/2;k1++)
583  for(k2=-b/2;k2<(b+1)/2;k2++)
584  for(k3=-2*a; k3<-a; k3++,k_s++)
585  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
586  else
587  for(k3=-2*a; k3<-a; k3++)
588  for(k1=-b/2;k1<(b+1)/2;k1++)
589  for(k2=-b/2;k2<(b+1)/2;k2++,k_s++)
590  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
591  }
592 
593  /* center */
594  for(k1=-Nc/2;k1<Nc/2;k1++)
595  for(k2=-Nc/2;k2<Nc/2;k2++)
596  for(k3=-Nc/2; k3<Nc/2; k3++,k_s++)
597  ths->index_sparse_to_full[k_s]=((k1+N/2)*N+k2+N/2)*N+k3+N/2;
598 }
599 #endif
600 
601 /* copies ths->f_hat to ths_plan->f_hat */
602 void nsfft_cp(nsfft_plan *ths, nfft_plan *ths_full_plan)
603 {
604  int k;
605 
606  /* initialize f_hat with zero values */
607  memset(ths_full_plan->f_hat, 0, ths_full_plan->N_total*sizeof(double _Complex));
608 
609  /* copy values at hyperbolic grid points */
610  for(k=0;k<ths->N_total;k++)
611  ths_full_plan->f_hat[ths->index_sparse_to_full[k]]=ths->f_hat[k];
612 
613  /* copy nodes */
614  memcpy(ths_full_plan->x,ths->act_nfft_plan->x,ths->M_total*ths->d*sizeof(double));
615 }
616 
617 #ifndef NSFTT_DISABLE_TEST
618 /* test copy_sparse_to_full */
619 static void test_copy_sparse_to_full_2d(nsfft_plan *ths, nfft_plan *ths_full_plan)
620 {
621  int r;
622  int k1, k2;
623  int a,b;
624  const int J=ths->J; /* N=2^J */
625  const int N=ths_full_plan->N[0]; /* size of full NFFT */
626  const int N_B=X(exp2i)(J); /* size of small blocks */
627 
628  /* copy sparse plan to full plan */
629  nsfft_cp(ths, ths_full_plan);
630 
631  /* show blockwise f_hat */
632  printf("f_hat blockwise\n");
633  for (r=0; r<=(J+1)/2; r++){
634  a=X(exp2i)(J-r); b=X(exp2i)(r);
635 
636  printf("top\n");
637  for (k1=0; k1<a; k1++){
638  for (k2=0; k2<b; k2++){
639  printf("(%1.1f,%1.1f) ", creal(ths->f_hat[(4*r+1)*N_B+ k1*b+k2]),
640  cimag(ths->f_hat[(4*r+1)*N_B+ k1*b+k2]));
641  }
642  printf("\n");
643  }
644 
645  printf("bottom\n");
646  for (k1=0; k1<a; k1++){
647  for (k2=0; k2<b; k2++){
648  printf("(%1.1f,%1.1f) ", creal(ths->f_hat[(4*r+3)*N_B+ k1*b+k2]),
649  cimag(ths->f_hat[(4*r+3)*N_B+ k1*b+k2]));
650  }
651  printf("\n");
652  }
653 
654  printf("right\n");
655  for (k2=0; k2<b; k2++){
656  for (k1=0; k1<a; k1++){
657  printf("(%1.1f,%1.1f) ", creal(ths->f_hat[(4*r+0)*N_B+ k2*a+k1]),
658  cimag(ths->f_hat[(4*r+0)*N_B+ k2*a+k1]));
659  }
660  printf("\n");
661  }
662 
663  printf("left\n");
664  for (k2=0; k2<b; k2++){
665  for (k1=0; k1<a; k1++){
666  printf("(%1.1f,%1.1f) ", creal(ths->f_hat[(4*r+2)*N_B+ k2*a+k1]),
667  cimag(ths->f_hat[(4*r+2)*N_B+ k2*a+k1]));
668  }
669  printf("\n");
670  }
671  }
672 
673  return;
674  /* show full f_hat */
675  printf("full f_hat\n");
676  for (k1=0;k1<N;k1++){
677  for (k2=0;k2<N;k2++){
678  printf("(%1.1f,%1.1f) ", creal(ths_full_plan->f_hat[k1*N+k2]),
679  cimag(ths_full_plan->f_hat[k1*N+k2]));
680  }
681  printf("\n");
682  }
683 }
684 #endif
685 
686 #ifndef NSFTT_DISABLE_TEST
687 static void test_sparse_to_full_2d(nsfft_plan* ths)
688 {
689  int k_S,k1,k2;
690  int N=X(exp2i)(ths->J+2);
691 
692  printf("N=%d\n\n",N);
693 
694  for(k1=0;k1<N;k1++)
695  for(k2=0;k2<N;k2++)
696  {
697  k_S=index_full_to_sparse_2d(ths->J, k1*N+k2);
698  if(k_S!=-1)
699  printf("(%+d, %+d)\t= %+d \t= %+d = %+d \n",k1-N/2,k2-N/2,
700  k1*N+k2, k_S, ths->index_sparse_to_full[k_S]);
701  }
702 }
703 #endif
704 
705 #ifndef NSFTT_DISABLE_TEST
706 static void test_sparse_to_full_3d(nsfft_plan* ths)
707 {
708  int k_S,k1,k2,k3;
709  int N=X(exp2i)(ths->J+2);
710 
711  printf("N=%d\n\n",N);
712 
713  for(k1=0;k1<N;k1++)
714  for(k2=0;k2<N;k2++)
715  for(k3=0;k3<N;k3++)
716  {
717  k_S=index_full_to_sparse_3d(ths->J, (k1*N+k2)*N+k3);
718  if(k_S!=-1)
719  printf("(%d, %d, %d)\t= %d \t= %d = %d \n",k1-N/2,k2-N/2,k3-N/2,
720  (k1*N+k2)*N+k3,k_S, ths->index_sparse_to_full[k_S]);
721  }
722 }
723 #endif
724 
725 
726 void nsfft_init_random_nodes_coeffs(nsfft_plan *ths)
727 {
728  int j;
729 
730  /* init frequencies */
732 
733  /* init nodes */
735 
736  if(ths->d==2)
737  for(j=0;j<ths->M_total;j++)
738  {
739  ths->x_transposed[2*j+0]=ths->act_nfft_plan->x[2*j+1];
740  ths->x_transposed[2*j+1]=ths->act_nfft_plan->x[2*j+0];
741  }
742  else /* this->d==3 */
743  for(j=0;j<ths->M_total;j++)
744  {
745  ths->x_102[3*j+0]=ths->act_nfft_plan->x[3*j+1];
746  ths->x_102[3*j+1]=ths->act_nfft_plan->x[3*j+0];
747  ths->x_102[3*j+2]=ths->act_nfft_plan->x[3*j+2];
748 
749  ths->x_201[3*j+0]=ths->act_nfft_plan->x[3*j+2];
750  ths->x_201[3*j+1]=ths->act_nfft_plan->x[3*j+0];
751  ths->x_201[3*j+2]=ths->act_nfft_plan->x[3*j+1];
752 
753  ths->x_120[3*j+0]=ths->act_nfft_plan->x[3*j+1];
754  ths->x_120[3*j+1]=ths->act_nfft_plan->x[3*j+2];
755  ths->x_120[3*j+2]=ths->act_nfft_plan->x[3*j+0];
756 
757  ths->x_021[3*j+0]=ths->act_nfft_plan->x[3*j+0];
758  ths->x_021[3*j+1]=ths->act_nfft_plan->x[3*j+2];
759  ths->x_021[3*j+2]=ths->act_nfft_plan->x[3*j+1];
760  }
761 }
762 
763 static void nsdft_trafo_2d(nsfft_plan *ths)
764 {
765  int j,k_S,k_L,k0,k1;
766  double omega;
767  int N=X(exp2i)(ths->J+2);
768 
769  memset(ths->f,0,ths->M_total*sizeof(double _Complex));
770 
771  for(k_S=0;k_S<ths->N_total;k_S++)
772  {
773  k_L=ths->index_sparse_to_full[k_S];
774  k0=k_L / N;
775  k1=k_L % N;
776 
777  for(j=0;j<ths->M_total;j++)
778  {
779  omega =
780  ((double)(k0 - N/2)) * ths->act_nfft_plan->x[2 * j + 0] +
781  ((double)(k1 - N/2)) * ths->act_nfft_plan->x[2 * j + 1];
782  ths->f[j] += ths->f_hat[k_S] * cexp( - I*2*PI*omega);
783  }
784  }
785 } /* void nsdft_trafo_2d */
786 
787 static void nsdft_trafo_3d(nsfft_plan *ths)
788 {
789  int j,k_S,k0,k1,k2;
790  double omega;
791  int N=X(exp2i)(ths->J+2);
792  int k_L;
793 
794  memset(ths->f,0,ths->M_total*sizeof(double _Complex));
795 
796  for(k_S=0;k_S<ths->N_total;k_S++)
797  {
798  k_L=ths->index_sparse_to_full[k_S];
799 
800  k0=k_L/(N*N);
801  k1=(k_L/N)%N;
802  k2=k_L%N;
803 
804  for(j=0;j<ths->M_total;j++)
805  {
806  omega =
807  ((double)(k0 - N/2)) * ths->act_nfft_plan->x[3 * j + 0] +
808  ((double)(k1 - N/2)) * ths->act_nfft_plan->x[3 * j + 1] +
809  ((double)(k2 - N/2)) * ths->act_nfft_plan->x[3 * j + 2];
810  ths->f[j] += ths->f_hat[k_S] * cexp( - I*2*PI*omega);
811  }
812  }
813 } /* void nsdft_trafo_3d */
814 
815 void nsfft_trafo_direct(nsfft_plan *ths)
816 {
817  if(ths->d==2)
818  nsdft_trafo_2d(ths);
819  else
820  nsdft_trafo_3d(ths);
821 }
822 
823 static void nsdft_adjoint_2d(nsfft_plan *ths)
824 {
825  int j,k_S,k_L,k0,k1;
826  double omega;
827  int N=X(exp2i)(ths->J+2);
828 
829  memset(ths->f_hat,0,ths->N_total*sizeof(double _Complex));
830 
831  for(k_S=0;k_S<ths->N_total;k_S++)
832  {
833  k_L=ths->index_sparse_to_full[k_S];
834  k0=k_L / N;
835  k1=k_L % N;
836 
837  for(j=0;j<ths->M_total;j++)
838  {
839  omega =
840  ((double)(k0 - N/2)) * ths->act_nfft_plan->x[2 * j + 0] +
841  ((double)(k1 - N/2)) * ths->act_nfft_plan->x[2 * j + 1];
842  ths->f_hat[k_S] += ths->f[j] * cexp( + _Complex_I*2*PI*omega);
843  }
844  }
845 } /* void nsdft_adjoint_2d */
846 
847 static void nsdft_adjoint_3d(nsfft_plan *ths)
848 {
849  int j,k_S,k0,k1,k2;
850  double omega;
851  int N=X(exp2i)(ths->J+2);
852  int k_L;
853 
854  memset(ths->f_hat,0,ths->N_total*sizeof(double _Complex));
855 
856  for(k_S=0;k_S<ths->N_total;k_S++)
857  {
858  k_L=ths->index_sparse_to_full[k_S];
859 
860  k0=k_L/(N*N);
861  k1=(k_L/N)%N;
862  k2=k_L%N;
863 
864  for(j=0;j<ths->M_total;j++)
865  {
866  omega =
867  ((double)(k0 - N/2)) * ths->act_nfft_plan->x[3 * j + 0] +
868  ((double)(k1 - N/2)) * ths->act_nfft_plan->x[3 * j + 1] +
869  ((double)(k2 - N/2)) * ths->act_nfft_plan->x[3 * j + 2];
870  ths->f_hat[k_S] += ths->f[j] * cexp( + _Complex_I*2*PI*omega);
871  }
872  }
873 } /* void nsdft_adjoint_3d */
874 
875 void nsfft_adjoint_direct(nsfft_plan *ths)
876 {
877  if(ths->d==2)
878  nsdft_adjoint_2d(ths);
879  else
880  nsdft_adjoint_3d(ths);
881 }
882 
883 static void nsfft_trafo_2d(nsfft_plan *ths)
884 {
885  int r,rr,j;
886  double temp;
887 
888  int M=ths->M_total;
889  int J=ths->J;
890 
891  /* center */
892  ths->center_nfft_plan->f_hat=ths->f_hat+4*((J+1)/2+1)*X(exp2i)(J);
893 
894  if (ths->center_nfft_plan->N[0]<=ths->center_nfft_plan->m)
895  nfft_trafo_direct(ths->center_nfft_plan);
896  else
898 
899  for (j=0; j<M; j++)
900  ths->f[j] = ths->center_nfft_plan->f[j];
901 
902  for(rr=0;rr<=(J+1)/2;rr++)
903  {
904  r=NFFT_MIN(rr,J-rr);
905  ths->act_nfft_plan->my_fftw_plan1 = ths->set_fftw_plan1[r];
906  ths->act_nfft_plan->N[0]=X(exp2i)(r); ths->act_nfft_plan->n[0]=ths->sigma*ths->act_nfft_plan->N[0];
907  ths->act_nfft_plan->N[1]=X(exp2i)(J-r); ths->act_nfft_plan->n[1]=ths->sigma*ths->act_nfft_plan->N[1];
908 
909  /*printf("%d x %d\n",ths->act_nfft_plan->N[0],ths->act_nfft_plan->N[1]);*/
910 
911  temp=-3.0*PI*X(exp2i)(J-rr);
912 
913  /* right */
914  ths->act_nfft_plan->f_hat=ths->f_hat+(4*rr+0)*X(exp2i)(J);
915 
916  if(r<rr)
918 
919  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
920  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
921  nfft_trafo_direct(ths->act_nfft_plan);
922  else
923  short_nfft_trafo_2d(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
924  else
926 
927  if(r<rr)
929 
930  for (j=0; j<M; j++)
931  ths->f[j] += ths->act_nfft_plan->f[j] *
932  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[2*j+1]);
933 
934  /* top */
935  ths->act_nfft_plan->f_hat=ths->f_hat+(4*rr+1)*X(exp2i)(J);
936 
937  if((r==rr)&&(J-rr!=rr))
939 
940  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
941  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
942  nfft_trafo_direct(ths->act_nfft_plan);
943  else
944  short_nfft_trafo_2d(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
945  else
947 
948  if((r==rr)&&(J-rr!=rr))
950 
951  for (j=0; j<M; j++)
952  ths->f[j] += ths->act_nfft_plan->f[j] *
953  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[2*j+0]);
954 
955  /* left */
956  ths->act_nfft_plan->f_hat=ths->f_hat+(4*rr+2)*X(exp2i)(J);
957 
958  if(r<rr)
960 
961  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
962  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
963  nfft_trafo_direct(ths->act_nfft_plan);
964  else
965  short_nfft_trafo_2d(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
966  else
968 
969  if(r<rr)
971 
972  for (j=0; j<M; j++)
973  ths->f[j] += ths->act_nfft_plan->f[j] *
974  cexp( - I*temp*ths->act_nfft_plan->x[2*j+1]);
975 
976  /* bottom */
977  ths->act_nfft_plan->f_hat=ths->f_hat+(4*rr+3)*X(exp2i)(J);
978 
979  if((r==rr)&&(J-rr!=rr))
981 
982  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
983  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
984  nfft_trafo_direct(ths->act_nfft_plan);
985  else
986  short_nfft_trafo_2d(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
987  else
989 
990  if((r==rr)&&(J-rr!=rr))
992 
993  for (j=0; j<M; j++)
994  ths->f[j] += ths->act_nfft_plan->f[j] *
995  cexp( - I*temp*ths->act_nfft_plan->x[2*j+0]);
996  } /* for(rr) */
997 } /* void nsfft_trafo_2d */
998 
999 static void nsfft_adjoint_2d(nsfft_plan *ths)
1000 {
1001  int r,rr,j;
1002  double temp;
1003 
1004  int M=ths->M_total;
1005  int J=ths->J;
1006 
1007  /* center */
1008  for (j=0; j<M; j++)
1009  ths->center_nfft_plan->f[j] = ths->f[j];
1010 
1011  ths->center_nfft_plan->f_hat=ths->f_hat+4*((J+1)/2+1)*X(exp2i)(J);
1012 
1013  if (ths->center_nfft_plan->N[0]<=ths->center_nfft_plan->m)
1014  nfft_adjoint_direct(ths->center_nfft_plan);
1015  else
1016  nfft_adjoint(ths->center_nfft_plan);
1017 
1018  for(rr=0;rr<=(J+1)/2;rr++)
1019  {
1020  r=NFFT_MIN(rr,J-rr);
1021  ths->act_nfft_plan->my_fftw_plan2 = ths->set_fftw_plan2[r];
1022  ths->act_nfft_plan->N[0]=X(exp2i)(r); ths->act_nfft_plan->n[0]=ths->sigma*ths->act_nfft_plan->N[0];
1023  ths->act_nfft_plan->N[1]=X(exp2i)(J-r); ths->act_nfft_plan->n[1]=ths->sigma*ths->act_nfft_plan->N[1];
1024 
1025  /*printf("%d x %d\n",ths->act_nfft_plan->N[0],ths->act_nfft_plan->N[1]);*/
1026 
1027  temp=-3.0*PI*X(exp2i)(J-rr);
1028 
1029  /* right */
1030  ths->act_nfft_plan->f_hat=ths->f_hat+(4*rr+0)*X(exp2i)(J);
1031 
1032  for (j=0; j<M; j++)
1033  ths->act_nfft_plan->f[j]= ths->f[j] *
1034  cexp( - I*temp*ths->act_nfft_plan->x[2*j+1]);
1035 
1036  if(r<rr)
1038 
1039  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1040  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1041  nfft_adjoint_direct(ths->act_nfft_plan);
1042  else
1043  short_nfft_adjoint_2d(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1044  else
1045  nfft_adjoint(ths->act_nfft_plan);
1046 
1047  if(r<rr)
1049 
1050  /* top */
1051  ths->act_nfft_plan->f_hat=ths->f_hat+(4*rr+1)*X(exp2i)(J);
1052 
1053  for (j=0; j<M; j++)
1054  ths->act_nfft_plan->f[j]= ths->f[j] *
1055  cexp( - I*temp*ths->act_nfft_plan->x[2*j+0]);
1056 
1057  if((r==rr)&&(J-rr!=rr))
1059 
1060  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1061  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1062  nfft_adjoint_direct(ths->act_nfft_plan);
1063  else
1064  short_nfft_adjoint_2d(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1065  else
1066  nfft_adjoint(ths->act_nfft_plan);
1067 
1068  if((r==rr)&&(J-rr!=rr))
1070 
1071  /* left */
1072  ths->act_nfft_plan->f_hat=ths->f_hat+(4*rr+2)*X(exp2i)(J);
1073 
1074  for (j=0; j<M; j++)
1075  ths->act_nfft_plan->f[j]= ths->f[j] *
1076  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[2*j+1]);
1077 
1078  if(r<rr)
1080 
1081  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1082  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1083  nfft_adjoint_direct(ths->act_nfft_plan);
1084  else
1085  short_nfft_adjoint_2d(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1086  else
1087  nfft_adjoint(ths->act_nfft_plan);
1088 
1089  if(r<rr)
1091 
1092  /* bottom */
1093  ths->act_nfft_plan->f_hat=ths->f_hat+(4*rr+3)*X(exp2i)(J);
1094 
1095  for (j=0; j<M; j++)
1096  ths->act_nfft_plan->f[j]= ths->f[j] *
1097  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[2*j+0]);
1098 
1099  if((r==rr)&&(J-rr!=rr))
1101 
1102  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1103  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1104  nfft_adjoint_direct(ths->act_nfft_plan);
1105  else
1106  short_nfft_adjoint_2d(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1107  else
1108  nfft_adjoint(ths->act_nfft_plan);
1109 
1110  if((r==rr)&&(J-rr!=rr))
1112  } /* for(rr) */
1113 } /* void nsfft_adjoint_2d */
1114 
1115 static void nsfft_trafo_3d(nsfft_plan *ths)
1116 {
1117  int r,rr,j;
1118  double temp;
1119  int sum_N_B_less_r,N_B_r,a,b;
1120 
1121  int M=ths->M_total;
1122  int J=ths->J;
1123 
1124  /* center */
1125  ths->center_nfft_plan->f_hat=ths->f_hat+6*X(exp2i)(J)*(X(exp2i)((J+1)/2+1)-1);
1126 
1127  if (ths->center_nfft_plan->N[0]<=ths->center_nfft_plan->m)
1128  nfft_trafo_direct(ths->center_nfft_plan);
1129  else
1131 
1132  for (j=0; j<M; j++)
1133  ths->f[j] = ths->center_nfft_plan->f[j];
1134 
1135  sum_N_B_less_r=0;
1136  for(rr=0;rr<=(J+1)/2;rr++)
1137  {
1138  a=X(exp2i)(J-rr);
1139  b=X(exp2i)(rr);
1140 
1141  N_B_r=a*b*b;
1142 
1143  r=NFFT_MIN(rr,J-rr);
1144  ths->act_nfft_plan->my_fftw_plan1 = ths->set_fftw_plan1[rr];
1145 
1146  ths->act_nfft_plan->N[0]=X(exp2i)(r);
1147  if(a<b)
1148  ths->act_nfft_plan->N[1]=X(exp2i)(J-r);
1149  else
1150  ths->act_nfft_plan->N[1]=X(exp2i)(r);
1151  ths->act_nfft_plan->N[2]=X(exp2i)(J-r);
1152 
1153  /*printf("\n\n%d x %d x %d:\t",ths->act_nfft_plan->N[0],ths->act_nfft_plan->N[1],ths->act_nfft_plan->N[2]); fflush(stdout);*/
1154 
1155  ths->act_nfft_plan->N_total=ths->act_nfft_plan->N[0]*ths->act_nfft_plan->N[1]*ths->act_nfft_plan->N[2];
1156  ths->act_nfft_plan->n[0]=ths->sigma*ths->act_nfft_plan->N[0];
1157  ths->act_nfft_plan->n[1]=ths->sigma*ths->act_nfft_plan->N[1];
1158  ths->act_nfft_plan->n[2]=ths->sigma*ths->act_nfft_plan->N[2];
1159  ths->act_nfft_plan->n_total=ths->act_nfft_plan->n[0]*ths->act_nfft_plan->n[1]*ths->act_nfft_plan->n[2];
1160 
1161  /* only for right - rear - top */
1162  if((J==0)||((J==1)&&(rr==1)))
1163  temp=-2.0*PI;
1164  else
1165  temp=-3.0*PI*X(exp2i)(J-rr);
1166 
1167  /* right */
1168  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*0;
1169 
1170  if(a>b)
1171  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_120);
1172 
1173  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1174  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1175  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1176  nfft_trafo_direct(ths->act_nfft_plan);
1177  else
1178  short_nfft_trafo_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1179  else
1180  short_nfft_trafo_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1181  else
1182  nfft_trafo(ths->act_nfft_plan);
1183 
1184  if(a>b)
1185  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_120);
1186 
1187  for (j=0; j<M; j++)
1188  ths->f[j] += ths->act_nfft_plan->f[j] *
1189  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[3*j+0]);
1190 
1191  /* rear */
1192  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*1;
1193 
1194  if(a>b)
1195  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_021);
1196  if(a<b)
1197  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_102);
1198 
1199  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1200  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1201  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1202  nfft_trafo_direct(ths->act_nfft_plan);
1203  else
1204  short_nfft_trafo_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1205  else
1206  short_nfft_trafo_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1207  else
1208  nfft_trafo(ths->act_nfft_plan);
1209 
1210  if(a>b)
1211  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_021);
1212  if(a<b)
1213  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_102);
1214 
1215  for (j=0; j<M; j++)
1216  ths->f[j] += ths->act_nfft_plan->f[j] *
1217  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[3*j+1]);
1218 
1219  /* top */
1220  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*2;
1221 
1222  if(a<b)
1223  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_201);
1224 
1225  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1226  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1227  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1228  nfft_trafo_direct(ths->act_nfft_plan);
1229  else
1230  short_nfft_trafo_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1231  else
1232  short_nfft_trafo_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1233  else
1234  nfft_trafo(ths->act_nfft_plan);
1235 
1236  if(a<b)
1237  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_201);
1238 
1239  for (j=0; j<M; j++)
1240  ths->f[j] += ths->act_nfft_plan->f[j] *
1241  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[3*j+2]);
1242 
1243  /* only for left - front - bottom */
1244  if((J==0)||((J==1)&&(rr==1)))
1245  temp=-4.0*PI;
1246  else
1247  temp=-3.0*PI*X(exp2i)(J-rr);
1248 
1249  /* left */
1250  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*3;
1251 
1252  if(a>b)
1253  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_120);
1254 
1255  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1256  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1257  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1258  nfft_trafo_direct(ths->act_nfft_plan);
1259  else
1260  short_nfft_trafo_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1261  else
1262  short_nfft_trafo_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1263  else
1264  nfft_trafo(ths->act_nfft_plan);
1265 
1266  if(a>b)
1267  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_120);
1268 
1269  for (j=0; j<M; j++)
1270  ths->f[j] += ths->act_nfft_plan->f[j] *
1271  cexp( - I*temp*ths->act_nfft_plan->x[3*j+0]);
1272 
1273  /* front */
1274  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*4;
1275 
1276  if(a>b)
1277  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_021);
1278  if(a<b)
1279  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_102);
1280 
1281  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1282  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1283  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1284  nfft_trafo_direct(ths->act_nfft_plan);
1285  else
1286  short_nfft_trafo_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1287  else
1288  short_nfft_trafo_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1289  else
1290  nfft_trafo(ths->act_nfft_plan);
1291 
1292  if(a>b)
1293  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_021);
1294  if(a<b)
1295  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_102);
1296 
1297  for (j=0; j<M; j++)
1298  ths->f[j] += ths->act_nfft_plan->f[j] *
1299  cexp( - I*temp*ths->act_nfft_plan->x[3*j+1]);
1300 
1301  /* bottom */
1302  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*5;
1303 
1304  if(a<b)
1305  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_201);
1306 
1307  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1308  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1309  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1310  nfft_trafo_direct(ths->act_nfft_plan);
1311  else
1312  short_nfft_trafo_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1313  else
1314  short_nfft_trafo_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1315  else
1316  nfft_trafo(ths->act_nfft_plan);
1317 
1318  if(a<b)
1319  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_201);
1320 
1321  for (j=0; j<M; j++)
1322  ths->f[j] += ths->act_nfft_plan->f[j] *
1323  cexp( - I*temp*ths->act_nfft_plan->x[3*j+2]);
1324 
1325  sum_N_B_less_r+=6*N_B_r;
1326  } /* for(rr) */
1327 } /* void nsfft_trafo_3d */
1328 
1329 static void nsfft_adjoint_3d(nsfft_plan *ths)
1330 {
1331  int r,rr,j;
1332  double temp;
1333  int sum_N_B_less_r,N_B_r,a,b;
1334 
1335  int M=ths->M_total;
1336  int J=ths->J;
1337 
1338  /* center */
1339  for (j=0; j<M; j++)
1340  ths->center_nfft_plan->f[j] = ths->f[j];
1341 
1342  ths->center_nfft_plan->f_hat=ths->f_hat+6*X(exp2i)(J)*(X(exp2i)((J+1)/2+1)-1);
1343 
1344  if (ths->center_nfft_plan->N[0]<=ths->center_nfft_plan->m)
1345  nfft_adjoint_direct(ths->center_nfft_plan);
1346  else
1347  nfft_adjoint(ths->center_nfft_plan);
1348 
1349  sum_N_B_less_r=0;
1350  for(rr=0;rr<=(J+1)/2;rr++)
1351  {
1352  a=X(exp2i)(J-rr);
1353  b=X(exp2i)(rr);
1354 
1355  N_B_r=a*b*b;
1356 
1357  r=NFFT_MIN(rr,J-rr);
1358  ths->act_nfft_plan->my_fftw_plan1 = ths->set_fftw_plan1[rr];
1359  ths->act_nfft_plan->my_fftw_plan2 = ths->set_fftw_plan2[rr];
1360 
1361  ths->act_nfft_plan->N[0]=X(exp2i)(r);
1362  if(a<b)
1363  ths->act_nfft_plan->N[1]=X(exp2i)(J-r);
1364  else
1365  ths->act_nfft_plan->N[1]=X(exp2i)(r);
1366  ths->act_nfft_plan->N[2]=X(exp2i)(J-r);
1367 
1368  /*printf("\n\n%d x %d x %d:\t",ths->act_nfft_plan->N[0],ths->act_nfft_plan->N[1],ths->act_nfft_plan->N[2]); fflush(stdout);*/
1369 
1370  ths->act_nfft_plan->N_total=ths->act_nfft_plan->N[0]*ths->act_nfft_plan->N[1]*ths->act_nfft_plan->N[2];
1371  ths->act_nfft_plan->n[0]=ths->sigma*ths->act_nfft_plan->N[0];
1372  ths->act_nfft_plan->n[1]=ths->sigma*ths->act_nfft_plan->N[1];
1373  ths->act_nfft_plan->n[2]=ths->sigma*ths->act_nfft_plan->N[2];
1374  ths->act_nfft_plan->n_total=ths->act_nfft_plan->n[0]*ths->act_nfft_plan->n[1]*ths->act_nfft_plan->n[2];
1375 
1376  /* only for right - rear - top */
1377  if((J==0)||((J==1)&&(rr==1)))
1378  temp=-2.0*PI;
1379  else
1380  temp=-3.0*PI*X(exp2i)(J-rr);
1381 
1382  /* right */
1383  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*0;
1384 
1385  for (j=0; j<M; j++)
1386  ths->act_nfft_plan->f[j]= ths->f[j] *
1387  cexp( - I*temp*ths->act_nfft_plan->x[3*j+0]);
1388 
1389  if(a>b)
1390  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_120);
1391 
1392  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1393  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1394  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1395  nfft_adjoint_direct(ths->act_nfft_plan);
1396  else
1397  short_nfft_adjoint_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1398  else
1399  short_nfft_adjoint_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1400  else
1401  nfft_adjoint(ths->act_nfft_plan);
1402 
1403  if(a>b)
1404  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_120);
1405 
1406  /* rear */
1407  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*1;
1408 
1409  for (j=0; j<M; j++)
1410  ths->act_nfft_plan->f[j]= ths->f[j] *
1411  cexp( - I*temp*ths->act_nfft_plan->x[3*j+1]);
1412 
1413  if(a>b)
1414  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_021);
1415  if(a<b)
1416  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_102);
1417 
1418  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1419  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1420  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1421  nfft_adjoint_direct(ths->act_nfft_plan);
1422  else
1423  short_nfft_adjoint_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1424  else
1425  short_nfft_adjoint_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1426  else
1427  nfft_adjoint(ths->act_nfft_plan);
1428 
1429  if(a>b)
1430  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_021);
1431  if(a<b)
1432  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_102);
1433 
1434  /* top */
1435  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*2;
1436 
1437  for (j=0; j<M; j++)
1438  ths->act_nfft_plan->f[j]= ths->f[j] *
1439  cexp( - I*temp*ths->act_nfft_plan->x[3*j+2]);
1440 
1441  if(a<b)
1442  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_201);
1443 
1444  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1445  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1446  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1447  nfft_adjoint_direct(ths->act_nfft_plan);
1448  else
1449  short_nfft_adjoint_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1450  else
1451  short_nfft_adjoint_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1452  else
1453  nfft_adjoint(ths->act_nfft_plan);
1454 
1455  if(a<b)
1456  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_201);
1457 
1458  /* only for left - front - bottom */
1459  if((J==0)||((J==1)&&(rr==1)))
1460  temp=-4.0*PI;
1461  else
1462  temp=-3.0*PI*X(exp2i)(J-rr);
1463 
1464  /* left */
1465  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*3;
1466 
1467  for (j=0; j<M; j++)
1468  ths->act_nfft_plan->f[j]= ths->f[j] *
1469  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[3*j+0]);
1470 
1471  if(a>b)
1472  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_120);
1473 
1474  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1475  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1476  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1477  nfft_adjoint_direct(ths->act_nfft_plan);
1478  else
1479  short_nfft_adjoint_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1480  else
1481  short_nfft_adjoint_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1482  else
1483  nfft_adjoint(ths->act_nfft_plan);
1484 
1485  if(a>b)
1486  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_120);
1487 
1488  /* front */
1489  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*4;
1490 
1491  for (j=0; j<M; j++)
1492  ths->act_nfft_plan->f[j]= ths->f[j] *
1493  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[3*j+1]);
1494 
1495  if(a>b)
1496  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_021);
1497  if(a<b)
1498  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_102);
1499 
1500  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1501  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1502  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1503  nfft_adjoint_direct(ths->act_nfft_plan);
1504  else
1505  short_nfft_adjoint_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1506  else
1507  short_nfft_adjoint_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1508  else
1509  nfft_adjoint(ths->act_nfft_plan);
1510 
1511  if(a>b)
1512  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_021);
1513  if(a<b)
1514  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_102);
1515 
1516  /* bottom */
1517  ths->act_nfft_plan->f_hat=ths->f_hat + sum_N_B_less_r + N_B_r*5;
1518 
1519  for (j=0; j<M; j++)
1520  ths->act_nfft_plan->f[j]= ths->f[j] *
1521  cexp( + _Complex_I*temp*ths->act_nfft_plan->x[3*j+2]);
1522 
1523  if(a<b)
1524  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_201);
1525 
1526  if(ths->act_nfft_plan->N[0]<=ths->act_nfft_plan->m)
1527  if(ths->act_nfft_plan->N[1]<=ths->act_nfft_plan->m)
1528  if(ths->act_nfft_plan->N[2]<=ths->act_nfft_plan->m)
1529  nfft_adjoint_direct(ths->act_nfft_plan);
1530  else
1531  short_nfft_adjoint_3d_1(ths->act_nfft_plan,&(ths->set_nfft_plan_1d[r]));
1532  else
1533  short_nfft_adjoint_3d_2(ths->act_nfft_plan,&(ths->set_nfft_plan_2d[r]));
1534  else
1535  nfft_adjoint(ths->act_nfft_plan);
1536 
1537  if(a<b)
1538  NFFT_SWAP_double(ths->act_nfft_plan->x,ths->x_201);
1539 
1540  sum_N_B_less_r+=6*N_B_r;
1541  } /* for(rr) */
1542 } /* void nsfft_adjoint_3d */
1543 
1544 void nsfft_trafo(nsfft_plan *ths)
1545 {
1546  if(ths->d==2)
1547  nsfft_trafo_2d(ths);
1548  else
1549  nsfft_trafo_3d(ths);
1550 }
1551 
1552 void nsfft_adjoint(nsfft_plan *ths)
1553 {
1554  if(ths->d==2)
1555  nsfft_adjoint_2d(ths);
1556  else
1557  nsfft_adjoint_3d(ths);
1558 }
1559 
1560 
1561 /*========================================================*/
1562 /* J >1, no precomputation at all!! */
1563 #ifdef GAUSSIAN
1564 static void nsfft_init_2d(nsfft_plan *ths, int J, int M, int m, unsigned snfft_flags)
1565 {
1566  int r;
1567  int N[2];
1568  int n[2];
1569 
1570  ths->flags=snfft_flags;
1571  ths->sigma=2;
1572  ths->J=J;
1573  ths->M_total=M;
1574  ths->N_total=(J+4)*X(exp2i)(J+1);
1575 
1576  /* memory allocation */
1577  ths->f = (double _Complex *)nfft_malloc(M*sizeof(double _Complex));
1578  ths->f_hat = (double _Complex *)nfft_malloc(ths->N_total*sizeof(double _Complex));
1579  ths->x_transposed= (double*)nfft_malloc(2*M*sizeof(double));
1580 
1581  ths->act_nfft_plan = (nfft_plan*)nfft_malloc(sizeof(nfft_plan));
1582  ths->center_nfft_plan = (nfft_plan*)nfft_malloc(sizeof(nfft_plan));
1583 
1584  ths->set_fftw_plan1=(fftw_plan*) nfft_malloc((J/2+1)*sizeof(fftw_plan));
1585  ths->set_fftw_plan2=(fftw_plan*) nfft_malloc((J/2+1)*sizeof(fftw_plan));
1586 
1587  ths->set_nfft_plan_1d = (nfft_plan*) nfft_malloc((X(log2i)(m)+1)*(sizeof(nfft_plan)));
1588 
1589  /* planning the small nffts */
1590  /* r=0 */
1591  N[0]=1; n[0]=ths->sigma*N[0];
1592  N[1]=X(exp2i)(J); n[1]=ths->sigma*N[1];
1593 
1594  nfft_init_guru(ths->act_nfft_plan,2,N,M,n,m, FG_PSI| MALLOC_X| MALLOC_F| FFTW_INIT, FFTW_MEASURE);
1595 
1596  if(ths->act_nfft_plan->nfft_flags & PRE_ONE_PSI)
1597  nfft_precompute_one_psi(ths->act_nfft_plan);
1598 
1599  ths->set_fftw_plan1[0]=ths->act_nfft_plan->my_fftw_plan1;
1600  ths->set_fftw_plan2[0]=ths->act_nfft_plan->my_fftw_plan2;
1601 
1602  for(r=1;r<=J/2;r++)
1603  {
1604  N[0]=X(exp2i)(r); n[0]=ths->sigma*N[0];
1605  N[1]=X(exp2i)(J-r); n[1]=ths->sigma*N[1];
1606  ths->set_fftw_plan1[r] =
1607  fftw_plan_dft(2, n, ths->act_nfft_plan->g1, ths->act_nfft_plan->g2,
1608  FFTW_FORWARD, ths->act_nfft_plan->fftw_flags);
1609 
1610  ths->set_fftw_plan2[r] =
1611  fftw_plan_dft(2, n, ths->act_nfft_plan->g2, ths->act_nfft_plan->g1,
1612  FFTW_BACKWARD, ths->act_nfft_plan->fftw_flags);
1613  }
1614 
1615  /* planning the 1d nffts */
1616  for(r=0;r<=X(log2i)(m);r++)
1617  {
1618  N[0]=X(exp2i)(J-r); n[0]=ths->sigma*N[0]; /* ==N[1] of the 2 dimensional plan */
1619 
1620  nfft_init_guru(&(ths->set_nfft_plan_1d[r]),1,N,M,n,m, MALLOC_X| MALLOC_F| FFTW_INIT, FFTW_MEASURE);
1621  ths->set_nfft_plan_1d[r].nfft_flags = ths->set_nfft_plan_1d[r].nfft_flags | FG_PSI;
1622  ths->set_nfft_plan_1d[r].K=ths->act_nfft_plan->K;
1623  ths->set_nfft_plan_1d[r].psi=ths->act_nfft_plan->psi;
1624  }
1625 
1626  /* center plan */
1627  /* J/2 == floor(((double)J) / 2.0) */
1628  N[0]=X(exp2i)(J/2+1); n[0]=ths->sigma*N[0];
1629  N[1]=X(exp2i)(J/2+1); n[1]=ths->sigma*N[1];
1630  nfft_init_guru(ths->center_nfft_plan,2,N,M,n, m, MALLOC_F| FFTW_INIT,
1631  FFTW_MEASURE);
1632  ths->center_nfft_plan->x= ths->act_nfft_plan->x;
1634  FG_PSI;
1635  ths->center_nfft_plan->K=ths->act_nfft_plan->K;
1636  ths->center_nfft_plan->psi=ths->act_nfft_plan->psi;
1637 
1638  if(ths->flags & NSDFT)
1639  {
1640  ths->index_sparse_to_full=(int*)nfft_malloc(ths->N_total*sizeof(int));
1641  init_index_sparse_to_full_2d(ths);
1642  }
1643 }
1644 #endif
1645 
1646 /*========================================================*/
1647 /* J >1, no precomputation at all!! */
1648 #ifdef GAUSSIAN
1649 static void nsfft_init_3d(nsfft_plan *ths, int J, int M, int m, unsigned snfft_flags)
1650 {
1651  int r,rr,a,b;
1652  int N[3];
1653  int n[3];
1654 
1655  ths->flags=snfft_flags;
1656  ths->sigma=2;
1657  ths->J=J;
1658  ths->M_total=M;
1659  ths->N_total=6*X(exp2i)(J)*(X(exp2i)((J+1)/2+1)-1)+X(exp2i)(3*(J/2+1));
1660 
1661  /* memory allocation */
1662  ths->f = (double _Complex *)nfft_malloc(M*sizeof(double _Complex));
1663  ths->f_hat = (double _Complex *)nfft_malloc(ths->N_total*sizeof(double _Complex));
1664 
1665  ths->x_102= (double*)nfft_malloc(3*M*sizeof(double));
1666  ths->x_201= (double*)nfft_malloc(3*M*sizeof(double));
1667  ths->x_120= (double*)nfft_malloc(3*M*sizeof(double));
1668  ths->x_021= (double*)nfft_malloc(3*M*sizeof(double));
1669 
1670  ths->act_nfft_plan = (nfft_plan*)nfft_malloc(sizeof(nfft_plan));
1671  ths->center_nfft_plan = (nfft_plan*)nfft_malloc(sizeof(nfft_plan));
1672 
1673  ths->set_fftw_plan1=(fftw_plan*) nfft_malloc(((J+1)/2+1)*sizeof(fftw_plan));
1674  ths->set_fftw_plan2=(fftw_plan*) nfft_malloc(((J+1)/2+1)*sizeof(fftw_plan));
1675 
1676  ths->set_nfft_plan_1d = (nfft_plan*) nfft_malloc((X(log2i)(m)+1)*(sizeof(nfft_plan)));
1677  ths->set_nfft_plan_2d = (nfft_plan*) nfft_malloc((X(log2i)(m)+1)*(sizeof(nfft_plan)));
1678 
1679  /* planning the small nffts */
1680  /* r=0 */
1681  N[0]=1; n[0]=ths->sigma*N[0];
1682  N[1]=1; n[1]=ths->sigma*N[1];
1683  N[2]=X(exp2i)(J); n[2]=ths->sigma*N[2];
1684 
1685  nfft_init_guru(ths->act_nfft_plan,3,N,M,n,m, FG_PSI| MALLOC_X| MALLOC_F, FFTW_MEASURE);
1686 
1687  if(ths->act_nfft_plan->nfft_flags & PRE_ONE_PSI)
1688  nfft_precompute_one_psi(ths->act_nfft_plan);
1689 
1690  /* malloc g1, g2 for maximal size */
1691  ths->act_nfft_plan->g1 = nfft_malloc(ths->sigma*ths->sigma*ths->sigma*X(exp2i)(J+(J+1)/2)*sizeof(double _Complex));
1692  ths->act_nfft_plan->g2 = nfft_malloc(ths->sigma*ths->sigma*ths->sigma*X(exp2i)(J+(J+1)/2)*sizeof(double _Complex));
1693 
1694  ths->act_nfft_plan->my_fftw_plan1 =
1695  fftw_plan_dft(3, n, ths->act_nfft_plan->g1, ths->act_nfft_plan->g2,
1696  FFTW_FORWARD, ths->act_nfft_plan->fftw_flags);
1697  ths->act_nfft_plan->my_fftw_plan2 =
1698  fftw_plan_dft(3, n, ths->act_nfft_plan->g2, ths->act_nfft_plan->g1,
1699  FFTW_BACKWARD, ths->act_nfft_plan->fftw_flags);
1700 
1701  ths->set_fftw_plan1[0]=ths->act_nfft_plan->my_fftw_plan1;
1702  ths->set_fftw_plan2[0]=ths->act_nfft_plan->my_fftw_plan2;
1703 
1704  for(rr=1;rr<=(J+1)/2;rr++)
1705  {
1706  a=X(exp2i)(J-rr);
1707  b=X(exp2i)(rr);
1708 
1709  r=NFFT_MIN(rr,J-rr);
1710 
1711  n[0]=ths->sigma*X(exp2i)(r);
1712  if(a<b)
1713  n[1]=ths->sigma*X(exp2i)(J-r);
1714  else
1715  n[1]=ths->sigma*X(exp2i)(r);
1716  n[2]=ths->sigma*X(exp2i)(J-r);
1717 
1718  ths->set_fftw_plan1[rr] =
1719  fftw_plan_dft(3, n, ths->act_nfft_plan->g1, ths->act_nfft_plan->g2,
1720  FFTW_FORWARD, ths->act_nfft_plan->fftw_flags);
1721  ths->set_fftw_plan2[rr] =
1722  fftw_plan_dft(3, n, ths->act_nfft_plan->g2, ths->act_nfft_plan->g1,
1723  FFTW_BACKWARD, ths->act_nfft_plan->fftw_flags);
1724  }
1725 
1726  /* planning the 1d nffts */
1727  for(r=0;r<=X(log2i)(m);r++)
1728  {
1729  N[0]=X(exp2i)(J-r); n[0]=ths->sigma*N[0];
1730  N[1]=X(exp2i)(J-r); n[1]=ths->sigma*N[1];
1731 
1732  if(N[0]>m)
1733  {
1734  nfft_init_guru(&(ths->set_nfft_plan_1d[r]),1,N,M,n,m, MALLOC_X| MALLOC_F| FFTW_INIT, FFTW_MEASURE);
1735  ths->set_nfft_plan_1d[r].nfft_flags = ths->set_nfft_plan_1d[r].nfft_flags | FG_PSI;
1736  ths->set_nfft_plan_1d[r].K=ths->act_nfft_plan->K;
1737  ths->set_nfft_plan_1d[r].psi=ths->act_nfft_plan->psi;
1738  nfft_init_guru(&(ths->set_nfft_plan_2d[r]),2,N,M,n,m, MALLOC_X| MALLOC_F| FFTW_INIT, FFTW_MEASURE);
1739  ths->set_nfft_plan_2d[r].nfft_flags = ths->set_nfft_plan_2d[r].nfft_flags | FG_PSI;
1740  ths->set_nfft_plan_2d[r].K=ths->act_nfft_plan->K;
1741  ths->set_nfft_plan_2d[r].psi=ths->act_nfft_plan->psi;
1742  }
1743  }
1744 
1745  /* center plan */
1746  /* J/2 == floor(((double)J) / 2.0) */
1747  N[0]=X(exp2i)(J/2+1); n[0]=ths->sigma*N[0];
1748  N[1]=X(exp2i)(J/2+1); n[1]=ths->sigma*N[1];
1749  N[2]=X(exp2i)(J/2+1); n[2]=ths->sigma*N[2];
1750  nfft_init_guru(ths->center_nfft_plan,3,N,M,n, m, MALLOC_F| FFTW_INIT,
1751  FFTW_MEASURE);
1752  ths->center_nfft_plan->x= ths->act_nfft_plan->x;
1754  FG_PSI;
1755  ths->center_nfft_plan->K=ths->act_nfft_plan->K;
1756  ths->center_nfft_plan->psi=ths->act_nfft_plan->psi;
1757 
1758  if(ths->flags & NSDFT)
1759  {
1760  ths->index_sparse_to_full=(int*)nfft_malloc(ths->N_total*sizeof(int));
1761  init_index_sparse_to_full_3d(ths);
1762  }
1763 }
1764 #endif
1765 
1766 #ifdef GAUSSIAN
1767 void nsfft_init(nsfft_plan *ths, int d, int J, int M, int m, unsigned flags)
1768 {
1769  ths->d=d;
1770 
1771  if(ths->d==2)
1772  nsfft_init_2d(ths, J, M, m, flags);
1773  else
1774  nsfft_init_3d(ths, J, M, m, flags);
1775 
1776 
1777  ths->mv_trafo = (void (*) (void* ))nsfft_trafo;
1778  ths->mv_adjoint = (void (*) (void* ))nsfft_adjoint;
1779 }
1780 #else
1781 void nsfft_init(nsfft_plan *ths, int d, int J, int M, int m, unsigned flags)
1782 {
1783  UNUSED(ths);
1784  UNUSED(d);
1785  UNUSED(J);
1786  UNUSED(M);
1787  UNUSED(m);
1788  UNUSED(flags);
1789  fprintf(stderr,
1790  "\nError in kernel/nsfft_init: require GAUSSIAN window function\n");
1791 }
1792 #endif
1793 
1794 static void nsfft_finalize_2d(nsfft_plan *ths)
1795 {
1796  int r;
1797 
1798  if(ths->flags & NSDFT)
1800 
1801  /* center plan */
1802  ths->center_nfft_plan->nfft_flags = ths->center_nfft_plan->nfft_flags ^ FG_PSI;
1803  nfft_finalize(ths->center_nfft_plan);
1804 
1805  /* the 1d nffts */
1806  for(r=0;r<=X(log2i)(ths->act_nfft_plan->m);r++)
1807  {
1808  ths->set_nfft_plan_1d[r].nfft_flags =
1809  ths->set_nfft_plan_1d[r].nfft_flags ^ FG_PSI;
1810  nfft_finalize(&(ths->set_nfft_plan_1d[r]));
1811  }
1812 
1813  /* finalize the small nffts */
1814  ths->act_nfft_plan->my_fftw_plan2=ths->set_fftw_plan2[0];
1815  ths->act_nfft_plan->my_fftw_plan1=ths->set_fftw_plan1[0];
1816 
1817  for(r=1;r<=ths->J/2;r++)
1818  {
1819  fftw_destroy_plan(ths->set_fftw_plan2[r]);
1820  fftw_destroy_plan(ths->set_fftw_plan1[r]);
1821  }
1822 
1823  /* r=0 */
1824  nfft_finalize(ths->act_nfft_plan);
1825 
1827 
1828  nfft_free(ths->set_fftw_plan2);
1829  nfft_free(ths->set_fftw_plan1);
1830 
1831  nfft_free(ths->x_transposed);
1832 
1833  nfft_free(ths->f_hat);
1834  nfft_free(ths->f);
1835 }
1836 
1837 static void nsfft_finalize_3d(nsfft_plan *ths)
1838 {
1839  int r;
1840 
1841  if(ths->flags & NSDFT)
1843 
1844  /* center plan */
1845  ths->center_nfft_plan->nfft_flags = ths->center_nfft_plan->nfft_flags ^ FG_PSI;
1846  nfft_finalize(ths->center_nfft_plan);
1847 
1848  /* the 1d and 2d nffts */
1849  for(r=0;r<=X(log2i)(ths->act_nfft_plan->m);r++)
1850  {
1851  if(X(exp2i)(ths->J-r)>ths->act_nfft_plan->m)
1852  {
1853  ths->set_nfft_plan_2d[r].nfft_flags = ths->set_nfft_plan_2d[r].nfft_flags ^ FG_PSI;
1854  nfft_finalize(&(ths->set_nfft_plan_2d[r]));
1855  ths->set_nfft_plan_1d[r].nfft_flags = ths->set_nfft_plan_1d[r].nfft_flags ^ FG_PSI;
1856  nfft_finalize(&(ths->set_nfft_plan_1d[r]));
1857  }
1858  }
1859 
1860  /* finalize the small nffts */
1861  ths->act_nfft_plan->my_fftw_plan2=ths->set_fftw_plan2[0];
1862  ths->act_nfft_plan->my_fftw_plan1=ths->set_fftw_plan1[0];
1863 
1864  for(r=1;r<=(ths->J+1)/2;r++)
1865  {
1866  fftw_destroy_plan(ths->set_fftw_plan2[r]);
1867  fftw_destroy_plan(ths->set_fftw_plan1[r]);
1868  }
1869 
1870  /* r=0 */
1871  nfft_finalize(ths->act_nfft_plan);
1872 
1875 
1876  nfft_free(ths->set_fftw_plan2);
1877  nfft_free(ths->set_fftw_plan1);
1878 
1879  nfft_free(ths->x_102);
1880  nfft_free(ths->x_201);
1881  nfft_free(ths->x_120);
1882  nfft_free(ths->x_021);
1883 
1884  nfft_free(ths->f_hat);
1885  nfft_free(ths->f);
1886 }
1887 
1888 void nsfft_finalize(nsfft_plan *ths)
1889 {
1890  if(ths->d==2)
1891  nsfft_finalize_2d(ths);
1892  else
1893  nsfft_finalize_3d(ths);
1894 }

Generated on Tue Apr 30 2013 by Doxygen 1.8.1