inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/func
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_func
00005 #define inlib_func
00006 
00007 // some common functions.
00008 
00009 #include "math"
00010 
00011 #include <cmath>
00012 #include <vector>
00013 
00014 namespace inlib {
00015 namespace func {
00016 
00017 class gaussian {
00018 public:
00019   gaussian(double a_scale = 1,double a_mean = 0,double a_sigma = 1){
00020     set(a_scale,a_mean,a_sigma);
00021   }
00022   virtual ~gaussian(){}
00023 public:
00024   gaussian(const gaussian& a_from)
00025   :m_scale(a_from.m_scale)
00026   ,m_mean(a_from.m_mean)
00027   ,m_sigma(a_from.m_sigma)
00028   {}
00029   gaussian& operator=(const gaussian& a_from){
00030     m_scale = a_from.m_scale;
00031     m_mean = a_from.m_mean;
00032     m_sigma = a_from.m_sigma;
00033     return *this;
00034   }
00035 public:
00036   bool in_domain(double) const {return true;}
00037   double value(double a_x) const {
00038     double value = (a_x - m_mean)/m_sigma;
00039     return m_scale * ::exp(-0.5 * value * value);
00040   }
00041 public:
00042   void set(double a_scale,double a_mean,double a_sigma){
00043     m_scale = a_scale;
00044     m_mean = a_mean;
00045     m_sigma = a_sigma;
00046     if(m_sigma<=0) m_sigma = 1;
00047   }
00048   void scale(double a_scale){m_scale = a_scale;}
00049   void mean(double a_mean){m_mean = a_mean;}
00050   void sigma(double a_sigma){
00051     m_sigma = a_sigma;
00052     if(m_sigma<=0) m_sigma = 1;
00053   }
00054   double scale() const {return m_scale;}
00055   double mean() const {return m_mean;}
00056   double sigma() const {return m_sigma;} 
00057 private:
00058   double m_scale,m_mean,m_sigma;
00059 };
00060 
00061 //Breit-Wigner
00062 class bw {
00063 public:
00064   bw(double a_height = 1,double a_center = 0,double a_width = 1){
00065     set(a_height,a_center,a_width);
00066   }
00067   virtual ~bw(){}
00068 public:
00069   bw(const bw& a_from)
00070   :m_height(a_from.m_height)
00071   ,m_center(a_from.m_center)
00072   ,m_width(a_from.m_width)
00073   {}
00074   bw& operator=(const bw& a_from){
00075     m_height = a_from.m_height;
00076     m_center = a_from.m_center;
00077     m_width = a_from.m_width;
00078     return *this;
00079   }
00080 public:
00081   bool in_domain(double) const {return true;}
00082   double value(double a_x) const {
00083     double value = 2.*(a_x - m_center)/m_width;
00084     return m_height/(1. + value * value);
00085   }
00086 public:
00087   void set(double a_height,double a_center,double a_width){
00088     m_height = a_height;
00089     m_center = a_center;
00090     m_width = a_width;
00091     if(m_width<=0) m_width = 1;
00092   }
00093   void height(double a_height){m_height = a_height;}
00094   void center(double a_center){m_center = a_center;}
00095   void width(double a_width){
00096     m_width = a_width;
00097     if(m_width<=0) m_width = 1;
00098   }
00099   double height() const {return m_height;}
00100   double center() const {return m_center;}
00101   double width() const {return m_width;}
00102 private:
00103   double m_height,m_center,m_width;
00104 };
00105 
00106 class expo {
00107 public:
00108   expo(double a_a = 0,double a_b = 1){
00109     // exp(a_a + a_b * a_x)  //Same as in PAW fitting definition.
00110     set(a_a,a_b);
00111   }
00112   virtual ~expo(){}
00113 public:
00114   expo(const expo& a_from)
00115   :m_a(a_from.m_a)
00116   ,m_b(a_from.m_b)
00117   {}
00118   expo& operator=(const expo& a_from){
00119     m_a = a_from.m_a;
00120     m_b = a_from.m_b;
00121     return *this;
00122   }
00123 public:
00124   bool in_domain(double) const {return true;}
00125   double value(double a_x) const {return ::exp(m_a + m_b * a_x);}
00126 public:
00127   void set(double a_a,double a_b){
00128     m_a = a_a;
00129     m_b = a_b;
00130   }
00131   void a(double a_a){m_a = a_a;}
00132   void b(double a_b){m_b = a_b;}
00133   double a() const {return m_a;}
00134   double b() const {return m_b;}
00135 private:
00136   double m_a,m_b;
00137 };
00138 
00139 class polynomial {
00140 public:
00141   polynomial(const std::vector<double>& a_params){
00142     // P[0] + P[1] x + P[2] x**2 + ...
00143     parameters(a_params);
00144   }
00145   virtual ~polynomial(){}
00146 public:
00147   polynomial(const polynomial& a_from)
00148   :m_params(a_from.m_params)
00149   {}
00150   polynomial& operator=(const polynomial& a_from){
00151     m_params = a_from.m_params;
00152     return *this;
00153   }
00154 public:
00155   bool in_domain(double) const {return true;}
00156   double value(double a_x) const {
00157     double value = 0;
00158     double xxx = 1;
00159     unsigned int pn = m_params.size();
00160     for(unsigned int i=0;i<pn;i++) {
00161       value += m_params[i] * xxx;
00162       xxx = xxx * a_x;
00163     }
00164     return value;
00165   }
00166 public:
00167   bool parameters(const std::vector<double>& a_params){
00168     m_params = a_params;
00169     return true;
00170   }
00171   const std::vector<double>& parameters() const {return m_params;}
00172   void parameter(unsigned int a_index,double a_value){
00173     if(a_index>=m_params.size()) return;
00174     m_params[a_index] = a_value;
00175   }
00176 private:
00177   std::vector<double> m_params;
00178 };
00179 
00180 class cauchy {
00181 public:
00182   cauchy(double a_height = 1,double a_center = 0,double a_width = 1){
00183     set(a_height,a_center,a_width);
00184   }
00185   virtual ~cauchy(){}
00186 public:
00187   cauchy(const cauchy& a_from)
00188   :m_height(a_from.m_height)
00189   ,m_center(a_from.m_center)
00190   ,m_width(a_from.m_width)
00191   {}
00192   cauchy& operator=(const cauchy& a_from){
00193     m_height = a_from.m_height;
00194     m_center = a_from.m_center;
00195     m_width = a_from.m_width;
00196     return *this;
00197   }
00198 public:  
00199   bool in_domain(double) const {return true;}
00200   double value(double a_x) const {
00201     // From Wikipedia.
00202     double b = m_width/2.;
00203     double value = (a_x - m_center)/b;
00204     return m_height/((value * value + 1)*b*inlib::pi());
00205   }
00206 public:  
00207   void set(double a_height,double a_center,double a_width){
00208     m_height = a_height;
00209     m_center = a_center;
00210     m_width = a_width;
00211     if(m_width<=0) m_width = 1;
00212   }
00213   void height(double a_height){m_height = a_height;}
00214   void center(double a_center){m_center = a_center;}
00215   void width(double a_width){
00216     m_width = a_width;
00217     if(m_width<=0) m_width = 1;
00218   }
00219   double height() const {return m_height;}
00220   double center() const {return m_center;}
00221   double width() const {return m_width;}
00222 private:
00223   double m_height,m_center,m_width;
00224 };
00225 
00226 class in_polygon {
00227 public:
00228   typedef std::pair<double,double> point;
00229 public:
00230   in_polygon(){}
00231   in_polygon(const std::vector<point>& a_points){set(a_points);}
00232   virtual ~in_polygon(){}
00233 public:
00234   in_polygon(const in_polygon& a_from)
00235   :m_points(a_from.m_points)
00236   {}
00237   in_polygon& operator=(const in_polygon& a_from){
00238     m_points = a_from.m_points;
00239     return *this;
00240   }
00241 public:
00242   bool in_domain(const point&) const {return true;}
00243   double value(const point& a_point) const {
00244     if(!m_points.size()) return 0;
00245     return (inside(a_point,m_points)?1:0);
00246   }
00247 public:
00248   bool set(const std::vector<point>& a_points){
00249     m_points = a_points;
00250     if(!m_points.size()) return false;
00251     //check closure :
00252     if((m_points.size()>=2) && (m_points[m_points.size()-1]!=m_points[0]) ) {
00253       m_points.push_back(m_points[0]);
00254     }
00255     return true;
00256   }
00257 
00258   bool set(unsigned int a_index,const point& a_point){
00259     if(a_index>=m_points.size()) return false;
00260     m_points[a_index] = a_point;
00261     return true;
00262   }
00263 
00264   const std::vector<point>& points() const {return m_points;}
00265 private:
00266   static double is_left(const point& P0,
00267                                const point& P1,
00268                                const point& P2){
00269     return ( (P1.first - P0.first) * (P2.second - P0.second)
00270            - (P2.first - P0.first) * (P1.second - P0.second) );
00271   }
00272 
00273   static bool inside(const point& a_P,const std::vector<point>& a_V) {
00274     // V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
00275 
00276     // From :
00277     //   http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
00278     // Copyright 2001, softSurfer (www.softsurfer.com)
00279     // This code may be freely used and modified for any purpose
00280     // providing that this copyright notice is included with it.
00281     // SoftSurfer makes no warranty for this code, and cannot be held
00282     // liable for any real or imagined damage resulting from its use.
00283     // Users of this code must verify correctness for their application.
00284 
00285     unsigned int n = a_V.size()-1;
00286 
00287     int    wn = 0;    // the winding number counter
00288 
00289     // loop through all edges of the polygon
00290     for (unsigned int i=0; i<n; i++) {   // edge from V[i] to V[i+1]
00291       if (a_V[i].second <= a_P.second) {         // start y <= P[1]
00292         if (a_V[i+1].second > a_P.second)      // an upward crossing
00293           if (is_left( a_V[i], a_V[i+1], a_P) > 0)  // P left of edge
00294             ++wn;            // have a valid up intersect
00295       } else {                       // start y > P[1] (no test needed)
00296         if (a_V[i+1].second <= a_P.second)     // a downward crossing
00297           if (is_left( a_V[i], a_V[i+1], a_P) < 0)  // P right of edge
00298             --wn;            // have a valid down intersect
00299       }
00300     }
00301   
00302     return ((wn!=0)?true:false);
00303   }
00304 private:
00305   std::vector<point> m_points;
00306 };
00307 
00308 class in_ellipse {
00309 public:
00310   in_ellipse():m_a(1),m_b(1){}
00311   virtual ~in_ellipse(){}
00312 public:
00313   in_ellipse(const in_ellipse& a_from):m_a(a_from.m_a),m_b(a_from.m_b){}
00314   in_ellipse& operator=(const in_ellipse& a_from){
00315     m_a = a_from.m_a;
00316     m_b = a_from.m_b;
00317     return *this;
00318   }
00319 public:
00320   bool in_domain(double,double) const {return true;}
00321   double value(double a_x,double a_y) const {
00322     if(m_a>=m_b) {
00323       double f = ::sqrt(m_a*m_a-m_b*m_b);
00324       double x1  = a_x-f;
00325       double x2  = a_x+f;
00326       double y2 = a_y*a_y;
00327       double d = ::sqrt(x1*x1+y2) + ::sqrt(x2*x2+y2);
00328       return (d>(2*m_a)?false:true); //border is outside.
00329     } else {
00330       double f = ::sqrt(m_b*m_b-m_a*m_a);
00331       double y1  = a_y-f;
00332       double y2  = a_y+f;
00333       double x2 = a_x*a_x;
00334       double d = ::sqrt(x2+y1*y1) + ::sqrt(x2+y2*y2);
00335       return (d>(2*m_b)?false:true); //border is outside.
00336     }
00337   }
00338 public:
00339   bool set_from_a_b(double a_a,double a_b) {
00340     if(a_a<=0) return false;
00341     if(a_b<=0) return false;
00342     m_a = a_a;
00343     m_b = a_b;
00344     return true;
00345   }
00346   double a() const {return m_a;}
00347   double b() const {return m_b;}
00348 private:
00349   double m_a;
00350   double m_b;
00351 };
00352 
00353 // wrapper to C function (for exa ::cos, etc...):
00354 class cfunc {
00355 public:
00356   typedef double(*func)(double);
00357 public:
00358   cfunc(func a_func):m_func(a_func){}
00359   virtual ~cfunc(){}
00360 public:
00361   cfunc(const cfunc& a_from):m_func(a_from.m_func){}
00362   cfunc& operator=(const cfunc& a_from){
00363     m_func = a_from.m_func;
00364     return *this;
00365   }
00366 public:
00367   bool in_domain(double) const {return true;}
00368   double value(double a_x) const {return m_func(a_x);}
00369 private:
00370   func m_func;
00371 };
00372 
00373 
00374 }}
00375 
00376 #endif
00377 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines