inlib
1.2.0
|
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