Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/math/math.h

Go to the documentation of this file.
00001 //  more/math.h -- various mathematical functions
00002 //  Copyright (C) 1998--2002  Petter Urkedal
00003 //
00004 //  This file is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This file 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.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 //
00018 //  As a special exception, you may use this file as part of a free
00019 //  software library without restriction.  Specifically, if other files
00020 //  instantiate templates or use macros or inline functions from this
00021 //  file, or you compile this file and link it with other files to
00022 //  produce an executable, this file does not by itself cause the
00023 //  resulting executable to be covered by the GNU General Public
00024 //  License.  This exception does not however invalidate any other
00025 //  reasons why the executable file might be covered by the GNU General
00026 //  Public License.
00027 //
00028 //  $Id: math.h,v 1.2 2002/08/24 13:53:19 petter_urkedal Exp $
00029 
00030 //  This file is primarily meant for signatures of float, double and
00031 //  long double.  But some generic templates may be defined here.
00032 
00033 #ifndef MORE_MATH_MATH_H
00034 #define MORE_MATH_MATH_H
00035 
00036 #include <stdexcept>
00037 #include <string>
00038 #include <more/bits/config.h>
00039 #include <more/bits/mathbits.h>
00040 #include <more/bits/infnan.h>
00041 #include <cmath>
00042 #include <cstdlib>
00043 #include <cfloat>
00044 
00045 namespace more {
00046 namespace math {
00047 
00048   extern "C" {
00049     double besjr(int, double);
00050     double besIr(double, double);
00051     double besir(int, double);
00052     double lagLc(int, int);
00053   }
00054 
00055   using std::ceil;  using std::floor;
00056   using std::sin;   using std::cos;   using std::tan;
00057   using std::asin;  using std::acos;  using std::atan;
00058   using std::sinh;  using std::cosh;  using std::tanh;
00059   using std::exp;   using std::log;   using std::log10;
00060   using std::sqrt;
00061   using std::fabs;  using std::abs;
00062 #ifdef CXX_HAVE_STD_DRAND48
00063   using std::drand48; using std::srand48;
00064 #elif CXX_HAVE_DRAND48
00065   using ::drand48; using ::srand48;
00066 #endif
00067 
00068   using std::atan2;
00069   using std::fmod;
00070   using std::ldexp;
00071   using std::frexp;
00072   using std::pow;
00073 
00074 
00075   /** Numerical constants.
00076    **
00077    ** The names of the constants are created in the following way.
00078    **
00079    ** Operators and numbers are separated by spaces.  Operators
00080    ** applies to the following item(s).  Binary operators are
00081    ** <ul>
00082    **     <li>\c f — fraction
00083    **     <li>\c p — product
00084    **     <li>\c x — exponentiation; \c x_a_b means <tt>pow(a, b)</tt>
00085    ** </ul>
00086    ** To express two binary operators applied to three arguments we
00087    ** use \c pp_x_y_z instead of \c p_p_x_y_z or \c p_x_p_y_z, etc.
00088    **
00089    ** If unary operators, like \c log is followed by a number (before
00090    ** the underscore) it belongs to the operator, and in the case of
00091    ** \c log, specifies the base.  Unary operators are \c sqrt (square
00092    ** root), \c log, \c log2, \c log10 (logarithms)
00093    **/
00094   namespace numbers {
00095     const double e =            2.7182818284590452354;
00096     const double log2_e =       1.4426950408889634074;  // log_2(e)
00097     const double log2_10 =      3.32192809488736234789; // log2(10)
00098     const double log_2 =        0.69314718055994530942; // log_e(2)
00099     const double log_10 =       2.30258509299404568402; // log_e(10)
00100     const double log10_2 =      0.30102999566398119521; // log10(2)
00101     const double log10_e =      0.43429448190325182765; // log_10(e)
00102     const double log_p_2_pi =   1.837877066409345;
00103     const double pi =           3.14159265358979323846; // pi
00104     const double p_4_pi =       12.56637061435917;      // 4*pi
00105     const double p_2_pi =       6.28318530717958647692; // 2*pi
00106     const double sqrt_pi =      1.77245385090551602729; // sqrt(pi)
00107     const double f_pi_2 =       1.57079632679489661923; // pi/2
00108     const double f_pi_4 =       0.78539816339744830962; // pi/4
00109     const double f_1_pi =       0.31830988618379067154; // 1/pi
00110     const double f_2_pi =       0.63661977236758134308; // 2/pi
00111     const double f_2_sqrt_pi =  1.12837916709551257390; // 2/sqrt(pi)
00112     const double sqrt_2 =       1.41421356237309504880; // sqrt(2)
00113     const double f_1_sqrt_2 =   0.70710678118654752440; // 1/sqrt(2)
00114     const double f_1_6 =        0.16666666666666666667;
00115     const double f_1_3 =        0.33333333333333333333;
00116     const double eulC =         0.57721566490153286061;  // Euler's constant
00117     const double catG =         0.915965594;  // Catalan's constant
00118   }
00119 
00120 
00121   // --- some additional functions and signatures ---
00122 
00123 # ifdef CXX_HAVE_STD_FINITE
00124   using std::finite;
00125 # elif defined(CXX_HAVE_FINITE)
00126   using ::finite;
00127 # else
00128 #   if defined (CXX_HAVE_STD_ISNAN) && defined(CXX_HAVE_STD_ISINF)
00129   using std::isnan; using std::isinf;
00130   inline int finite(double x) { return !isinf(x) && !isnan(x); }
00131 #   elif defined(CXX_HAVE_ISNAN_ISINF)
00132   inline int finite(double x) { return !isinf(x) && !isnan(x); }
00133 #   else
00134   inline int finite(double x) { return 1; }
00135 #   endif
00136 # endif
00137 
00138   template<typename T>
00139     inline T max(T const& x, T const& y) { return x < y? y : x; }
00140   template<typename T>
00141     inline T min(T const& x, T const& y) { return x < y? x : y; }
00142   template<typename T>
00143     inline T abs(T const& x) { return x >= T(0)? x : -x; }
00144 
00145   // ISO/IEC 14882:1998(E) 4.9.1.  An rvalue of a floating point type
00146   // can be converted to an rvalue of an integer type. The conversion
00147   // truncates; that is, the fractional part is discarded. The
00148   // behavior is undefined if the truncated value cannot be
00149   // represented in the destination type. [Note: If the destination
00150   // type is bool, see 4.12. ]
00151 //   inline int ifloor(double x)
00152 //      { return x >= 0.0? (int)x : (int)(x-x*DBL_EPSILON)-1; }
00153 //   inline int iceil(double x)
00154 //      { return x > 0.0? (int)(x-x*DBL_EPSILON)+1 : (int)x; }
00155 //   inline int itrunc(double x) { return (int)x; }
00156 //   inline int iround(double x) { return ifloor(x+0.5); }
00157 
00158 #if HAVE_STD_LROUND
00159   using std::lround(double);
00160 #elif HAVE_LROUND
00161   using ::lround(double);
00162   inline int iround(double x) { return lround(x); }
00163 #else
00164   inline long lround(double x) { return long(x >= 0.0? x + 0.5 : x - 0.5); }
00165   inline int iround(double x) { return int(x >= 0.0? x + 0.5 : x - 0.5); }
00166 #endif
00167   inline long lfloor(double x) { return long(floor(x)); }
00168   inline long lceil(double x)  { return long(ceil(x)); }
00169   inline long ltrunc(double x) { return long(x); }
00170 
00171   inline int ifloor(double x) { return int(floor(x)); }
00172   inline int iceil(double x) { return int(ceil(x)); }
00173   inline int itrunc(double x) { return int(x); }
00174 
00175   inline float real(float x) { return x; }
00176   inline double real(double x) { return x; }
00177   inline long double real(long double x) { return x; }
00178   inline float imag(float x) { return 0.0; }
00179   inline double imag(double x) { return 0.0; }
00180   inline long double imag(long double x) { return 0.0L; }
00181 
00182   template<typename T>
00183     inline T pow2(const T& x) { return x*x; }
00184   template<typename T>
00185     inline T pow3(const T& x) { return x*x*x; }
00186   template<typename T>
00187     inline T pow4(const T& x) { return pow2(pow2(x)); }
00188   template<typename T>
00189     inline T pow5(const T& x) { return x*pow4(x); }
00190   template<typename T>
00191     inline T pow6(const T& x) { return pow2(pow3(x)); }
00192   template<typename T>
00193     inline T pow7(const T& x) { return x*pow6(x); }
00194   template<typename T>
00195     inline T pow8(const T& x) { return pow2(pow4(x)); }
00196   template<typename T>
00197     inline T pow9(const T& x) { return pow8(x)*x; }
00198   template<typename T>
00199     inline T pow10(const T& x) { return pow2(pow5(x)); }
00200 
00201   inline float conj(float x) { return x; }
00202   inline double conj(double x) { return x; }
00203   inline long double conj(long double x) { return x; }
00204 
00205   inline unsigned int norm(unsigned int x) { return x*x; }
00206   inline int norm(int x) { return x*x; }
00207   inline float norm(float x) { return x*x; }
00208   inline double norm(double x) { return x*x; }
00209   inline long double norm(long double x) { return x*x; }
00210 
00211   inline int ldexp(int x, int n) { return x << n; }
00212   inline int ldexp(long x, int n) { return x << n; }
00213   inline unsigned int ldexp(unsigned int x, int n) { return x << n; }
00214   inline unsigned long ldexp(unsigned long x, int n) { return x << n; }
00215 
00216   inline int rank(float) { return 0; }
00217   inline int rank(double) { return 0; }
00218   inline int rank(long double) { return 0; }
00219   inline int size0(float) { return 1; }
00220   inline int size0(double) { return 1; }
00221   inline int size0(long double) { return 1; }
00222   inline int size1(float) { return 1; }
00223   inline int size1(double) { return 1; }
00224   inline int size1(long double) { return 1; }
00225   inline int size2(float) { return 1; }
00226   inline int size2(double) { return 1; }
00227   inline int size2(long double) { return 1; }
00228   template<typename T> inline int rank(T const&x) { return x.rank(); }
00229   template<typename T> inline int size0(T const&x) { return x.size0(); }
00230   template<typename T> inline int size1(T const&x) { return x.size1(); }
00231   template<typename T> inline int size2(T const&x) { return x.size2(); }
00232   template<typename T> inline T trace(T const& x) { return x; }
00233 
00234   inline float dot(float x, float y) { return x*y; }
00235   inline double dot(double x, double y) { return x*y; }
00236   inline long double dot(long double x, long double y) { return x*y; }
00237 
00238   template<typename T>
00239     inline T
00240     subscript(T const& x, int i, int j=0, int k=0)
00241     {
00242 #ifdef MORE_CHECK_BOUNDS
00243         if (i != 0 || j != 0 || k != 0)
00244             throw std::logic_error("more::math::subscript: "
00245                                    "Index out of bounds in subscript().");
00246 #endif
00247         return x;
00248     }
00249 
00250   template<typename T>
00251     inline T&
00252     subscript(T& x, int i, int j=0, int k=0)
00253     {
00254 #ifdef MORE_CHECK_BOUNDS
00255         if (i != 0 || j != 0 || k != 0)
00256             throw std::logic_error("more::math::subscript: "
00257                                    "Index out of bounds in subscript().");
00258 #endif
00259         return x;
00260     }
00261 
00262 
00263   // --- combinatorics ---
00264 
00265   //  XXX optimize
00266   inline int
00267   factorial(int n, int m = 0)
00268   {
00269 #ifdef MORE_THROW_LOGIC_ERROR
00270       if (n < m)
00271           throw std::domain_error("more::math::factorial(int n, int m): "
00272                                   "Undefined for n < m.");
00273 #endif
00274       if(n == m) return 1;
00275       int k = n;
00276       while(--n > m) k *= n;
00277       return k;
00278   }
00279 
00280   //  XXX optimize
00281   inline int
00282   double_factorial(int n, int m = 0)
00283   {
00284 #ifdef MORE_THROW_LOGIC_ERROR
00285       if(n < m)
00286           throw std::domain_error("more::math::double_factorial"
00287                                   "(int n, int m): "
00288                                   "Undefined for n < m.");
00289       else if (n%2 != m%2)
00290           throw std::domain_error("more::math::double_factorial"
00291                                   "(int n, int m): "
00292                                   "Only defined for n, m both even"
00293                                   " or both odd.");
00294 #endif
00295       int k = 1;
00296       while(n > m) { k *= n; n -= 2; }
00297       return k;
00298   }
00299 
00300   //  XXX optimize
00301   inline int
00302   binominal(int n, int i)
00303   {
00304 #ifdef MORE_THROW_LOGIC_ERROR
00305       if (n < 0)
00306           throw std::domain_error("more::math::binominal(int n, int): "
00307                                   "Undefined for n < 0.");
00308 #endif
00309       if (i >= n)
00310           return i == n? 1 : 0;
00311       if (i <= 0)
00312           return i == 0? 1 : 0;
00313       int j = n - i;
00314       if (i > j) {
00315           j = i;
00316           i = n - j;
00317       }
00318       return factorial(n, j)/factorial(i);
00319   }
00320 
00321 
00322   // --- miscellaneous ---
00323 
00324 //   template<typename T>
00325 //     inline T partial_exp(int n, T x) {
00326 //      T res = 1.0;
00327 //      T term = 1.0;
00328 //      for(int i = 1; i <= n; ++i) {
00329 //          term *= x/i;
00330 //          res += term;
00331 //      }
00332 //      return res;
00333 //     }
00334 
00335   // --- a fractal function ---
00336 
00337   unsigned int bitpow(unsigned int, int);
00338   unsigned long bitpow(unsigned long, int);
00339 #ifdef CXX_HAVE_LONG_LONG
00340   unsigned long long bitpow(unsigned long long, int);
00341 #endif
00342   float bitpow(float, int);
00343   double bitpow(double, int);
00344   long double bitpow(long double, int);
00345 
00346   int upper_bit(unsigned int);
00347   int lower_bit(unsigned int);
00348 //   int lowbit(unsigned long);
00349 // #ifdef CXX_HAVE_LONG_LONG
00350 //   int lowbit(unsigned long long);
00351 // #endif
00352 
00353 }
00354 #if defined(MORE_BACKWARD) && MORE_BACKWARD < 20010615
00355 using namespace math;
00356 #endif
00357 }
00358 
00359 #endif

Generated on Sat Sep 7 19:11:18 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.