numeric
FitPolynom.hpp
Go to the documentation of this file.
1 #ifndef __NUMERIC_FITPOLYNOM_HPP__
2 #define __NUMERIC_FITPOLYNOM_HPP__
3 
4 #include <math.h>
5 #include <vector>
6 #include <gsl/gsl_multifit.h>
7 #include <gsl/gsl_errno.h>
8 #include <gsl/gsl_math.h>
9 #include <gsl/gsl_min.h>
10 #include <iterator>
11 #include <stdexcept>
12 #include <iostream>
13 #include <gsl/gsl_poly.h>
14 
15 namespace numeric
16 {
17  //template for calculating a polynomial fit
18  //
19  //Parameters
20  //degree ==> number of returned parameters (order of the polynom + 1)
21  //all dereferenced values must be float compatible
22  //the result will be a vector of coefficients with the highest order at the end
23  //TODO
24  //add parameter for number of points to prevent counting them
25  template<typename TIter1,typename TIter2,typename TResult>
26  bool fitPolynom(int degree, TIter1 start_iter_x,
27  TIter1 end_iter_x,
28  TIter2 start_iter_y,
29  TIter2 end_iter_y,
30  std::vector<TResult> &result,
31  double &chisq)
32  {
33  gsl_multifit_linear_workspace *ws;
34  gsl_matrix *cov, *X;
35  gsl_vector *y, *c;
36  result.clear();
37 
38  int i, j;
39 
40  //TODO get rid of this !!!
41  //we have to count the number of points first;
42  TIter1 iter = start_iter_x;
43  int number_of_points = 0;
44  while(iter != end_iter_x)
45  {
46  ++iter;
47  ++number_of_points;
48  }
49 
50  //allocate memory
51  //TODO find a solution so we do not have to allocate memory all the time
52  //Maybe use a object polyfit
53  X = gsl_matrix_alloc(number_of_points, degree);
54  y = gsl_vector_alloc(number_of_points);
55  c = gsl_vector_alloc(degree);
56  cov = gsl_matrix_alloc(degree, degree);
57 
58  for(i=0; i <number_of_points; i++)
59  {
60  gsl_matrix_set(X, i, 0, 1.0);
61  for(j=0; j < degree; j++) {
62  gsl_matrix_set(X, i, j, pow((float)*(start_iter_x), j));
63  }
64  gsl_vector_set(y, i, (float)*(start_iter_y));
65 
66  ++start_iter_x;
67  ++start_iter_y;
68  }
69 
70  ws = gsl_multifit_linear_alloc(number_of_points, degree);
71  gsl_multifit_linear(X, y, c, cov, &chisq, ws);
72 
73  /* store result ... */
74  for(i=0; i < degree; i++)
75  result.push_back(gsl_vector_get(c, i));
76 
77  gsl_multifit_linear_free(ws);
78  gsl_matrix_free(X);
79  gsl_matrix_free(cov);
80  gsl_vector_free(y);
81  gsl_vector_free(c);
82  return true;
83  }
84 
85  template<typename TIter,typename TResult>
86  bool fitPolynom(int degree, TIter start_iter,
87  TIter end_iter,
88  std::vector<TResult> &result,double &chisq)
89  {
90  //generate x vector
91  std::vector<float> x;
92 
93  TIter iter = start_iter;
94  for(int i=0;iter != end_iter;++i,++iter)
95  x.push_back(i);
96  return fitPolynom<typename std::vector<float>::iterator,TIter,TResult>(degree,x.begin(),x.end(),start_iter,end_iter,result,chisq);
97  }
98 
99  //calculates the coefficients of a polynomial which is derivation of the given polynomial
100  //the given coefficients must sorted in ascending order (highest order last)
101  template<typename TIter1,typename TIter2>
102  void derivePolynom(TIter1 start_coefficient,TIter2 end_coefficient,TIter2 start_result)
103  {
104  TIter2 result = start_result;
105  ++start_coefficient;
106  for(int i = 1;start_coefficient!= end_coefficient;++start_coefficient,++i,++result)
107  *result = *start_coefficient*i;
108  if(result == start_result)
109  *result = 0;
110  }
111  void derivePolynom(std::vector<double> &coefficients,std::vector<double> &result)
112  {
113  result.resize(std::max(1,(int)coefficients.size()-1));
114  derivePolynom(coefficients.begin(),coefficients.end(),result.begin());
115  }
116 
117  //calculates the roots of the polynomial given by the coefficients
118  //coefficients must be in ascending order
119  //the roots are stored as result[2n] = real part, result[2n+1] imaginer part
120  void calcPolyRoots(const std::vector<double> &coefficients,std::vector<double> &roots)
121  {
122  roots.resize((coefficients.size()-1)*2);
123  gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc (coefficients.size());
124  gsl_poly_complex_solve (&coefficients[0], coefficients.size(), w, &roots[0]);
125  gsl_poly_complex_workspace_free (w);
126  }
127 
128  //calculates the value of a polynomial on a given position
129  //coefficients order is from lowest to highest
130  double calcPolyVal(const std::vector<double> &coefficients,double position)
131  {
132  if(coefficients.empty())
133  throw std::runtime_error("calcPolyVal: No coefficients are given!");
134 
135  double result = 0;
136  double temp = 1;
137  std::vector<double>::const_iterator iter = coefficients.begin();
138  for(;iter != coefficients.end();++iter,temp = temp*position)
139  result += temp*(*iter);
140 
141  return result;
142  }
143 
144 };
145 #endif
void calcPolyRoots(const std::vector< double > &coefficients, std::vector< double > &roots)
Definition: FitPolynom.hpp:120
Definition: Circle.hpp:6
bool fitPolynom(int degree, TIter1 start_iter_x, TIter1 end_iter_x, TIter2 start_iter_y, TIter2 end_iter_y, std::vector< TResult > &result, double &chisq)
Definition: FitPolynom.hpp:26
void derivePolynom(TIter1 start_coefficient, TIter2 end_coefficient, TIter2 start_result)
Definition: FitPolynom.hpp:102
double calcPolyVal(const std::vector< double > &coefficients, double position)
Definition: FitPolynom.hpp:130