Carry out optimal estimation retrieval.
114 {
115
116 static int ipa[
N], iqa[
N];
117
118 FILE *out;
119
120 char filename[2 *
LEN];
121
122 double chisq, disq = 0, lmpar = 0.001;
123
124 int it = 0;
125
126
127
128
129
130
131 const size_t m =
obs2y(ctl, obs_meas, NULL, NULL, NULL);
132 const size_t n =
atm2x(ctl, atm_apr, NULL, iqa, ipa);
133 if (m == 0 || n == 0)
134 ERRMSG(
"Check problem definition!");
135
136
137 LOG(1,
"Problem size: m= %d / n= %d "
138 "(alloc= %.4g MB / stat= %.4g MB)",
139 (int) m, (int) n,
140 (double) (3 * m * n + 4 * n * n + 8 * m +
141 8 * n) * sizeof(double) / 1024. / 1024.,
142 (
double) (5 *
sizeof(
atm_t) + 3 *
sizeof(
obs_t)
143 + 2 *
N *
sizeof(
int)) / 1024. / 1024.);
144
145
146 gsl_matrix *a = gsl_matrix_alloc(n, n);
147 gsl_matrix *cov = gsl_matrix_alloc(n, n);
148 gsl_matrix *k_i = gsl_matrix_alloc(m, n);
149 gsl_matrix *s_a_inv = gsl_matrix_alloc(n, n);
150
151 gsl_vector *b = gsl_vector_alloc(n);
152 gsl_vector *dx = gsl_vector_alloc(n);
153 gsl_vector *dy = gsl_vector_alloc(m);
154 gsl_vector *sig_eps_inv = gsl_vector_alloc(m);
155 gsl_vector *sig_formod = gsl_vector_alloc(m);
156 gsl_vector *sig_noise = gsl_vector_alloc(m);
157 gsl_vector *x_a = gsl_vector_alloc(n);
158 gsl_vector *x_i = gsl_vector_alloc(n);
159 gsl_vector *x_step = gsl_vector_alloc(n);
160 gsl_vector *y_aux = gsl_vector_alloc(m);
161 gsl_vector *y_i = gsl_vector_alloc(m);
162 gsl_vector *y_m = gsl_vector_alloc(m);
163
164
167 formod(ctl, tbl, atm_i, obs_i);
168
169
170 atm2x(ctl, atm_apr, x_a, NULL, NULL);
171 atm2x(ctl, atm_i, x_i, NULL, NULL);
172 obs2y(ctl, obs_meas, y_m, NULL, NULL);
173 obs2y(ctl, obs_i, y_i, NULL, NULL);
174
175
178 atm_i, obs_i, "x", "x", "r");
180
181
182 set_cov_meas(ret, ctl, obs_meas, sig_noise, sig_formod, sig_eps_inv);
183
184
185 sprintf(filename,
"%s/costs.tab", ret->
dir);
186 if (!(out = fopen(filename, "w")))
187 ERRMSG(
"Cannot create cost function file!");
188
189
190 fprintf(out,
191 "# $1 = iteration number\n"
192 "# $2 = normalized cost function\n"
193 "# $3 = number of measurements\n"
194 "# $4 = number of state vector elements\n\n");
195
196
197 gsl_vector_memcpy(dx, x_i);
198 gsl_vector_sub(dx, x_a);
199 gsl_vector_memcpy(dy, y_m);
200 gsl_vector_sub(dy, y_i);
201
202
204
205
206 LOG(1,
"it= %d / chi^2/m= %g", it, chisq);
207
208
209 fprintf(out, "%d %g %d %d\n", it, chisq, (int) m, (int) n);
210
211
212 kernel(ctl, tbl, atm_i, obs_i, k_i);
213
214
215
216
217
218
220
221
222 double chisq_old = chisq;
223
224
226 kernel(ctl, tbl, atm_i, obs_i, k_i);
227
228
231
232
233 for (size_t i = 0; i < m; i++)
234 gsl_vector_set(y_aux, i, gsl_vector_get(dy, i)
235 *
POW2(gsl_vector_get(sig_eps_inv, i)));
236 gsl_blas_dgemv(CblasTrans, 1.0, k_i, y_aux, 0.0, b);
237 gsl_blas_dgemv(CblasNoTrans, -1.0, s_a_inv, dx, 1.0, b);
238
239
240 for (int it2 = 0; it2 < 20; it2++) {
241
242
243 gsl_matrix_memcpy(a, s_a_inv);
244 gsl_matrix_scale(a, 1 + lmpar);
245 gsl_matrix_add(a, cov);
246
247
248 gsl_linalg_cholesky_decomp(a);
249 gsl_linalg_cholesky_solve(a, b, x_step);
250
251
252 gsl_vector_add(x_i, x_step);
255 x2atm(ctl, x_i, atm_i);
256
257
258 for (
int ip = 0; ip < atm_i->
np; ip++) {
259 atm_i->
p[ip] =
MIN(
MAX(atm_i->
p[ip], 5e-7), 5e4);
260 atm_i->
t[ip] =
MIN(
MAX(atm_i->
t[ip], 100), 400);
261 for (
int ig = 0; ig < ctl->
ng; ig++)
262 atm_i->
q[ig][ip] =
MIN(
MAX(atm_i->
q[ig][ip], 0), 1);
263 for (
int iw = 0; iw < ctl->
nw; iw++)
264 atm_i->
k[iw][ip] =
MAX(atm_i->
k[iw][ip], 0);
265 }
268 for (
int icl = 0; icl < ctl->
ncl; icl++)
269 atm_i->
clk[icl] =
MAX(atm_i->
clk[icl], 0);
271 for (
int isf = 0; isf < ctl->
nsf; isf++)
273
274
275 formod(ctl, tbl, atm_i, obs_i);
276 obs2y(ctl, obs_i, y_i, NULL, NULL);
277
278
279 gsl_vector_memcpy(dx, x_i);
280 gsl_vector_sub(dx, x_a);
281 gsl_vector_memcpy(dy, y_m);
282 gsl_vector_sub(dy, y_i);
283
284
286
287
288 if (chisq > chisq_old) {
289 lmpar *= 10;
290 gsl_vector_sub(x_i, x_step);
291 } else {
292 lmpar /= 10;
293 break;
294 }
295 }
296
297
298 LOG(1,
"it= %d / chi^2/m= %g", it, chisq);
299
300
301 fprintf(out, "%d %g %d %d\n", it, chisq, (int) m, (int) n);
302
303
304 gsl_blas_ddot(x_step, b, &disq);
305 disq /= (double) n;
306
307
309 break;
310 }
311
312
313 fclose(out);
314
315
319 atm_i, obs_i, "y", "x", "r");
320
321
322
323
324
325
327
328
329 gsl_matrix *auxnm = gsl_matrix_alloc(n, m);
330 gsl_matrix *corr = gsl_matrix_alloc(n, n);
331 gsl_matrix *gain = gsl_matrix_alloc(n, m);
332
333
334
336 gsl_matrix_add(cov, s_a_inv);
337
338
341 atm_i, obs_i, "x", "x", "r");
343
344
345 for (size_t i = 0; i < n; i++)
346 for (size_t j = 0; j < n; j++)
347 gsl_matrix_set(corr, i, j, gsl_matrix_get(cov, i, j)
348 / sqrt(gsl_matrix_get(cov, i, i))
349 / sqrt(gsl_matrix_get(cov, j, j)));
351 atm_i, obs_i, "x", "x", "r");
352
353
354
355 for (size_t i = 0; i < n; i++)
356 for (size_t j = 0; j < m; j++)
357 gsl_matrix_set(auxnm, i, j, gsl_matrix_get(k_i, j, i)
358 *
POW2(gsl_vector_get(sig_eps_inv, j)));
359 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, cov, auxnm, 0.0, gain);
361 atm_i, obs_i, "x", "y", "c");
362
363
366
367
370
371
372
373 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, gain, k_i, 0.0, a);
375 atm_i, obs_i, "x", "x", "r");
376
377
379
380
381 gsl_matrix_free(auxnm);
382 gsl_matrix_free(corr);
383 gsl_matrix_free(gain);
384 }
385
386
387
388
389
390 gsl_matrix_free(a);
391 gsl_matrix_free(cov);
392 gsl_matrix_free(k_i);
393 gsl_matrix_free(s_a_inv);
394
395 gsl_vector_free(b);
396 gsl_vector_free(dx);
397 gsl_vector_free(dy);
398 gsl_vector_free(sig_eps_inv);
399 gsl_vector_free(sig_formod);
400 gsl_vector_free(sig_noise);
401 gsl_vector_free(x_a);
402 gsl_vector_free(x_i);
403 gsl_vector_free(x_step);
404 gsl_vector_free(y_aux);
405 gsl_vector_free(y_i);
406 gsl_vector_free(y_m);
407}
void matrix_product(gsl_matrix *a, gsl_vector *b, int transpose, gsl_matrix *c)
void write_atm(const char *dirname, const char *filename, const ctl_t *ctl, const atm_t *atm)
void set_cov_apr(ret_t *ret, ctl_t *ctl, atm_t *atm, int *iqa, int *ipa, gsl_matrix *s_a)
void x2atm(const ctl_t *ctl, const gsl_vector *x, atm_t *atm)
void analyze_avk(ret_t *ret, ctl_t *ctl, atm_t *atm, int *iqa, int *ipa, gsl_matrix *avk)
void set_cov_meas(ret_t *ret, ctl_t *ctl, obs_t *obs, gsl_vector *sig_noise, gsl_vector *sig_formod, gsl_vector *sig_eps_inv)
void write_stddev(const char *quantity, ret_t *ret, ctl_t *ctl, atm_t *atm, gsl_matrix *s)
void copy_obs(const ctl_t *ctl, obs_t *obs_dest, const obs_t *obs_src, const int init)
Copy or initialize observation geometry and radiance data.
void write_obs(const char *dirname, const char *filename, const ctl_t *ctl, const obs_t *obs)
void kernel(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs, gsl_matrix *k)
Compute the Jacobian (kernel) matrix by finite differences.
void matrix_invert(gsl_matrix *a)
void formod(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs)
Execute the selected forward model.
void copy_atm(const ctl_t *ctl, atm_t *atm_dest, const atm_t *atm_src, const int init)
Copy or initialize atmospheric profile data.
size_t obs2y(const ctl_t *ctl, const obs_t *obs, gsl_vector *y, int *ida, int *ira)
Convert observation radiances into a measurement vector.
double cost_function(gsl_vector *dx, gsl_vector *dy, gsl_matrix *s_a_inv, gsl_vector *sig_eps_inv)
size_t atm2x(const ctl_t *ctl, const atm_t *atm, gsl_vector *x, int *iqa, int *ipa)
Convert atmospheric data to state vector elements.
void write_matrix(const char *dirname, const char *filename, const ctl_t *ctl, const gsl_matrix *matrix, const atm_t *atm, const obs_t *obs, const char *rowspace, const char *colspace, const char *sort)
#define N
Maximum size of state vector.
#define LEN
Maximum length of ASCII data lines.
#define POW2(x)
Compute the square of a value.
#define MIN(a, b)
Determine the minimum of two values.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define LOG(level,...)
Print a log message with a specified logging level.
#define MAX(a, b)
Determine the maximum of two values.
Atmospheric profile data.
double sfeps[NSF]
Surface emissivity.
double k[NW][NP]
Extinction [km^-1].
double t[NP]
Temperature [K].
double clz
Cloud layer height [km].
int np
Number of data points.
double cldz
Cloud layer depth [km].
double sft
Surface temperature [K].
double clk[NCL]
Cloud layer extinction [km^-1].
double q[NG][NP]
Volume mixing ratio [ppv].
double p[NP]
Pressure [hPa].
int nw
Number of spectral windows.
int ng
Number of emitters.
int ncl
Number of cloud layer spectral grid points.
int nsf
Number of surface layer spectral grid points.
Observation geometry and radiance data.
int err_ana
Carry out error analysis (0=no, 1=yes).
double conv_dmin
Minimum normalized step size in state space.
int kernel_recomp
Re-computation of kernel matrix (number of iterations).
int conv_itmax
Maximum number of iterations.
char dir[LEN]
Working directory.