fit/fit-ex.cc

Example of using general fitting classes.
00001 #include <gslmm/fit/fit.hh>
00002 #include <iostream>
00003 #include <sstream>
00004 #include <gslmm/random/gaussian.hh>
00005 #include <gslmm/error/error_handler.hh>
00006 #include <iomanip>
00007 #include <vector>
00008 
00009 struct expo 
00010 {
00011   std::vector<double> y;
00012   std::vector<double> sigma;
00013   
00014   int function(const gslmm::vector<double>& x, gslmm::vector<double>& f)
00015   {
00016     double A      = x[0];
00017     double lambda = x[1];
00018     double b      = x[2];
00019     for (size_t i = 0; i < y.size(); i++) {
00020       double t  = i;
00021       double yi = A * exp(-lambda * t) + b;
00022       f[i]      = (yi - y[i]) / sigma[i];
00023     }
00024     return GSL_SUCCESS;
00025   }
00026   int jacobian(const gslmm::vector<double>& x, gslmm::matrix<double>& j)
00027   {
00028     double A      = x[0];
00029     double lambda = x[1];
00030     double b      = x[2];
00031     for (size_t i = 0; i < y.size(); i++) {
00032       double t   = i;
00033       double s   = sigma[i];
00034       double e   = exp(-lambda * t);
00035       j(i, 0) = e / s;
00036       j(i, 1) = -t * A * e / s;
00037       j(i, 2) = 1 / s;
00038     }
00039     return GSL_SUCCESS;
00040   }
00041   int iterate() { return GSL_SUCCESS; }
00042   expo(size_t n) 
00043     : y(n), sigma(n)
00044   {
00045     gslmm::generator::env_setup();
00046     gslmm::generator g;
00047     gslmm::gaussian  r(0.1, g);
00048     
00049     for (size_t i = 0; i < n; i++) {
00050       double t = i;
00051       y[i]     = 1. + 5 * exp(-0.1 * t) + r.sample();
00052       sigma[i] = .1;
00053     }
00054   }
00055 };
00056 
00057 void 
00058 print_status(size_t iter, const gslmm::fitter<expo>& fit, bool cont) 
00059 {
00060   gslmm::vector<double> p(fit.position());
00061   gslmm::vector<double> f(fit.values());
00062   std::cout << std::setw(4) << iter << " x=("
00063             << std::setw(10) << p[0] << ","
00064             << std::setw(10) << p[1] << ","
00065             << std::setw(10) << p[2] << ") |f(x)|="
00066             << std::setw(10) << f.length() << "\t" 
00067             << (cont ? "continue" : "done") << std::endl;
00068 }
00069 
00070 int main()
00071 {
00072   expo e(40);
00073   gslmm::vector<double> initial(3);
00074   initial[0] = 1;
00075   gslmm::fitter<expo> fit;
00076   fit.initialize(e, gslmm::fitter<expo>::scaled_levenberg_marquardt, 
00077                initial, 40);
00078   
00079   print_status(0, fit, true);
00080   size_t iter = 1;
00081   int status  = 0;
00082   bool cont = true;
00083   do {
00084     status = fit.iterate();
00085     if (status) { 
00086       std::cout << "bad status " << status << std::endl;
00087       break;
00088     }
00089     cont = !fit.test_delta(1e-4, 1e-4);
00090     print_status(iter, fit, cont);
00091   } while (cont && ++iter < 500);
00092   gslmm::matrix<double> c(3,3);
00093   gslmm::vector<double> p(fit.position());
00094   fit.covariance(c, 0);
00095   
00096   for (size_t i = 0; i < 3; i++) {
00097     std::cout << (i == 0 ? "A" : (i == 1 ? "lambda" : "b"))
00098               << "\t\t= " << std::setw(10) << p[i] 
00099               << " +/" << std::setw(10) << sqrt(c(i,i)) << std::endl;
00100   }
00101   gslmm::vector<double> f(fit.values());
00102   double chisq = f.length();
00103   std::cout << "chi^2/dof\t= " << std::setw(10) << (chisq*chisq) 
00104             << " / 37 = " << (chisq*chisq)/37 << "\nstatus=" 
00105             << gslmm::error_handler<>::code_to_string(status) << std::endl;
00106   return status;
00107 }
00108 
00109   
00110 
00111   
00112       
Top of page Last update Tue May 9 10:11:10 2006
Christian Holm
Created by DoxyGen 1.4.6