NFFT  3.4.1
glacier.c
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 
19 #include <stdio.h>
20 #include <math.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <complex.h>
24 
25 #define NFFT_PRECISION_DOUBLE
26 
27 #include "nfft3mp.h"
28 
37 static NFFT_R my_weight(NFFT_R z, NFFT_R a, NFFT_R b, NFFT_R c)
38 {
39  return NFFT_M(pow)(NFFT_K(0.25) - z * z, b) / (c + NFFT_M(pow)(NFFT_M(fabs)(z), NFFT_K(2.0) * a));
40 }
41 
43 static void glacier(int N, int M)
44 {
45  int j, k, k0, k1, l, my_N[2], my_n[2];
46  NFFT_R tmp_y;
47  NFFT(plan) p;
48  SOLVER(plan_complex) ip;
49  FILE* fp;
50 
51  /* initialise p */
52  my_N[0] = N;
53  my_n[0] = (int)NFFT(next_power_of_2)(N);
54  my_N[1] = N;
55  my_n[1] = (int)NFFT(next_power_of_2)(N);
56  NFFT(init_guru)(&p, 2, my_N, M, my_n, 6,
60  FFTW_MEASURE | FFTW_DESTROY_INPUT);
61 
62  /* initialise ip, specific */
63  SOLVER(init_advanced_complex)(&ip, (NFFT(mv_plan_complex)*) (&p),
65  fprintf(stderr, "Using the generic solver!");
66 
67  /* init nodes */
68  fp = fopen("input_data.dat", "r");
69  for (j = 0; j < p.M_total; j++)
70  {
71  fscanf(fp, "%" NFFT__FES__ " %" NFFT__FES__ " %" NFFT__FES__, &p.x[2 * j + 0], &p.x[2 * j + 1], &tmp_y);
72  ip.y[j] = tmp_y;
73  }
74  fclose(fp);
75 
76  /* precompute psi */
77  if (p.flags & PRE_ONE_PSI)
78  NFFT(precompute_one_psi)(&p);
79 
80  /* initialise damping factors */
81  if (ip.flags & PRECOMPUTE_DAMP)
82  for (k0 = 0; k0 < p.N[0]; k0++)
83  for (k1 = 0; k1 < p.N[1]; k1++)
84  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])),
85  NFFT_K(0.5), NFFT_K(3.0), NFFT_K(0.001))
86  * 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));
87 
88  /* init some guess */
89  for (k = 0; k < p.N_total; k++)
90  ip.f_hat_iter[k] = NFFT_K(0.0);
91 
92  /* inverse trafo */
93  SOLVER(before_loop_complex)(&ip);
94 
95  for (l = 0; l < 40; l++)
96  {
97  fprintf(stderr, "Residual ||r||=%" NFFT__FES__ ",\n", NFFT_M(sqrt)(ip.dot_r_iter));
98  SOLVER(loop_one_step_complex)(&ip);
99  }
100 
101  for (k = 0; k < p.N_total; k++)
102  printf("%" NFFT__FES__ " %" NFFT__FES__ "\n", NFFT_M(creal)(ip.f_hat_iter[k]), NFFT_M(cimag)(ip.f_hat_iter[k]));
103 
104  SOLVER(finalize_complex)(&ip);
105  NFFT(finalize)(&p);
106 }
107 
109 static void glacier_cv(int N, int M, int M_cv, unsigned solver_flags)
110 {
111  int j, k, k0, k1, l, my_N[2], my_n[2];
112  NFFT_R tmp_y, r;
113  NFFT(plan) p, cp;
114  SOLVER(plan_complex) ip;
115  NFFT_C* cp_y;
116  FILE* fp;
117  int M_re = M - M_cv;
118 
119  /* initialise p for reconstruction */
120  my_N[0] = N;
121  my_n[0] = (int)NFFT(next_power_of_2)(N);
122  my_N[1] = N;
123  my_n[1] = (int)NFFT(next_power_of_2)(N);
124  NFFT(init_guru)(&p, 2, my_N, M_re, my_n, 6,
128  FFTW_MEASURE | FFTW_DESTROY_INPUT);
129 
130  /* initialise ip, specific */
131  SOLVER(init_advanced_complex)(&ip, (NFFT(mv_plan_complex)*) (&p), solver_flags);
132 
133  /* initialise cp for validation */
134  cp_y = (NFFT_C*) NFFT(malloc)((size_t)(M) * sizeof(NFFT_C));
135  NFFT(init_guru)(&cp, 2, my_N, M, my_n, 6,
137  MALLOC_X | MALLOC_F |
139  FFTW_MEASURE | FFTW_DESTROY_INPUT);
140 
141  cp.f_hat = ip.f_hat_iter;
142 
143  /* set up data in cp and cp_y */
144  fp = fopen("input_data.dat", "r");
145  for (j = 0; j < cp.M_total; j++)
146  {
147  fscanf(fp, "%" NFFT__FES__ " %" NFFT__FES__ " %" NFFT__FES__, &cp.x[2 * j + 0], &cp.x[2 * j + 1], &tmp_y);
148  cp_y[j] = tmp_y;
149  }
150  fclose(fp);
151 
152  /* copy part of the data to p and ip */
153  for (j = 0; j < p.M_total; j++)
154  {
155  p.x[2 * j + 0] = cp.x[2 * j + 0];
156  p.x[2 * j + 1] = cp.x[2 * j + 1];
157  ip.y[j] = tmp_y;
158  }
159 
160  /* precompute psi */
161  if (p.flags & PRE_ONE_PSI)
162  NFFT(precompute_one_psi)(&p);
163 
164  /* precompute psi */
165  if (cp.flags & PRE_ONE_PSI)
166  NFFT(precompute_one_psi)(&cp);
167 
168  /* initialise damping factors */
169  if (ip.flags & PRECOMPUTE_DAMP)
170  for (k0 = 0; k0 < p.N[0]; k0++)
171  for (k1 = 0; k1 < p.N[1]; k1++)
172  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])),
173  NFFT_K(0.5), NFFT_K(3.0), NFFT_K(0.001))
174  * 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));
175 
176  /* init some guess */
177  for (k = 0; k < p.N_total; k++)
178  ip.f_hat_iter[k] = NFFT_K(0.0);
179 
180  /* inverse trafo */
181  SOLVER(before_loop_complex)(&ip);
182  // fprintf(stderr,"iteration starts,\t");
183  for (l = 0; l < 40; l++)
184  SOLVER(loop_one_step_complex)(&ip);
185 
186  //fprintf(stderr,"r=%1.2e, ",sqrt(ip.dot_r_iter)/M_re);
187 
188  NFFT_CSWAP(p.f_hat, ip.f_hat_iter);
189  NFFT(trafo)(&p);
190  NFFT_CSWAP(p.f_hat, ip.f_hat_iter);
191  NFFT(upd_axpy_complex)(p.f, -1, ip.y, M_re);
192  r = NFFT_M(sqrt)(NFFT(dot_complex)(p.f, M_re) / NFFT(dot_complex)(cp_y, M));
193  fprintf(stderr, "r=%1.2" NFFT__FES__ ", ", r);
194  printf("$%1.1" NFFT__FES__ "$ & ", r);
195 
196  NFFT(trafo)(&cp);
197  NFFT(upd_axpy_complex)(&cp.f[M_re], -1, &cp_y[M_re], M_cv);
198  r = NFFT_M(sqrt)(NFFT(dot_complex)(&cp.f[M_re], M_cv) / NFFT(dot_complex)(cp_y, M));
199  fprintf(stderr, "r_1=%1.2" NFFT__FES__ "\t", r);
200  printf("$%1.1" NFFT__FES__ "$ & ", r);
201 
202  NFFT(finalize)(&cp);
203  SOLVER(finalize_complex)(&ip);
204  NFFT(finalize)(&p);
205 }
206 
208 int main(int argc, char **argv)
209 {
210  int M_cv;
211 
212  if (argc < 3)
213  {
214  fprintf(stderr, "Call this program from the Matlab script glacier.m!");
215  return EXIT_FAILURE;
216  }
217 
218  if (argc == 3)
219  glacier(atoi(argv[1]), atoi(argv[2]));
220  else
221  for (M_cv = atoi(argv[3]); M_cv <= atoi(argv[5]); M_cv += atoi(argv[4]))
222  {
223  fprintf(stderr, "\nM_cv=%d,\t", M_cv);
224  printf("$%d$ & ", M_cv);
225  fprintf(stderr, "cgne+damp: ");
226  glacier_cv(atoi(argv[1]), atoi(argv[2]), M_cv, CGNE | PRECOMPUTE_DAMP);
227  //fprintf(stderr,"cgne: ");
228  //glacier_cv(atoi(argv[1]),atoi(argv[2]),M_cv,CGNE);
229  fprintf(stderr, "cgnr: ");
230  glacier_cv(atoi(argv[1]), atoi(argv[2]), M_cv, CGNR);
231  fprintf(stderr, "cgnr: ");
232  glacier_cv(atoi(argv[1]) / 4, atoi(argv[2]), M_cv, CGNR);
233  printf("XXX \\\\\n");
234  }
235 
236  fprintf(stderr, "\n");
237 
238  return EXIT_SUCCESS;
239 }
240 /* \} */
#define PRECOMPUTE_DAMP
Definition: nfft3.h:792
#define MALLOC_X
Definition: nfft3.h:199
#define MALLOC_F_HAT
Definition: nfft3.h:200
int main(int argc, char **argv)
Main routine.
Definition: glacier.c:208
#define CGNE
Definition: nfft3.h:789
static NFFT_R my_weight(NFFT_R z, NFFT_R a, NFFT_R b, NFFT_R c)
Generalised Sobolev weight.
Definition: glacier.c:37
#define FFTW_INIT
Definition: nfft3.h:203
static void glacier(int N, int M)
Reconstruction routine.
Definition: glacier.c:43
#define MALLOC_F
Definition: nfft3.h:201
#define FFT_OUT_OF_PLACE
Definition: nfft3.h:202
#define CGNR
Definition: nfft3.h:788
static void glacier_cv(int N, int M, int M_cv, unsigned solver_flags)
Reconstruction routine with cross validation.
Definition: glacier.c:109
#define PRE_FULL_PSI
Definition: nfft3.h:198
#define PRE_PHI_HUT
Definition: nfft3.h:193
#define PRE_ONE_PSI
Definition: nfft3.h:206