예제 #1
0
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);
}
예제 #2
0
/** 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;
}
예제 #3
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;
}
예제 #4
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);
}
예제 #5
0
/** 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;
}