14 #if !defined(GEOGRAPHICLIB_MATH_HPP) 15 #define GEOGRAPHICLIB_MATH_HPP 1 20 #if !defined(GEOGRAPHICLIB_CXX11_MATH) 26 # if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 7 \ 27 && __cplusplus >= 201103 && \ 28 !(defined(__ANDROID__) || defined(ANDROID) || defined(__CYGWIN__)) 29 # define GEOGRAPHICLIB_CXX11_MATH 1 31 # elif defined(_MSC_VER) && _MSC_VER >= 1800 32 # define GEOGRAPHICLIB_CXX11_MATH 1 34 # define GEOGRAPHICLIB_CXX11_MATH 0 38 #if !defined(GEOGRAPHICLIB_WORDS_BIGENDIAN) 39 # define GEOGRAPHICLIB_WORDS_BIGENDIAN 0 42 #if !defined(GEOGRAPHICLIB_HAVE_LONG_DOUBLE) 43 # define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 0 46 #if !defined(GEOGRAPHICLIB_PRECISION) 56 # define GEOGRAPHICLIB_PRECISION 2 63 #if GEOGRAPHICLIB_PRECISION == 4 64 #include <boost/multiprecision/float128.hpp> 65 #include <boost/math/special_functions/hypot.hpp> 66 #include <boost/math/special_functions/expm1.hpp> 67 #include <boost/math/special_functions/log1p.hpp> 68 #include <boost/math/special_functions/atanh.hpp> 69 #include <boost/math/special_functions/asinh.hpp> 70 #include <boost/math/special_functions/cbrt.hpp> 71 #elif GEOGRAPHICLIB_PRECISION == 5 75 #if GEOGRAPHICLIB_PRECISION > 3 77 #define GEOGRAPHICLIB_VOLATILE 80 #define GEOGRAPHICLIB_PANIC \ 81 (throw GeographicLib::GeographicErr("Convergence failure"), false) 83 #define GEOGRAPHICLIB_VOLATILE volatile 86 #define GEOGRAPHICLIB_PANIC false 106 "Bad value of precision");
111 #if GEOGRAPHICLIB_HAVE_LONG_DOUBLE 121 #if GEOGRAPHICLIB_PRECISION == 2 129 #elif GEOGRAPHICLIB_PRECISION == 1 131 #elif GEOGRAPHICLIB_PRECISION == 3 132 typedef extended
real;
133 #elif GEOGRAPHICLIB_PRECISION == 4 134 typedef boost::multiprecision::float128
real;
135 #elif GEOGRAPHICLIB_PRECISION == 5 136 typedef mpfr::mpreal
real;
145 #if GEOGRAPHICLIB_PRECISION != 5 146 return std::numeric_limits<real>::digits;
148 return std::numeric_limits<real>::digits();
161 #if GEOGRAPHICLIB_PRECISION != 5 164 mpfr::mpreal::set_default_prec(ndigits >= 2 ? ndigits : 2);
173 #if GEOGRAPHICLIB_PRECISION != 5 174 return std::numeric_limits<real>::digits10;
176 return std::numeric_limits<real>::digits10();
186 digits10() > std::numeric_limits<double>::digits10 ?
187 digits10() - std::numeric_limits<double>::digits10 : 0;
190 #if GEOGRAPHICLIB_PRECISION <= 3 197 static const int extradigits =
198 std::numeric_limits<real>::digits10 >
199 std::numeric_limits<double>::digits10 ?
200 std::numeric_limits<real>::digits10 -
201 std::numeric_limits<double>::digits10 : 0;
213 template<
typename T>
static inline T
pi() {
215 static const T pi = atan2(T(0), T(-1));
221 static inline real
pi() {
return pi<real>(); }
227 template<
typename T>
static inline T
degree() {
228 static const T degree = pi<T>() / 180;
234 static inline real
degree() {
return degree<real>(); }
243 template<
typename T>
static inline T
sq(T x)
254 template<
typename T>
static inline T
hypot(T x, T y) {
255 #if GEOGRAPHICLIB_CXX11_MATH 256 using std::hypot;
return hypot(x, y);
258 using std::abs;
using std::sqrt;
259 x = abs(x); y = abs(y);
260 if (x < y) std::swap(x, y);
262 return x * sqrt(1 + y * y);
276 template<
typename T>
static inline T
expm1(T x) {
277 #if GEOGRAPHICLIB_CXX11_MATH 278 using std::expm1;
return expm1(x);
280 using std::exp;
using std::abs;
using std::log;
288 return abs(x) > 1 ? z : (z == 0 ? x : x * z / log(y));
299 template<
typename T>
static inline T
log1p(T x) {
300 #if GEOGRAPHICLIB_CXX11_MATH 301 using std::log1p;
return log1p(x);
311 return z == 0 ? x : x * log(y) / z;
322 template<
typename T>
static inline T
asinh(T x) {
323 #if GEOGRAPHICLIB_CXX11_MATH 324 using std::asinh;
return asinh(x);
326 using std::abs; T y = abs(x);
327 y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
328 return x < 0 ? -y : y;
339 template<
typename T>
static inline T
atanh(T x) {
340 #if GEOGRAPHICLIB_CXX11_MATH 341 using std::atanh;
return atanh(x);
343 using std::abs; T y = abs(x);
344 y = log1p(2 * y/(1 - y))/2;
345 return x < 0 ? -y : y;
356 template<
typename T>
static inline T
cbrt(T x) {
357 #if GEOGRAPHICLIB_CXX11_MATH 358 using std::cbrt;
return cbrt(x);
360 using std::abs;
using std::pow;
361 T y = pow(abs(x), 1/T(3));
362 return x < 0 ? -y : y;
378 template<
typename T>
static inline T
sum(T u, T v, T& t) {
400 {
return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); }
412 {
using std::fmod;
return AngNormalize<T>(fmod(x, T(360))); }
429 template<
typename T>
static inline T
AngDiff(T x, T y) {
430 T t, d = sum(-x, y, t);
431 if ((d - T(180)) + t > T(0))
433 else if ((d + T(180)) + t <= T(0))
445 template<
typename T>
static inline bool isfinite(T x) {
446 #if GEOGRAPHICLIB_CXX11_MATH 447 using std::isfinite;
return isfinite(x);
450 return abs(x) <= (std::numeric_limits<T>::max)();
460 template<
typename T>
static inline T
NaN() {
461 return std::numeric_limits<T>::has_quiet_NaN ?
462 std::numeric_limits<T>::quiet_NaN() :
463 (std::numeric_limits<T>::max)();
468 static inline real
NaN() {
return NaN<real>(); }
477 template<
typename T>
static inline bool isnan(T x) {
478 #if GEOGRAPHICLIB_CXX11_MATH 479 using std::isnan;
return isnan(x);
492 return std::numeric_limits<T>::has_infinity ?
493 std::numeric_limits<T>::infinity() :
494 (std::numeric_limits<T>::max)();
499 static inline real
infinity() {
return infinity<real>(); }
508 template<
typename T>
static inline T
swab(T x) {
511 unsigned char c[
sizeof(T)];
514 for (
int i =
sizeof(T)/2; i--; )
515 std::swap(b.c[i], b.c[
sizeof(T) - 1 - i]);
519 #if GEOGRAPHICLIB_PRECISION == 4 520 typedef boost::math::policies::policy
521 < boost::math::policies::domain_error
522 <boost::math::policies::errno_on_error>,
523 boost::math::policies::pole_error
524 <boost::math::policies::errno_on_error>,
525 boost::math::policies::overflow_error
526 <boost::math::policies::errno_on_error>,
527 boost::math::policies::evaluation_error
528 <boost::math::policies::errno_on_error> >
529 boost_special_functions_policy;
531 static inline real hypot(real x, real y)
532 {
return boost::math::hypot(x, y, boost_special_functions_policy()); }
534 static inline real expm1(real x)
535 {
return boost::math::expm1(x, boost_special_functions_policy()); }
537 static inline real log1p(real x)
538 {
return boost::math::log1p(x, boost_special_functions_policy()); }
540 static inline real asinh(real x)
541 {
return boost::math::asinh(x, boost_special_functions_policy()); }
543 static inline real atanh(real x)
544 {
return boost::math::atanh(x, boost_special_functions_policy()); }
546 static inline real cbrt(real x)
547 {
return boost::math::cbrt(x, boost_special_functions_policy()); }
549 static inline bool isnan(real x) {
return boost::math::isnan(x); }
551 static inline bool isfinite(real x) {
return boost::math::isfinite(x); }
557 #endif // GEOGRAPHICLIB_MATH_HPP static T AngNormalize(T x)
static T sum(T u, T v, T &t)
static int set_digits(int ndigits)
#define GEOGRAPHICLIB_EXPORT
#define GEOGRAPHICLIB_WORDS_BIGENDIAN
GeographicLib::Math::real real
static bool isfinite(T x)
Mathematical functions needed by GeographicLib.
#define GEOGRAPHICLIB_PRECISION
#define GEOGRAPHICLIB_VOLATILE
static int extra_digits()
Namespace for GeographicLib.
static T AngDiff(T x, T y)
Header for GeographicLib::Constants class.
static T AngNormalize2(T x)