latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*-------------------------------------------------------------------- 00025 * project ....: LTI-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiPolynomRoots.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 6.4.2003 00030 * revisions ..: $Id: ltiPolynomRoots.h,v 1.9 2006/02/08 12:39:35 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_POLYNOM_ROOTS_H_ 00034 #define _LTI_POLYNOM_ROOTS_H_ 00035 00036 #include "ltiMath.h" 00037 #include "ltiFunctor.h" 00038 #include "ltiVector.h" 00039 #include "ltiComplex.h" 00040 00041 namespace lti { 00042 /** 00043 * Find the roots of a polygon with real coefficients. 00044 * 00045 * The equation \c f(x)=0 with the polynom of n-th degree \c f(x) with 00046 * real coefficients has n solutions, where some of them can be complex. 00047 * 00048 * Complex roots for polynoms with real coefficients exist always 00049 * as conjugate pairs. 00050 * 00051 * For an explanation of the algorithms used see: 00052 * W. Press et. at. "Numerical Recipes in C", 2nd edition, 1992. 00053 * 00054 */ 00055 class polynomRoots : public functor { 00056 public: 00057 /** 00058 * the parameters for the class polynomRoots 00059 */ 00060 class parameters : public functor::parameters { 00061 public: 00062 /** 00063 * default constructor 00064 */ 00065 parameters(); 00066 00067 /** 00068 * copy constructor 00069 * @param other the parameters object to be copied 00070 */ 00071 parameters(const parameters& other); 00072 00073 /** 00074 * destructor 00075 */ 00076 ~parameters(); 00077 00078 /** 00079 * returns name of this type 00080 */ 00081 const char* getTypeName() const; 00082 00083 /** 00084 * copy the contents of a parameters object 00085 * @param other the parameters object to be copied 00086 * @return a reference to this parameters object 00087 */ 00088 parameters& copy(const parameters& other); 00089 00090 /** 00091 * copy the contents of a parameters object 00092 * @param other the parameters object to be copied 00093 * @return a reference to this parameters object 00094 */ 00095 parameters& operator=(const parameters& other); 00096 00097 00098 /** 00099 * returns a pointer to a clone of the parameters 00100 */ 00101 virtual functor::parameters* clone() const; 00102 00103 /** 00104 * write the parameters in the given ioHandler 00105 * @param handler the ioHandler to be used 00106 * @param complete if true (the default) the enclosing begin/end will 00107 * be also written, otherwise only the data block will be written. 00108 * @return true if write was successful 00109 */ 00110 virtual bool write(ioHandler& handler,const bool complete=true) const; 00111 00112 /** 00113 * read the parameters from the given ioHandler 00114 * @param handler the ioHandler to be used 00115 * @param complete if true (the default) the enclosing begin/end will 00116 * be also written, otherwise only the data block will be written. 00117 * @return true if write was successful 00118 */ 00119 virtual bool read(ioHandler& handler,const bool complete=true); 00120 00121 # ifdef _LTI_MSC_6 00122 /** 00123 * this function is required by MSVC only, as a workaround for a 00124 * very awful bug, which exists since MSVC V.4.0, and still by 00125 * V.6.0 with all bugfixes (so called "service packs") remains 00126 * there... This method is also public due to another bug, so please 00127 * NEVER EVER call this method directly: use read() instead 00128 */ 00129 bool readMS(ioHandler& handler,const bool complete=true); 00130 00131 /** 00132 * this function is required by MSVC only, as a workaround for a 00133 * very awful bug, which exists since MSVC V.4.0, and still by 00134 * V.6.0 with all bugfixes (so called "service packs") remains 00135 * there... This method is also public due to another bug, so please 00136 * NEVER EVER call this method directly: use write() instead 00137 */ 00138 bool writeMS(ioHandler& handler,const bool complete=true) const; 00139 # endif 00140 00141 // ------------------------------------------------ 00142 // the parameters 00143 // ------------------------------------------------ 00144 00145 }; 00146 00147 /** 00148 * default constructor 00149 */ 00150 polynomRoots(); 00151 00152 /** 00153 * Construct a functor using the given parameters 00154 */ 00155 polynomRoots(const parameters& par); 00156 00157 /** 00158 * copy constructor 00159 * @param other the object to be copied 00160 */ 00161 polynomRoots(const polynomRoots& other); 00162 00163 /** 00164 * destructor 00165 */ 00166 virtual ~polynomRoots(); 00167 00168 /** 00169 * returns the name of this type ("polynomRoots") 00170 */ 00171 virtual const char* getTypeName() const; 00172 00173 /** 00174 * Solves the quadratic equation \f$ ax^2 + bx + c = 0 \f$, 00175 * for real \e a, \e b and \e c coefficients. 00176 * 00177 * @param a coefficient for the x^2 term 00178 * @param b coefficient for the x term 00179 * @param c constant term 00180 * 00181 * @param rex1 real part of the first solution 00182 * @param imx1 imaginary part of the first solution 00183 * @param rex2 real part of the second solution 00184 * @param imx2 imaginary part of the second solution 00185 * 00186 * @return the number of real solutions. 00187 */ 00188 int quadratic(const double& a, const double& b, const double& c, 00189 double& rex1, double& imx1, 00190 double& rex2, double& imx2) const; 00191 00192 00193 /** 00194 * Solves the quadratic equation \f$ ax^2 + bx + c = 0 \f$, 00195 * for real \e a, \e b and \e c coefficients. 00196 * 00197 * @param a coefficient for the x^2 term 00198 * @param b coefficient for the x term 00199 * @param c constant term 00200 * 00201 * @param x1 first solution 00202 * @param x2 second solution 00203 * 00204 * @return the number of real solutions. 00205 */ 00206 int quadratic(const double& a, const double& b, const double& c, 00207 complex<double>& x1, complex<double>& x2) const; 00208 00209 /** 00210 * Solves the quadratic equation \f$ x^2 + p*x + q = 0 \f$, 00211 * for real \e p and \e q coefficients. 00212 * 00213 * @param p coefficient for the x term 00214 * @param q constant term 00215 * 00216 * @param rex1 real part of the first solution 00217 * @param imx1 imaginary part of the first solution 00218 * @param rex2 real part of the second solution 00219 * @param imx2 imaginary part of the second solution 00220 * 00221 * @return the number of real solutions. 00222 */ 00223 int quadratic(const double& p, const double& q, 00224 double& rex1, double& imx1, 00225 double& rex2, double& imx2) const; 00226 00227 00228 /** 00229 * Solves the quadratic equation \f$ x^2 + p*x + q = 0 \f$, 00230 * for real \e p and \e q coefficients. 00231 * 00232 * @param p coefficient for the x term 00233 * @param q constant term 00234 * 00235 * @param x1 first solution 00236 * @param x2 second solution 00237 * 00238 * @return the number of real solutions. 00239 */ 00240 int quadratic(const double& p, const double& q, 00241 complex<double>& x1, complex<double>& x2) const; 00242 00243 00244 /** 00245 * Solves the equation \f$ x^3 + a*x^2 + b*x + c= 0\f$, 00246 * for real \c a, \c b and \c c coefficients. 00247 * 00248 * @param a coefficient for the x^2 term 00249 * @param b coefficient for the x term 00250 * @param c constant term 00251 * 00252 * @param rex1 real part of the first solution 00253 * @param imx1 imaginary part of the first solution 00254 * @param rex2 real part of the second solution 00255 * @param imx2 imaginary part of the second solution 00256 * @param rex3 real part of the third solution 00257 * @param imx3 imaginary part of the third solution 00258 * 00259 * @return the number of real solutions. 00260 */ 00261 int cubic(const double& a, const double& b, const double& c, 00262 double& rex1, double& imx1, 00263 double& rex2, double& imx2, 00264 double& rex3, double& imx3) const; 00265 00266 /** 00267 * Solves the equation \f$ x^3 + a*x^2 + b*x + c= 0\f$, 00268 * for real \c a, \c b and \c c coefficients. 00269 * 00270 * @param a coefficient for the x^2 term 00271 * @param b coefficient for the x term 00272 * @param c constant term 00273 * 00274 * @param x1 first solution 00275 * @param x2 second solution 00276 * @param x3 third solution 00277 * 00278 * @return the number of real solutions. 00279 */ 00280 int cubic(const double& a, const double& b, const double& c, 00281 complex<double>& x1, 00282 complex<double>& x2, 00283 complex<double>& x3) const; 00284 00285 00286 /** 00287 * General apply method. The described polygon is 00288 * p[0]+p[1]*x + p[2]*x^2 + .. + p[n-1]*x^(n-1), with \a n the size of \a p 00289 * 00290 * @param p coefficients for the polynom 00291 * @param re real parts of the solutions 00292 * @param im imaginary parts of the solutions 00293 * 00294 * \warning at this point, only solutions for polynoms of first, second 00295 * and third degree have being implemented 00296 * 00297 * @return the number of real solutions or negative if an error occurred 00298 */ 00299 virtual int apply(const vector<double>& p, 00300 vector<double>& re, 00301 vector<double>& im) const; 00302 00303 /** 00304 * General apply method. The described polygon is 00305 * p[0]+p[1]*x + p[2]*x^2 + .. + p[n-1]*x^(n-1), with \a n the size of \a p 00306 * 00307 * @param p coefficients for the polynom 00308 * @param roots the solutions 00309 * 00310 * \warning at this point, only solutions for polynoms of first, second 00311 * and third degree have being implemented 00312 * 00313 * @return the number of real solutions 00314 */ 00315 virtual int apply(const vector<double>& p, 00316 vector< complex<double> >& roots) const; 00317 00318 /** 00319 * Solves the quadratic equation \f$ ax^2 + bx + c = 0 \f$, 00320 * for real \e a, \e b and \e c coefficients. 00321 * 00322 * @param a coefficient for the x^2 term 00323 * @param b coefficient for the x term 00324 * @param c constant term 00325 * 00326 * @param rex1 real part of the first solution 00327 * @param imx1 imaginary part of the first solution 00328 * @param rex2 real part of the second solution 00329 * @param imx2 imaginary part of the second solution 00330 * 00331 * @return the number of real solutions. 00332 */ 00333 inline int apply(const double& a, const double& b, const double& c, 00334 double& rex1, double& imx1, 00335 double& rex2, double& imx2) const { 00336 return quadratic(a,b,c,rex1,imx1,rex2,imx2); 00337 } 00338 00339 00340 /** 00341 * Solves the quadratic equation \f$ x^2 + p*x + q = 0 \f$, 00342 * for real \e p and \e q coefficients. 00343 * 00344 * @param p coefficient for the x term 00345 * @param q constant term 00346 * 00347 * @param rex1 real part of the first solution 00348 * @param imx1 imaginary part of the first solution 00349 * @param rex2 real part of the second solution 00350 * @param imx2 imaginary part of the second solution 00351 * 00352 * @return the number of real solutions. 00353 */ 00354 inline int apply(const double& p, const double& q, 00355 double& rex1, double& imx1, 00356 double& rex2, double& imx2) const { 00357 return quadratic(p,q,rex1,imx1,rex2,imx2); 00358 }; 00359 00360 00361 /** 00362 * Solves the equation \f$ x^3 + a*x^2 + b*x + c= 0\f$, 00363 * for real \c a, \c b, \c c and \c d coefficients. 00364 * 00365 * @param a coefficient for the x^2 term 00366 * @param b coefficient for the x term 00367 * @param c constant term 00368 * 00369 * @param rex1 real part of the first solution 00370 * @param imx1 imaginary part of the first solution 00371 * @param rex2 real part of the second solution 00372 * @param imx2 imaginary part of the second solution 00373 * @param rex3 real part of the third solution 00374 * @param imx3 imaginary part of the third solution 00375 * 00376 * @return the number of real solutions. 00377 */ 00378 int apply(const double& a, const double& b, const double& c, 00379 double& rex1, double& imx1, 00380 double& rex2, double& imx2, 00381 double& rex3, double& imx3) const { 00382 return cubic(a,b,c,rex1,imx1,rex2,imx2,rex3,imx3); 00383 } 00384 00385 /** 00386 * copy data of "other" functor. 00387 * @param other the functor to be copied 00388 * @return a reference to this functor object 00389 */ 00390 polynomRoots& copy(const polynomRoots& other); 00391 00392 /** 00393 * alias for copy member 00394 * @param other the functor to be copied 00395 * @return a reference to this functor object 00396 */ 00397 polynomRoots& operator=(const polynomRoots& other); 00398 00399 /** 00400 * returns a pointer to a clone of this functor. 00401 */ 00402 virtual functor* clone() const; 00403 00404 /** 00405 * returns used parameters 00406 */ 00407 const parameters& getParameters() const; 00408 00409 /** 00410 * Laguerre's method to find the roots of a polynom of n-th degree. 00411 * 00412 * @param p polynom coefficients. The polynom represented by this 00413 * vector is p[0] + p[1]*x + p[2]*x^2 + ... + p[n]*x^n, which 00414 * means the size of the vector is n+1. 00415 * @param degree number of elements of p to consider minus one (degree of 00416 * polynom) 00417 * @param root solution found. The value given here is used as a 00418 * first estimation, which will be improved until convergence 00419 * @return number of iterations required until convergence 00420 */ 00421 int laguerre(const vector< complex<double> >& p, 00422 const int degree, 00423 complex<double>& root) const; 00424 00425 /** 00426 * Search in succession for each root, through deflation. 00427 * 00428 * @param p polynom coefficients The polynom represented by this 00429 * vector is p[0] + p[1]*x + p[2]*x^2 + ... + p[n]*x^n, which 00430 * means the size of the vector is n+1. 00431 * @param roots the n solutions found. 00432 * @param polish if true, the found solutions will be "polished", i.e. 00433 * after finding all n solutions, they will be improved using 00434 * again the laguerre method, without deflating the polynom 00435 * @return number of real roots. 00436 */ 00437 int findRoots(const vector<double>& p , 00438 vector< complex<double> >& roots, 00439 const bool polish=true) const; 00440 00441 00442 }; 00443 00444 00445 } 00446 00447 #endif