00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00018 #include "yanera.h"
00019 #include "yanera_lstsq.h"
00020 #include "yanera_quadrature.h"
00021 #include "yanera_reflectivity.h"
00022 #include "yanera_util.h"
00023
00024 int yanera_lstsq_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;
00055 lstsq_func.df = &lstsq_df;
00056 lstsq_func.fdf = &lstsq_fdf;
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
00068 yanera_report(yanera, count, solvr);
00069
00070 do
00071 {
00072 count++;
00073
00074 stop1 = gsl_multifit_fdfsolver_iterate(solvr);
00075
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
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(const gsl_vector *parameters, \
00116 void *yanera_pointer, \
00117 gsl_vector *r, gsl_matrix *J)
00118 {
00119 lstsq_f (parameters, yanera_pointer, r);
00120 lstsq_df(parameters, yanera_pointer, J);
00121 return GSL_SUCCESS;
00122 }
00123
00124
00125
00126 int lstsq_f(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
00146
00147
00148 r_index = 0;
00149 for (j=0; j<yanera->number_of_models; j++)
00150 {
00151
00152
00153
00154 if ((yanera->type == MODEL_COMPONENT) ||
00155 (yanera->type == MODEL_SLAB) ||
00156 (yanera->type == MODEL_FUNCTION))
00157 { doQuadrature(&yanera->models_complete[j], yanera); }
00158
00159
00160
00161 for (i=0; i<yanera->data[j].n; i++)
00162 {
00163 tmp = calcReflectivity(yanera->data[j].q[i], \
00164 &yanera->data[j].resolution, \
00165 &yanera->models_complete[j], \
00166 yanera);
00167 tmp = (tmp - yanera->data[j].R[i]) / yanera->data[j].e[i];
00168 gsl_vector_set(r, r_index, tmp);
00169 r_index++;
00170 }
00171
00172
00173
00174 }
00175
00176 return GSL_SUCCESS;
00177 }
00178
00179
00180
00181 int lstsq_df(const gsl_vector *parameters, \
00182 void *yanera_pointer, \
00183 gsl_matrix *J)
00184 {
00185 int i, j, k;
00186 int r_index;
00187 double res, err;
00188 gsl_function F;
00189 yanera_container *yanera;
00190
00191
00192
00193 yanera = (yanera_container *)yanera_pointer;
00194
00195
00196
00197 for(i=0; i<yanera->parameters.n; i++)
00198 {
00199 yanera->parameters.tmp[i] = gsl_vector_get(parameters, i);
00200 }
00201
00202
00203
00204 F.function = &lstsq_derivatives;
00205 F.params = yanera_pointer;
00206
00207
00208
00209 r_index = 0;
00210 for (k=0; k<yanera->number_of_models; k++)
00211 {
00212
00213
00214
00215
00216
00217 yanera->idx = k;
00218
00219
00220
00221 for (i=0; i<yanera->data[k].n; i++)
00222 {
00223 yanera->data[k].idx = i;
00224
00225
00226
00227 for (j=0; j<yanera->parameters.n; j++)
00228 {
00229 yanera->parameters.idx = j;
00230
00231
00232
00233 if (yanera->parameters.f[j] == YES) res=0.0;
00234 else gsl_deriv_central(&F, yanera->parameters.tmp[j], 1e-5, &res, &err);
00235 gsl_matrix_set(J, r_index, j, res);
00236 }
00237 r_index++;
00238 }
00239
00240
00241
00242 }
00243
00244 return GSL_SUCCESS;
00245 }
00246
00247
00248
00249 double lstsq_derivatives(double new_p, void *yanera_pointer)
00250 {
00251 int i;
00252 double tmp;
00253 yanera_container *yanera;
00254
00255
00256
00257 yanera = (yanera_container *)yanera_pointer;
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 for(i=0; i<yanera->parameters.n; i++)
00268 {
00269 yanera->parameters.p[i] = yanera->parameters.tmp[i];
00270 }
00271 yanera->parameters.p[yanera->parameters.idx] = new_p;
00272 if ((yanera->type == MODEL_COMPONENT) ||
00273 (yanera->type == MODEL_SLAB) ||
00274 (yanera->type == MODEL_FUNCTION))
00275 { doQuadrature(&yanera->models_complete[yanera->idx], yanera); }
00276
00277 tmp = 0.0;
00278 i = yanera->data[yanera->idx].idx;
00279 tmp = calcReflectivity(yanera->data[yanera->idx].q[i], \
00280 &yanera->data[yanera->idx].resolution, \
00281 &yanera->models_complete[yanera->idx], \
00282 yanera);
00283 tmp = (tmp - yanera->data[yanera->idx].R[i]) / \
00284 yanera->data[yanera->idx].e[i];
00285 return tmp;
00286 }
00287