00001
00008
00009 #include "gsl_fit.h"
00010
00011 gsl_fit *gsl_fit_alloc(unsigned int method, \
00012 unsigned int algotrithm, \
00013 unsigned int max_iter, \
00014 unsigned int type)
00015 {
00016
00017
00018
00019
00020 gsl_fit *gft;
00021
00022
00023 if ((method<MULTIDIM_MINIMIZAION)||(method>SIMULATED_ANNEAL)) {
00024 GSL_ERROR_VAL("Not a valid method", \
00025 GSL_EINVAL, NULL); }
00026 if ((algotrithm<CONJUGATE_FR)||(algotrithm>LMDR)) {
00027 GSL_ERROR_VAL("Not a valid algortithm", \
00028 GSL_EINVAL, NULL); }
00029 if ((method == MULTIDIM_MINIMIZAION) && (algotrithm > STEEPEST_DESCENT)) {
00030 GSL_ERROR_VAL("Wrong method/algotrithm pair.", \
00031 GSL_EINVAL, NULL); }
00032 else if (method == LEAST_SQUARES) {
00033 if ((algotrithm <= STEEPEST_DESCENT) || (algotrithm > LMDR)) {
00034 GSL_ERROR_VAL("Wrong method/algotrithm pair.", \
00035 GSL_EINVAL, NULL); } }
00036 if ((method!=SIMULATED_ANNEAL)&&(max_iter<=0)) {
00037 GSL_ERROR_VAL("Not enough iterations", \
00038 GSL_EINVAL, NULL); }
00039 if ((type!=SINGLE)&&(type!=MULTIPLE)) {
00040 GSL_ERROR_VAL("Not valid type", \
00041 GSL_EINVAL, NULL); }
00042
00043 gft = (gsl_fit *)malloc(sizeof(gsl_fit));
00044 if (gft==NULL) {
00045 GSL_ERROR_VAL("Failed to allocate a gsl_fit", \
00046 GSL_ENOMEM, NULL); }
00047
00048
00049 gft->numd = 0;
00050 gft->data = NULL;
00051
00052
00053 gft->chis = 0.0;
00054 gft->maxi = max_iter;
00055 gft->indx = 0;
00056 gft->type = type;
00057
00058
00059 gft->para.num = 0;
00060 gft->para.idx = 0;
00061 gft->para.par = NULL;
00062 gft->para.fix = NULL;
00063 gft->para.err = NULL;
00064 gft->para.tmp = NULL;
00065
00066
00067 gft->numf = 0;
00068 gft->func = NULL;
00069
00070
00071
00072 switch (method) {
00073 case LEAST_SQUARES:
00074 gft->meth.solver_function_call = &lstsq_main;
00075 break;
00076 case MULTIDIM_MINIMIZAION:
00077 gft->meth.solver_function_call = &mdmin_main;
00078 break;
00079 case SIMULATED_ANNEAL:
00080 gft->meth.solver_function_call = &siman_main;
00081 break;
00082 default:
00083 gft->meth.solver_function_call = &lstsq_main;
00084 }
00085
00086 switch (algotrithm) {
00087 case CONJUGATE_FR:
00088 gft->meth.mdmin_type = gsl_multimin_fdfminimizer_conjugate_fr;
00089 break;
00090 case CONJUGATE_PR:
00091 gft->meth.mdmin_type = gsl_multimin_fdfminimizer_conjugate_pr;
00092 break;
00093 case VECTOR_BFGS:
00094 gft->meth.mdmin_type = gsl_multimin_fdfminimizer_vector_bfgs;
00095 break;
00096 case STEEPEST_DESCENT:
00097 gft->meth.mdmin_type = \
00098 gsl_multimin_fdfminimizer_steepest_descent;
00099 break;
00100 case LMSDR:
00101 gft->meth.lstsq_type = gsl_multifit_fdfsolver_lmsder;
00102 break;
00103 case LMDR:
00104 gft->meth.lstsq_type = gsl_multifit_fdfsolver_lmder;
00105 break;
00106 default:
00107 gft->meth.lstsq_type = gsl_multifit_fdfsolver_lmder;
00108 break;
00109 }
00110
00111 return gft;
00112 }
00113
00114 int gsl_fit_add_dataset(gsl_fit *gft, \
00115 double *xpt, double *ypt, double *sig, \
00116 unsigned int num)
00117 {
00118 int i;
00119
00120
00121 if (gft==NULL) {
00122 GSL_ERROR("Attempt to add data to null gsl_fit", \
00123 GSL_EFAULT); }
00124 if ((gft->type==SINGLE)&&(gft->numd!=0)) {
00125 GSL_ERROR("Already have data to fit", \
00126 GSL_EINVAL); }
00127 if (num<=2) {
00128 GSL_ERROR("Not enough data points", \
00129 GSL_EINVAL); }
00130
00131
00132
00133 gft->data = realloc(gft->data, (gft->numd+1)*sizeof(struct _data));
00134 if (gft->data == NULL) {
00135 GSL_ERROR("No memory for data set",\
00136 GSL_ENOMEM); }
00137
00138
00139 gft->data[gft->numd].xpt = (double *)malloc(num*sizeof(double));
00140 gft->data[gft->numd].ypt = (double *)malloc(num*sizeof(double));
00141 gft->data[gft->numd].sig = (double *)malloc(num*sizeof(double));
00142 if ((gft->data[gft->numd].xpt == NULL) || \
00143 (gft->data[gft->numd].ypt == NULL) || \
00144 (gft->data[gft->numd].sig == NULL)) {
00145 GSL_ERROR("No memory for data set",\
00146 GSL_ENOMEM); }
00147
00148
00149 gft->data[gft->numd].num = num;
00150 gft->data[gft->numd].idx = 0;
00151
00152
00153 for (i=0; i<num; i++)
00154 {
00155 gft->data[gft->numd].xpt[i] = xpt[i];
00156 gft->data[gft->numd].ypt[i] = ypt[i];
00157 gft->data[gft->numd].sig[i] = sig[i];
00158 }
00159
00160
00161 gft->numd += 1;
00162
00163
00164 return GSL_SUCCESS;
00165 }
00166
00167 int gsl_fit_add_model_multiple(gsl_fit *gft, \
00168 double (*fun)(double, double *, \
00169 unsigned int, unsigned int), \
00170 double *par, unsigned int *fix, unsigned int num)
00171 {
00172 unsigned int i;
00173
00174
00175 if (gft==NULL) {
00176 GSL_ERROR("Attempt to add data to null gsl_fit", \
00177 GSL_EFAULT); }
00178 if (num<=0) {
00179 GSL_ERROR("Not enough data points", \
00180 GSL_EINVAL); }
00181 if (gft->type==SINGLE) {
00182 GSL_ERROR("Wrong model type", \
00183 GSL_EINVAL); }
00184
00185 gft->func = realloc(gft->func, (gft->numf+1)*sizeof(struct _func));
00186 gft->para.par = realloc(gft->para.par, (gft->para.num+num)*sizeof(double));
00187 gft->para.fix = realloc(gft->para.fix, \
00188 (gft->para.num+num)*sizeof(unsigned int));
00189 gft->para.err = realloc(gft->para.err, (gft->para.num+num)*sizeof(double));
00190 gft->para.tmp = realloc(gft->para.tmp, (gft->para.num+num)*sizeof(double));
00191
00192 gft->func[gft->numf].fun_m = fun;
00193 gft->func[gft->numf].fun_s = NULL;
00194 gft->func[gft->numf].num = num;
00195 gft->func[gft->numf].idx = gft->para.num;
00196
00197 for (i=0; i<num; i++)
00198 {
00199 gft->para.par[i+gft->para.num] = par[i];
00200 gft->para.fix[i+gft->para.num] = fix[i];
00201 gft->para.err[i+gft->para.num] = 0.0;
00202 gft->para.tmp[i+gft->para.num] = 0.0;
00203 }
00204
00205 gft->numf += 1;
00206 gft->para.num += num;
00207
00208 return GSL_SUCCESS;
00209 }
00210
00211 int gsl_fit_add_model_single(gsl_fit *gft, \
00212 double (*fun)(double, double *), \
00213 double *par, unsigned int *fix, unsigned int num)
00214 {
00215 unsigned int i;
00216
00217
00218 if (gft==NULL) {
00219 GSL_ERROR("Attempt to add data to null gsl_fit", \
00220 GSL_EFAULT); }
00221 if (num<=0) {
00222 GSL_ERROR("Not enough data points", \
00223 GSL_EINVAL); }
00224 if (gft->type==MULTIPLE) {
00225 GSL_ERROR("Wrong model type", \
00226 GSL_EINVAL); }
00227
00228 gft->func = realloc(gft->func, (gft->numf+1)*sizeof(struct _func));
00229 gft->para.par = realloc(gft->para.par, (gft->para.num+num)*sizeof(double));
00230 gft->para.fix = realloc(gft->para.fix, \
00231 (gft->para.num+num)*sizeof(unsigned int));
00232 gft->para.err = realloc(gft->para.err, (gft->para.num+num)*sizeof(double));
00233 gft->para.tmp = realloc(gft->para.tmp, (gft->para.num+num)*sizeof(double));
00234
00235 gft->func[gft->numf].fun_m = NULL;
00236 gft->func[gft->numf].fun_s = fun;
00237 gft->func[gft->numf].num = num;
00238 gft->func[gft->numf].idx = gft->para.num;
00239
00240 for (i=0; i<num; i++)
00241 {
00242 gft->para.par[i+gft->para.num] = par[i];
00243 gft->para.fix[i+gft->para.num] = fix[i];
00244 gft->para.err[i+gft->para.num] = 0.0;
00245 gft->para.tmp[i+gft->para.num] = 0.0;
00246 }
00247
00248 gft->numf += 1;
00249 gft->para.num += num;
00250
00251 return GSL_SUCCESS;
00252 }
00253
00254 int gsl_fit_print(gsl_fit *gft, char *filename)
00255 {
00256 int i, j, k;
00257 double tmp;
00258 FILE *fp;
00259
00260
00261 if (gft==NULL) {
00262 GSL_ERROR("Attempt to print data from a null gsl_fit", \
00263 GSL_EFAULT); }
00264
00265 fp = fopen(filename, "w");
00266 if (fp==NULL) {
00267 GSL_ERROR("Cannot open file for writing", \
00268 GSL_ENOMEM); }
00269
00270
00271 for (k=0; k<gft->numd; k++)
00272 {
00273
00274 for (i=0; i<gft->data[k].num; i++)
00275 {
00276
00277 tmp = 0.0;
00278 for (j=0; j<gft->numf; j++)
00279 {
00280 if (gft->type == MULTIPLE)
00281 {
00282 tmp += gft->func[j].fun_m(gft->data[k].xpt[i], \
00283 gft->para.par+gft->func[j].idx, k, j);
00284 }
00285 else
00286 {
00287 tmp += gft->func[j].fun_s(gft->data[k].xpt[i], \
00288 gft->para.par+gft->func[j].idx);
00289 }
00290 }
00291 fprintf(fp,"%f\t%f\n", gft->data[k].xpt[i], tmp);
00292 }
00293 fprintf(fp,"\n");
00294 }
00295
00296 fclose(fp);
00297
00298 return GSL_SUCCESS;
00299 }
00300
00301 int gsl_fit_get_result(gsl_fit *gft, \
00302 unsigned int function, \
00303 double *par, double *err, unsigned int num)
00304 {
00305 int i;
00306
00307
00308 if (gft==NULL) {
00309 GSL_ERROR(" attempt to get results from a null gsl_fit", \
00310 GSL_EINVAL); }
00311 if (function>=gft->numf) {
00312 GSL_ERROR(" attempt to get results from non-existant function", \
00313 GSL_EINVAL); }
00314 if (num!=gft->func[function].num) {
00315 GSL_ERROR(" wrong number of parameters to get", \
00316 GSL_EINVAL); }
00317
00318 for (i=0; i<num; i++)
00319 {
00320 par[i] = (gft->para.par+gft->func[function].idx)[i];
00321 err[i] = (gft->para.err+gft->func[function].idx)[i];
00322 }
00323 return GSL_SUCCESS;
00324 }
00325
00326 int gsl_fit_do(gsl_fit *gft)
00327 {
00328 int status;
00329
00330 status = gft->meth.solver_function_call(gft);
00331
00332 return status;
00333 }
00334
00335 void gsl_fit_free(gsl_fit *gft)
00336 {
00337 int k;
00338
00339 if (gft == NULL) return;
00340
00341 for(k=0; k<gft->numd; k++)
00342 {
00343 free(gft->data[k].xpt);
00344 free(gft->data[k].ypt);
00345 free(gft->data[k].sig);
00346 }
00347 if (gft->numd) free(gft->data);
00348
00349 if (gft->para.num)
00350 {
00351 free(gft->para.par);
00352 free(gft->para.fix);
00353 free(gft->para.err);
00354 free(gft->para.tmp);
00355 }
00356
00357 if (gft->numf)
00358 {
00359 free(gft->func);
00360 }
00361
00362 free(gft);
00363
00364 return;
00365 }