static void simple_test_nfct_1d(void) { NFCT(plan) p; const char *error_str; int N = 14; int M = 19; /** init an one dimensional plan */ NFCT(init_1d)(&p,N,M); /** init pseudo random nodes */ NFFT(vrand_real)(p.x, p.M_total, NFFT_K(0.0), NFFT_K(0.5)); /** precompute psi, the entries of the matrix B */ if( p.flags & PRE_ONE_PSI) NFCT(precompute_one_psi)(&p); /** init pseudo random Fourier coefficients and show them */ NFFT(vrand_real)(p.f_hat, p.N_total, NFFT_K(0.0), NFFT_K(1.0)); NFFT(vpr_double)(p.f_hat,p.N_total,"given Fourier coefficients, vector f_hat"); /** check for valid parameters before calling any trafo/adjoint method */ error_str = NFCT(check)(&p); if (error_str != 0) { printf("Error in nfct module: %s\n", error_str); return; } /** direct trafo and show the result */ NFCT(trafo_direct)(&p); NFFT(vpr_double)(p.f,p.M_total,"ndct, vector f"); /** approx. trafo and show the result */ NFCT(trafo)(&p); NFFT(vpr_double)(p.f,p.M_total,"nfct, vector f"); /** approx. adjoint and show the result */ NFCT(adjoint_direct)(&p); NFFT(vpr_double)(p.f_hat,p.N_total,"adjoint ndct, vector f_hat"); /** approx. adjoint and show the result */ NFCT(adjoint)(&p); NFFT(vpr_double)(p.f_hat,p.N_total,"adjoint nfct, vector f_hat"); /** finalise the one dimensional plan */ NFCT(finalize)(&p); }
/** generates the points x with weights w * for the linogram grid with T slopes and R offsets */ static int linogram_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++) { if (t < 0) { x[2 * ((t + T / 2) * S + (r + S / 2)) + 0] = (NFFT_R) r / (NFFT_R)(S); x[2 * ((t + T / 2) * S + (r + S / 2)) + 1] = NFFT_K(4.0) * ((NFFT_R)(t) + (NFFT_R)(T) / NFFT_K(4.0)) / (NFFT_R)(T) * (NFFT_R)(r) / (NFFT_R)(S); } else { x[2 * ((t + T / 2) * S + (r + S / 2)) + 0] = -NFFT_K(4.0) * ((NFFT_R)(t) - (NFFT_R)(T) / NFFT_K(4.0)) / (NFFT_R)(T) * (NFFT_R)(r) / (NFFT_R)(S); x[2 * ((t + T / 2) * S + (r + S / 2)) + 1] = (NFFT_R) r / (NFFT_R)(S); } 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 0; }
/** generates the points x with weights w * for the polar grid with T angles and R offsets */ 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 0; }
/** Simple test routine for the inverse nfft */ static void simple_test_solver_nfft_1d(int N, int M, int iter) { int k, l; /**< index for nodes, freqencies,iter*/ NFFT(plan) p; /**< plan for the nfft */ SOLVER(plan_complex) ip; /**< plan for the inverse nfft */ const char *error_str; /** initialise an one dimensional plan */ NFFT(init_1d)(&p, N, M); /** init pseudo random nodes */ NFFT(vrand_shifted_unit_double)(p.x, p.M_total); /** precompute psi, the entries of the matrix B */ if (p.flags & PRE_ONE_PSI) NFFT(precompute_one_psi)(&p); /** initialise inverse plan */ SOLVER(init_complex)(&ip, (NFFT(mv_plan_complex)*) (&p)); /** init pseudo random samples and show them */ NFFT(vrand_unit_complex)(ip.y, p.M_total); NFFT(vpr_complex)(ip.y, p.M_total, "Given data, vector y"); /** initialise some guess f_hat_0 and solve */ for (k = 0; k < p.N_total; k++) ip.f_hat_iter[k] = NFFT_K(0.0); NFFT(vpr_complex)(ip.f_hat_iter, p.N_total, "Initial guess, vector f_hat_iter"); /** check for valid parameters before calling any trafo/adjoint method */ error_str = NFFT(check)(&p); if (error_str != 0) { printf("Error in nfft module: %s\n", error_str); return; } NFFT_CSWAP(ip.f_hat_iter, p.f_hat); NFFT(trafo)(&p); NFFT(vpr_complex)(p.f, p.M_total, "Data fit, vector f"); NFFT_CSWAP(ip.f_hat_iter, p.f_hat); SOLVER(before_loop_complex)(&ip); printf("\n Residual r=%" NFFT__FES__ "\n", ip.dot_r_iter); for (l = 0; l < iter; l++) { printf("\n********** Iteration l=%d **********\n", l); SOLVER(loop_one_step_complex)(&ip); NFFT(vpr_complex)(ip.f_hat_iter, p.N_total, "Approximate solution, vector f_hat_iter"); NFFT_CSWAP(ip.f_hat_iter, p.f_hat); NFFT(trafo)(&p); NFFT(vpr_complex)(p.f, p.M_total, "Data fit, vector f"); NFFT_CSWAP(ip.f_hat_iter, p.f_hat); printf("\n Residual r=%" NFFT__FES__ "\n", ip.dot_r_iter); } SOLVER(finalize_complex)(&ip); NFFT(finalize)(&p); }
/** computes the inverse discrete Radon transform of Rf * on the grid given by gridfcn() with T angles and R offsets * by a NFFT-based CG-type algorithm */ static int inverse_radon_trafo(int (*gridfcn)(), int T, int S, NFFT_R *Rf, int NN, NFFT_R *f, int max_i) { int j, k; /**< index for nodes and freqencies */ NFFT(plan) my_nfft_plan; /**< plan for the nfft-2D */ SOLVER(plan_complex) my_infft_plan; /**< plan for the inverse nfft */ NFFT_C *fft; /**< variable for the fftw-1Ds */ FFTW(plan) my_fftw_plan; /**< plan for the fftw-1Ds */ int t, r; /**< index for directions and offsets */ NFFT_R *x, *w; /**< knots and associated weights */ int l; /**< index for iterations */ 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]; fft = (NFFT_C *) NFFT(malloc)((size_t)(S) * sizeof(NFFT_C)); my_fftw_plan = FFTW(plan_dft_1d)(S, fft, fft, FFTW_FORWARD, FFTW_MEASURE); 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; /** init two dimensional NFFT plan */ NFFT(init_guru)(&my_nfft_plan, 2, N, M, n, 4, PRE_PHI_HUT | PRE_PSI | MALLOC_X | MALLOC_F_HAT | MALLOC_F | FFTW_INIT | FFT_OUT_OF_PLACE, FFTW_MEASURE | FFTW_DESTROY_INPUT); /** init two dimensional infft plan */ SOLVER(init_advanced_complex)(&my_infft_plan, (NFFT(mv_plan_complex)*) (&my_nfft_plan), CGNR | PRECOMPUTE_WEIGHT); /** init nodes and weights of grid*/ gridfcn(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 (j % S) my_infft_plan.w[j] = w[j]; else my_infft_plan.w[j] = NFFT_K(0.0); } /** precompute psi, the entries of the matrix B */ 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); /** compute 1D-ffts and init given samples and weights */ for (t = 0; t < T; t++) { /* for(r=0; r<R/2; r++) fft[r] = cexp(I*NFFT_KPI*r)*Rf[t*R+(r+R/2)]; for(r=0; r<R/2; r++) fft[r+R/2] = cexp(I*NFFT_KPI*r)*Rf[t*R+r]; */ for (r = 0; r < S; r++) fft[r] = Rf[t * S + r] + _Complex_I * NFFT_K(0.0); NFFT(fftshift_complex_int)(fft, 1, &S); FFTW(execute)(my_fftw_plan); NFFT(fftshift_complex_int)(fft, 1, &S); my_infft_plan.y[t * S] = NFFT_K(0.0); for (r = -S / 2 + 1; r < S / 2; r++) my_infft_plan.y[t * S + (r + S / 2)] = fft[r + S / 2] / KERNEL(r); } /** initialise some guess f_hat_0 */ 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); /** solve the system */ 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); /*if (sqrt(my_infft_plan.dot_r_iter)<=1e-12) break;*/ } } /*printf("after %d iteration(s): weighted 2-norm of original residual vector = %g\n",l-1,sqrt(my_infft_plan.dot_r_iter));*/ /** copy result */ for (k = 0; k < my_nfft_plan.N_total; k++) f[k] = NFFT_M(creal)(my_infft_plan.f_hat_iter[k]); /** finalise the plans and free the variables */ FFTW(destroy_plan)(my_fftw_plan); NFFT(free)(fft); SOLVER(finalize_complex)(&my_infft_plan); NFFT(finalize)(&my_nfft_plan); NFFT(free)(x); NFFT(free)(w); return 0; }