FastMathFunctions.H

Go to the documentation of this file.
00001 /*!@file Util/FastMathFunctions.H Miscellaneous math functions */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/FastMathFunctions.H $
00035 // $Id: FastMathFunctions.H 12979 2010-03-07 17:10:23Z lior $
00036 //
00037 
00038 #ifndef FASTMATHFUNCTIONS_H_DEFINED
00039 #define FASTMATHFUNCTIONS_H_DEFINED
00040 #include "Util/Assert.H"
00041 #include "Util/Promotions.H"
00042 #include "rutz/compat_cmath.h" // for M_PI, M_E if not present in <cmath>
00043 
00044 // ######################################################################
00045 // ##### Fast Square Root functions
00046 // ######################################################################
00047 /*! @name Fast Square Root Methods
00048 
00049     These are several methods for computing a quick square root
00050     approximation. The order is by decreasing speed / increasing accuracy
00051 
00052     Name           : opperation time relative to sqrt()
00053 
00054     fastSqrt_2     : 1/5
00055     fastSqrt_Bab   : 1/2
00056     fastSqrt_Q3    : 2/3
00057     fastSqrt_Bab_2 : 2/3
00058 
00059     Details:
00060 
00061     fastSqrt_2     - This is a simple log base 2 approximation using a union
00062                      to int and an 4 simple arith operations.
00063 
00064     fastSqrt_Bab   - This is the fastSqrt_2 with a Babylonian step added
00065                      to give it a quadratic improvement.
00066 
00067     fastSqrt_Q3    - This uses the Quake 3 InvRoot function with a
00068                      quick estimation and a single Newton step. This will call
00069                      invSqrt listed below.
00070 
00071     fastSqrt_Bab_2 - This is the fastSqrt_Bab with two Babylonian Steps instead
00072                      of just one.
00073 
00074 */
00075 //@{
00076 
00077 // For Magic Derivation see:
00078 // Chris Lomont
00079 // http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
00080 // Credited to Greg Walsh.
00081 // 32  Bit float magic number
00082 #define SQRT_MAGIC_F 0x5f3759df
00083 
00084 // 64  Bit float magic number
00085 #ifdef LONG_IS_32_BITS
00086 //Fit into 2 longs
00087 #define SQRT_MAGIC_D 0x5fe6ec85e7de30daLL
00088 #else
00089 #define SQRT_MAGIC_D 0x5fe6ec85e7de30da
00090 #endif
00091 
00092 // A constant which can make the fastSqrt_2 method faster
00093 #define KIMS_CONST_F 0x4C000
00094 #define KIMS_CONST_D (KIMS_CONST_F << 29)
00095 // ######################################################################
00096 //! Fast and dirty Log Base 2 appoximiation for square root
00097 /*! This method is most useful if the number is a power of 2. In this case,
00098     the results are accurate. The largest error tends to be with numbers
00099     half way between two powers of 2. So as an example:
00100 
00101     fastSqrt_2(2) and fastSqrt_2(4) will give exact answers while
00102     fastSqrt_2(3) will give 1.5 when the answer should be 1.414
00103 
00104     See: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
00105 
00106     Time savings using this is approx 1/5 the time of a normal square root.
00107 */
00108 inline float fastSqrt_2(const float x)
00109 {
00110   union     // Use a union to operate on a float like an integer
00111   {
00112     int i;
00113     float x;
00114   } u;
00115   u.x = x;
00116   /*
00117   This line is a compressed version if this:
00118 
00119   u.i -= 1<<23;   // Remove last bit so 1.0 gives 1.0
00120   // u.i is now an approximation to logbase2(x)
00121   u.i = u.i >> 1; // divide by 2
00122   u.i += 1<<29;   // add 64 to exponent: (e+127)/2 =(e/2)+63,
00123                   // that represents (e/2)-64 but we want e/2
00124   */
00125   u.i = (1<<29) + (u.i >> 1) - (1<<22) - KIMS_CONST_F;
00126   return u.x;
00127 }
00128 
00129 //! Fast and dirty Log Base 2 appoximiation for square root
00130 inline double fastSqrt_2(const double x)
00131 {
00132 #ifdef INVT_USE_64_BIT
00133 
00134   union      // Use a union to operate on a float like an integer
00135   {
00136 #ifdef LONG_IS_32_BITS
00137     long long i;
00138 #else
00139     long i;
00140 #endif
00141     double x;
00142   } u;
00143   u.x = x;
00144   /*
00145   This line is a compressed version if this:
00146 
00147   u.i -= ((long)1)<<52; // Remove last bit so 1.0 gives 1.0
00148   // u.i is now an approximation to logbase2(x)
00149   u.i = u.i >> 1;       // divide by 2
00150   u.i += ((long)1)<<61; // add 512 to exponent: (e+1023)/2 =(e/2)+511,
00151                         // that represents (e/2)-512 but we want e/2
00152   */
00153 #ifdef LONG_IS_32_BITS
00154   u.i = (((long long)1)<<61) + (u.i >> 1) - (((long long)1)<<51) - KIMS_CONST_D;
00155 #else
00156   u.i = (((long)1)<<61) + (u.i >> 1) - (((long)1)<<51) - KIMS_CONST_D;
00157 #endif
00158 
00159   return u.x;
00160 
00161 #else
00162   return (double)fastSqrt_2((float)x);
00163 #endif
00164 }
00165 
00166 // ######################################################################
00167 //! Fast and dirty Log Base 2 appoximiation with a Babylonian Step Clean up
00168 /*! Time savings using this is approx 1/2 the time of a normal square root. */
00169 inline float fastSqrt_Bab(const float x)
00170 {
00171   union     // Use a union to operate on a float like an integer
00172   {
00173     int i;
00174     float x;
00175   } u;
00176   u.x = x;
00177   u.i = (1<<29) + (u.i >> 1) - (1<<22) - KIMS_CONST_F;  // Log2 Approximation y0
00178   u.x = 0.5f * (u.x + x/u.x);                           // One Babylonian Step
00179 
00180   return u.x;
00181 }
00182 
00183 //! Fast and dirty Log Base 2 appoximiation with a Babylonian Step Clean up
00184 inline double fastSqrt_Bab(const double x)
00185 {
00186 #ifdef INVT_USE_64_BIT
00187   union      // Use a union to operate on a float like an integer
00188   {
00189 #ifdef LONG_IS_32_BITS
00190     long long i;
00191 #else
00192     long i;
00193 #endif
00194 
00195     double x;
00196   } u;
00197   u.x = x;
00198 
00199 #ifdef LONG_IS_32_BITS
00200   u.i = (((long long)1)<<61) + (u.i >> 1) - (((long long)1)<<51) - KIMS_CONST_D;// Log2 Approximation y0
00201 #else
00202   u.i = (((long)1)<<61) + (u.i >> 1) - (((long)1)<<51) - KIMS_CONST_D;// Log2 Approximation y0
00203 #endif
00204   u.x = 0.5F * (u.x + x/u.x);                                         // One Babylonian Step
00205   return u.x;
00206 #else
00207   return (double)fastSqrt_Bab((float)x);
00208 #endif
00209 }
00210 
00211 // ######################################################################
00212 //! Quake 3 Fast Square Root Approximation
00213 /*! The integer-shift approximation produced a relative error of less than 4%,
00214     and the error dropped further to 0.15% with one iteration of Newton's
00215     method on the following line. In computer graphics it is a very efficient
00216     way to normalize a vector.
00217 
00218     Note: This must be a floating point due to the IEEE method for
00219     approx. of sqrt. See the double method below which uses a different
00220     magic constant.
00221 
00222     To get the square root, divide 1 by the final x.
00223     See: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
00224 */
00225 inline float invSqrt(const float x)
00226 {
00227   const float xhalf = 0.5f*x;
00228 
00229   union // get bits for floating value
00230   {
00231     float x;
00232     int i;
00233   } u;
00234   u.x = x;
00235   u.i = SQRT_MAGIC_F - (u.i >> 1);  // gives initial guess y0
00236   return u.x*(1.5f - xhalf*u.x*u.x);// Newton step, repeating increases accuracy
00237 }
00238 
00239 //! Fast Square Root Approximation
00240 /*! Time savings using this is approx 2/3 the time of a normal square root.*/
00241 inline float fastSqrt_Q3(const float x)
00242 {
00243   // return 1.0f / invSqrt(x);
00244   return x * invSqrt(x);
00245 }
00246 
00247 //! Quake 3 Fast Square Root Approximation
00248 inline double invSqrt(const double x)
00249 {
00250 #ifdef INVT_USE_64_BIT
00251   const double xhalf = 0.5F*x;
00252 
00253   union // get bits for floating value
00254   {
00255     double x;
00256 #ifdef LONG_IS_32_BITS
00257     long long i;
00258 #else
00259     long i;
00260 #endif
00261   } u;
00262   u.x = x;
00263   u.i = SQRT_MAGIC_D - (u.i >> 1);  // gives initial guess y0
00264   return u.x*(1.5F - xhalf*u.x*u.x);// Newton step, repeating increases accuracy
00265 
00266 #else
00267   return (double)invSqrt((float)x);
00268 #endif
00269 }
00270 
00271 //! Fast Square Root Approximation
00272 /*! Time savings using this is approx 2/3 the time of a normal square root.*/
00273 inline double fastSqrt_Q3(const double x)
00274 {
00275   // return 1.0F / invSqrt(x);
00276   return x * invSqrt(x);
00277 }
00278 
00279 // ######################################################################
00280 //! Fast and dirty Log Base 2 appoximiation with two Babylonian Steps
00281 /*! Time savings using this is approx 2/3 the time of a normal square root.
00282 
00283     This one gives fairly good estimates with a 50% speed up:
00284 
00285       | sqrt(x)       | Result     | Actual Answer using libm
00286 
00287     0 | 1.000000      | 1.000000   | 1.000000
00288     1 | 2.000000      | 1.414216   | 1.414214
00289     2 | 8.000000      | 2.828431   | 2.828427
00290     3 | 100.000000    | 10.000000  | 10.000000
00291     4 | 3.141593      | 1.772454   | 1.772454
00292     5 | 100000.000000 | 316.227783 | 316.227753
00293     6 | 0.333333      | 0.577350   | 0.577350
00294 */
00295 inline float fastSqrt_Bab_2(const float x)
00296 {
00297   union     // Use a union to operate on a float like an integer
00298   {
00299     int i;
00300     float x;
00301   } u;
00302   u.x = x;
00303   u.i = (1<<29) + (u.i >> 1) - (1<<22) - KIMS_CONST_F; // Log2 Approximation y0
00304 
00305   // Two Babylonian Steps (simplified from:)
00306   // u.x = 0.5f * (u.x + x/u.x);
00307   // u.x = 0.5f * (u.x + x/u.x);
00308   u.x =       u.x + x/u.x;              // First Babylonian Step
00309   u.x = 0.25f*u.x + x/u.x;              // Second Babylonian Step
00310 
00311   return u.x;
00312 }
00313 
00314 //! Fast and dirty Log Base 2 appoximiation with two Babylonian Steps
00315 inline double fastSqrt_Bab_2(const double x)
00316 {
00317 #ifdef INVT_USE_64_BIT
00318   union       // Use a union to operate on a float like an integer
00319   {
00320 #ifdef LONG_IS_32_BITS
00321     long long i;
00322 #else
00323     long i;
00324 #endif
00325     double x;
00326   } u;
00327   u.x = x;
00328 #ifdef LONG_IS_32_BITS
00329   u.i = (((long long)1)<<61) + (u.i >> 1) - (((long long)1)<<51) - KIMS_CONST_D; // Log2 Approximation y0
00330 #else
00331   u.i = (((long)1)<<61) + (u.i >> 1) - (((long)1)<<51) - KIMS_CONST_D; // Log2 Approximation y0
00332 #endif
00333 
00334   // Two Babylonian Steps (simplified from:)
00335   // u.x = 0.5F * (u.x + x/u.x);
00336   // u.x = 0.5F * (u.x + x/u.x);
00337   u.x =       u.x + x/u.x;                 // First Babylonian Step
00338   u.x = 0.25F*u.x + x/u.x;                 // Second Babylonian Step
00339   return u.x;
00340 
00341 #else
00342   return (double)fastSqrt_Bab_2((float)x);
00343 #endif
00344 }
00345 
00346 // ######################################################################
00347 //! This just creates a default function call
00348 
00349 // If we are using the fast math methods then call them, otherwise redirect
00350 // to the standard methods. Election to use fast math is set in configure
00351 // using the switch --enable-fastmath-func
00352 
00353 /* Speed up test:
00354 test-fastMath::main: >>> Time Int SQRT BASELINE - 431742 mcs
00355 test-fastMath::main: >>> Time Int SQRT - 102694 mcs
00356 test-fastMath::main: >>> Time Float SQRT BASELINE - 175870 mcs
00357 test-fastMath::main: >>> Time Float SQRT - 122220 mcs
00358 */
00359 
00360 #ifdef INVT_USE_FASTMATH
00361 
00362 //! This just creates a default function call
00363 inline char fastSqrt(const char x)
00364 {
00365   return static_cast<char>(fastSqrt_2((float)x));
00366 }
00367 
00368 //! This just creates a default function call
00369 inline int fastSqrt(const int x)
00370 {
00371   return static_cast<int>(fastSqrt_Bab((float)x));
00372 }
00373 
00374 //! This just creates a default function call
00375 inline float fastSqrt(const float x)
00376 {
00377   return fastSqrt_Bab_2(x);
00378 }
00379 
00380 //! This just creates a default function call
00381 inline double fastSqrt(const double x)
00382 {
00383   return fastSqrt_Bab_2(x);
00384 }
00385 
00386 #else
00387 
00388 //! This just creates a default function call
00389 inline char fastSqrt(const char x)
00390 {
00391   return static_cast<char>(sqrt(x));
00392 }
00393 
00394 //! This just creates a default function call
00395 inline int fastSqrt(const int x)
00396 {
00397   return static_cast<int>(sqrt(x));
00398 }
00399 
00400 //! This just creates a default function call
00401 inline float fastSqrt(const float x)
00402 {
00403   return static_cast<float>(sqrt(x));
00404 }
00405 
00406 //! This just creates a default function call
00407 inline double fastSqrt(const double x)
00408 {
00409   return static_cast<double>(sqrt(x));
00410 }
00411 
00412 #define ACOS_TABLE_SIZE  513
00413 inline float fastacos(int x)
00414 {
00415 //Got this from opencv
00416 static const float acos_table[ACOS_TABLE_SIZE] = {
00417     3.14159265f, 3.05317551f, 3.01651113f, 2.98834964f, 2.96458497f, 2.94362719f,
00418     2.92466119f, 2.90720289f, 2.89093699f, 2.87564455f, 2.86116621f, 2.84738169f,
00419     2.83419760f, 2.82153967f, 2.80934770f, 2.79757211f, 2.78617145f, 2.77511069f,
00420     2.76435988f, 2.75389319f, 2.74368816f, 2.73372510f, 2.72398665f, 2.71445741f,
00421     2.70512362f, 2.69597298f, 2.68699438f, 2.67817778f, 2.66951407f, 2.66099493f,
00422     2.65261279f, 2.64436066f, 2.63623214f, 2.62822133f, 2.62032277f, 2.61253138f,
00423     2.60484248f, 2.59725167f, 2.58975488f, 2.58234828f, 2.57502832f, 2.56779164f,
00424     2.56063509f, 2.55355572f, 2.54655073f, 2.53961750f, 2.53275354f, 2.52595650f,
00425     2.51922417f, 2.51255441f, 2.50594525f, 2.49939476f, 2.49290115f, 2.48646269f,
00426     2.48007773f, 2.47374472f, 2.46746215f, 2.46122860f, 2.45504269f, 2.44890314f,
00427     2.44280867f, 2.43675809f, 2.43075025f, 2.42478404f, 2.41885841f, 2.41297232f,
00428     2.40712480f, 2.40131491f, 2.39554173f, 2.38980439f, 2.38410204f, 2.37843388f,
00429     2.37279910f, 2.36719697f, 2.36162673f, 2.35608768f, 2.35057914f, 2.34510044f,
00430     2.33965094f, 2.33423003f, 2.32883709f, 2.32347155f, 2.31813284f, 2.31282041f,
00431     2.30753373f, 2.30227228f, 2.29703556f, 2.29182309f, 2.28663439f, 2.28146900f,
00432     2.27632647f, 2.27120637f, 2.26610827f, 2.26103177f, 2.25597646f, 2.25094195f,
00433     2.24592786f, 2.24093382f, 2.23595946f, 2.23100444f, 2.22606842f, 2.22115104f,
00434     2.21625199f, 2.21137096f, 2.20650761f, 2.20166166f, 2.19683280f, 2.19202074f,
00435     2.18722520f, 2.18244590f, 2.17768257f, 2.17293493f, 2.16820274f, 2.16348574f,
00436     2.15878367f, 2.15409630f, 2.14942338f, 2.14476468f, 2.14011997f, 2.13548903f,
00437     2.13087163f, 2.12626757f, 2.12167662f, 2.11709859f, 2.11253326f, 2.10798044f,
00438     2.10343994f, 2.09891156f, 2.09439510f, 2.08989040f, 2.08539725f, 2.08091550f,
00439     2.07644495f, 2.07198545f, 2.06753681f, 2.06309887f, 2.05867147f, 2.05425445f,
00440     2.04984765f, 2.04545092f, 2.04106409f, 2.03668703f, 2.03231957f, 2.02796159f,
00441     2.02361292f, 2.01927344f, 2.01494300f, 2.01062146f, 2.00630870f, 2.00200457f,
00442     1.99770895f, 1.99342171f, 1.98914271f, 1.98487185f, 1.98060898f, 1.97635399f,
00443     1.97210676f, 1.96786718f, 1.96363511f, 1.95941046f, 1.95519310f, 1.95098292f,
00444     1.94677982f, 1.94258368f, 1.93839439f, 1.93421185f, 1.93003595f, 1.92586659f,
00445     1.92170367f, 1.91754708f, 1.91339673f, 1.90925250f, 1.90511432f, 1.90098208f,
00446     1.89685568f, 1.89273503f, 1.88862003f, 1.88451060f, 1.88040664f, 1.87630806f,
00447     1.87221477f, 1.86812668f, 1.86404371f, 1.85996577f, 1.85589277f, 1.85182462f,
00448     1.84776125f, 1.84370256f, 1.83964848f, 1.83559892f, 1.83155381f, 1.82751305f,
00449     1.82347658f, 1.81944431f, 1.81541617f, 1.81139207f, 1.80737194f, 1.80335570f,
00450     1.79934328f, 1.79533460f, 1.79132959f, 1.78732817f, 1.78333027f, 1.77933581f,
00451     1.77534473f, 1.77135695f, 1.76737240f, 1.76339101f, 1.75941271f, 1.75543743f,
00452     1.75146510f, 1.74749565f, 1.74352900f, 1.73956511f, 1.73560389f, 1.73164527f,
00453     1.72768920f, 1.72373560f, 1.71978441f, 1.71583556f, 1.71188899f, 1.70794462f,
00454     1.70400241f, 1.70006228f, 1.69612416f, 1.69218799f, 1.68825372f, 1.68432127f,
00455     1.68039058f, 1.67646160f, 1.67253424f, 1.66860847f, 1.66468420f, 1.66076139f,
00456     1.65683996f, 1.65291986f, 1.64900102f, 1.64508338f, 1.64116689f, 1.63725148f,
00457     1.63333709f, 1.62942366f, 1.62551112f, 1.62159943f, 1.61768851f, 1.61377831f,
00458     1.60986877f, 1.60595982f, 1.60205142f, 1.59814349f, 1.59423597f, 1.59032882f,
00459     1.58642196f, 1.58251535f, 1.57860891f, 1.57470259f, 1.57079633f, 1.56689007f,
00460     1.56298375f, 1.55907731f, 1.55517069f, 1.55126383f, 1.54735668f, 1.54344917f,
00461     1.53954124f, 1.53563283f, 1.53172389f, 1.52781434f, 1.52390414f, 1.51999323f,
00462     1.51608153f, 1.51216900f, 1.50825556f, 1.50434117f, 1.50042576f, 1.49650927f,
00463     1.49259163f, 1.48867280f, 1.48475270f, 1.48083127f, 1.47690845f, 1.47298419f,
00464     1.46905841f, 1.46513106f, 1.46120207f, 1.45727138f, 1.45333893f, 1.44940466f,
00465     1.44546850f, 1.44153038f, 1.43759024f, 1.43364803f, 1.42970367f, 1.42575709f,
00466     1.42180825f, 1.41785705f, 1.41390346f, 1.40994738f, 1.40598877f, 1.40202755f,
00467     1.39806365f, 1.39409701f, 1.39012756f, 1.38615522f, 1.38217994f, 1.37820164f,
00468     1.37422025f, 1.37023570f, 1.36624792f, 1.36225684f, 1.35826239f, 1.35426449f,
00469     1.35026307f, 1.34625805f, 1.34224937f, 1.33823695f, 1.33422072f, 1.33020059f,
00470     1.32617649f, 1.32214834f, 1.31811607f, 1.31407960f, 1.31003885f, 1.30599373f,
00471     1.30194417f, 1.29789009f, 1.29383141f, 1.28976803f, 1.28569989f, 1.28162688f,
00472     1.27754894f, 1.27346597f, 1.26937788f, 1.26528459f, 1.26118602f, 1.25708205f,
00473     1.25297262f, 1.24885763f, 1.24473698f, 1.24061058f, 1.23647833f, 1.23234015f,
00474     1.22819593f, 1.22404557f, 1.21988898f, 1.21572606f, 1.21155670f, 1.20738080f,
00475     1.20319826f, 1.19900898f, 1.19481283f, 1.19060973f, 1.18639955f, 1.18218219f,
00476     1.17795754f, 1.17372548f, 1.16948589f, 1.16523866f, 1.16098368f, 1.15672081f,
00477     1.15244994f, 1.14817095f, 1.14388370f, 1.13958808f, 1.13528396f, 1.13097119f,
00478     1.12664966f, 1.12231921f, 1.11797973f, 1.11363107f, 1.10927308f, 1.10490563f,
00479     1.10052856f, 1.09614174f, 1.09174500f, 1.08733820f, 1.08292118f, 1.07849378f,
00480     1.07405585f, 1.06960721f, 1.06514770f, 1.06067715f, 1.05619540f, 1.05170226f,
00481     1.04719755f, 1.04268110f, 1.03815271f, 1.03361221f, 1.02905939f, 1.02449407f,
00482     1.01991603f, 1.01532509f, 1.01072102f, 1.00610363f, 1.00147268f, 0.99682798f,
00483     0.99216928f, 0.98749636f, 0.98280898f, 0.97810691f, 0.97338991f, 0.96865772f,
00484     0.96391009f, 0.95914675f, 0.95436745f, 0.94957191f, 0.94475985f, 0.93993099f,
00485     0.93508504f, 0.93022170f, 0.92534066f, 0.92044161f, 0.91552424f, 0.91058821f,
00486     0.90563319f, 0.90065884f, 0.89566479f, 0.89065070f, 0.88561619f, 0.88056088f,
00487     0.87548438f, 0.87038629f, 0.86526619f, 0.86012366f, 0.85495827f, 0.84976956f,
00488     0.84455709f, 0.83932037f, 0.83405893f, 0.82877225f, 0.82345981f, 0.81812110f,
00489     0.81275556f, 0.80736262f, 0.80194171f, 0.79649221f, 0.79101352f, 0.78550497f,
00490     0.77996593f, 0.77439569f, 0.76879355f, 0.76315878f, 0.75749061f, 0.75178826f,
00491     0.74605092f, 0.74027775f, 0.73446785f, 0.72862033f, 0.72273425f, 0.71680861f,
00492     0.71084240f, 0.70483456f, 0.69878398f, 0.69268952f, 0.68654996f, 0.68036406f,
00493     0.67413051f, 0.66784794f, 0.66151492f, 0.65512997f, 0.64869151f, 0.64219789f,
00494     0.63564741f, 0.62903824f, 0.62236849f, 0.61563615f, 0.60883911f, 0.60197515f,
00495     0.59504192f, 0.58803694f, 0.58095756f, 0.57380101f, 0.56656433f, 0.55924437f,
00496     0.55183778f, 0.54434099f, 0.53675018f, 0.52906127f, 0.52126988f, 0.51337132f,
00497     0.50536051f, 0.49723200f, 0.48897987f, 0.48059772f, 0.47207859f, 0.46341487f,
00498     0.45459827f, 0.44561967f, 0.43646903f, 0.42713525f, 0.41760600f, 0.40786755f,
00499     0.39790449f, 0.38769946f, 0.37723277f, 0.36648196f, 0.35542120f, 0.34402054f,
00500     0.33224495f, 0.32005298f, 0.30739505f, 0.29421096f, 0.28042645f, 0.26594810f,
00501     0.25065566f, 0.23438976f, 0.21693146f, 0.19796546f, 0.17700769f, 0.15324301f,
00502     0.12508152f, 0.08841715f, 0.00000000f
00503 };
00504 
00505 if (x >= 0 && x<ACOS_TABLE_SIZE)
00506   return acos_table[x];
00507 else
00508   return 0;
00509 
00510 }
00511 
00512 //@}
00513 #endif
00514 // ######################################################################
00515 // ##### Fast Log Function
00516 // ######################################################################
00517 /*! @Fast Log Function
00518 */
00519 //@{
00520 static const double TBL_LOG_P[] = {
00521 /* ONE   */  1.0,
00522 /* TWO52 */  4503599627370496.0,
00523 /* LN2HI */  6.93147180369123816490e-01,        /* 3fe62e42, fee00000 */
00524 /* LN2LO */  1.90821492927058770002e-10,        /* 3dea39ef, 35793c76 */
00525 /* A1    */ -6.88821452420390473170286327331268694251775741577e-0002,
00526 /* A2    */  1.97493380704769294631262255279580131173133850098e+0000,
00527 /* A3    */  2.24963218866067560242072431719861924648284912109e+0000,
00528 /* A4    */ -9.02975906958474405783476868236903101205825805664e-0001,
00529 /* A5    */ -1.47391630715542865104339398385491222143173217773e+0000,
00530 /* A6    */  1.86846544648220058704168877738993614912033081055e+0000,
00531 /* A7    */  1.82277370459347465292410106485476717352867126465e+0000,
00532 /* A8    */  1.25295479915214102994980294170090928673744201660e+0000,
00533 /* A9    */  1.96709676945198275177517643896862864494323730469e+0000,
00534 /* A10   */ -4.00127989749189894030934055990655906498432159424e-0001,
00535 /* A11   */  3.01675528558798333733648178167641162872314453125e+0000,
00536 /* A12   */ -9.52325445049240770778453679668018594384193420410e-0001,
00537 /* B1    */ -1.25041641589283658575482149899471551179885864258e-0001,
00538 /* B2    */  1.87161713283355151891381127914642725337613123482e+0000,
00539 /* B3    */ -1.89082956295731507978530316904652863740921020508e+0000,
00540 /* B4    */ -2.50562891673640253387134180229622870683670043945e+0000,
00541 /* B5    */  1.64822828085258366037635369139024987816810607910e+0000,
00542 /* B6    */ -1.24409107065868340669112512841820716857910156250e+0000,
00543 /* B7    */  1.70534231658220414296067701798165217041969299316e+0000,
00544 /* B8    */  1.99196833784655646937267192697618156671524047852e+0000,
00545 };
00546 
00547 #define        ONE   TBL_LOG_P[0]
00548 #define        TWO52 TBL_LOG_P[1]
00549 #define        LN2HI TBL_LOG_P[2]
00550 #define        LN2LO TBL_LOG_P[3]
00551 #define        A1    TBL_LOG_P[4]
00552 #define        A2    TBL_LOG_P[5]
00553 #define        A3    TBL_LOG_P[6]
00554 #define        A4    TBL_LOG_P[7]
00555 #define        A5    TBL_LOG_P[8]
00556 #define        A6    TBL_LOG_P[9]
00557 #define        A7    TBL_LOG_P[10]
00558 #define        A8    TBL_LOG_P[11]
00559 #define        A9    TBL_LOG_P[12]
00560 #define        A10   TBL_LOG_P[13]
00561 #define        A11   TBL_LOG_P[14]
00562 #define        A12   TBL_LOG_P[15]
00563 #define        B1    TBL_LOG_P[16]
00564 #define        B2    TBL_LOG_P[17]
00565 #define        B3    TBL_LOG_P[18]
00566 #define        B4    TBL_LOG_P[19]
00567 #define        B5    TBL_LOG_P[20]
00568 #define        B6    TBL_LOG_P[21]
00569 #define        B7    TBL_LOG_P[22]
00570 #define        B8    TBL_LOG_P[23]
00571 
00572 static const double _TBL_log[] = {
00573 9.47265623608246343e-02, 1.05567010464380857e+01, -2.35676082856530300e+00,
00574 9.66796869131412717e-02, 1.03434344062203838e+01, -2.33635196153499791e+00,
00575 9.86328118117651004e-02, 1.01386139321308306e+01, -2.31635129573594156e+00,
00576 1.00585936733578435e-01, 9.94174764856737347e+00, -2.29674282498938709e+00,
00577 1.02539062499949152e-01, 9.75238095238578850e+00, -2.27751145544242561e+00,
00578 1.04492186859904843e-01, 9.57009351656812157e+00, -2.25864297726331742e+00,
00579 1.06445312294918631e-01, 9.39449543094380957e+00, -2.24012392529694537e+00,
00580 1.08398437050250693e-01, 9.22522526350104144e+00, -2.22194160843615762e+00,
00581 1.10351562442130582e-01, 9.06194690740703912e+00, -2.20408398741152212e+00,
00582 1.12304686894746625e-01, 8.90434787407592943e+00, -2.18653968262558962e+00,
00583 1.14257811990227776e-01, 8.75213679118525256e+00, -2.16929787526329321e+00,
00584 1.16210936696872255e-01, 8.60504207627572093e+00, -2.15234831939887172e+00,
00585 1.18164061975360682e-01, 8.46280995492959498e+00, -2.13568126444263484e+00,
00586 1.20117187499996322e-01, 8.32520325203277523e+00, -2.11928745022706622e+00,
00587 1.22070312499895098e-01, 8.19200000000703987e+00, -2.10315806829801133e+00,
00588 1.24023436774175100e-01, 8.06299217317146599e+00, -2.08728472499318229e+00,
00589 1.26953123746900931e-01, 7.87692315467275872e+00, -2.06393736501443570e+00,
00590 1.30859374098123454e-01, 7.64179109744297769e+00, -2.03363201254049386e+00,
00591 1.34765623780674720e-01, 7.42028992220936967e+00, -2.00421812948999545e+00,
00592 1.38671874242985771e-01, 7.21126764500034501e+00, -1.97564475345722457e+00,
00593 1.42578124148616536e-01, 7.01369867201821506e+00, -1.94786518986246371e+00,
00594 1.46484374166731490e-01, 6.82666670549979404e+00, -1.92083651719164372e+00,
00595 1.50390624434435488e-01, 6.64935067435644189e+00, -1.89451920694646070e+00,
00596 1.54296874339723084e-01, 6.48101268596180624e+00, -1.86887677685174936e+00,
00597 1.58203124999987427e-01, 6.32098765432149001e+00, -1.84387547036714849e+00,
00598 1.62109374999815342e-01, 6.16867469880220742e+00, -1.81948401724404896e+00,
00599 1.66015624243955634e-01, 6.02352943919619310e+00, -1.79567337310324682e+00,
00600 1.69921874302298687e-01, 5.88505749542848644e+00, -1.77241651049093640e+00,
00601 1.73828124315277527e-01, 5.75280901142480605e+00, -1.74968825924644555e+00,
00602 1.77734374286237506e-01, 5.62637364896854919e+00, -1.72746512253855222e+00,
00603 1.81640624146994889e-01, 5.50537636993989743e+00, -1.70572513658236602e+00,
00604 1.85546874316304788e-01, 5.38947370406942916e+00, -1.68444773712372431e+00,
00605 1.89453124405085355e-01, 5.27835053203882509e+00, -1.66361364967629299e+00,
00606 1.93359374570531595e-01, 5.17171718320401652e+00, -1.64320477712600699e+00,
00607 1.97265624263334577e-01, 5.06930694962380368e+00, -1.62320411193263148e+00,
00608 2.01171874086291030e-01, 4.97087380898513764e+00, -1.60359564135180399e+00,
00609 2.05078123979995308e-01, 4.87619050044336610e+00, -1.58436427985572159e+00,
00610 2.08984373896073439e-01, 4.78504675424820736e+00, -1.56549579585994181e+00,
00611 2.12890623963011144e-01, 4.69724772930228163e+00, -1.54697674768135762e+00,
00612 2.16796874723889421e-01, 4.61261261848719517e+00, -1.52879442500076479e+00,
00613 2.20703124198150608e-01, 4.53097346778917753e+00, -1.51093680996032553e+00,
00614 2.24609374375627030e-01, 4.45217392541970725e+00, -1.49339249945607477e+00,
00615 2.28515625000094036e-01, 4.37606837606657528e+00, -1.47615069024134016e+00,
00616 2.32421873924349737e-01, 4.30252102831546246e+00, -1.45920113655598627e+00,
00617 2.36328123935216378e-01, 4.23140497774241098e+00, -1.44253408394829741e+00,
00618 2.40234375000066919e-01, 4.16260162601510064e+00, -1.42614026966681173e+00,
00619 2.44140623863132178e-01, 4.09600001907347711e+00, -1.41001089239381727e+00,
00620 2.48046874999894917e-01, 4.03149606299383390e+00, -1.39413753858134015e+00,
00621 2.53906248590769879e-01, 3.93846156032078243e+00, -1.37079018013412401e+00,
00622 2.61718748558906533e-01, 3.82089554342693294e+00, -1.34048483059486401e+00,
00623 2.69531249159214337e-01, 3.71014493910979404e+00, -1.31107094300173976e+00,
00624 2.77343749428383191e-01, 3.60563381024826013e+00, -1.28249756949928795e+00,
00625 2.85156249289339359e-01, 3.50684932380819214e+00, -1.25471800582335113e+00,
00626 2.92968749999700462e-01, 3.41333333333682321e+00, -1.22768933094427446e+00,
00627 3.00781248554318814e-01, 3.32467534065511261e+00, -1.20137202743229921e+00,
00628 3.08593748521894806e-01, 3.24050634463533127e+00, -1.17572959680235023e+00,
00629 3.16406249999639899e-01, 3.16049382716409077e+00, -1.15072828980826181e+00,
00630 3.24218749999785061e-01, 3.08433734939963511e+00, -1.12633683668362750e+00,
00631 3.32031248841858584e-01, 3.01176471638753718e+00, -1.10252619147729547e+00,
00632 3.39843749265406558e-01, 2.94252874199264314e+00, -1.07926932798654107e+00,
00633 3.47656249999834799e-01, 2.87640449438338930e+00, -1.05654107474789782e+00,
00634 3.55468749999899247e-01, 2.81318681318761055e+00, -1.03431793796299587e+00,
00635 3.63281249999864997e-01, 2.75268817204403371e+00, -1.01257795132667816e+00,
00636 3.71093749064121570e-01, 2.69473684890124421e+00, -9.91300555400967731e-01,
00637 3.78906249999751032e-01, 2.63917525773369288e+00, -9.70466465976836723e-01,
00638 3.86718748879039009e-01, 2.58585859335407608e+00, -9.50057597243619156e-01,
00639 3.94531249999987899e-01, 2.53465346534661240e+00, -9.30056927638333697e-01,
00640 4.02343749999485523e-01, 2.48543689320706163e+00, -9.10448456251205407e-01,
00641 4.10156249578856991e-01, 2.43809524059864202e+00, -8.91217095348825872e-01,
00642 4.17968749447214571e-01, 2.39252336765021800e+00, -8.72348611340208357e-01,
00643 4.25781248601723117e-01, 2.34862386092395203e+00, -8.53829565534445223e-01,
00644 4.33593749393073047e-01, 2.30630630953458038e+00, -8.35647244566987801e-01,
00645 4.41406248572254134e-01, 2.26548673299152270e+00, -8.17789629001761220e-01,
00646 4.49218749348472501e-01, 2.22608695975035964e+00, -8.00245317566669279e-01,
00647 4.57031249277175089e-01, 2.18803419149470768e+00, -7.83003511263371976e-01,
00648 4.64843748529596368e-01, 2.15126051100659366e+00, -7.66053954531254355e-01,
00649 4.72656248830947701e-01, 2.11570248457175136e+00, -7.49386901356188240e-01,
00650 4.80468748609962581e-01, 2.08130081902951236e+00, -7.32993092000230995e-01,
00651 4.88281249241778237e-01, 2.04800000318021258e+00, -7.16863708730099525e-01,
00652 4.96093748931098810e-01, 2.01574803583926521e+00, -7.00990360175606675e-01,
00653 5.07812497779701388e-01, 1.96923077784079825e+00, -6.77642998396260410e-01,
00654 5.23437498033319737e-01, 1.91044776837204044e+00, -6.47337648285891021e-01,
00655 5.39062498006593560e-01, 1.85507247062801328e+00, -6.17923763020271188e-01,
00656 5.54687498964024250e-01, 1.80281690477552603e+00, -5.89350388745976339e-01,
00657 5.70312499806522322e-01, 1.75342465812909332e+00, -5.61570823110474571e-01,
00658 5.85937497921867001e-01, 1.70666667271966777e+00, -5.34542153929987052e-01,
00659 6.01562498226483444e-01, 1.66233766723853860e+00, -5.08224845014116688e-01,
00660 6.17187498682654212e-01, 1.62025316801528496e+00, -4.82582413587029357e-01,
00661 6.32812500000264566e-01, 1.58024691357958624e+00, -4.57581109246760320e-01,
00662 6.48437499353274216e-01, 1.54216867623689291e+00, -4.33189657120379490e-01,
00663 6.64062498728508976e-01, 1.50588235582451335e+00, -4.09379009344016609e-01,
00664 6.79687498865382267e-01, 1.47126437027210688e+00, -3.86122146934356092e-01,
00665 6.95312498728747119e-01, 1.43820224982050338e+00, -3.63393896015796081e-01,
00666 7.10937499999943157e-01, 1.40659340659351906e+00, -3.41170757402847080e-01,
00667 7.26562499999845568e-01, 1.37634408602179792e+00, -3.19430770766573779e-01,
00668 7.42187500000120126e-01, 1.34736842105241350e+00, -2.98153372318914478e-01,
00669 7.57812499999581890e-01, 1.31958762886670744e+00, -2.77319285416786077e-01,
00670 7.73437498602746576e-01, 1.29292929526503420e+00, -2.56910415591577124e-01,
00671 7.89062500000142664e-01, 1.26732673267303819e+00, -2.36909747078176913e-01,
00672 8.04687500000259015e-01, 1.24271844660154174e+00, -2.17301275689659512e-01,
00673 8.20312499999677036e-01, 1.21904761904809900e+00, -1.98069913762487504e-01,
00674 8.35937499999997113e-01, 1.19626168224299478e+00, -1.79201429457714445e-01,
00675 8.51562499999758749e-01, 1.17431192660583728e+00, -1.60682381690756770e-01,
00676 8.67187500000204725e-01, 1.15315315315288092e+00, -1.42500062607046951e-01,
00677 8.82812500000407896e-01, 1.13274336283133503e+00, -1.24642445206814556e-01,
00678 8.98437499999816813e-01, 1.11304347826109651e+00, -1.07098135556570995e-01,
00679 9.14062499999708455e-01, 1.09401709401744296e+00, -8.98563291221800009e-02,
00680 9.29687500000063949e-01, 1.07563025210076635e+00, -7.29067708080189947e-02,
00681 9.45312499999844014e-01, 1.05785123966959604e+00, -5.62397183230410880e-02,
00682 9.60937500000120459e-01, 1.04065040650393459e+00, -3.98459085470743157e-02,
00683 9.76562499999976685e-01, 1.02400000000002445e+00, -2.37165266173399170e-02,
00684 9.92187500000169420e-01, 1.00787401574785940e+00, -7.84317746085513856e-03,
00685 1.01562500000004907e+00, 9.84615384615337041e-01,  1.55041865360135717e-02,
00686 1.04687500000009237e+00, 9.55223880596930641e-01,  4.58095360313824362e-02,
00687 1.07812500000002154e+00, 9.27536231884039442e-01,  7.52234212376075018e-02,
00688 1.10937499999982481e+00, 9.01408450704367703e-01,  1.03796793681485644e-01,
00689 1.14062500000007416e+00, 8.76712328767066285e-01,  1.31576357788784293e-01,
00690 1.17187500000009659e+00, 8.53333333333263000e-01,  1.58605030176721007e-01,
00691 1.20312499999950173e+00, 8.31168831169175393e-01,  1.84922338493597849e-01,
00692 1.23437500000022027e+00, 8.10126582278336449e-01,  2.10564769107528083e-01,
00693 1.26562500000064615e+00, 7.90123456789720069e-01,  2.35566071313277448e-01,
00694 1.29687500000144706e+00, 7.71084337348537208e-01,  2.59957524438041876e-01,
00695 1.32812499999945932e+00, 7.52941176470894757e-01,  2.83768173130237500e-01,
00696 1.35937500055846350e+00, 7.35632183605830825e-01,  3.07025035705735583e-01,
00697 1.39062499999999467e+00, 7.19101123595508374e-01,  3.29753286372464149e-01,
00698 1.42187500000017564e+00, 7.03296703296616421e-01,  3.51976423157301710e-01,
00699 1.45312500161088876e+00, 6.88172042247866766e-01,  3.73716410902152685e-01,
00700 1.48437500134602307e+00, 6.73684209915422660e-01,  3.94993809147663466e-01,
00701 1.51562499999932343e+00, 6.59793814433284220e-01,  4.15827895143264570e-01,
00702 1.54687500000028200e+00, 6.46464646464528614e-01,  4.36236766775100371e-01,
00703 1.57812500000061906e+00, 6.33663366336385092e-01,  4.56237433481979870e-01,
00704 1.60937500243255216e+00, 6.21359222361793417e-01,  4.75845906381452632e-01,
00705 1.64062500000026312e+00, 6.09523809523711768e-01,  4.95077266798011895e-01,
00706 1.67187500000027911e+00, 5.98130841121395473e-01,  5.13945751102401260e-01,
00707 1.70312500224662178e+00, 5.87155962528224662e-01,  5.32464800188589216e-01,
00708 1.73437500283893620e+00, 5.76576575632799071e-01,  5.50647119589526390e-01,
00709 1.76562500399259092e+00, 5.66371680135198341e-01,  5.68504737613959144e-01,
00710 1.79687500443862880e+00, 5.56521737755718449e-01,  5.86049047473771623e-01,
00711 1.82812500114411280e+00, 5.47008546666207462e-01,  6.03290852063923744e-01,
00712 1.85937500250667465e+00, 5.37815125325376786e-01,  6.20240411099985067e-01,
00713 1.89062500504214515e+00, 5.28925618424108568e-01,  6.36907464903988974e-01,
00714 1.92187500371610143e+00, 5.20325202245941476e-01,  6.53301273946326866e-01,
00715 1.95312500494870611e+00, 5.11999998702726389e-01,  6.69430656476366792e-01,
00716 1.98437500351688123e+00, 5.03937006980894941e-01,  6.85304004871206018e-01,
00717 2.03125000000003997e+00, 4.92307692307682621e-01,  7.08651367095930240e-01,
00718 2.09375000579615866e+00, 4.77611938976327366e-01,  7.38956719359554093e-01,
00719 2.15625000000061062e+00, 4.63768115941897652e-01,  7.68370601797816022e-01,
00720 2.21875000323311955e+00, 4.50704224695355204e-01,  7.96943975698769513e-01,
00721 2.28125000853738547e+00, 4.38356162743050726e-01,  8.24723542091080120e-01,
00722 2.34374999999916556e+00, 4.26666666666818573e-01,  8.51752210736227866e-01,
00723 2.40625000438447856e+00, 4.15584414827170512e-01,  8.78069520876078258e-01,
00724 2.46875000884389584e+00, 4.05063289688167072e-01,  9.03711953249632494e-01,
00725 2.53124999999940403e+00, 3.95061728395154743e-01,  9.28713251872476775e-01,
00726 2.59375000434366632e+00, 3.85542168029044230e-01,  9.53104706671537905e-01,
00727 2.65625000734081196e+00, 3.76470587194880080e-01,  9.76915356454189698e-01,
00728 2.71875000787161980e+00, 3.67816090889081959e-01,  1.00017221875016560e+00,
00729 2.78125001557333462e+00, 3.59550559784484969e-01,  1.02290047253181449e+00,
00730 2.84375001147093220e+00, 3.51648350229895601e-01,  1.04512360775085789e+00,
00731 2.90625000771072894e+00, 3.44086020592463127e-01,  1.06686359300668343e+00,
00732 2.96875001371853831e+00, 3.36842103706616824e-01,  1.08814099342179560e+00,
00733 3.03125000512624965e+00, 3.29896906658595002e-01,  1.10897507739479018e+00,
00734 3.09375001373132807e+00, 3.23232321797685962e-01,  1.12938395177327244e+00,
00735 3.15625001204422961e+00, 3.16831681959289180e-01,  1.14938461785752644e+00,
00736 3.21875000888250318e+00, 3.10679610793130057e-01,  1.16899308818952186e+00,
00737 3.28125000000102052e+00, 3.04761904761809976e-01,  1.18822444735810784e+00,
00738 3.34375001587649123e+00, 2.99065419140752298e-01,  1.20709293641028914e+00,
00739 3.40625000791328070e+00, 2.93577980969346064e-01,  1.22561198175258212e+00,
00740 3.46875000615970519e+00, 2.88288287776354346e-01,  1.24379430028837845e+00,
00741 3.53125000516822674e+00, 2.83185840293502689e-01,  1.26165191737618265e+00,
00742 3.59375001425228779e+00, 2.78260868461675415e-01,  1.27919622952937750e+00,
00743 3.65625001719730669e+00, 2.73504272217836075e-01,  1.29643803670156643e+00,
00744 3.71875000856489324e+00, 2.68907562405871714e-01,  1.31338759261496740e+00,
00745 3.78125001788371806e+00, 2.64462808666557803e-01,  1.33005464752659286e+00,
00746 3.84375001532508964e+00, 2.60162600588744020e-01,  1.34644845655970613e+00,
00747 3.90625000429340918e+00, 2.55999999718627136e-01,  1.36257783560168733e+00,
00748 3.96875001912740766e+00, 2.51968502722644594e-01,  1.37845118847836900e+00,
00749 4.06250002536431332e+00, 2.46153844616978895e-01,  1.40179855389937913e+00,
00750 4.18750001743208244e+00, 2.38805969155131859e-01,  1.43210390131407017e+00,
00751 4.31250002253733200e+00, 2.31884056759177282e-01,  1.46151778758352613e+00,
00752 4.43750000671406397e+00, 2.25352112335092170e-01,  1.49009115631456268e+00,
00753 4.56250002627485340e+00, 2.19178080929562313e-01,  1.51787072466748185e+00,
00754 4.68750001185115028e+00, 2.13333332793974317e-01,  1.54489939382477459e+00,
00755 4.81250001682742301e+00, 2.07792207065640028e-01,  1.57121670311050998e+00,
00756 4.93750000000042366e+00, 2.02531645569602875e-01,  1.59685913022732606e+00,
00757 5.06249999999927613e+00, 1.97530864197559108e-01,  1.62186043243251454e+00,
00758 5.18750002327641901e+00, 1.92771083472381588e-01,  1.64625189004383721e+00,
00759 5.31250002381002329e+00, 1.88235293273997795e-01,  1.67006253873242194e+00,
00760 5.43750000000577405e+00, 1.83908045976816203e-01,  1.69331939641586438e+00,
00761 5.56250002193114934e+00, 1.79775280190080267e-01,  1.71604765143503712e+00,
00762 5.68749999999938005e+00, 1.75824175824194989e-01,  1.73827078427695980e+00,
00763 5.81250002749782002e+00, 1.72043009938785768e-01,  1.76001077564428243e+00,
00764 5.93749999999874767e+00, 1.68421052631614471e-01,  1.78128816936054868e+00,
00765 6.06250001966917473e+00, 1.64948453073088669e-01,  1.80212225950800153e+00,
00766 6.18750003004243609e+00, 1.61616160831459688e-01,  1.82253113275015188e+00,
00767 6.31250002448351388e+00, 1.58415840969730465e-01,  1.84253179848005466e+00,
00768 6.43750001359968849e+00, 1.55339805497076044e-01,  1.86214026810242750e+00,
00769 6.56250003345742350e+00, 1.52380951604072529e-01,  1.88137163301601618e+00,
00770 6.68750002403557531e+00, 1.49532709742937614e-01,  1.90024011581622965e+00,
00771 6.81250003423489581e+00, 1.46788990088028509e-01,  1.91875916501466826e+00,
00772 6.93750003062940923e+00, 1.44144143507740546e-01,  1.93694148348760287e+00,
00773 7.06250002747386052e+00, 1.41592919803171097e-01,  1.95479910036266347e+00,
00774 7.18750003617887856e+00, 1.39130434082284093e-01,  1.97234341115705192e+00,
00775 7.31250000000050537e+00, 1.36752136752127301e-01,  1.98958521255804399e+00,
00776 7.43750002212249761e+00, 1.34453781112678528e-01,  2.00653477384620160e+00,
00777 7.56250003604752941e+00, 1.32231404328381430e-01,  2.02320182812357530e+00,
00778 7.68750005007207449e+00, 1.30081299965731312e-01,  2.03959563964607682e+00,
00779 7.81249996125652668e+00, 1.28000000634773070e-01,  2.05572501010335529e+00,
00780 7.93750005224239974e+00, 1.25984251139310915e-01,  2.07159837080052966e+00,
00781 8.12500004244456164e+00, 1.23076922433975874e-01,  2.09494573343974722e+00,
00782 8.37500006149772425e+00, 1.19402984197849338e-01,  2.12525108505414195e+00,
00783 8.62500006593247370e+00, 1.15942028099206410e-01,  2.15466497056176820e+00,
00784 8.87500007743793873e+00, 1.12676055354884341e-01,  2.18323834408688100e+00,
00785 9.12500001754142609e+00, 1.09589040885222130e-01,  2.21101790139090326e+00,
00786 9.37500007707016181e+00, 1.06666665789779500e-01,  2.23804658007729174e+00,
00787 9.62500004426353151e+00, 1.03896103418305616e-01,  2.26436388477265638e+00,
00788 9.87500006518495788e+00, 1.01265822116353585e-01,  2.29000631738819393e+00,
00789 1.01250000000026539e+01, 9.87654320987395445e-02,  2.31500761299286495e+00,
00790 1.03750000409819823e+01, 9.63855417879450060e-02,  2.33939907006683256e+00,
00791 1.06250000362555337e+01, 9.41176467376672460e-02,  2.36320971822276604e+00,
00792 1.08750000879032314e+01, 9.19540222452362582e-02,  2.38646658505780351e+00,
00793 1.11250000697274576e+01, 8.98876398860551373e-02,  2.40919483431994053e+00,
00794 1.13750000462194141e+01, 8.79120875548795450e-02,  2.43141796890025930e+00,
00795 1.16250000714972366e+01, 8.60215048472860316e-02,  2.45315795762371991e+00,
00796 1.18750000788855150e+01, 8.42105257563797310e-02,  2.47443535656369562e+00,
00797 1.21250000895724916e+01, 8.24742261948517991e-02,  2.49526944421096886e+00,
00798 1.23750000985058719e+01, 8.08080801648427965e-02,  2.51567831641482442e+00,
00799 1.26250000894226950e+01, 7.92079202310506381e-02,  2.53567898224440924e+00,
00800 1.28750000768594433e+01, 7.76699024489580225e-02,  2.55528745251946532e+00,
00801 1.31250000578007420e+01, 7.61904758549435401e-02,  2.57451881288155349e+00,
00802 1.33750000809310077e+01, 7.47663546877819496e-02,  2.59338729883298669e+00,
00803 1.36250000915049636e+01, 7.33944949199294983e-02,  2.61190634726526838e+00,
00804 1.38750000830616607e+01, 7.20720716406179490e-02,  2.63008866561892418e+00,
00805 1.41249999999960103e+01, 7.07964601770111474e-02,  2.64794627703222218e+00,
00806 1.43750000290097564e+01, 6.95652172509168693e-02,  2.66549058870148414e+00,
00807 1.46250000868097665e+01, 6.83760679702078294e-02,  2.68273239905363070e+00,
00808 1.48750000966053975e+01, 6.72268903196987927e-02,  2.69968195792617394e+00,
00809 1.51250001097012756e+01, 6.61157019998031836e-02,  2.71634901116988203e+00,
00810 1.53750000510427132e+01, 6.50406501905787804e-02,  2.73274281701243282e+00,
00811 1.56250001080665442e+01, 6.39999995573594382e-02,  2.74887220253872400e+00,
00812 1.58750000434989929e+01, 6.29921258116476201e-02,  2.76474554751884938e+00,
00813 1.62500000641781739e+01, 6.15384612954199342e-02,  2.78809291272517257e+00,
00814 1.67500001015987401e+01, 5.97014921751882754e-02,  2.81839826433667184e+00,
00815 1.72500001048300184e+01, 5.79710141404578272e-02,  2.84781214955447126e+00,
00816 1.77500001262529885e+01, 5.63380277682904579e-02,  2.87638552303426920e+00,
00817 1.82500001543340602e+01, 5.47945200845665337e-02,  2.90416508848516131e+00,
00818 1.87500001096404212e+01, 5.33333330214672482e-02,  2.93119375826390893e+00,
00819 1.92500001680268191e+01, 5.19480514946147609e-02,  2.95751106946245912e+00,
00820 1.97500000329124035e+01, 5.06329113080278073e-02,  2.98315349301358168e+00,
00821 2.02500001270002485e+01, 4.93827157396732261e-02,  3.00815479982416534e+00,
00822 2.07500001519906796e+01, 4.81927707313324349e-02,  3.03254625400155930e+00,
00823 2.12500001425219267e+01, 4.70588232137922752e-02,  3.05635690207734001e+00,
00824 2.17500000758314478e+01, 4.59770113339538697e-02,  3.07961376102119644e+00,
00825 2.22500001767207358e+01, 4.49438198677525880e-02,  3.10234201655475417e+00,
00826 2.27500001365873317e+01, 4.39560436921389575e-02,  3.12456515140079816e+00,
00827 2.32500001697599998e+01, 4.30107523741288036e-02,  3.14630513933487066e+00,
00828 2.37500001766865303e+01, 4.21052628446554611e-02,  3.16758253792008304e+00,
00829 };
00830 
00831 #define        HIWORD                1
00832 #define        LOWORD                0
00833 
00834 //! Fast Log - Stripped version of libm's Log(x)
00835 /*! This is the libm log stripped down with slightly less precision and
00836     no handling for inf, 0 etc.
00837 
00838     For an idea of how this works see:
00839 
00840     http://www.informatik.uni-trier.de/Reports/TR-08-2004/rnc6_07_dinechin.pdf
00841 
00842     This is about 15% faster than the standard log()
00843 */
00844 #ifdef INVT_USE_FASTMATH
00845 inline double fastLog(const double x)
00846 {
00847   union
00848   {
00849     int    i[2];
00850     double x;
00851   } u;
00852 
00853   u.x = x;
00854 
00855   /* get exponent part, store in dn */
00856   const int hx = u.i[HIWORD];     // Get the top half of the double
00857   const int ix = hx & 0x7fffffff; // condition ix
00858   double dn    = (double)((ix >> 20) - 0x3ff); // Shift to get E
00859 
00860   /* Now we take advantage of the float point identity:
00861 
00862      log(x) = E × log(2) + log(y)
00863 
00864      Where E is the exponent part of the float and y is from the mentisa.
00865 
00866      y is then set to be on the interval from 11/16 to 23/16 using
00867      a bit shift to divide it by 2.
00868 
00869      log(y) needs to be scaled and approximated on a table. Then we use the
00870      Horner scheme polynomial to approximated the final log
00871   */
00872 
00873   const double dn1 = dn * LN2HI;                       // Low Order E * log(2)
00874   int i            = (ix & 0x000fffff) | 0x3ff00000;   // scale x to [1,2]
00875   u.i[HIWORD]      = i;                                // copy back E
00876   i                = (i - 0x3fb80000) >> 15;           // mantisa table addr
00877   const double *tb = (double *)_TBL_log + (i + i + i); // Get table const's
00878   const double s   = (u.x - tb[0]) * tb[1];            // initial estimate
00879   dn               = dn * LN2LO + tb[2];               // High order E * log(2)
00880 
00881   // 8th order Polynomial in Horner form
00882   return (dn1 + (dn + ((B1 * s) * (B2 + s * (B3 + s))) *
00883                  (((B4 + s * B5) + (s * s) * (B6 + s)) *
00884                   (B7 + s * (B8 + s)))));
00885 
00886 };
00887 #else
00888 inline double fastLog(const double x)
00889 {
00890   return log(x);
00891 }
00892 #endif
00893 #undef        ONE
00894 #undef        TWO52
00895 #undef        LN2HI
00896 #undef        LN2LO
00897 #undef        A1
00898 #undef        A2
00899 #undef        A3
00900 #undef        A4
00901 #undef        A5
00902 #undef        A6
00903 #undef        A7
00904 #undef        A8
00905 #undef        A9
00906 #undef        A10
00907 #undef        A11
00908 #undef        A12
00909 #undef        B1
00910 #undef        B2
00911 #undef        B3
00912 #undef        B4
00913 #undef        B5
00914 #undef        B6
00915 #undef        B7
00916 #undef        B8
00917 #undef        HIWORD
00918 #undef        LOWORD
00919 
00920 #endif
00921 
Generated on Sun May 8 08:06:58 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3