00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 namespace numbers {
00095 const double e = 2.7182818284590452354;
00096 const double log2_e = 1.4426950408889634074;
00097 const double log2_10 = 3.32192809488736234789;
00098 const double log_2 = 0.69314718055994530942;
00099 const double log_10 = 2.30258509299404568402;
00100 const double log10_2 = 0.30102999566398119521;
00101 const double log10_e = 0.43429448190325182765;
00102 const double log_p_2_pi = 1.837877066409345;
00103 const double pi = 3.14159265358979323846;
00104 const double p_4_pi = 12.56637061435917;
00105 const double p_2_pi = 6.28318530717958647692;
00106 const double sqrt_pi = 1.77245385090551602729;
00107 const double f_pi_2 = 1.57079632679489661923;
00108 const double f_pi_4 = 0.78539816339744830962;
00109 const double f_1_pi = 0.31830988618379067154;
00110 const double f_2_pi = 0.63661977236758134308;
00111 const double f_2_sqrt_pi = 1.12837916709551257390;
00112 const double sqrt_2 = 1.41421356237309504880;
00113 const double f_1_sqrt_2 = 0.70710678118654752440;
00114 const double f_1_6 = 0.16666666666666666667;
00115 const double f_1_3 = 0.33333333333333333333;
00116 const double eulC = 0.57721566490153286061;
00117 const double catG = 0.915965594;
00118 }
00119
00120
00121
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
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
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
00264
00265
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
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
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
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
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
00349
00350
00351
00352
00353 }
00354 #if defined(MORE_BACKWARD) && MORE_BACKWARD < 20010615
00355 using namespace math;
00356 #endif
00357 }
00358
00359 #endif