NFFT Logo 3.2.3
taylor_nfft.c
Go to the documentation of this file.
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: taylor_nfft.c 3896 2012-10-10 12:19:26Z tovo $ */
20 
30 #include "config.h"
31 
32 #include <stdio.h>
33 #include <math.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #ifdef HAVE_COMPLEX_H
37 #include <complex.h>
38 #endif
39 
40 #include "nfft3util.h"
41 #include "nfft3.h"
42 #include "infft.h"
43 
44 typedef struct
45 {
48  int *idx0;
50  double *deltax0;
51 } taylor_plan;
52 
64 static void taylor_init(taylor_plan *ths, int N, int M, int n, int m)
65 {
66  /* Note: no nfft precomputation! */
67  nfft_init_guru((nfft_plan*)ths, 1, &N, M, &n, m,
68  MALLOC_X| MALLOC_F_HAT| MALLOC_F|
69  FFTW_INIT| FFT_OUT_OF_PLACE,
70  FFTW_ESTIMATE| FFTW_PRESERVE_INPUT);
71 
72  ths->idx0=(int*)nfft_malloc(M*sizeof(int));
73  ths->deltax0=(double*)nfft_malloc(M*sizeof(double));
74 }
75 
83 static void taylor_precompute(taylor_plan *ths)
84 {
85  int j;
86 
87  nfft_plan* cths=(nfft_plan*)ths;
88 
89  for(j=0;j<cths->M_total;j++)
90  {
91  ths->idx0[j] = ((int)round((cths->x[j]+0.5)*cths->n[0]) +
92  cths->n[0]/2)%cths->n[0];
93  ths->deltax0[j] = cths->x[j] - (round((cths->x[j]+0.5)*cths->n[0]) /
94  cths->n[0] - 0.5);
95  }
96 }
97 
105 static void taylor_finalize(taylor_plan *ths)
106 {
107  nfft_free(ths->deltax0);
108  nfft_free(ths->idx0);
109 
110  nfft_finalize((nfft_plan*)ths);
111 }
112 
123 static void taylor_trafo(taylor_plan *ths)
124 {
125  int j,k,l,ll;
126  double _Complex *f, *f_hat, *g1;
127  double *deltax;
128  int *idx;
129 
130  nfft_plan *cths=(nfft_plan*)ths;
131 
132  for(j=0, f=cths->f; j<cths->M_total; j++)
133  *f++ = 0;
134 
135  for(k=0; k<cths->n_total; k++)
136  cths->g1[k]=0;
137 
138  for(k=-cths->N_total/2, g1=cths->g1+cths->n_total-cths->N_total/2,
139  f_hat=cths->f_hat; k<0; k++)
140  (*g1++)=cpow( - 2*PI*_Complex_I*k,cths->m)* (*f_hat++);
141 
142  cths->g1[0]=cths->f_hat[cths->N_total/2];
143 
144  for(k=1, g1=cths->g1+1, f_hat=cths->f_hat+cths->N_total/2+1;
145  k<cths->N_total/2; k++)
146  (*g1++)=cpow( - 2*PI*_Complex_I*k,cths->m)* (*f_hat++);
147 
148  for(l=cths->m-1; l>=0; l--)
149  {
150  for(k=-cths->N_total/2, g1=cths->g1+cths->n_total-cths->N_total/2;
151  k<0; k++)
152  (*g1++) /= (-2*PI*_Complex_I*k);
153 
154  for(k=1, g1=cths->g1+1; k<cths->N_total/2; k++)
155  (*g1++) /= (-2*PI*_Complex_I*k);
156 
157  fftw_execute(cths->my_fftw_plan1);
158 
159  ll=(l==0?1:l);
160  for(j=0, f=cths->f, deltax=ths->deltax0, idx=ths->idx0; j<cths->M_total;
161  j++, f++)
162  (*f) = ((*f) * (*deltax++) + cths->g2[*idx++]) /ll;
163  }
164 }
165 
179 static void taylor_time_accuracy(int N, int M, int n, int m, int n_taylor,
180  int m_taylor, unsigned test_accuracy)
181 {
182  int r;
183  double t_ndft, t_nfft, t_taylor, t;
184  double _Complex *swapndft = NULL;
185  ticks t0, t1;
186 
187  taylor_plan tp;
188  nfft_plan np;
189 
190  printf("%d\t%d\t",N, M);
191 
192  taylor_init(&tp,N,M,n_taylor,m_taylor);
193 
194  nfft_init_guru(&np, 1, &N, M, &n, m,
195  PRE_PHI_HUT| PRE_FG_PSI|
196  FFTW_INIT| FFT_OUT_OF_PLACE,
197  FFTW_ESTIMATE| FFTW_DESTROY_INPUT);
198 
200  np.x=tp.p.x;
201  np.f_hat=tp.p.f_hat;
202  np.f=tp.p.f;
203 
205  if(test_accuracy)
206  swapndft=(double _Complex*)nfft_malloc(M*sizeof(double _Complex));
207 
210 
212  taylor_precompute(&tp);
213 
215  if(np.nfft_flags & PRE_ONE_PSI)
216  nfft_precompute_one_psi(&np);
217 
220 
222  if(test_accuracy)
223  {
224  NFFT_SWAP_complex(np.f,swapndft);
225 
226  t_ndft=0;
227  r=0;
228  while(t_ndft<0.01)
229  {
230  r++;
231  t0 = getticks();
232  nfft_trafo_direct(&np);
233  t1 = getticks();
234 t = nfft_elapsed_seconds(t1,t0);
235  t_ndft+=t;
236  }
237  t_ndft/=r;
238 
239  NFFT_SWAP_complex(np.f,swapndft);
240  printf("%.2e\t",t_ndft);
241  }
242  else
243  printf("nan\t\t");
244 
246  t_nfft=0;
247  r=0;
248  while(t_nfft<0.01)
249  {
250  r++;
251  t0 = getticks();
252  nfft_trafo(&np);
253  t1 = getticks();
254 t = nfft_elapsed_seconds(t1,t0);
255  t_nfft+=t;
256  }
257  t_nfft/=r;
258 
259  printf("%.2f\t%d\t%.2e\t",((double)n)/N, m, t_nfft);
260 
261  if(test_accuracy)
262  printf("%.2e\t",X(error_l_infty_complex)(swapndft, np.f, np.M_total));
263  else
264  printf("nan\t\t");
265 
267  t_taylor=0;
268  r=0;
269  while(t_taylor<0.01)
270  {
271  r++;
272  t0 = getticks();
273  taylor_trafo(&tp);
274  t1 = getticks();
275 t = nfft_elapsed_seconds(t1,t0);
276  t_taylor+=t;
277  }
278  t_taylor/=r;
279 
280 
281  printf("%.2f\t%d\t%.2e\t",((double)n_taylor)/N,m_taylor,t_taylor);
282 
283  if(test_accuracy)
284  printf("%.2e\n",X(error_l_infty_complex)(swapndft, np.f, np.M_total));
285  else
286  printf("nan\t\n");
287 
288  fflush(stdout);
289 
291  if(test_accuracy)
292  nfft_free(swapndft);
293 
294  nfft_finalize(&np);
295  taylor_finalize(&tp);
296 }
297 
298 int main(int argc,char **argv)
299 {
300  int l,m,trial,N;
301 
302  if(argc<=2)
303  {
304  fprintf(stderr,"taylor_nfft type first last trials sigma_nfft sigma_taylor.\n");
305  return -1;
306  }
307 
308  fprintf(stderr,"Testing the Nfft & a Taylor expansion based version.\n\n");
309  fprintf(stderr,"Columns: N, M, t_ndft, sigma_nfft, m_nfft, t_nfft, e_nfft");
310  fprintf(stderr,", sigma_taylor, m_taylor, t_taylor, e_taylor\n");
311 
312  /* time vs. N=M */
313  if(atoi(argv[1])==0)
314  {
315  fprintf(stderr,"Fixed target accuracy, timings.\n\n");
316  for(l=atoi(argv[2]); l<=atoi(argv[3]); l++)
317  for(trial=0; trial<atoi(argv[4]); trial++)
318  if(l<=10)
319  taylor_time_accuracy((1U<< l), (1U<< l), (int)(atof(argv[5])*
320  (1U<< l)), 6, (int)(atof(argv[6])*(1U<< l)),
321  6, 1);
322  else
323  taylor_time_accuracy((1U<< l), (1U<< l), (int)(atof(argv[5])*
324  (1U<< l)), 6, (int)(atof(argv[6])*(1U<< l)),
325  6, 0);
326  }
327 
328  /* error vs. m */
329  if(atoi(argv[1])==1)
330  {
331  N=atoi(argv[7]);
332  fprintf(stderr,"Fixed N=M=%d, error vs. m.\n\n",N);
333  for(m=atoi(argv[2]); m<=atoi(argv[3]); m++)
334  for(trial=0; trial<atoi(argv[4]); trial++)
335  taylor_time_accuracy(N,N, (int)(atof(argv[5])*N), m,
336  (int)(atof(argv[6])*N), m, 1);
337  }
338 
339  return 1;
340 }

Generated on Tue Apr 30 2013 by Doxygen 1.8.1