NFFT  3.3.2
glacier.c
00001 /*
00002  * Copyright (c) 2002, 2016 Jens Keiner, Stefan Kunis, Daniel Potts
00003  *
00004  * This program is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU General Public License as published by the Free Software
00006  * Foundation; either version 2 of the License, or (at your option) any later
00007  * version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but WITHOUT
00010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00012  * details.
00013  *
00014  * You should have received a copy of the GNU General Public License along with
00015  * this program; if not, write to the Free Software Foundation, Inc., 51
00016  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #include <stdio.h>
00020 #include <math.h>
00021 #include <string.h>
00022 #include <stdlib.h>
00023 #include <complex.h>
00024 
00025 #define NFFT_PRECISION_DOUBLE
00026 
00027 #include "nfft3mp.h"
00028 
00037 static NFFT_R my_weight(NFFT_R z, NFFT_R a, NFFT_R b, NFFT_R c)
00038 {
00039   return NFFT_M(pow)(NFFT_K(0.25) - z * z, b) / (c + NFFT_M(pow)(NFFT_M(fabs)(z), NFFT_K(2.0) * a));
00040 }
00041 
00043 static void glacier(int N, int M)
00044 {
00045   int j, k, k0, k1, l, my_N[2], my_n[2];
00046   NFFT_R tmp_y;
00047   NFFT(plan) p;
00048   SOLVER(plan_complex) ip;
00049   FILE* fp;
00050 
00051   /* initialise p */
00052   my_N[0] = N;
00053   my_n[0] = (int)NFFT(next_power_of_2)(N);
00054   my_N[1] = N;
00055   my_n[1] = (int)NFFT(next_power_of_2)(N);
00056   NFFT(init_guru)(&p, 2, my_N, M, my_n, 6,
00057   PRE_PHI_HUT | PRE_FULL_PSI |
00058   MALLOC_X | MALLOC_F_HAT | MALLOC_F |
00059   FFTW_INIT | FFT_OUT_OF_PLACE,
00060   FFTW_MEASURE | FFTW_DESTROY_INPUT);
00061 
00062   /* initialise ip, specific */
00063   SOLVER(init_advanced_complex)(&ip, (NFFT(mv_plan_complex)*) (&p),
00064       CGNE | PRECOMPUTE_DAMP);
00065   fprintf(stderr, "Using the generic solver!");
00066 
00067   /* init nodes */
00068   fp = fopen("input_data.dat", "r");
00069   for (j = 0; j < p.M_total; j++)
00070   {
00071     fscanf(fp, "%" NFFT__FES__ " %" NFFT__FES__ " %" NFFT__FES__, &p.x[2 * j + 0], &p.x[2 * j + 1], &tmp_y);
00072     ip.y[j] = tmp_y;
00073   }
00074   fclose(fp);
00075 
00076   /* precompute psi */
00077   if (p.flags & PRE_ONE_PSI)
00078     NFFT(precompute_one_psi)(&p);
00079 
00080   /* initialise damping factors */
00081   if (ip.flags & PRECOMPUTE_DAMP)
00082     for (k0 = 0; k0 < p.N[0]; k0++)
00083       for (k1 = 0; k1 < p.N[1]; k1++)
00084         ip.w_hat[k0 * p.N[1] + k1] = my_weight(((NFFT_R) ((NFFT_R)(k0) - (NFFT_R)(p.N[0]) / NFFT_K(2.0))) / ((NFFT_R)(p.N[0])),
00085             NFFT_K(0.5), NFFT_K(3.0), NFFT_K(0.001))
00086             * my_weight((((NFFT_R)(k1) - (NFFT_R)(p.N[1]) / NFFT_K(2.0))) / ((NFFT_R)(p.N[1])), NFFT_K(0.5), NFFT_K(3.0), NFFT_K(0.001));
00087 
00088   /* init some guess */
00089   for (k = 0; k < p.N_total; k++)
00090     ip.f_hat_iter[k] = NFFT_K(0.0);
00091 
00092   /* inverse trafo */
00093   SOLVER(before_loop_complex)(&ip);
00094 
00095   for (l = 0; l < 40; l++)
00096   {
00097     fprintf(stderr, "Residual ||r||=%" NFFT__FES__ ",\n", NFFT_M(sqrt)(ip.dot_r_iter));
00098     SOLVER(loop_one_step_complex)(&ip);
00099   }
00100 
00101   for (k = 0; k < p.N_total; k++)
00102     printf("%" NFFT__FES__ " %" NFFT__FES__ "\n", NFFT_M(creal)(ip.f_hat_iter[k]), NFFT_M(cimag)(ip.f_hat_iter[k]));
00103 
00104   SOLVER(finalize_complex)(&ip);
00105   NFFT(finalize)(&p);
00106 }
00107 
00109 static void glacier_cv(int N, int M, int M_cv, unsigned solver_flags)
00110 {
00111   int j, k, k0, k1, l, my_N[2], my_n[2];
00112   NFFT_R tmp_y, r;
00113   NFFT(plan) p, cp;
00114   SOLVER(plan_complex) ip;
00115   NFFT_C* cp_y;
00116   FILE* fp;
00117   int M_re = M - M_cv;
00118 
00119   /* initialise p for reconstruction */
00120   my_N[0] = N;
00121   my_n[0] = (int)NFFT(next_power_of_2)(N);
00122   my_N[1] = N;
00123   my_n[1] = (int)NFFT(next_power_of_2)(N);
00124   NFFT(init_guru)(&p, 2, my_N, M_re, my_n, 6,
00125   PRE_PHI_HUT | PRE_FULL_PSI |
00126   MALLOC_X | MALLOC_F_HAT | MALLOC_F |
00127   FFTW_INIT | FFT_OUT_OF_PLACE,
00128   FFTW_MEASURE | FFTW_DESTROY_INPUT);
00129 
00130   /* initialise ip, specific */
00131   SOLVER(init_advanced_complex)(&ip, (NFFT(mv_plan_complex)*) (&p), solver_flags);
00132 
00133   /* initialise cp for validation */
00134   cp_y = (NFFT_C*) NFFT(malloc)((size_t)(M) * sizeof(NFFT_C));
00135   NFFT(init_guru)(&cp, 2, my_N, M, my_n, 6,
00136   PRE_PHI_HUT | PRE_FULL_PSI |
00137   MALLOC_X | MALLOC_F |
00138   FFTW_INIT | FFT_OUT_OF_PLACE,
00139   FFTW_MEASURE | FFTW_DESTROY_INPUT);
00140 
00141   cp.f_hat = ip.f_hat_iter;
00142 
00143   /* set up data in cp and cp_y */
00144   fp = fopen("input_data.dat", "r");
00145   for (j = 0; j < cp.M_total; j++)
00146   {
00147     fscanf(fp, "%" NFFT__FES__ " %" NFFT__FES__ " %" NFFT__FES__, &cp.x[2 * j + 0], &cp.x[2 * j + 1], &tmp_y);
00148     cp_y[j] = tmp_y;
00149   }
00150   fclose(fp);
00151 
00152   /* copy part of the data to p and ip */
00153   for (j = 0; j < p.M_total; j++)
00154   {
00155     p.x[2 * j + 0] = cp.x[2 * j + 0];
00156     p.x[2 * j + 1] = cp.x[2 * j + 1];
00157     ip.y[j] = tmp_y;
00158   }
00159 
00160   /* precompute psi */
00161   if (p.flags & PRE_ONE_PSI)
00162     NFFT(precompute_one_psi)(&p);
00163 
00164   /* precompute psi */
00165   if (cp.flags & PRE_ONE_PSI)
00166     NFFT(precompute_one_psi)(&cp);
00167 
00168   /* initialise damping factors */
00169   if (ip.flags & PRECOMPUTE_DAMP)
00170     for (k0 = 0; k0 < p.N[0]; k0++)
00171       for (k1 = 0; k1 < p.N[1]; k1++)
00172         ip.w_hat[k0 * p.N[1] + k1] = my_weight((((NFFT_R)(k0) - (NFFT_R)(p.N[0]) / NFFT_K(2.0))) / ((NFFT_R)(p.N[0])),
00173             NFFT_K(0.5), NFFT_K(3.0), NFFT_K(0.001))
00174             * my_weight((((NFFT_R)(k1) - (NFFT_R)(p.N[1]) / NFFT_K(2.0))) / ((NFFT_R)(p.N[1])), NFFT_K(0.5), NFFT_K(3.0), NFFT_K(0.001));
00175 
00176   /* init some guess */
00177   for (k = 0; k < p.N_total; k++)
00178     ip.f_hat_iter[k] = NFFT_K(0.0);
00179 
00180   /* inverse trafo */
00181   SOLVER(before_loop_complex)(&ip);
00182   //  fprintf(stderr,"iteration starts,\t");
00183   for (l = 0; l < 40; l++)
00184     SOLVER(loop_one_step_complex)(&ip);
00185 
00186   //fprintf(stderr,"r=%1.2e, ",sqrt(ip.dot_r_iter)/M_re);
00187 
00188   NFFT_CSWAP(p.f_hat, ip.f_hat_iter);
00189   NFFT(trafo)(&p);
00190   NFFT_CSWAP(p.f_hat, ip.f_hat_iter);
00191   NFFT(upd_axpy_complex)(p.f, -1, ip.y, M_re);
00192   r = NFFT_M(sqrt)(NFFT(dot_complex)(p.f, M_re) / NFFT(dot_complex)(cp_y, M));
00193   fprintf(stderr, "r=%1.2" NFFT__FES__ ", ", r);
00194   printf("$%1.1" NFFT__FES__ "$ & ", r);
00195 
00196   NFFT(trafo)(&cp);
00197   NFFT(upd_axpy_complex)(&cp.f[M_re], -1, &cp_y[M_re], M_cv);
00198   r = NFFT_M(sqrt)(NFFT(dot_complex)(&cp.f[M_re], M_cv) / NFFT(dot_complex)(cp_y, M));
00199   fprintf(stderr, "r_1=%1.2" NFFT__FES__ "\t", r);
00200   printf("$%1.1" NFFT__FES__ "$ & ", r);
00201 
00202   NFFT(finalize)(&cp);
00203   SOLVER(finalize_complex)(&ip);
00204   NFFT(finalize)(&p);
00205 }
00206 
00208 int main(int argc, char **argv)
00209 {
00210   int M_cv;
00211 
00212   if (argc < 3)
00213   {
00214     fprintf(stderr, "Call this program from the Matlab script glacier.m!");
00215     return EXIT_FAILURE;
00216   }
00217 
00218   if (argc == 3)
00219     glacier(atoi(argv[1]), atoi(argv[2]));
00220   else
00221     for (M_cv = atoi(argv[3]); M_cv <= atoi(argv[5]); M_cv += atoi(argv[4]))
00222     {
00223       fprintf(stderr, "\nM_cv=%d,\t", M_cv);
00224       printf("$%d$ & ", M_cv);
00225       fprintf(stderr, "cgne+damp: ");
00226       glacier_cv(atoi(argv[1]), atoi(argv[2]), M_cv, CGNE | PRECOMPUTE_DAMP);
00227       //fprintf(stderr,"cgne: ");
00228       //glacier_cv(atoi(argv[1]),atoi(argv[2]),M_cv,CGNE);
00229       fprintf(stderr, "cgnr: ");
00230       glacier_cv(atoi(argv[1]), atoi(argv[2]), M_cv, CGNR);
00231       fprintf(stderr, "cgnr: ");
00232       glacier_cv(atoi(argv[1]) / 4, atoi(argv[2]), M_cv, CGNR);
00233       printf("XXX \\\\\n");
00234     }
00235 
00236   fprintf(stderr, "\n");
00237 
00238   return EXIT_SUCCESS;
00239 }
00240 /* \} */