00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00018 #ifdef HAVE_LEVMAR
00019
00020 #include "yanera.h"
00021 #include "lm.h"
00022 #include "yanera_levmar.h"
00023 #include "yanera_quadrature.h"
00024 #include "yanera_reflectivity.h"
00025 #include "yanera_util.h"
00026
00027 void levmar_f( double *p, double *y, int np, int ny, void *yanera_pointer)
00028 {
00029 int i, j;
00030 int y_index;
00031 double tmp;
00032 yanera_container *yanera;
00033
00034
00035
00036 yanera = (yanera_container *)yanera_pointer;
00037
00038
00039
00040 if (yanera->parameters.n != np)
00041 {
00042 yanera_error("Error in levmar.", __FILE__, __LINE__, yanera);
00043 }
00044
00045 for(i=0; i<yanera->parameters.n; i++)
00046 {
00047 yanera->parameters.p[i] = p[i];
00048 }
00049
00050
00051
00052 y_index = 0;
00053 for (j=0; j<yanera->number_of_models; j++)
00054 {
00055
00056
00057
00058 if ((yanera->type == MODEL_COMPONENT) || \
00059 (yanera->type == MODEL_SLAB) || \
00060 (yanera->type == MODEL_FUNCTION))
00061 { doQuadrature(&yanera->models_complete[j], yanera); }
00062
00063
00064
00065 for (i=0; i<yanera->data[j].n; i++)
00066 {
00067 tmp = calcReflectivity(yanera->data[j].q[i], \
00068 &yanera->data[j].resolution, \
00069 &yanera->models_complete[j], \
00070 yanera);
00071 tmp = tmp / yanera->data[j].e[i];
00072 y[y_index] = tmp;
00073 y_index++;
00074 if (y_index > ny)
00075 {
00076 yanera_error("Error in levmar.", __FILE__, __LINE__, yanera);
00077 }
00078 }
00079
00080
00081
00082 }
00083
00084 return;
00085 }
00086
00087 double levmar_derivatives(double new_p, void *yanera_pointer)
00088 {
00089 int i;
00090 double tmp;
00091 yanera_container *yanera;
00092
00093
00094
00095 yanera = (yanera_container *)yanera_pointer;
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 for(i=0; i<yanera->parameters.n; i++)
00106 {
00107 yanera->parameters.p[i] = yanera->parameters.tmp[i];
00108 }
00109 yanera->parameters.p[yanera->parameters.idx] = new_p;
00110 if ((yanera->type == MODEL_COMPONENT) || \
00111 (yanera->type == MODEL_SLAB) || \
00112 (yanera->type == MODEL_FUNCTION))
00113 { doQuadrature(&yanera->models_complete[yanera->idx], yanera); }
00114
00115 tmp = 0.0;
00116 i = yanera->data[yanera->idx].idx;
00117 tmp = calcReflectivity(yanera->data[yanera->idx].q[i], \
00118 &yanera->data[yanera->idx].resolution, \
00119 &yanera->models_complete[yanera->idx], \
00120 yanera);
00121 tmp = tmp / yanera->data[yanera->idx].e[i];
00122
00123 return tmp;
00124 }
00125
00126 void levmar_df(double *p, double *j, int np, int ny, void *yanera_pointer)
00127 {
00128 static short iter = 0;
00129 int i, l, k;
00130 int j_index;
00131 double res, err;
00132 gsl_function F;
00133 yanera_container *yanera;
00134
00135
00136
00137
00138 yanera = (yanera_container *)yanera_pointer;
00139 yanera_report(yanera, iter++, NULL);
00140
00141
00142
00143 if (yanera->parameters.n != np)
00144 {
00145 yanera_error("Error in levmar.", __FILE__, __LINE__, yanera);
00146 }
00147 for(i=0; i<yanera->parameters.n; i++)
00148 {
00149 yanera->parameters.tmp[i] = p[i];
00150 }
00151
00152
00153
00154 F.function = &levmar_derivatives;
00155 F.params = yanera_pointer;
00156
00157
00158
00159 j_index = 0;
00160 for (k=0; k<yanera->number_of_models; k++)
00161 {
00162
00163
00164
00165
00166
00167 yanera->idx = k;
00168
00169
00170
00171 for (i=0; i<yanera->data[k].n; i++)
00172 {
00173 yanera->data[k].idx = i;
00174
00175
00176
00177 for (l=0; l<yanera->parameters.n; l++)
00178 {
00179 yanera->parameters.idx = l;
00180
00181
00182
00183 if (yanera->parameters.f[l] == YES) res=0.0;
00184 else gsl_deriv_central(&F, yanera->parameters.tmp[l], 1e-5, &res, &err);
00185 j[j_index] = res;
00186 j_index++;
00187 }
00188 }
00189 }
00190
00191 return;
00192 }
00193
00194 int yanera_levmar_main(yanera_container *yanera)
00195 {
00196 int i, j, count;
00197 double opts[4], info[LM_INFO_SZ];
00198 double tmp, *y, *p, *work;
00199
00200
00201
00202
00203
00204
00205
00206 count = 0;
00207 for (i=0; i<yanera->number_of_models; i++)
00208 { count += yanera->data[i].n; }
00209 y = (double *)malloc(count*sizeof(double));
00210 if (y == NULL)
00211 {
00212 yanera_error("Error in levmar.", __FILE__, __LINE__, yanera);
00213 }
00214 count = 0;
00215 tmp = 10000.5;
00216 for (i=0; i<yanera->number_of_models; i++)
00217 {
00218 for (j=0; j<yanera->data[i].n; j++)
00219 {
00220 y[count] = yanera->data[i].R[j] / yanera->data[i].e[j];
00221 if (tmp > yanera->data[i].R[j] * yanera->data[i].e[j])
00222 {
00223 tmp = yanera->data[i].R[j] * yanera->data[i].e[j];
00224 }
00225 count++;
00226 }
00227 }
00228
00229
00230
00231
00232
00233 p = (double *)malloc(yanera->parameters.n*sizeof(double));
00234 for (i=0; i<yanera->parameters.n; i++)
00235 {
00236 p[i] = yanera->parameters.p[i];
00237 }
00238
00239
00240
00241
00242 opts[0] = tmp*10.0;
00243 opts[1] = 1E-8;
00244 opts[2] = 1E-8;
00245 opts[3] = 1E-8;
00246
00247
00248
00249 work = (double *)malloc(LM_DIF_WORKSZ(yanera->parameters.n,count)* \
00250 sizeof(double));
00251 if (work == NULL)
00252 {
00253 yanera_error("Error in levmar.", __FILE__, __LINE__, yanera);
00254 }
00255
00256
00257
00258
00259
00260
00261 tmp = dlevmar_bc_der(levmar_f, levmar_df, \
00262 p, y, \
00263 yanera->parameters.n, count, \
00264 yanera->parameters.min, yanera->parameters.max, \
00265 yanera->misc.fit_iterations, opts, info, \
00266 work, NULL, (void *)yanera);
00267
00268
00269
00270 for (i=0; i<yanera->parameters.n; i++)
00271 {
00272 yanera->parameters.p[i] = p[i];
00273 }
00274 yanera_report(yanera, -1, NULL);
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 free(p);
00292 free(y);
00293 free(work);
00294
00295 return (GSL_SUCCESS);
00296 }
00297
00298 #endif