NFFT Logo 3.2.3
ndft_fast.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: ndft_fast.c 3896 2012-10-10 12:19:26Z tovo $ */
20 
27 #include "config.h"
28 
29 #include <stdio.h>
30 #include <math.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #ifdef HAVE_COMPLEX_H
34 #include <complex.h>
35 #endif
36 
37 #include "nfft3util.h"
38 #include "nfft3.h"
39 #include "infft.h"
40 
41 static void ndft_horner_trafo(nfft_plan *ths)
42 {
43  int j,k;
44  double _Complex *f_hat_k, *f_j;
45  double _Complex exp_omega_0;
46 
47  for(j=0, f_j=ths->f; j<ths->M_total; j++, f_j++)
48  (*f_j) =0;
49 
50  for(j=0, f_j=ths->f; j<ths->M_total; j++, f_j++)
51  {
52  exp_omega_0 = cexp(+2*PI*_Complex_I*ths->x[j]);
53  for(k=0, f_hat_k= ths->f_hat; k<ths->N[0]; k++, f_hat_k++)
54  {
55  (*f_j)+=(*f_hat_k);
56  (*f_j)*=exp_omega_0;
57  }
58  (*f_j)*=cexp(-PI*_Complex_I*ths->N[0]*ths->x[j]);
59  }
60 } /* ndft_horner_trafo */
61 
62 static void ndft_pre_full_trafo(nfft_plan *ths, double _Complex *A)
63 {
64  int j,k;
65  double _Complex *f_hat_k, *f_j;
66  double _Complex *A_local;
67 
68  for(j=0, f_j=ths->f; j<ths->M_total; j++, f_j++)
69  (*f_j) =0;
70 
71  for(j=0, f_j=ths->f, A_local=A; j<ths->M_total; j++, f_j++)
72  for(k=0, f_hat_k= ths->f_hat; k<ths->N[0]; k++, f_hat_k++, A_local++)
73  (*f_j) += (*f_hat_k)*(*A_local);
74 } /* ndft_pre_full_trafo */
75 
76 static void ndft_pre_full_init(nfft_plan *ths, double _Complex *A)
77 {
78  int j,k;
79  double _Complex *f_hat_k, *f_j, *A_local;
80 
81  for(j=0, f_j=ths->f, A_local=A; j<ths->M_total; j++, f_j++)
82  for(k=0, f_hat_k= ths->f_hat; k<ths->N[0]; k++, f_hat_k++, A_local++)
83  (*A_local) = cexp(-2*PI*_Complex_I*(k-ths->N[0]/2)*ths->x[j]);
84 
85 } /* ndft_pre_full_init */
86 
87 static void ndft_time(int N, int M, unsigned test_ndft, unsigned test_pre_full)
88 {
89  int r;
90  double t, t_ndft, t_horner, t_pre_full, t_nfft;
91  double _Complex *A = NULL;
92  ticks t0, t1;
93 
94  nfft_plan np;
95 
96  printf("%d\t%d\t",N, M);
97 
98  nfft_init_1d(&np, N, M);
99 
102 
103  if(test_pre_full)
104  {
105  A=(double _Complex*)nfft_malloc(N*M*sizeof(double _Complex));
106  ndft_pre_full_init(&np, A);
107  }
108 
111 
113  if(test_ndft)
114  {
115  t_ndft=0;
116  r=0;
117  while(t_ndft<0.1)
118  {
119  r++;
120  t0 = getticks();
121  nfft_trafo_direct(&np);
122  t1 = getticks();
123  t = nfft_elapsed_seconds(t1,t0);
124  t_ndft+=t;
125  }
126  t_ndft/=r;
127 
128  printf("%.2e\t",t_ndft);
129  }
130  else
131  printf("nan\t\t");
132 
134  t_horner=0;
135  r=0;
136  while(t_horner<0.1)
137  {
138  r++;
139  t0 = getticks();
140  ndft_horner_trafo(&np);
141  t1 = getticks();
142  t = nfft_elapsed_seconds(t1,t0);
143  t_horner+=t;
144  }
145  t_horner/=r;
146 
147  printf("%.2e\t", t_horner);
148 
150  if(test_pre_full)
151  {
152  t_pre_full=0;
153  r=0;
154  while(t_pre_full<0.1)
155  {
156  r++;
157  t0 = getticks();
158  ndft_pre_full_trafo(&np,A);
159  t1 = getticks();
160  t = nfft_elapsed_seconds(t1,t0);
161  t_pre_full+=t;
162  }
163  t_pre_full/=r;
164 
165  printf("%.2e\t", t_pre_full);
166  }
167  else
168  printf("nan\t\t");
169 
170  t_nfft=0;
171  r=0;
172  while(t_nfft<0.1)
173  {
174  r++;
175  t0 = getticks();
176  nfft_trafo(&np);
177  t1 = getticks();
178  t = nfft_elapsed_seconds(t1,t0);
179  t_nfft+=t;
180  }
181  t_nfft/=r;
182 
183  printf("%.2e\n", t_nfft);
184 
185  fflush(stdout);
186 
187  if(test_pre_full)
188  nfft_free(A);
189 
190  nfft_finalize(&np);
191 }
192 
193 int main(int argc,char **argv)
194 {
195  int l,trial;
196 
197  if(argc<=2)
198  {
199  fprintf(stderr,"ndft_fast type first last trials\n");
200  return -1;
201  }
202 
203  fprintf(stderr,"Testing ndft, Horner-like ndft, fully precomputed ndft.\n");
204  fprintf(stderr,"Columns: N, M, t_ndft, t_horner, t_pre_full, t_nfft\n\n");
205 
206  /* time vs. N=M */
207  if(atoi(argv[1])==0)
208  {
209  for(l=atoi(argv[2]); l<=atoi(argv[3]); l++)
210  for(trial=0; trial<atoi(argv[4]); trial++)
211  if(l<=13)
212  ndft_time((1U<< l), (1U<< l), 1, 1);
213  else
214  if(l<=15)
215  ndft_time((1U<< l), (1U<< l), 1, 0);
216  else
217  ndft_time((1U<< l), (1U<< l), 0, 0);
218  }
219 
220  return 1;
221 }

Generated on Tue Apr 30 2013 by Doxygen 1.8.1