00001
00008 #include "gsl_fit.h"
00009
00010 int lstsq_main(void *void_gsl_fit_struct)
00011 {
00012 unsigned int count, i;
00013 int stop1, stop2;
00014 gsl_vector *guess;
00015 gsl_vector *gradt;
00016 gsl_matrix *covar;
00017 gsl_multifit_function_fdf lstsq_func;
00018 gsl_multifit_fdfsolver *solvr;
00019 gsl_fit *gft;
00020
00021 gft = (gsl_fit *)void_gsl_fit_struct;
00022
00023
00024 guess = gsl_vector_alloc(gft->para.num);
00025 for (i=0; i<gft->para.num; i++)
00026 {
00027 gsl_vector_set(guess, i, gft->para.par[i]);
00028 }
00029
00030
00031 count = 0;
00032 for (i=0; i<gft->numd; i++) count += gft->data[i].num;
00033
00034
00035 gradt = gsl_vector_alloc(gft->para.num);
00036
00037
00038 covar = gsl_matrix_alloc(gft->para.num,gft->para.num);
00039
00040 lstsq_func.f = &lstsq_f;
00041 lstsq_func.df = &lstsq_df;
00042 lstsq_func.fdf = &lstsq_fdf;
00043 lstsq_func.n = count;
00044 lstsq_func.p = gft->para.num;
00045 lstsq_func.params = (void *)gft;
00046
00047 solvr = gsl_multifit_fdfsolver_alloc(gft->meth.lstsq_type, \
00048 lstsq_func.n, lstsq_func.p);
00049
00050
00051 count = 0;
00052 gsl_multifit_fdfsolver_set(solvr, &lstsq_func, guess);
00053 gsl_multifit_covar(solvr->J, 0.0, covar);
00054 lstsq_status(gft, count, solvr, covar);
00055
00056 do
00057 {
00058 count++;
00059 stop1 = gsl_multifit_fdfsolver_iterate(solvr);
00060 gsl_multifit_covar(solvr->J, 0.0, covar);
00061 lstsq_status(gft, count, solvr, covar);
00062
00063 if (stop1)
00064 {
00065 fprintf(stderr,"STATUS: %s\n", gsl_strerror(stop1));
00066 break;
00067 }
00068
00069
00070 stop1 = gsl_multifit_test_delta(solvr->dx, solvr->x, 1e-6, 1e-6);
00071
00072
00073 gsl_multifit_gradient(solvr->J, solvr->f, gradt);
00074 stop2 = gsl_multifit_test_gradient(gradt, 1e-6);
00075
00076 if ((stop1==GSL_SUCCESS) && (stop2==GSL_SUCCESS))
00077 {
00078 fprintf(stderr,"STATUS: %s\n", gsl_strerror(stop1));
00079 }
00080
00081 } while (((stop1 == GSL_CONTINUE) || (stop2 == GSL_CONTINUE)) \
00082 && (count < gft->maxi));
00083
00084
00085 gsl_multifit_covar(solvr->J, 0.0, covar);
00086 lstsq_status(gft, -1, solvr, covar);
00087
00088
00089
00090 gsl_multifit_fdfsolver_free(solvr);
00091 gsl_matrix_free(covar);
00092 gsl_vector_free(guess);
00093 gsl_vector_free(gradt);
00094
00095 return GSL_SUCCESS;
00096 }
00097
00098
00099
00100 int lstsq_fdf(const gsl_vector *parameters, \
00101 void *void_gsl_fit_struct, \
00102 gsl_vector *r, gsl_matrix *J)
00103 {
00104 lstsq_f (parameters, void_gsl_fit_struct, r);
00105 lstsq_df(parameters, void_gsl_fit_struct, J);
00106 return GSL_SUCCESS;
00107 }
00108
00109
00110
00111 int lstsq_f(const gsl_vector *parameters, \
00112 void *void_gsl_fit_struct, \
00113 gsl_vector *r)
00114 {
00115 int i, j, k;
00116 int r_index;
00117 double tmp;
00118 gsl_fit *gft;
00119
00120 gft = (gsl_fit *)void_gsl_fit_struct;
00121
00122
00123
00124
00125
00126 for(i=0; i<gft->para.num; i++)
00127 {
00128 gft->para.par[i] = gsl_vector_get(parameters, i);
00129 }
00130
00131
00132
00133 r_index = 0;
00134 for (k=0; k<gft->numd; k++)
00135 {
00136
00137
00138
00139 for (i=0; i<gft->data[k].num; i++)
00140 {
00141
00142
00143
00144 tmp = 0.0;
00145 for (j=0; j<gft->numf; j++)
00146 {
00147 if (gft->type==MULTIPLE)
00148 {
00149 tmp += gft->func[j].fun_m(gft->data[k].xpt[i], \
00150 gft->para.par + gft->func[j].idx, \
00151 k, j);
00152 }
00153 else
00154 {
00155 tmp += gft->func[j].fun_s(gft->data[k].xpt[i], \
00156 gft->para.par + gft->func[j].idx);
00157 }
00158 }
00159 tmp = (tmp - gft->data[k].ypt[i]) / gft->data[k].sig[i];
00160 gsl_vector_set(r, r_index, tmp);
00161 r_index++;
00162 }
00163 }
00164 return GSL_SUCCESS;
00165 }
00166
00167
00168
00169 int lstsq_df(const gsl_vector *parameters, \
00170 void *void_gsl_fit_struct, \
00171 gsl_matrix *J)
00172 {
00173 int i, j, k;
00174 int r_index;
00175 double res, err;
00176 gsl_function F;
00177 gsl_fit *gft;
00178
00179 gft = (gsl_fit *)void_gsl_fit_struct;
00180
00181
00182
00183
00184
00185 for(i=0; i<gft->para.num; i++)
00186 {
00187 gft->para.par[i] = gsl_vector_get(parameters,i);
00188 }
00189
00190 F.params = void_gsl_fit_struct;
00191 F.function = &lstsq_derivatives;
00192
00193
00194
00195
00196 r_index = 0;
00197 for (k=0; k<gft->numd; k++)
00198 {
00199 gft->indx = k;
00200
00201
00202
00203
00204
00205
00206
00207
00208 for (i=0; i<gft->data[k].num; i++)
00209 {
00210 gft->data[k].idx = i;
00211
00212
00213
00214
00215 for (j=0; j<gft->para.num; j++)
00216 {
00217 gft->para.idx = j;
00218
00219
00220
00221 if (gft->para.fix[j]) res=0.0;
00222 else gsl_deriv_central(&F, gft->para.par[j], 1e-4, &res, &err);
00223 gsl_matrix_set(J, r_index, j, res);
00224 }
00225 r_index += 1;
00226 }
00227 }
00228
00229 return GSL_SUCCESS;
00230 }
00231
00232
00233
00234 double lstsq_derivatives(double p, void *void_gsl_fit_struct)
00235 {
00236 int i, j;
00237 double tmp;
00238 gsl_fit *gft;
00239
00240 gft = (gsl_fit *)void_gsl_fit_struct;
00241
00242
00243
00244
00245
00246 for(i=0; i<gft->para.num; i++) gft->para.tmp[i] = gft->para.par[i];
00247 gft->para.tmp[gft->para.idx] = p;
00248
00249 tmp = 0.0;
00250 i = gft->data[gft->indx].idx;
00251 for (j=0; j<gft->numf; j++)
00252 {
00253 if (gft->type == MULTIPLE)
00254 {
00255 tmp += gft->func[j].fun_m(gft->data[gft->indx].xpt[i], \
00256 gft->para.tmp+gft->func[j].idx, \
00257 gft->indx, j);
00258 }
00259 else
00260 {
00261 tmp += gft->func[j].fun_s(gft->data[gft->indx].xpt[i], \
00262 gft->para.tmp+gft->func[j].idx);
00263 }
00264 }
00265 tmp = (tmp - gft->data[gft->indx].ypt[i]) / gft->data[gft->indx].sig[i];
00266 return tmp;
00267 }
00268
00269
00270
00271 int lstsq_status(gsl_fit *gft, \
00272 int iteration, \
00273 gsl_multifit_fdfsolver *s, \
00274 gsl_matrix *c)
00275 {
00276 int j;
00277 double chisq;
00278
00279 if (iteration >= 0)
00280 {
00281 fprintf(stderr,"ITERATION:%3u ", iteration);
00282 fprintf(stderr,"===================\n");
00283 }
00284 else
00285 {
00286 fprintf(stderr,"COMPLETE ");
00287 fprintf(stderr,"===================\n");
00288 }
00289 chisq = gsl_blas_dnrm2(s->f)/(double)((gft->numd)-(gft->para.num));
00290 fprintf(stderr,"ChiSq: %12.6e\n", chisq);
00291
00292 for (j=0; j<gft->para.num; j++)
00293 {
00294 fprintf(stderr,"%3d: %12.6f +/- %8.6f\n",
00295 j,
00296 gsl_vector_get(s->x, j),
00297 sqrt(gsl_matrix_get(c, j, j)));
00298 }
00299 fprintf(stderr,"\n");
00300
00301 if (iteration < 0)
00302 {
00303 for (j=0; j<gft->para.num; j++)
00304 {
00305 gft->para.par[j] = gsl_vector_get(s->x, j);
00306 gft->para.err[j] = sqrt(gsl_matrix_get(c, j, j));
00307 }
00308 gft->chis = chisq;
00309 }
00310
00311 return GSL_SUCCESS;
00312 }