polar_fft_test.c
Go to the documentation of this file.
/*
* Copyright (c) 2002, 2017 Jens Keiner, Stefan Kunis, Daniel Potts
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <math.h>
#include <stdlib.h>
#include <complex.h>
#define NFFT_PRECISION_DOUBLE
#include "nfft3mp.h"
static int polar_grid(int T, int S, NFFT_R *x, NFFT_R *w)
{
int t, r;
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));
for (t = -T / 2; t < T / 2; t++)
{
for (r = -S / 2; r < S / 2; r++)
{
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));
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));
if (r == 0)
w[(t + T / 2) * S + (r + S / 2)] = NFFT_K(1.0) / NFFT_K(4.0) / W;
else
w[(t + T / 2) * S + (r + S / 2)] = NFFT_M(fabs)((NFFT_R) r) / W;
}
}
return T * S;
}
static int polar_dft(NFFT_C *f_hat, int NN, NFFT_C *f, int T, int S,
int m)
{
int j, k;
NFFT(plan) my_nfft_plan;
NFFT_R *x, *w;
int N[2], n[2];
int M = T * S;
N[0] = NN;
n[0] = 2 * N[0];
N[1] = NN;
n[1] = 2 * N[1];
x = (NFFT_R *) NFFT(malloc)((size_t)(2 * T * S) * (sizeof(NFFT_R)));
if (x == NULL)
return EXIT_FAILURE;
w = (NFFT_R *) NFFT(malloc)((size_t)(T * S) * (sizeof(NFFT_R)));
if (w == NULL)
return EXIT_FAILURE;
NFFT(init_guru)(&my_nfft_plan, 2, N, M, n, m,
PRE_PHI_HUT | PRE_PSI | MALLOC_X | MALLOC_F_HAT | MALLOC_F | FFTW_INIT
| FFT_OUT_OF_PLACE,
FFTW_MEASURE | FFTW_DESTROY_INPUT);
polar_grid(T, S, x, w);
for (j = 0; j < my_nfft_plan.M_total; j++)
{
my_nfft_plan.x[2 * j + 0] = x[2 * j + 0];
my_nfft_plan.x[2 * j + 1] = x[2 * j + 1];
}
for (k = 0; k < my_nfft_plan.N_total; k++)
my_nfft_plan.f_hat[k] = f_hat[k];
NFFT(trafo_direct)(&my_nfft_plan);
for (j = 0; j < my_nfft_plan.M_total; j++)
f[j] = my_nfft_plan.f[j];
NFFT(finalize)(&my_nfft_plan);
NFFT(free)(x);
NFFT(free)(w);
return EXIT_SUCCESS;
}
static int polar_fft(NFFT_C *f_hat, int NN, NFFT_C *f, int T, int S,
int m)
{
int j, k;
NFFT(plan) my_nfft_plan;
NFFT_R *x, *w;
int N[2], n[2];
int M = T * S;
N[0] = NN;
n[0] = 2 * N[0];
N[1] = NN;
n[1] = 2 * N[1];
x = (NFFT_R *) NFFT(malloc)((size_t)(2 * T * S) * (sizeof(NFFT_R)));
if (x == NULL)
return EXIT_FAILURE;
w = (NFFT_R *) NFFT(malloc)((size_t)(T * S) * (sizeof(NFFT_R)));
if (w == NULL)
return EXIT_FAILURE;
NFFT(init_guru)(&my_nfft_plan, 2, N, M, n, m,
PRE_PHI_HUT | PRE_PSI | MALLOC_X | MALLOC_F_HAT | MALLOC_F | FFTW_INIT
| FFT_OUT_OF_PLACE,
FFTW_MEASURE | FFTW_DESTROY_INPUT);
polar_grid(T, S, x, w);
for (j = 0; j < my_nfft_plan.M_total; j++)
{
my_nfft_plan.x[2 * j + 0] = x[2 * j + 0];
my_nfft_plan.x[2 * j + 1] = x[2 * j + 1];
}
if (my_nfft_plan.flags & PRE_LIN_PSI)
NFFT(precompute_lin_psi)(&my_nfft_plan);
if (my_nfft_plan.flags & PRE_PSI)
NFFT(precompute_psi)(&my_nfft_plan);
if (my_nfft_plan.flags & PRE_FULL_PSI)
NFFT(precompute_full_psi)(&my_nfft_plan);
for (k = 0; k < my_nfft_plan.N_total; k++)
my_nfft_plan.f_hat[k] = f_hat[k];
NFFT(trafo)(&my_nfft_plan);
for (j = 0; j < my_nfft_plan.M_total; j++)
f[j] = my_nfft_plan.f[j];
NFFT(finalize)(&my_nfft_plan);
NFFT(free)(x);
NFFT(free)(w);
return EXIT_SUCCESS;
}
static int inverse_polar_fft(NFFT_C *f, int T, int S, NFFT_C *f_hat,
int NN, int max_i, int m)
{
int j, k;
NFFT(plan) my_nfft_plan;
SOLVER(plan_complex) my_infft_plan;
NFFT_R *x, *w;
int l;
int N[2], n[2];
int M = T * S;
N[0] = NN;
n[0] = 2 * N[0];
N[1] = NN;
n[1] = 2 * N[1];
x = (NFFT_R *) NFFT(malloc)((size_t)(2 * T * S) * (sizeof(NFFT_R)));
if (x == NULL)
return EXIT_FAILURE;
w = (NFFT_R *) NFFT(malloc)((size_t)(T * S) * (sizeof(NFFT_R)));
if (w == NULL)
return EXIT_FAILURE;
NFFT(init_guru)(&my_nfft_plan, 2, N, M, n, m,
PRE_PHI_HUT | PRE_PSI | MALLOC_X | MALLOC_F_HAT | MALLOC_F | FFTW_INIT
| FFT_OUT_OF_PLACE,
FFTW_MEASURE | FFTW_DESTROY_INPUT);
SOLVER(init_advanced_complex)(&my_infft_plan,
(NFFT(mv_plan_complex)*) (&my_nfft_plan), CGNR | PRECOMPUTE_WEIGHT);
polar_grid(T, S, x, w);
for (j = 0; j < my_nfft_plan.M_total; j++)
{
my_nfft_plan.x[2 * j + 0] = x[2 * j + 0];
my_nfft_plan.x[2 * j + 1] = x[2 * j + 1];
my_infft_plan.y[j] = f[j];
my_infft_plan.w[j] = w[j];
}
if (my_nfft_plan.flags & PRE_LIN_PSI)
NFFT(precompute_lin_psi)(&my_nfft_plan);
if (my_nfft_plan.flags & PRE_PSI)
NFFT(precompute_psi)(&my_nfft_plan);
if (my_nfft_plan.flags & PRE_FULL_PSI)
NFFT(precompute_full_psi)(&my_nfft_plan);
if (my_infft_plan.flags & PRECOMPUTE_DAMP)
for (j = 0; j < my_nfft_plan.N[0]; j++)
for (k = 0; k < my_nfft_plan.N[1]; k++)
{
my_infft_plan.w_hat[j * my_nfft_plan.N[1] + k] = (
NFFT_M(sqrt)(
NFFT_M(pow)((NFFT_R) (j - my_nfft_plan.N[0] / 2), NFFT_K(2.0))
+ NFFT_M(pow)((NFFT_R) (k - my_nfft_plan.N[1] / 2), NFFT_K(2.0)))
> ((NFFT_R) (my_nfft_plan.N[0] / 2)) ? 0 : 1);
}
for (k = 0; k < my_nfft_plan.N_total; k++)
my_infft_plan.f_hat_iter[k] = NFFT_K(0.0) + _Complex_I * NFFT_K(0.0);
SOLVER(before_loop_complex)(&my_infft_plan);
if (max_i < 1)
{
l = 1;
for (k = 0; k < my_nfft_plan.N_total; k++)
my_infft_plan.f_hat_iter[k] = my_infft_plan.p_hat_iter[k];
}
else
{
for (l = 1; l <= max_i; l++)
{
SOLVER(loop_one_step_complex)(&my_infft_plan);
}
}
for (k = 0; k < my_nfft_plan.N_total; k++)
f_hat[k] = my_infft_plan.f_hat_iter[k];
SOLVER(finalize_complex)(&my_infft_plan);
NFFT(finalize)(&my_nfft_plan);
NFFT(free)(x);
NFFT(free)(w);
return EXIT_SUCCESS;
}
int main(int argc, char **argv)
{
int N;
int T, S;
int M;
NFFT_R *x, *w;
NFFT_C *f_hat, *f, *f_direct, *f_tilde;
int k;
int max_i;
int m = 1;
NFFT_R temp1, temp2, E_max = NFFT_K(0.0);
FILE *fp1, *fp2;
char filename[30];
if (argc != 4)
{
printf("polar_fft_test N T R \n");
printf("\n");
printf("N polar FFT of size NxN \n");
printf("T number of slopes \n");
printf("R number of offsets \n");
exit(EXIT_FAILURE);
}
N = atoi(argv[1]);
T = atoi(argv[2]);
S = atoi(argv[3]);
printf("N=%d, polar grid with T=%d, R=%d => ", N, T, S);
x = (NFFT_R *) NFFT(malloc)((size_t)(2 * 5 * (T / 2) * (S / 2)) * (sizeof(NFFT_R)));
w = (NFFT_R *) NFFT(malloc)((size_t)(5 * (T / 2) * (S / 2)) * (sizeof(NFFT_R)));
f_hat = (NFFT_C *) NFFT(malloc)(sizeof(NFFT_C) * (size_t)(N * N));
f = (NFFT_C *) NFFT(malloc)(sizeof(NFFT_C) * (size_t)(T * S));
f_direct = (NFFT_C *) NFFT(malloc)(sizeof(NFFT_C) * (size_t)(T * S));
f_tilde = (NFFT_C *) NFFT(malloc)(sizeof(NFFT_C) * (size_t)(N * N));
M = polar_grid(T, S, x, w);
printf("M=%d.\n", M);
fp1 = fopen("input_data_r.dat", "r");
fp2 = fopen("input_data_i.dat", "r");
if (fp1 == NULL)
return (-1);
for (k = 0; k < N * N; k++)
{
fscanf(fp1, NFFT__FR__ " ", &temp1);
fscanf(fp2, NFFT__FR__ " ", &temp2);
f_hat[k] = temp1 + _Complex_I * temp2;
}
fclose(fp1);
fclose(fp2);
polar_dft(f_hat, N, f_direct, T, S, m);
// polar_fft(f_hat,N,f_direct,T,R,12);
printf("\nTest of the polar FFT: \n");
fp1 = fopen("polar_fft_error.dat", "w+");
for (m = 1; m <= 12; m++)
{
polar_fft(f_hat, N, f, T, S, m);
E_max = NFFT(error_l_infty_complex)(f_direct, f, M);
printf("m=%2d: E_max = %" NFFT__FES__ "\n", m, E_max);
fprintf(fp1, "%" NFFT__FES__ "\n", E_max);
}
fclose(fp1);
for (m = 3; m <= 9; m += 3)
{
printf("\nTest of the inverse polar FFT for m=%d: \n", m);
sprintf(filename, "polar_ifft_error%d.dat", m);
fp1 = fopen(filename, "w+");
for (max_i = 0; max_i <= 100; max_i += 10)
{
inverse_polar_fft(f_direct, T, S, f_tilde, N, max_i, m);
/* E_max=0.0;
for(k=0;k<N*N;k++)
{
temp = cabs((f_hat[k]-f_tilde[k])/f_hat[k]);
if (temp>E_max) E_max=temp;
}
*/
E_max = NFFT(error_l_infty_complex)(f_hat, f_tilde, N * N);
printf("%3d iterations: E_max = %" NFFT__FES__ "\n", max_i, E_max);
fprintf(fp1, "%" NFFT__FES__ "\n", E_max);
}
fclose(fp1);
}
NFFT(free)(x);
NFFT(free)(w);
NFFT(free)(f_hat);
NFFT(free)(f);
NFFT(free)(f_direct);
NFFT(free)(f_tilde);
return EXIT_SUCCESS;
}
/* \} */
max_i
static int max_i(int a, int b)
max
Definition: fastsum.c:46
polar_fft
static int polar_fft(NFFT_C *f_hat, int NN, NFFT_C *f, int T, int S, int m)
NFFT-based polar FFT.
Definition: polar_fft_test.c:153
PRECOMPUTE_DAMP
#define PRECOMPUTE_DAMP
Definition: nfft3.h:790
MALLOC_X
#define MALLOC_X
Definition: nfft3.h:199
MALLOC_F_HAT
#define MALLOC_F_HAT
Definition: nfft3.h:200
PRECOMPUTE_WEIGHT
#define PRECOMPUTE_WEIGHT
Definition: nfft3.h:789
FFTW_INIT
#define FFTW_INIT
Definition: nfft3.h:203
polar_dft
static int polar_dft(NFFT_C *f_hat, int NN, NFFT_C *f, int T, int S, int m)
discrete polar FFT
Definition: polar_fft_test.c:95
MALLOC_F
#define MALLOC_F
Definition: nfft3.h:201
FFT_OUT_OF_PLACE
#define FFT_OUT_OF_PLACE
Definition: nfft3.h:202
PRE_LIN_PSI
#define PRE_LIN_PSI
Definition: nfft3.h:195
PRE_PSI
#define PRE_PSI
Definition: nfft3.h:197
CGNR
#define CGNR
Definition: nfft3.h:786
polar_grid
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. ...
Definition: polar_fft_test.c:73
PRE_FULL_PSI
#define PRE_FULL_PSI
Definition: nfft3.h:198
PRE_PHI_HUT
#define PRE_PHI_HUT
Definition: nfft3.h:193
inverse_polar_fft
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
Definition: polar_fft_test.c:221
main
int main(int argc, char **argv)
test program for various parameters
Definition: polar_fft_test.c:324