00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00018 #include "yanera.h"
00019 #include "yanera_lstsq_constrained.h"
00020 #include "yanera_quadrature.h"
00021 #include "yanera_reflectivity.h"
00022 #include "yanera_util.h"
00023
00024 int yanera_lstsq_constrained_main(yanera_container *yanera)
00025 {
00026 unsigned int i;
00027 int count, stop1, stop2;
00028 gsl_vector *guess;
00029 gsl_vector *gradt;
00030 gsl_matrix *covar;
00031 gsl_multifit_function_fdf lstsq_func;
00032 gsl_multifit_fdfsolver *solvr;
00033
00034
00035 guess = gsl_vector_alloc(yanera->parameters.n);
00036 for (i=0; i<yanera->parameters.n; i++)
00037 {
00038 gsl_vector_set(guess, i, yanera->parameters.p[i]);
00039 }
00040
00041
00042 count = 0;
00043 for (i=0; i<yanera->number_of_models; i++)
00044 {
00045 count += yanera->data[i].n;
00046 }
00047
00048
00049 gradt = gsl_vector_alloc(yanera->parameters.n);
00050
00051
00052 covar = gsl_matrix_alloc(yanera->parameters.n, yanera->parameters.n);
00053
00054 lstsq_func.f = &lstsq_f_constrained;
00055 lstsq_func.df = &lstsq_df_constrained;
00056 lstsq_func.fdf = &lstsq_fdf_constrained;
00057 lstsq_func.n = count;
00058 lstsq_func.p = yanera->parameters.n;
00059 lstsq_func.params = (void *)yanera;
00060
00061 solvr = gsl_multifit_fdfsolver_alloc(\
00062 yanera->misc.fit_method_lstsq, lstsq_func.n, lstsq_func.p);
00063
00064
00065 count = 0;
00066 gsl_multifit_fdfsolver_set(solvr, &lstsq_func, guess);
00067 gsl_multifit_covar(solvr->J, 0.0, covar);
00068 yanera_report(yanera, count, solvr);
00069
00070 do
00071 {
00072 count++;
00073
00074 stop1 = gsl_multifit_fdfsolver_iterate(solvr);
00075 gsl_multifit_covar(solvr->J, 0.0, covar);
00076 yanera_report(yanera, count, solvr);
00077
00078 if (stop1)
00079 {
00080 fprintf(stderr,"STATUS: %s\n", gsl_strerror(stop1));
00081 break;
00082 }
00083
00084
00085 stop1 = gsl_multifit_test_delta(solvr->dx, solvr->x, 1e-6, 1e-6);
00086
00087
00088 gsl_multifit_gradient(solvr->J, solvr->f, gradt);
00089 stop2 = gsl_multifit_test_gradient(gradt, 1e-6);
00090
00091 if ((stop1==GSL_SUCCESS) && (stop2==GSL_SUCCESS))
00092 {
00093 fprintf(stderr,"STATUS: %s\n", gsl_strerror(stop1));
00094 }
00095
00096 } while (((stop1 == GSL_CONTINUE) || (stop2 == GSL_CONTINUE)) \
00097 && (count < yanera->misc.fit_iterations));
00098
00099
00100 gsl_multifit_covar(solvr->J, 0.0, covar);
00101 yanera_report(yanera, -1, solvr);
00102
00103
00104
00105 gsl_multifit_fdfsolver_free(solvr);
00106 gsl_matrix_free(covar);
00107 gsl_vector_free(guess);
00108 gsl_vector_free(gradt);
00109
00110 return GSL_SUCCESS;
00111 }
00112
00113
00114
00115 int lstsq_fdf_constrained(const gsl_vector *parameters, \
00116 void *yanera_pointer, \
00117 gsl_vector *r, gsl_matrix *J)
00118 {
00119 lstsq_f_constrained (parameters, yanera_pointer, r);
00120 lstsq_df_constrained(parameters, yanera_pointer, J);
00121 return GSL_SUCCESS;
00122 }
00123
00124
00125
00126 int lstsq_f_constrained(const gsl_vector *parameters, \
00127 void *yanera_pointer, \
00128 gsl_vector *r)
00129 {
00130 int i, j;
00131 int r_index;
00132 double tmp;
00133 yanera_container *yanera;
00134
00135
00136
00137 yanera = (yanera_container *)yanera_pointer;
00138
00139
00140
00141 for(i=0; i<yanera->parameters.n; i++)
00142 {
00143 yanera->parameters.p[i] = gsl_vector_get(parameters, i);
00144
00145 if ((yanera->parameters.con[i] == CONSTRAIN_MAX) || \
00146 (yanera->parameters.con[i] == CONSTRAIN_BOTH))
00147 {
00148 if (yanera->parameters.p[i] > yanera->parameters.max[i])
00149 {
00150 yanera->parameters.p[i] = yanera->parameters.max[i];
00151 }
00152 }
00153
00154 if ((yanera->parameters.con[i] == CONSTRAIN_MIN) || \
00155 (yanera->parameters.con[i] == CONSTRAIN_BOTH))
00156 {
00157 if (yanera->parameters.p[i] < yanera->parameters.min[i])
00158 {
00159 yanera->parameters.p[i] = yanera->parameters.min[i];
00160 }
00161 }
00162 }
00163
00164
00165
00166 r_index = 0;
00167 for (j=0; j<yanera->number_of_models; j++)
00168 {
00169
00170
00171
00172 if ((yanera->type == MODEL_COMPONENT) || \
00173 (yanera->type == MODEL_SLAB) || \
00174 (yanera->type == MODEL_FUNCTION))
00175 { doQuadrature(&yanera->models_complete[j], yanera); }
00176
00177
00178
00179 for (i=0; i<yanera->data[j].n; i++)
00180 {
00181 tmp = calcReflectivity(yanera->data[j].q[i], \
00182 &yanera->data[j].resolution, \
00183 &yanera->models_complete[j], \
00184 yanera);
00185 tmp = (tmp - yanera->data[j].R[i]) / yanera->data[j].e[i];
00186 gsl_vector_set(r, r_index, tmp);
00187 r_index++;
00188 }
00189
00190
00191
00192 }
00193
00194 return GSL_SUCCESS;
00195 }
00196
00197
00198
00199 int lstsq_df_constrained(const gsl_vector *parameters, \
00200 void *yanera_pointer, \
00201 gsl_matrix *J)
00202 {
00203 int i, j, k;
00204 int r_index;
00205 double res, err;
00206 gsl_function F;
00207 yanera_container *yanera;
00208
00209
00210
00211 yanera = (yanera_container *)yanera_pointer;
00212
00213
00214
00215 for(i=0; i<yanera->parameters.n; i++)
00216 {
00217 yanera->parameters.tmp[i] = gsl_vector_get(parameters, i);
00218
00219 if ((yanera->parameters.con[i] == CONSTRAIN_MAX) || \
00220 (yanera->parameters.con[i] == CONSTRAIN_BOTH))
00221 {
00222 if (yanera->parameters.tmp[i] > yanera->parameters.max[i])
00223 {
00224 yanera->parameters.tmp[i] = yanera->parameters.max[i];
00225
00226
00227
00228
00229 yanera->parameters.f[i] = YES;
00230 }
00231 }
00232
00233 if ((yanera->parameters.con[i] == CONSTRAIN_MIN) || \
00234 (yanera->parameters.con[i] == CONSTRAIN_BOTH))
00235 {
00236 if (yanera->parameters.tmp[i] < yanera->parameters.min[i])
00237 {
00238 yanera->parameters.tmp[i] = yanera->parameters.min[i];
00239 yanera->parameters.f[i] = YES;
00240 }
00241 }
00242 }
00243
00244
00245
00246 F.function = &lstsq_derivatives_constrained;
00247 F.params = yanera_pointer;
00248
00249
00250
00251 r_index = 0;
00252 for (k=0; k<yanera->number_of_models; k++)
00253 {
00254
00255
00256
00257
00258
00259 yanera->idx = k;
00260
00261
00262
00263 for (i=0; i<yanera->data[k].n; i++)
00264 {
00265 yanera->data[k].idx = i;
00266
00267
00268
00269 for (j=0; j<yanera->parameters.n; j++)
00270 {
00271 yanera->parameters.idx = j;
00272
00273
00274
00275 if (yanera->parameters.f[j] == YES) res=0.0;
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 else gsl_deriv_central(&F, yanera->parameters.tmp[j], 1e-5, &res, &err);
00293 gsl_matrix_set(J, r_index, j, res);
00294 }
00295 r_index++;
00296 }
00297
00298
00299
00300 }
00301
00302 return GSL_SUCCESS;
00303 }
00304
00305
00306
00307 double lstsq_derivatives_constrained(double new_p, void *yanera_pointer)
00308 {
00309 int i;
00310 double tmp;
00311 yanera_container *yanera;
00312
00313
00314
00315 yanera = (yanera_container *)yanera_pointer;
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 for(i=0; i<yanera->parameters.n; i++)
00326 {
00327 yanera->parameters.p[i] = yanera->parameters.tmp[i];
00328 }
00329 yanera->parameters.p[yanera->parameters.idx] = new_p;
00330 if ((yanera->type == MODEL_COMPONENT) || \
00331 (yanera->type == MODEL_SLAB) || \
00332 (yanera->type == MODEL_FUNCTION))
00333 { doQuadrature(&yanera->models_complete[yanera->idx], yanera); }
00334
00335 tmp = 0.0;
00336 i = yanera->data[yanera->idx].idx;
00337 tmp = calcReflectivity(yanera->data[yanera->idx].q[i], \
00338 &yanera->data[yanera->idx].resolution, \
00339 &yanera->models_complete[yanera->idx], \
00340 yanera);
00341 tmp = (tmp - yanera->data[yanera->idx].R[i]) / \
00342 yanera->data[yanera->idx].e[i];
00343 return tmp;
00344 }
00345