NFFT 3.6.0
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
37static 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
43static 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
109static 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,
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
208int 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/* \} */
static void glacier_cv(int N, int M, int M_cv, unsigned solver_flags)
Reconstruction routine with cross validation.
Definition glacier.c:109
static NFFT_R my_weight(NFFT_R z, NFFT_R a, NFFT_R b, NFFT_R c)
Generalised Sobolev weight.
Definition glacier.c:37
static void glacier(int N, int M)
Reconstruction routine.
Definition glacier.c:43
#define MALLOC_F_HAT
Definition nfft3.h:194
#define MALLOC_X
Definition nfft3.h:193
#define PRE_ONE_PSI
Definition nfft3.h:200
#define PRE_FULL_PSI
Definition nfft3.h:192
#define FFT_OUT_OF_PLACE
Definition nfft3.h:196
#define MALLOC_F
Definition nfft3.h:195
#define FFTW_INIT
Definition nfft3.h:197
#define PRE_PHI_HUT
Definition nfft3.h:187
#define CGNR
Definition nfft3.h:808
#define PRECOMPUTE_DAMP
Definition nfft3.h:812
#define CGNE
Definition nfft3.h:809