NFFT  3.4.1
polar_fft_test.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002, 2017 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 
28 #include <math.h>
29 #include <stdlib.h>
30 #include <complex.h>
31 
32 #define NFFT_PRECISION_DOUBLE
33 
34 #include "nfft3mp.h"
35 
73 static int polar_grid(int T, int S, NFFT_R *x, NFFT_R *w)
74 {
75  int t, r;
76  NFFT_R W = (NFFT_R) T * (((NFFT_R) S / NFFT_K(2.0)) * ((NFFT_R) S / NFFT_K(2.0)) + NFFT_K(1.0) / NFFT_K(4.0));
77 
78  for (t = -T / 2; t < T / 2; t++)
79  {
80  for (r = -S / 2; r < S / 2; r++)
81  {
82  x[2 * ((t + T / 2) * S + (r + S / 2)) + 0] = (NFFT_R) (r) / (NFFT_R)(S) * NFFT_M(cos)(NFFT_KPI * (NFFT_R)(t) / (NFFT_R)(T));
83  x[2 * ((t + T / 2) * S + (r + S / 2)) + 1] = (NFFT_R) (r) / (NFFT_R)(S) * NFFT_M(sin)(NFFT_KPI * (NFFT_R)(t) / (NFFT_R)(T));
84  if (r == 0)
85  w[(t + T / 2) * S + (r + S / 2)] = NFFT_K(1.0) / NFFT_K(4.0) / W;
86  else
87  w[(t + T / 2) * S + (r + S / 2)] = NFFT_M(fabs)((NFFT_R) r) / W;
88  }
89  }
90 
91  return T * S;
92 }
93 
95 static int polar_dft(NFFT_C *f_hat, int NN, NFFT_C *f, int T, int S,
96  int m)
97 {
98  int j, k;
99  NFFT(plan) my_nfft_plan;
101  NFFT_R *x, *w;
103  int N[2], n[2];
104  int M = T * S;
106  N[0] = NN;
107  n[0] = 2 * N[0];
108  N[1] = NN;
109  n[1] = 2 * N[1];
111  x = (NFFT_R *) NFFT(malloc)((size_t)(2 * T * S) * (sizeof(NFFT_R)));
112  if (x == NULL)
113  return EXIT_FAILURE;
114 
115  w = (NFFT_R *) NFFT(malloc)((size_t)(T * S) * (sizeof(NFFT_R)));
116  if (w == NULL)
117  return EXIT_FAILURE;
118 
120  NFFT(init_guru)(&my_nfft_plan, 2, N, M, n, m,
123  FFTW_MEASURE | FFTW_DESTROY_INPUT);
124 
126  polar_grid(T, S, x, w);
127  for (j = 0; j < my_nfft_plan.M_total; j++)
128  {
129  my_nfft_plan.x[2 * j + 0] = x[2 * j + 0];
130  my_nfft_plan.x[2 * j + 1] = x[2 * j + 1];
131  }
132 
134  for (k = 0; k < my_nfft_plan.N_total; k++)
135  my_nfft_plan.f_hat[k] = f_hat[k];
136 
138  NFFT(trafo_direct)(&my_nfft_plan);
139 
141  for (j = 0; j < my_nfft_plan.M_total; j++)
142  f[j] = my_nfft_plan.f[j];
143 
145  NFFT(finalize)(&my_nfft_plan);
146  NFFT(free)(x);
147  NFFT(free)(w);
148 
149  return EXIT_SUCCESS;
150 }
151 
153 static int polar_fft(NFFT_C *f_hat, int NN, NFFT_C *f, int T, int S,
154  int m)
155 {
156  int j, k;
157  NFFT(plan) my_nfft_plan;
159  NFFT_R *x, *w;
161  int N[2], n[2];
162  int M = T * S;
164  N[0] = NN;
165  n[0] = 2 * N[0];
166  N[1] = NN;
167  n[1] = 2 * N[1];
169  x = (NFFT_R *) NFFT(malloc)((size_t)(2 * T * S) * (sizeof(NFFT_R)));
170  if (x == NULL)
171  return EXIT_FAILURE;
172 
173  w = (NFFT_R *) NFFT(malloc)((size_t)(T * S) * (sizeof(NFFT_R)));
174  if (w == NULL)
175  return EXIT_FAILURE;
176 
178  NFFT(init_guru)(&my_nfft_plan, 2, N, M, n, m,
181  FFTW_MEASURE | FFTW_DESTROY_INPUT);
182 
184  polar_grid(T, S, x, w);
185  for (j = 0; j < my_nfft_plan.M_total; j++)
186  {
187  my_nfft_plan.x[2 * j + 0] = x[2 * j + 0];
188  my_nfft_plan.x[2 * j + 1] = x[2 * j + 1];
189  }
190 
192  if (my_nfft_plan.flags & PRE_LIN_PSI)
193  NFFT(precompute_lin_psi)(&my_nfft_plan);
194 
195  if (my_nfft_plan.flags & PRE_PSI)
196  NFFT(precompute_psi)(&my_nfft_plan);
197 
198  if (my_nfft_plan.flags & PRE_FULL_PSI)
199  NFFT(precompute_full_psi)(&my_nfft_plan);
200 
202  for (k = 0; k < my_nfft_plan.N_total; k++)
203  my_nfft_plan.f_hat[k] = f_hat[k];
204 
206  NFFT(trafo)(&my_nfft_plan);
207 
209  for (j = 0; j < my_nfft_plan.M_total; j++)
210  f[j] = my_nfft_plan.f[j];
211 
213  NFFT(finalize)(&my_nfft_plan);
214  NFFT(free)(x);
215  NFFT(free)(w);
216 
217  return EXIT_SUCCESS;
218 }
219 
221 static int inverse_polar_fft(NFFT_C *f, int T, int S, NFFT_C *f_hat,
222  int NN, int max_i, int m)
223 {
224  int j, k;
225  NFFT(plan) my_nfft_plan;
226  SOLVER(plan_complex) my_infft_plan;
228  NFFT_R *x, *w;
229  int l;
231  int N[2], n[2];
232  int M = T * S;
234  N[0] = NN;
235  n[0] = 2 * N[0];
236  N[1] = NN;
237  n[1] = 2 * N[1];
239  x = (NFFT_R *) NFFT(malloc)((size_t)(2 * T * S) * (sizeof(NFFT_R)));
240  if (x == NULL)
241  return EXIT_FAILURE;
242 
243  w = (NFFT_R *) NFFT(malloc)((size_t)(T * S) * (sizeof(NFFT_R)));
244  if (w == NULL)
245  return EXIT_FAILURE;
246 
248  NFFT(init_guru)(&my_nfft_plan, 2, N, M, n, m,
251  FFTW_MEASURE | FFTW_DESTROY_INPUT);
252 
254  SOLVER(init_advanced_complex)(&my_infft_plan,
255  (NFFT(mv_plan_complex)*) (&my_nfft_plan), CGNR | PRECOMPUTE_WEIGHT);
256 
258  polar_grid(T, S, x, w);
259  for (j = 0; j < my_nfft_plan.M_total; j++)
260  {
261  my_nfft_plan.x[2 * j + 0] = x[2 * j + 0];
262  my_nfft_plan.x[2 * j + 1] = x[2 * j + 1];
263  my_infft_plan.y[j] = f[j];
264  my_infft_plan.w[j] = w[j];
265  }
266 
268  if (my_nfft_plan.flags & PRE_LIN_PSI)
269  NFFT(precompute_lin_psi)(&my_nfft_plan);
270 
271  if (my_nfft_plan.flags & PRE_PSI)
272  NFFT(precompute_psi)(&my_nfft_plan);
273 
274  if (my_nfft_plan.flags & PRE_FULL_PSI)
275  NFFT(precompute_full_psi)(&my_nfft_plan);
276 
278  if (my_infft_plan.flags & PRECOMPUTE_DAMP)
279  for (j = 0; j < my_nfft_plan.N[0]; j++)
280  for (k = 0; k < my_nfft_plan.N[1]; k++)
281  {
282  my_infft_plan.w_hat[j * my_nfft_plan.N[1] + k] = (
283  NFFT_M(sqrt)(
284  NFFT_M(pow)((NFFT_R) (j - my_nfft_plan.N[0] / 2), NFFT_K(2.0))
285  + NFFT_M(pow)((NFFT_R) (k - my_nfft_plan.N[1] / 2), NFFT_K(2.0)))
286  > ((NFFT_R) (my_nfft_plan.N[0] / 2)) ? 0 : 1);
287  }
288 
290  for (k = 0; k < my_nfft_plan.N_total; k++)
291  my_infft_plan.f_hat_iter[k] = NFFT_K(0.0) + _Complex_I * NFFT_K(0.0);
292 
294  SOLVER(before_loop_complex)(&my_infft_plan);
295 
296  if (max_i < 1)
297  {
298  l = 1;
299  for (k = 0; k < my_nfft_plan.N_total; k++)
300  my_infft_plan.f_hat_iter[k] = my_infft_plan.p_hat_iter[k];
301  }
302  else
303  {
304  for (l = 1; l <= max_i; l++)
305  {
306  SOLVER(loop_one_step_complex)(&my_infft_plan);
307  }
308  }
309 
311  for (k = 0; k < my_nfft_plan.N_total; k++)
312  f_hat[k] = my_infft_plan.f_hat_iter[k];
313 
315  SOLVER(finalize_complex)(&my_infft_plan);
316  NFFT(finalize)(&my_nfft_plan);
317  NFFT(free)(x);
318  NFFT(free)(w);
319 
320  return EXIT_SUCCESS;
321 }
322 
324 int main(int argc, char **argv)
325 {
326  int N;
327  int T, S;
328  int M;
329  NFFT_R *x, *w;
330  NFFT_C *f_hat, *f, *f_direct, *f_tilde;
331  int k;
332  int max_i;
333  int m = 1;
334  NFFT_R temp1, temp2, E_max = NFFT_K(0.0);
335  FILE *fp1, *fp2;
336  char filename[30];
337 
338  if (argc != 4)
339  {
340  printf("polar_fft_test N T R \n");
341  printf("\n");
342  printf("N polar FFT of size NxN \n");
343  printf("T number of slopes \n");
344  printf("R number of offsets \n");
345  exit(EXIT_FAILURE);
346  }
347 
348  N = atoi(argv[1]);
349  T = atoi(argv[2]);
350  S = atoi(argv[3]);
351  printf("N=%d, polar grid with T=%d, R=%d => ", N, T, S);
352 
353  x = (NFFT_R *) NFFT(malloc)((size_t)(2 * 5 * (T / 2) * (S / 2)) * (sizeof(NFFT_R)));
354  w = (NFFT_R *) NFFT(malloc)((size_t)(5 * (T / 2) * (S / 2)) * (sizeof(NFFT_R)));
355 
356  f_hat = (NFFT_C *) NFFT(malloc)(sizeof(NFFT_C) * (size_t)(N * N));
357  f = (NFFT_C *) NFFT(malloc)(sizeof(NFFT_C) * (size_t)(T * S));
358  f_direct = (NFFT_C *) NFFT(malloc)(sizeof(NFFT_C) * (size_t)(T * S));
359  f_tilde = (NFFT_C *) NFFT(malloc)(sizeof(NFFT_C) * (size_t)(N * N));
360 
362  M = polar_grid(T, S, x, w);
363  printf("M=%d.\n", M);
364 
366  fp1 = fopen("input_data_r.dat", "r");
367  fp2 = fopen("input_data_i.dat", "r");
368  if (fp1 == NULL)
369  return (-1);
370  for (k = 0; k < N * N; k++)
371  {
372  fscanf(fp1, NFFT__FR__ " ", &temp1);
373  fscanf(fp2, NFFT__FR__ " ", &temp2);
374  f_hat[k] = temp1 + _Complex_I * temp2;
375  }
376  fclose(fp1);
377  fclose(fp2);
378 
380  polar_dft(f_hat, N, f_direct, T, S, m);
381  // polar_fft(f_hat,N,f_direct,T,R,12);
382 
384  printf("\nTest of the polar FFT: \n");
385  fp1 = fopen("polar_fft_error.dat", "w+");
386  for (m = 1; m <= 12; m++)
387  {
389  polar_fft(f_hat, N, f, T, S, m);
390 
392  E_max = NFFT(error_l_infty_complex)(f_direct, f, M);
393  printf("m=%2d: E_max = %" NFFT__FES__ "\n", m, E_max);
394  fprintf(fp1, "%" NFFT__FES__ "\n", E_max);
395  }
396  fclose(fp1);
397 
399  for (m = 3; m <= 9; m += 3)
400  {
401  printf("\nTest of the inverse polar FFT for m=%d: \n", m);
402  sprintf(filename, "polar_ifft_error%d.dat", m);
403  fp1 = fopen(filename, "w+");
404  for (max_i = 0; max_i <= 100; max_i += 10)
405  {
407  inverse_polar_fft(f_direct, T, S, f_tilde, N, max_i, m);
408 
410  /* E_max=0.0;
411  for(k=0;k<N*N;k++)
412  {
413  temp = cabs((f_hat[k]-f_tilde[k])/f_hat[k]);
414  if (temp>E_max) E_max=temp;
415  }
416  */
417  E_max = NFFT(error_l_infty_complex)(f_hat, f_tilde, N * N);
418  printf("%3d iterations: E_max = %" NFFT__FES__ "\n", max_i, E_max);
419  fprintf(fp1, "%" NFFT__FES__ "\n", E_max);
420  }
421  fclose(fp1);
422  }
423 
425  NFFT(free)(x);
426  NFFT(free)(w);
427  NFFT(free)(f_hat);
428  NFFT(free)(f);
429  NFFT(free)(f_direct);
430  NFFT(free)(f_tilde);
431 
432  return EXIT_SUCCESS;
433 }
434 /* \} */
static int max_i(int a, int b)
max
Definition: fastsum.c:46
static int polar_fft(NFFT_C *f_hat, int NN, NFFT_C *f, int T, int S, int m)
NFFT-based polar FFT.
#define PRECOMPUTE_DAMP
Definition: nfft3.h:792
#define MALLOC_X
Definition: nfft3.h:199
#define MALLOC_F_HAT
Definition: nfft3.h:200
#define PRECOMPUTE_WEIGHT
Definition: nfft3.h:791
#define FFTW_INIT
Definition: nfft3.h:203
static int polar_dft(NFFT_C *f_hat, int NN, NFFT_C *f, int T, int S, int m)
discrete polar FFT
#define MALLOC_F
Definition: nfft3.h:201
#define FFT_OUT_OF_PLACE
Definition: nfft3.h:202
#define PRE_LIN_PSI
Definition: nfft3.h:195
#define PRE_PSI
Definition: nfft3.h:197
#define CGNR
Definition: nfft3.h:788
static int polar_grid(int T, int S, NFFT_R *x, NFFT_R *w)
Generates the points with weights for the polar grid with angles and offsets. ...
#define PRE_FULL_PSI
Definition: nfft3.h:198
#define PRE_PHI_HUT
Definition: nfft3.h:193
static int inverse_polar_fft(NFFT_C *f, int T, int S, NFFT_C *f_hat, int NN, int max_i, int m)
inverse NFFT-based polar FFT
int main(int argc, char **argv)
test program for various parameters