Alex Bikfalvi
SimStream Documentation
Math.h
00001 #pragma once 00002 00003 #include <math.h> 00004 #include <stdlib.h> 00005 #include <limits.h> 00006 00007 #define MATH_DBL_EPSILON 2.2204460492503131e-16 00008 #define MATH_SQRT_DBL_EPSILON 1.4901161193847656e-08 00009 #define MATH_ROOT3_DBL_EPSILON 6.0554544523933429e-06 00010 #define MATH_ROOT4_DBL_EPSILON 1.2207031250000000e-04 00011 #define MATH_ROOT5_DBL_EPSILON 7.4009597974140505e-04 00012 #define MATH_ROOT6_DBL_EPSILON 2.4607833005759251e-03 00013 #define MATH_LOG_DBL_EPSILON (-3.6043653389117154e+01) 00014 00015 #define MATH_DBL_MIN 2.2250738585072014e-308 00016 #define MATH_SQRT_DBL_MIN 1.4916681462400413e-154 00017 #define MATH_ROOT3_DBL_MIN 2.8126442852362996e-103 00018 #define MATH_ROOT4_DBL_MIN 1.2213386697554620e-77 00019 #define MATH_ROOT5_DBL_MIN 2.9476022969691763e-62 00020 #define MATH_ROOT6_DBL_MIN 5.3034368905798218e-52 00021 #define MATH_LOG_DBL_MIN (-7.0839641853226408e+02) 00022 00023 #define MATH_DBL_MAX 1.7976931348623157e+308 00024 #define MATH_SQRT_DBL_MAX 1.3407807929942596e+154 00025 #define MATH_ROOT3_DBL_MAX 5.6438030941222897e+102 00026 #define MATH_ROOT4_DBL_MAX 1.1579208923731620e+77 00027 #define MATH_ROOT5_DBL_MAX 4.4765466227572707e+61 00028 #define MATH_ROOT6_DBL_MAX 2.3756689782295612e+51 00029 #define MATH_LOG_DBL_MAX 7.0978271289338397e+02 00030 00031 #define MATH_FLT_EPSILON 1.1920928955078125e-07 00032 #define MATH_SQRT_FLT_EPSILON 3.4526698300124393e-04 00033 #define MATH_ROOT3_FLT_EPSILON 4.9215666011518501e-03 00034 #define MATH_ROOT4_FLT_EPSILON 1.8581361171917516e-02 00035 #define MATH_ROOT5_FLT_EPSILON 4.1234622211652937e-02 00036 #define MATH_ROOT6_FLT_EPSILON 7.0153878019335827e-02 00037 #define MATH_LOG_FLT_EPSILON (-1.5942385152878742e+01) 00038 00039 #define MATH_FLT_MIN 1.1754943508222875e-38 00040 #define MATH_SQRT_FLT_MIN 1.0842021724855044e-19 00041 #define MATH_ROOT3_FLT_MIN 2.2737367544323241e-13 00042 #define MATH_ROOT4_FLT_MIN 3.2927225399135965e-10 00043 #define MATH_ROOT5_FLT_MIN 2.5944428542140822e-08 00044 #define MATH_ROOT6_FLT_MIN 4.7683715820312542e-07 00045 #define MATH_LOG_FLT_MIN (-8.7336544750553102e+01) 00046 00047 #define MATH_FLT_MAX 3.4028234663852886e+38 00048 #define MATH_SQRT_FLT_MAX 1.8446743523953730e+19 00049 #define MATH_ROOT3_FLT_MAX 6.9814635196223242e+12 00050 #define MATH_ROOT4_FLT_MAX 4.2949672319999986e+09 00051 #define MATH_ROOT5_FLT_MAX 5.0859007855960041e+07 00052 #define MATH_ROOT6_FLT_MAX 2.6422459233807749e+06 00053 #define MATH_LOG_FLT_MAX 8.8722839052068352e+01 00054 00055 #define MATH_SFLT_EPSILON 4.8828125000000000e-04 00056 #define MATH_SQRT_SFLT_EPSILON 2.2097086912079612e-02 00057 #define MATH_ROOT3_SFLT_EPSILON 7.8745065618429588e-02 00058 #define MATH_ROOT4_SFLT_EPSILON 1.4865088937534013e-01 00059 #define MATH_ROOT5_SFLT_EPSILON 2.1763764082403100e-01 00060 #define MATH_ROOT6_SFLT_EPSILON 2.8061551207734325e-01 00061 #define MATH_LOG_SFLT_EPSILON (-7.6246189861593985e+00) 00062 00063 #ifndef M_E 00064 #define M_E 2.71828182845904523536028747135 /* e */ 00065 #endif 00066 00067 #ifndef M_LOG2E 00068 #define M_LOG2E 1.44269504088896340735992468100 /* log_2 (e) */ 00069 #endif 00070 00071 #ifndef M_LOG10E 00072 #define M_LOG10E 0.43429448190325182765112891892 /* log_10 (e) */ 00073 #endif 00074 00075 #ifndef M_SQRT2 00076 #define M_SQRT2 1.41421356237309504880168872421 /* sqrt(2) */ 00077 #endif 00078 00079 #ifndef M_SQRT1_2 00080 #define M_SQRT1_2 0.70710678118654752440084436210 /* sqrt(1/2) */ 00081 #endif 00082 00083 00084 #ifndef M_SQRT3 00085 #define M_SQRT3 1.73205080756887729352744634151 /* sqrt(3) */ 00086 #endif 00087 00088 #ifndef M_PI 00089 #define M_PI 3.14159265358979323846264338328 /* pi */ 00090 #endif 00091 00092 #ifndef M_PI_2 00093 #define M_PI_2 1.57079632679489661923132169164 /* pi/2 */ 00094 #endif 00095 00096 #ifndef M_PI_4 00097 #define M_PI_4 0.78539816339744830961566084582 /* pi/4 */ 00098 #endif 00099 00100 #ifndef M_SQRTPI 00101 #define M_SQRTPI 1.77245385090551602729816748334 /* sqrt(pi) */ 00102 #endif 00103 00104 #ifndef M_2_SQRTPI 00105 #define M_2_SQRTPI 1.12837916709551257389615890312 /* 2/sqrt(pi) */ 00106 #endif 00107 00108 #ifndef M_1_PI 00109 #define M_1_PI 0.31830988618379067153776752675 /* 1/pi */ 00110 #endif 00111 00112 #ifndef M_2_PI 00113 #define M_2_PI 0.63661977236758134307553505349 /* 2/pi */ 00114 #endif 00115 00116 #ifndef M_LN10 00117 #define M_LN10 2.30258509299404568401799145468 /* ln(10) */ 00118 #endif 00119 00120 #ifndef M_LN2 00121 #define M_LN2 0.69314718055994530941723212146 /* ln(2) */ 00122 #endif 00123 00124 #ifndef M_LNPI 00125 #define M_LNPI 1.14472988584940017414342735135 /* ln(pi) */ 00126 #endif 00127 00128 #ifndef M_EULER 00129 #define M_EULER 0.57721566490153286060651209008 /* Euler constant */ 00130 #endif 00131 00132 double Nan (void); 00133 double PosInf (void); 00134 double NegInf (void); 00135 00136 #ifdef INFINITY 00137 # define MATH_POSINF INFINITY 00138 # define MATH_NEGINF (-INFINITY) 00139 #elif defined(HUGE_VAL) 00140 # define MATH_POSINF HUGE_VAL 00141 # define MATH_NEGINF (-HUGE_VAL) 00142 #else 00143 # define MATH_POSINF (PosInf()) 00144 # define MATH_NEGINF (NegInf()) 00145 #endif 00146 00147 #ifdef NAN 00148 # define MATH_NAN NAN 00149 #elif defined(INFINITY) 00150 # define MATH_NAN (INFINITY/INFINITY) 00151 #else 00152 # define MATH_NAN (Nan()) 00153 #endif 00154 00155 #define MATH_POSZERO (+0) 00156 #define MATH_NEGZERO (-0) 00157 00158 double Div(double x, double y); 00159 double Nan (void); 00160 double PosInf (void); 00161 double NegInf (void); 00162 00163 enum { 00164 MATH_SUCCESS = 0, 00165 MATH_FAILURE = -1, 00166 MATH_CONTINUE = -2, /* iteration has not converged */ 00167 MATH_EDOM = 1, /* input domain error, e.g sqrt(-1) */ 00168 MATH_ERANGE = 2, /* output range error, e.g. exp(1e100) */ 00169 MATH_EFAULT = 3, /* invalid pointer */ 00170 MATH_EINVAL = 4, /* invalid argument supplied by user */ 00171 MATH_EFAILED = 5, /* generic failure */ 00172 MATH_EFACTOR = 6, /* factorization failed */ 00173 MATH_ESANITY = 7, /* sanity check failed - shouldn't happen */ 00174 MATH_ENOMEM = 8, /* malloc failed */ 00175 MATH_EBADFUNC = 9, /* problem with user-supplied function */ 00176 MATH_ERUNAWAY = 10, /* iterative process is out of control */ 00177 MATH_EMAXITER = 11, /* exceeded max number of iterations */ 00178 MATH_EZERODIV = 12, /* tried to divide by zero */ 00179 MATH_EBADTOL = 13, /* user specified an invalid tolerance */ 00180 MATH_ETOL = 14, /* failed to reach the specified tolerance */ 00181 MATH_EUNDRFLW = 15, /* underflow */ 00182 MATH_EOVRFLW = 16, /* overflow */ 00183 MATH_ELOSS = 17, /* loss of accuracy */ 00184 MATH_EROUND = 18, /* failed because of roundoff error */ 00185 MATH_EBADLEN = 19, /* matrix, vector lengths are not conformant */ 00186 MATH_ENOTSQR = 20, /* matrix not square */ 00187 MATH_ESING = 21, /* apparent singularity detected */ 00188 MATH_EDIVERGE = 22, /* integral or series is divergent */ 00189 MATH_EUNSUP = 23, /* requested feature is not supported by the hardware */ 00190 MATH_EUNIMPL = 24, /* requested feature not (yet) implemented */ 00191 MATH_ECACHE = 25, /* cache limit exceeded */ 00192 MATH_ETABLE = 26, /* table limit exceeded */ 00193 MATH_ENOPROG = 27, /* iteration is not making progress towards solution */ 00194 MATH_ENOPROGJ = 28, /* jacobian evaluations are not improving the solution */ 00195 MATH_ETOLF = 29, /* cannot reach the specified tolerance in F */ 00196 MATH_ETOLX = 30, /* cannot reach the specified tolerance in X */ 00197 MATH_ETOLG = 31, /* cannot reach the specified tolerance in gradient */ 00198 MATH_EOF = 32 /* end of file */ 00199 } ; 00200 00201 #define MATH_ERROR_SELECT_2(a,b) ((a) != MATH_SUCCESS ? (a) : ((b) != MATH_SUCCESS ? (b) : MATH_SUCCESS)) 00202 #define MATH_ERROR_SELECT_3(a,b,c) ((a) != MATH_SUCCESS ? (a) : MATH_ERROR_SELECT_2(b,c)) 00203 #define MATH_ERROR_SELECT_4(a,b,c,d) ((a) != MATH_SUCCESS ? (a) : MATH_ERROR_SELECT_3(b,c,d)) 00204 #define MATH_ERROR_SELECT_5(a,b,c,d,e) ((a) != MATH_SUCCESS ? (a) : MATH_ERROR_SELECT_4(b,c,d,e)) 00205 00206 #define LogRootTwoPi_ 0.9189385332046727418 00207 00208 #define MATH_IS_ODD(n) ((n) & 1) 00209 #define MATH_IS_EVEN(n) (!(MATH_IS_ODD(n))) 00210 #define MATH_SIGN(x) ((x) >= 0.0 ? 1 : -1) 00211 #define MATH_ERROR(a, b) throw a 00212 00213 00214 #define OVERFLOW_ERROR(result) do { (result)->val = MATH_POSINF; (result)->err = MATH_POSINF; MATH_ERROR ("overflow", MATH_EOVRFLW); } while(0) 00215 00216 #define UNDERFLOW_ERROR(result) do { (result)->val = 0.0; (result)->err = MATH_DBL_MIN; MATH_ERROR ("underflow", MATH_EUNDRFLW); } while(0) 00217 00218 #define INTERNAL_OVERFLOW_ERROR(result) do { (result)->val = MATH_POSINF; (result)->err = MATH_POSINF; return MATH_EOVRFLW; } while(0) 00219 00220 #define INTERNAL_UNDERFLOW_ERROR(result) do { (result)->val = 0.0; (result)->err = MATH_DBL_MIN; return MATH_EUNDRFLW; } while(0) 00221 00222 #define DOMAIN_ERROR(result) do { (result)->val = MATH_NAN; (result)->err = MATH_NAN; MATH_ERROR ("domain error", MATH_EDOM); } while(0) 00223 00224 #define DOMAIN_ERROR_MSG(msg, result) do { (result)->val = MATH_NAN; (result)->err = MATH_NAN; MATH_ERROR ((msg), MATH_EDOM); } while(0) 00225 00226 #define DOMAIN_ERROR_E10(result) do { (result)->val = MATH_NAN; (result)->err = MATH_NAN; (result)->e10 = 0 ; MATH_ERROR ("domain error", MATH_EDOM); } while(0) 00227 00228 #define OVERFLOW_ERROR_E10(result) do { (result)->val = MATH_POSINF; (result)->err = MATH_POSINF; (result)->e10 = 0; MATH_ERROR ("overflow", MATH_EOVRFLW); } while(0) 00229 #define UNDERFLOW_ERROR_E10(result) do { (result)->val = 0.0; (result)->err = MATH_DBL_MIN; (result)->e10 = 0; MATH_ERROR ("underflow", MATH_EUNDRFLW); } while(0) 00230 00231 00232 #define OVERFLOW_ERROR_2(r1,r2) do { (r1)->val = MATH_POSINF; (r1)->err = MATH_POSINF; (r2)->val = MATH_POSINF ; (r2)->err=MATH_POSINF; MATH_ERROR ("overflow", MATH_EOVRFLW); } while(0) 00233 00234 #define UNDERFLOW_ERROR_2(r1,r2) do { (r1)->val = 0.0; (r1)->err = MATH_DBL_MIN; (r2)->val = 0.0 ; (r2)->err = MATH_DBL_MIN; MATH_ERROR ("underflow", MATH_EUNDRFLW); } while(0) 00235 00236 #define DOMAIN_ERROR_2(r1,r2) do { (r1)->val = MATH_NAN; (r1)->err = MATH_NAN; (r2)->val = MATH_NAN; (r2)->err = MATH_NAN; MATH_ERROR ("domain error", MATH_EDOM); } while(0) 00237 00238 00239 00240 00241 /* Define MAX and MIN macros/functions if they don't exist. */ 00242 00243 /* plain old macros for general use */ 00244 #define MATH_MAX(a,b) ((a) > (b) ? (a) : (b)) 00245 #define MATH_MIN(a,b) ((a) < (b) ? (a) : (b)) 00246 00247 /* function versions of the above, in case they are needed */ 00248 double gsl_max (double a, double b); 00249 double gsl_min (double a, double b); 00250 00251 /* inline-friendly strongly typed versions */ 00252 #ifdef HAVE_INLINE 00253 00254 INLINE_FUN int MATH_MAX_INT (int a, int b); 00255 INLINE_FUN int MATH_MIN_INT (int a, int b); 00256 INLINE_FUN double MATH_MAX_DBL (double a, double b); 00257 INLINE_FUN double MATH_MIN_DBL (double a, double b); 00258 INLINE_FUN long double MATH_MAX_LDBL (long double a, long double b); 00259 INLINE_FUN long double MATH_MIN_LDBL (long double a, long double b); 00260 00261 INLINE_FUN int 00262 MATH_MAX_INT (int a, int b) 00263 { 00264 return MATH_MAX (a, b); 00265 } 00266 00267 INLINE_FUN int 00268 MATH_MIN_INT (int a, int b) 00269 { 00270 return MATH_MIN (a, b); 00271 } 00272 00273 INLINE_FUN double 00274 MATH_MAX_DBL (double a, double b) 00275 { 00276 return MATH_MAX (a, b); 00277 } 00278 00279 INLINE_FUN double 00280 MATH_MIN_DBL (double a, double b) 00281 { 00282 return MATH_MIN (a, b); 00283 } 00284 00285 INLINE_FUN long double 00286 MATH_MAX_LDBL (long double a, long double b) 00287 { 00288 return MATH_MAX (a, b); 00289 } 00290 00291 INLINE_FUN long double 00292 MATH_MIN_LDBL (long double a, long double b) 00293 { 00294 return MATH_MIN (a, b); 00295 } 00296 #else 00297 #define MATH_MAX_INT(a,b) MATH_MAX(a,b) 00298 #define MATH_MIN_INT(a,b) MATH_MIN(a,b) 00299 #define MATH_MAX_DBL(a,b) MATH_MAX(a,b) 00300 #define MATH_MIN_DBL(a,b) MATH_MIN(a,b) 00301 #define MATH_MAX_LDBL(a,b) MATH_MAX(a,b) 00302 #define MATH_MIN_LDBL(a,b) MATH_MIN(a,b) 00303 #endif /* HAVE_INLINE */ 00304 00305 00306 00307 struct MathResult_struct { 00308 double val; 00309 double err; 00310 }; 00311 typedef struct MathResult_struct MathResult; 00312 00313 #define EVAL_RESULT(fn) \ 00314 MathResult result; \ 00315 int status = fn; \ 00316 if (status != MATH_SUCCESS) { \ 00317 throw "error"; \ 00318 } ; \ 00319 return result.val; 00320 00321 #define EVAL_DOUBLE(fn) \ 00322 int status = fn; \ 00323 if (status != MATH_SUCCESS) { \ 00324 throw "error"; \ 00325 } ; \ 00326 return result;
Last updated: February 8, 2011