math_lib.h
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
00038 #ifndef MATH_MATH_LIB_H
00039 #define MATH_MATH_LIB_H
00040
00041 #include "fastlib/base/base.h"
00042
00043 #include <math.h>
00044
00051 namespace math {
00053 const double SQRT2 = 1.41421356237309504880;
00055 const double E = 2.7182818284590452354;
00057 const double LOG2_E = 1.4426950408889634074;
00059 const double LOG10_E = 0.43429448190325182765;
00061 const double LN_2 = 0.69314718055994530942;
00063 const double LN_10 = 2.30258509299404568402;
00065 const double PI = 3.141592653589793238462643383279;
00067 const double PI_2 = 1.57079632679489661923;
00068
00070 template<typename T>
00071 inline T Sqr(T v) {
00072 return v * v;
00073 }
00074
00078 inline int64 RoundInt(double d) {
00079 return int64(nearbyint(d));
00080 }
00081
00087 inline double ClampNonNegative(double d) {
00088 return (d + fabs(d)) / 2;
00089 }
00090
00096 inline double ClampNonPositive(double d) {
00097 return (d - fabs(d)) / 2;
00098 }
00099
00108 inline double ClampRange(double value, double range_min, double range_max) {
00109 if (unlikely(value <= range_min)) {
00110 return range_min;
00111 } else if (unlikely(value >= range_max)) {
00112 return range_max;
00113 } else {
00114 return value;
00115 }
00116 }
00117
00121 inline double Random() {
00122 return rand() * (1.0 / RAND_MAX);
00123 }
00124
00128 inline double Random(double lo, double hi) {
00129 return Random() * (hi - lo) + lo;
00130 }
00131
00135 inline int RandInt(int hi_exclusive) {
00136 return rand() % hi_exclusive;
00137 }
00141 inline int RandInt(int lo, int hi_exclusive) {
00142 return (rand() % (hi_exclusive - lo)) + lo;
00143 }
00144 };
00145
00146 #include "fastlib/math/math_lib_impl.h"
00147
00148
00149 namespace math {
00157 template<int t_numerator, int t_denominator>
00158 inline double Pow(double d) {
00159 return math__private::ZPowImpl<t_numerator, t_denominator>::Calculate(d);
00160 }
00161
00171 template<int t_numerator, int t_denominator>
00172 inline double PowAbs(double d) {
00173
00174
00175 return math__private::ZPowAbsImpl<t_numerator, t_denominator,
00176 (t_numerator%t_denominator == 0) && ((t_numerator/t_denominator)%2 == 0)>::Calculate(fabs(d));
00177 }
00178 };
00179
00188 template<typename TValue>
00189 class MinMaxVal {
00190 public:
00191 typedef TValue Value;
00192
00193 public:
00195 Value val;
00196
00197 OBJECT_TRAVERSAL(MinMaxVal) {
00198 OT_OBJ(val);
00199 }
00200
00201 public:
00205 operator Value() const { return val; }
00206
00210 const Value& operator = (Value val_in) {
00211 return (val = val_in);
00212 }
00213
00220 void MinWith(Value incoming_val) {
00221 if (unlikely(incoming_val < val)) {
00222 val = incoming_val;
00223 }
00224 }
00225
00232 void MaxWith(Value incoming_val) {
00233 if (unlikely(incoming_val > val)) {
00234 val = incoming_val;
00235 }
00236 }
00237 };
00238
00244 struct DRange {
00245 public:
00249 double lo;
00253 double hi;
00254
00255 OBJECT_TRAVERSAL(DRange) {
00256 OT_OBJ(lo);
00257 OT_OBJ(hi);
00258 }
00259
00260 public:
00262 DRange(double lo_in, double hi_in)
00263 : lo(lo_in), hi(hi_in)
00264 {}
00265
00267 void InitEmptySet() {
00268 lo = DBL_MAX;
00269 hi = -DBL_MAX;
00270 }
00271
00273 void InitUniversalSet() {
00274 lo = -DBL_MAX;
00275 hi = DBL_MAX;
00276 }
00277
00279 void Init(double lo_in, double hi_in) {
00280 lo = lo_in;
00281 hi = hi_in;
00282 }
00283
00290 void Reset(double lo_in, double hi_in) {
00291 lo = lo_in;
00292 hi = hi_in;
00293 }
00294
00298 double width() const {
00299 return hi - lo;
00300 }
00301
00305 double mid() const {
00306 return (hi + lo) / 2;
00307 }
00308
00312 double interpolate(double factor) const {
00313 return factor * width() + lo;
00314 }
00315
00319 const DRange& operator |= (double d) {
00320 if (unlikely(d < lo)) {
00321 lo = d;
00322 }
00323 if (unlikely(d > hi)) {
00324 hi = d;
00325 }
00326 return *this;
00327 }
00328
00333 const DRange& operator &= (double d) {
00334 if (likely(d > lo)) {
00335 lo = d;
00336 }
00337 if (likely(d < hi)) {
00338 hi = d;
00339 }
00340 return *this;
00341 }
00342
00346 const DRange& operator |= (const DRange& other) {
00347 if (unlikely(other.lo < lo)) {
00348 lo = other.lo;
00349 }
00350 if (unlikely(other.hi > hi)) {
00351 hi = other.hi;
00352 }
00353 return *this;
00354 }
00355
00360 const DRange& operator &= (const DRange& other) {
00361 if (unlikely(other.lo > lo)) {
00362 lo = other.lo;
00363 }
00364 if (unlikely(other.hi < hi)) {
00365 hi = other.hi;
00366 }
00367 return *this;
00368 }
00369
00371 friend DRange operator - (const DRange& r) {
00372 return DRange(-r.hi, -r.lo);
00373 }
00374
00376 const DRange& operator *= (double d) {
00377 DEBUG_ASSERT_MSG(d >= 0, "don't multiply DRanges by negatives, explicitly negate");
00378 lo *= d;
00379 hi *= d;
00380 return *this;
00381 }
00382
00384 friend DRange operator * (const DRange& r, double d) {
00385 DEBUG_ASSERT_MSG(d >= 0, "don't multiply DRanges by negatives, explicitly negate");
00386 return DRange(r.lo * d, r.hi * d);
00387 }
00388
00390 friend DRange operator * (double d, const DRange& r) {
00391 DEBUG_ASSERT_MSG(d >= 0, "don't multiply DRanges by negatives, explicitly negate");
00392 return DRange(r.lo * d, r.hi * d);
00393 }
00394
00396 const DRange& operator += (const DRange& other) {
00397 lo += other.lo;
00398 hi += other.hi;
00399 return *this;
00400 }
00401
00406 const DRange& operator -= (const DRange& other) {
00407 lo -= other.hi;
00408 hi -= other.lo;
00409 return *this;
00410 }
00411
00413 const DRange& operator += (double d) {
00414 lo += d;
00415 hi += d;
00416 return *this;
00417 }
00418
00420 const DRange& operator -= (double d) {
00421 lo -= d;
00422 hi -= d;
00423 return *this;
00424 }
00425
00426 friend DRange operator + (const DRange& a, const DRange& b) {
00427 DRange result;
00428 result.lo = a.lo + b.lo;
00429 result.hi = a.hi + b.hi;
00430 return result;
00431 }
00432
00433 friend DRange operator - (const DRange& a, const DRange& b) {
00434 DRange result;
00435 result.lo = a.lo - b.hi;
00436 result.hi = a.hi - b.lo;
00437 return result;
00438 }
00439
00440 friend DRange operator + (const DRange& a, double b) {
00441 DRange result;
00442 result.lo = a.lo + b;
00443 result.hi = a.hi + b;
00444 return result;
00445 }
00446
00447 friend DRange operator - (const DRange& a, double b) {
00448 DRange result;
00449 result.lo = a.lo - b;
00450 result.hi = a.hi - b;
00451 return result;
00452 }
00453
00457 void MaxWith(const DRange& range) {
00458 if (unlikely(range.lo > lo)) {
00459 lo = range.lo;
00460 }
00461 if (unlikely(range.hi > hi)) {
00462 hi = range.hi;
00463 }
00464 }
00465
00469 void MinWith(const DRange& range) {
00470 if (unlikely(range.lo < lo)) {
00471 lo = range.lo;
00472 }
00473 if (unlikely(range.hi < hi)) {
00474 hi = range.hi;
00475 }
00476 }
00477
00481 void MaxWith(double v) {
00482 if (unlikely(v > lo)) {
00483 lo = v;
00484 if (unlikely(v > hi)) {
00485 hi = v;
00486 }
00487 }
00488 }
00489
00493 void MinWith(double v) {
00494 if (unlikely(v < hi)) {
00495 hi = v;
00496 if (unlikely(v < lo)) {
00497 lo = v;
00498 }
00499 }
00500 }
00501
00505 friend bool operator < (const DRange& a, const DRange& b) {
00506 return a.hi < b.lo;
00507 }
00508 EXPAND_LESS_THAN(DRange);
00512 friend bool operator == (const DRange& a, const DRange& b) {
00513 return a.lo == b.lo && a.hi == b.hi;
00514 }
00515 EXPAND_EQUALS(DRange);
00516
00520 friend bool operator < (const DRange& a, double b) {
00521 return a.hi < b;
00522 }
00523 EXPAND_HETERO_LESS_THAN(DRange, double);
00527 friend bool operator < (double a, const DRange& b) {
00528 return a < b.lo;
00529 }
00530 EXPAND_HETERO_LESS_THAN(double, DRange);
00531
00535 bool Contains(double d) const {
00536 return d >= lo || d <= hi;
00537 }
00538 };
00539
00540 #include "fastlib/math/discrete.h"
00541 #include "fastlib/math/kernel.h"
00542 #include "fastlib/math/geometry.h"
00543
00544
00545
00546
00547 #endif