Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

math.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------+
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2002  Qgar Project, LORIA                             |
00004  |                                                                     |
00005  | This library is free software; you can redistribute it and/or       |
00006  | modify it under the terms of the GNU Lesser General Public          |
00007  | License version 2.1, as published by the Free Software Foundation.  |
00008  |                                                                     |
00009  | This library is distributed in the hope that it will be useful,     |
00010  | but WITHOUT ANY WARRANTY; without even the implied warranty of      |
00011  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                |
00012  | See the GNU Lesser General Public License for more details.         |
00013  |                                                                     |
00014  | The GNU Lesser General Public License is included in the file       |
00015  | LICENSE.LGPL, in the root directory of the Qgar packaging. See      |
00016  | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. |
00017  | To receive a paper copy, write to the Free Software Foundation,     |
00018  | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.       |
00019  |                                                                     |
00020  | Contact Project Qgar for any information:                           |
00021  |   LORIA - équipe Qgar                                               |
00022  |   B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France                |
00023  |   email: qgar-contact@loria.fr                                      |
00024  |   http://www.qgar.org/                                              |
00025  *---------------------------------------------------------------------*/
00026 
00027 
00028 /**
00029  * @file  math.C
00030  * @brief Implementation of utilities for mathematical operations.
00031  *
00032  * See file math.H for the interface.
00033  *
00034  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00035  * @date   December 06, 2004  18:08
00036  * @since  Qgar 2.2
00037  */
00038 
00039 
00040 
00041 // STL
00042 #include <limits>
00043 // QGAR
00044 #include <qgarlib/math.H>
00045 
00046 
00047 
00048 namespace qgar
00049 {
00050 
00051 
00052 /*---------------------------------------------------------------------*
00053  |                                                                     |
00054  |                    C  L  A  S  S      M  A  T  H                    |
00055  |                                                                     |
00056  *---------------------------------------------------------------------*/
00057 
00058 
00059 // ---------------------------------------------------------------------
00060 // CONSTANTS TO PRESERVE COMPATIBILITY WITH WINDOWS OS
00061 // ----------------------------------------------------------------------
00062 
00063 
00064 // Maximum double number
00065 const double
00066 Math::QG_DOUBLE_MAX = 1.79769313486231570e+308;
00067 
00068 // Minimum double number
00069 const double
00070 Math::QG_DOUBLE_MIN = 4.94065645841246544e-324;
00071 
00072 // Maximum float number.
00073 const float
00074 Math::QG_FLOAT_MAX  = 3.40282346638528860e+38;
00075 
00076 // Minimum double number
00077 const float
00078 Math::QG_FLOAT_MIN  = 1.40129846432481707e-45;
00079 
00080 
00081 // ----------------------------------------------------------------------
00082 // CONSTANTS RELATED TO E
00083 // ----------------------------------------------------------------------
00084 
00085 // ALL VALUES COMPUTED BY MAPLE
00086 // ============================
00087 
00088 
00089 // E            = 2.718281828459045235360287471352662497757
00090 const double
00091 Math::QG_E      = 2.7182818284590452354;
00092 
00093 
00094 // log_2(E)     = 1.442695040888963407359924681001892137426
00095 const double
00096 Math::QG_LOG2E  = 1.4426950408889634074;
00097 
00098 // log_10(E)    = 0.434294481903251827651128918916605082294
00099 const double
00100 Math::QG_LOG10E = 0.43429448190325182765;
00101 
00102 // Log_E(2)     = 0.693147180559945309417232121458176568075
00103 const double
00104 Math::QG_LN2    = 0.69314718055994530942;
00105 
00106 // Log_E(10)    = 2.302585092994045684017991454684364207601
00107 const double
00108 Math::QG_LN10   = 2.30258509299404568402;
00109 
00110 
00111 // ----------------------------------------------------------------------
00112 // CONSTANTS RELATED TO PI
00113 // ----------------------------------------------------------------------
00114 
00115 // ALL VALUES COMPUTED BY MAPLE
00116 
00117 
00118 // PI               = 3.141592653589793238462643383279502884197
00119 const double
00120 Math::QG_PI         = 3.14159265358979323846;
00121 
00122 // PI/2             = 1.570796326794896619231321691639751442098
00123 const double
00124 Math::QG_PI_2       = 1.57079632679489661923; 
00125 
00126 // PI/3             = 1.047197551196597746154214461093167628066
00127 const double
00128 Math::QG_PI_3       = 1.04719755119659774615;
00129 
00130 // PI/4             = 0.7853981633974483096156608458198757210492
00131 const double
00132 Math::QG_PI_4       = 0.78539816339744830962;
00133 
00134 // PI/6             = 0.5235987755982988730771072305465838140329
00135 const double
00136 Math::QG_PI_6       = 0.52359877559829887308;
00137 
00138 // 2*PI             = 6.283185307179586476925286766559005768394
00139 const double
00140 Math::QG_2PI        = 6.28318530717958647692;
00141 
00142 
00143 // sqrt(2*PI)       = 2.506628274631000502415765284811045253008
00144 const double
00145 Math::QG_SQRT_2PI   = 2.50662827463100050242;
00146 
00147 // sqrt(PI)         = 1.772453850905516027298167483341145182798
00148 const double
00149 Math::QG_SQRT_PI    = 1.77245385090551602730;
00150 
00151 
00152 // 1/(2*PI)         = 0.1591549430918953357688837633725143620344
00153 const double
00154 Math::QG_1_2PI      = 0.15915494309189533577;
00155 
00156 // 1/PI             = 0.3183098861837906715377675267450287240689
00157 const double
00158 Math::QG_1_PI       = 0.31830988618379067154; 
00159 
00160 // 1/sqrt(PI)       = 0.5641895835477562869480794515607725858441
00161 const double
00162 Math::QG_1_SQRT_PI  = 0.56418958354775628695;
00163 
00164 // 1/sqrt(2*PI)     = 0.3989422804014326779399460599343818684758
00165 const double
00166 Math::QG_1_SQRT_2PI = 0.39894228040143267794;
00167 
00168 
00169 // 2/PI             = 0.6366197723675813430755350534900574481378
00170 const double
00171 Math::QG_2_PI       = 0.63661977236758134308;
00172 
00173 // 2/sqrt(PI)       = 1.1283791670955125738961589031215451716881
00174 const double
00175 Math::QG_2_SQRT_PI  = 1.12837916709551257390;
00176 
00177 
00178 // ----------------------------------------------------------------------
00179 // CONSTANTS RELATED TO SQRT(2)
00180 // ----------------------------------------------------------------------
00181 
00182 // ALL VALUES COMPUTED BY MAPLE
00183 
00184 
00185 // sqrt(2)           = 1.414213562373095048801688724209698078570
00186 const double
00187 Math::QG_SQRT_2      = 1.41421356237309504880;
00188 
00189 // 1/sqrt(2)         = 0.7071067811865475244008443621048490392847
00190 const double
00191 Math::QG_1_SQRT_2    = 0.70710678118654752440; 
00192 
00193 
00194 // ----------------------------------------------------------------------
00195 // CONSTANTS RELATED TO SQRT(3)
00196 // ----------------------------------------------------------------------
00197 
00198 // ALL VALUES COMPUTED BY MAPLE
00199 
00200 
00201 // sqrt(3)           = 1.732050807568877293527446341505872366943
00202 const double
00203 Math::QG_SQRT_3      = 1.73205080756887729353;
00204 
00205 // 1/sqrt(3)         = 0.5773502691896257645091487805019574556475
00206 const double
00207 Math::QG_1_SQRT_3    = 0.57735026918962576451;
00208 
00209 
00210 // ----------------------------------------------------------------------
00211 // CONSTANTS FOR CONVERSIONS
00212 // ----------------------------------------------------------------------
00213 
00214 // ALL VALUES COMPUTED BY MAPLE
00215 
00216 
00217 // To convert radians to degrees: 180 / PI
00218 const double
00219 Math::QG_RADIANS_TO_DEGREES = 57.2957795130823208768;
00220 
00221 // To convert degrees to radians: PI / 180
00222 const double
00223 Math::QG_DEGREES_TO_RADIANS =  0.01745329251994329577;
00224 
00225 
00226 // ----------------------------------------------------------------------
00227 // LIMITS
00228 // ----------------------------------------------------------------------
00229 
00230 
00231 // Square root of the maximum positive integer coded on 4 bytes
00232 const int
00233 Math::QG_SQRT_MAX_INT16b = 46340;
00234 
00235 
00236 // ---------------------------------------------------------------------
00237 // THRESHOLDS FOR (IN)EQUALITY TESTS
00238 // ---------------------------------------------------------------------
00239 
00240 
00241 // Threshold for double numbers
00242 double
00243 Math::_s_epsilon_double = 0.0001;
00244 
00245 
00246 // Threshold for float numbers
00247 float
00248 Math::_s_epsilon_float = 0.0001f;
00249 
00250 
00251 // Threshold for integer numbers
00252 int
00253 Math::_s_epsilon_int = 1;
00254 
00255 // Threshold for angles in radians
00256 // 0.005 radian ~ 0.25 degree
00257 double
00258 Math::_s_epsilon_radian = 0.005;
00259 
00260 // Threshold for angles in degrees
00261 // 0.25 degree ~ 0.005 radian
00262 double
00263 Math::_s_epsilon_degree = 0.25;
00264 
00265 
00266 // ---------------------------------------------------------------------
00267 // THRESHOLDS FOR NUMERIC CALCULUS
00268 // ---------------------------------------------------------------------
00269 
00270 
00271 // Relative error for floating point numeric calculus
00272 // The default value corresponds to 12 significant figures
00273 double
00274 Math::_s_rel_error_fp = 1.e-12;
00275 
00276 
00277 
00278 
00279 /***********************************************************************
00280  *                                                                     *
00281  *                  G L O B A L   F U N C T I O N S                    *
00282  *                                                                     *
00283  ***********************************************************************/
00284 
00285 
00286 
00287 // *********************************************************************
00288 // ERROR FUNCTIONS
00289 // *********************************************************************
00290 
00291 
00292 // Code inspired by various pieces of free code
00293 
00294 
00295 // COMPUTE THE ERROR FUNCTION OF THE ARGUMENT
00296 //
00297 // erf(x) = 1 - erfc(x)
00298 //        = 2/sqrt(pi) * integral_0^x e^{-t^2} dt
00299 //
00300 // -1 <= erf(x) <= 1
00301 //
00302 // For |x| <= 2.2, the integral is calculated as:
00303 //
00304 //  x - x^3/3 + x^5/(5*2!) - x^7/(7*3!) + ...
00305 //
00306 double
00307 qgErf(double x)
00308 {
00309   // Use erfc(x) when |x| > 2.2
00310   if (fabs(x) > 2.2)
00311     {
00312       return 1. - qgErfc(x);
00313     }
00314 
00315   double sum  = x;
00316   double term = x;
00317   double xsqr = x * x;
00318 
00319   int iCnt = 1;
00320 
00321   do
00322     {
00323       term *= xsqr / iCnt;
00324       sum -= term / ((2 * iCnt) + 1);
00325       ++iCnt;
00326 
00327       term *= xsqr / iCnt;
00328       sum += term / ((2 * iCnt) + 1);
00329       ++iCnt;
00330     }
00331   while (fabs(term/sum) > Math::relError());
00332 
00333   return Math::QG_2_SQRT_PI * sum;
00334 }
00335 
00336 
00337 // COMPUTE THE COMPLEMENTARY ERROR FUNCTION OF THE ARGUMENT
00338 //
00339 // erfc(x) = 1 - erf(x)
00340 //         = 2/sqrt(pi) * integral_x^infinity  e^{-t^2} dt
00341 //
00342 // 0 <= erfc(x) <= 2
00343 //
00344 // For x >= 2.2, erfc(x) is calculated as:
00345 //
00346 //    e^{-x^2}/sqrt(pi)
00347 //  * 
00348 //    (1 / (x + (2/2 / (x + (3/2 / x + (4/2 / (x +...)))))))
00349 //
00350 double
00351 qgErfc(double x)
00352 {
00353   // Use erf(x) when |x| < 2.2
00354   if (fabs(x) < 2.2)
00355     {
00356       return 1. - qgErf(x);
00357     }
00358 
00359   // The calculus hereafter is only valid for x >= 0
00360   //
00361   // It would be certainly better to use function signbit()
00362   // from <cmath>, but this function is not (yet) in the standard
00363   // if (signbit(x))
00364   if (x < 0.)
00365     {
00366       return 2.0 - qgErfc(-x);
00367     }
00368 
00369   // Numerator
00370   double n = 1.;
00371   // Last two convergent numerators
00372   double n1 = 1.;
00373   double n2 = x;
00374   // Last two convergent denominators
00375   double d1 = x;
00376   double d2 = (x * x) + 0.5;
00377   // Last two convergents quotients: n1/d1 and n2/d2
00378   double nd1;
00379   double nd2 = n2 / d2;
00380 
00381   do
00382     {
00383       double tmp = (n1 * n) + (n2 * x);
00384       n1 = n2;
00385       n2 = tmp;
00386 
00387       tmp = (d1 * n) + (d2 * x);
00388       d1 = d2;
00389       d2 = tmp;
00390 
00391       nd1 = nd2;
00392       nd2 = n2 / d2;
00393 
00394       n += 0.5;
00395     }
00396   while ((fabs(nd1 - nd2) / nd2) > Math::relError());
00397 
00398   return Math::QG_1_SQRT_PI * exp(-x * x) * nd2;
00399 }
00400 
00401 
00402 // *********************************************************************
00403 
00404 } // namespace qgar