gsl_fit.c

Go to the documentation of this file.
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    * This instance will be created in memory and the 
00018    * pointer to it passed back to the user 
00019    */
00020   gsl_fit *gft;
00021   
00022   /* Sanity checks */
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   /* Allocate memory for the gsl_fit */
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   /* Initialize the data struct */
00049   gft->numd = 0;
00050   gft->data = NULL;
00051   
00052   /* Initialize stuff */
00053   gft->chis = 0.0;  
00054   gft->maxi = max_iter;
00055   gft->indx = 0;
00056   gft->type = type;
00057   
00058   /* Initialize the paramter struct */
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   /* Initialize the function struct */
00067   gft->numf = 0;
00068   gft->func = NULL;
00069 
00070   /*------------------------------------------------------*/
00071   /* Set the fitting method */
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   /* Sanity checks */
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   /* allocate the memory for the */
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   /* Sanity checks */
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   /* Sanity checks */
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   /* Sanity checks */
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   /* loop over the data sets */
00271   for (k=0; k<gft->numd; k++)
00272   {
00273     /* loop over the data points in data set k */
00274     for (i=0; i<gft->data[k].num; i++)
00275     {
00276       /* loop over the model functions */
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   /* Sanity checks */
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 }

Generated on Fri Jan 19 14:54:26 2007 for gsl_fit by  doxygen 1.4.7