00001
00008 #include "gsl_fit.h"
00009
00010 int mdmin_main(void *void_gsl_fit_struct)
00011 {
00012 int count;
00013 int status;
00014 gsl_vector *guess;
00015 gsl_multimin_function_fdf mdmin_func;
00016 gsl_multimin_fdfminimizer *solvr;
00017 gsl_fit *gft;
00018
00019 gft = (gsl_fit *)void_gsl_fit_struct;
00020
00021
00022 guess = gsl_vector_alloc(gft->para.num);
00023 for (count=0; count<gft->para.num; count++)
00024 {
00025 gsl_vector_set(guess, count, gft->para.par[count]);
00026 }
00027
00028 mdmin_func.f = &mdmin_f;
00029 mdmin_func.df = &mdmin_df;
00030 mdmin_func.fdf = &mdmin_fdf;
00031 mdmin_func.n = gft->para.num;
00032 mdmin_func.params = (void *)gft;
00033
00034 solvr = gsl_multimin_fdfminimizer_alloc(gft->meth.mdmin_type, \
00035 gft->para.num);
00036
00037
00038 count = 0;
00039 gsl_multimin_fdfminimizer_set(solvr, &mdmin_func, guess, 0.01, 1e-6);
00040 mdmin_status(gft, count, solvr);
00041
00042 do
00043 {
00044 count++;
00045
00046 status = gsl_multimin_fdfminimizer_iterate(solvr);
00047 if (status != GSL_SUCCESS)
00048 {
00049 fprintf(stderr,"STATUS: %s\n", gsl_strerror(status));
00050 break;
00051 }
00052
00053 mdmin_status(gft, count, solvr);
00054
00055 status = gsl_multimin_test_gradient(solvr->gradient, 1e-6);
00056
00057 if (status == GSL_SUCCESS)
00058 {
00059 fprintf(stderr,"STATUS: %s\n", gsl_strerror(status));
00060 }
00061
00062 } while ((status == GSL_CONTINUE) && (count < gft->maxi));
00063
00064 mdmin_status(gft, -1, solvr);
00065
00066 gsl_multimin_fdfminimizer_free(solvr);
00067 gsl_vector_free(guess);
00068
00069 return GSL_SUCCESS;
00070 }
00071
00072 void mdmin_fdf(const gsl_vector *parameters, \
00073 void *void_gsl_fit_struct, \
00074 double *f, gsl_vector *df)
00075 {
00076 *f = mdmin_f(parameters, void_gsl_fit_struct);
00077 mdmin_df(parameters, void_gsl_fit_struct, df);
00078 return;
00079 }
00080
00081 double mdmin_f(const gsl_vector *parameters, \
00082 void *void_gsl_fit_struct)
00083 {
00084 int i;
00085 double tmp;
00086 gsl_fit *gft;
00087
00088 gft = (gsl_fit *)void_gsl_fit_struct;
00089
00090
00091
00092
00093 for(i=0; i<gft->para.num; i++)
00094 {
00095 gft->para.tmp[i] = gsl_vector_get(parameters, i);
00096 }
00097
00098 tmp = mdmin_chisq(gft);
00099
00100 return tmp;
00101 }
00102
00103 void mdmin_df(const gsl_vector *parameters, \
00104 void *void_gsl_fit_struct, \
00105 gsl_vector *df)
00106 {
00107 int i;
00108 double res, err;
00109 gsl_function F;
00110 gsl_fit *gft;
00111
00112 gft = (gsl_fit *)void_gsl_fit_struct;
00113
00114
00115
00116
00117 for(i=0; i<gft->para.num; i++)
00118 {
00119 gft->para.par[i] = gsl_vector_get(parameters, i);
00120 }
00121
00122
00123
00124
00125
00126 F.params = void_gsl_fit_struct;
00127 F.function = &mdmin_derivatives;
00128
00129
00130
00131
00132
00133
00134
00135 for (i=0; i<gft->para.num; i++)
00136 {
00137 gft->para.idx = i;
00138 if (gft->para.fix[i]) res=0.0;
00139 else gsl_deriv_central(&F, gft->para.par[i], 1e-4, &res, &err);
00140 gsl_vector_set(df, i, res);
00141 }
00142
00143 return;
00144 }
00145
00146 double mdmin_derivatives(double p, void *void_gsl_fit_struct)
00147 {
00148 int i;
00149 double tmp;
00150 gsl_fit *gft;
00151
00152 gft = (gsl_fit *)void_gsl_fit_struct;
00153
00154
00155
00156
00157
00158
00159 for(i=0; i<gft->para.num; i++) gft->para.tmp[i] = gft->para.par[i];
00160 gft->para.tmp[gft->para.idx] = p;
00161
00162 tmp = mdmin_chisq(gft);
00163
00164 return tmp;
00165 }
00166
00167 double mdmin_chisq(gsl_fit *gft)
00168 {
00169 int i, j, k;
00170 double tmp;
00171 double residual = 0.0;
00172 int numdata;
00173
00174
00175
00176
00177 numdata = 0;
00178 for (k=0; k<gft->numd; k++)
00179 {
00180
00181
00182
00183 for (i=0; i<gft->data[k].num; i++)
00184 {
00185
00186
00187
00188 tmp = 0.0;
00189 for (j=0; j<gft->numf; j++)
00190 {
00191 if (gft->type == MULTIPLE)
00192 {
00193 tmp += gft->func[j].fun_m(gft->data[k].xpt[i], \
00194 gft->para.tmp + gft->func[j].idx, \
00195 k, j);
00196 }
00197 else
00198 {
00199 tmp += gft->func[j].fun_s(gft->data[k].xpt[i], \
00200 gft->para.tmp + gft->func[j].idx);
00201 }
00202 }
00203 tmp = (tmp - gft->data[k].ypt[i]) / gft->data[k].sig[i];
00204 residual += tmp * tmp;
00205 numdata++;
00206 }
00207 }
00208
00209 tmp = residual / (numdata - gft->para.num);
00210 return tmp;
00211 }
00212
00213 void mdmin_status(gsl_fit *gft, \
00214 int iteration, \
00215 gsl_multimin_fdfminimizer *s)
00216 {
00217 int j;
00218 double chisq;
00219
00220 if (iteration >= 0)
00221 {
00222 fprintf(stderr,"ITERATION:%3u ", iteration);
00223 fprintf(stderr,"===================\n");
00224 }
00225 else
00226 {
00227 fprintf(stderr,"COMPLETE ");
00228 fprintf(stderr,"===================\n");
00229 }
00230
00231
00232 for (j=0; j<gft->para.num; j++)
00233 {
00234 gft->para.par[j] = gsl_vector_get(s->x, j);
00235 gft->para.tmp[j] = gsl_vector_get(s->x, j);
00236 }
00237 chisq = mdmin_chisq(gft);
00238 fprintf(stderr,"ChiSq: %12.6e\n", chisq);
00239 for (j=0; j<gft->para.num; j++)
00240 {
00241 fprintf(stderr,"%3d: %12.6f\n", j, gsl_vector_get(s->x, j));
00242 }
00243 fprintf(stderr,"\n");
00244
00245
00246 if (iteration < 0)
00247 {
00248 for (j=0; j<gft->para.num; j++)
00249 {
00250 gft->para.par[j] = gsl_vector_get(s->x, j);
00251 gft->para.err[j] = 0.0;
00252 }
00253 gft->chis = chisq;
00254 }
00255
00256 return;
00257 }