14 #if !defined(GEOGRAPHICLIB_MATH_HPP)
15 #define GEOGRAPHICLIB_MATH_HPP 1
20 #if !defined(GEOGRAPHICLIB_CXX11_MATH)
28 # if defined(__GNUC__) && __cplusplus >= 201103 && \
29 !(defined(__ANDROID__) || defined(ANDROID) || defined(__CYGWIN__))
30 # define GEOGRAPHICLIB_CXX11_MATH 1
32 # elif defined(_MSC_VER) && _MSC_VER >= 1800
33 # define GEOGRAPHICLIB_CXX11_MATH 1
35 # define GEOGRAPHICLIB_CXX11_MATH 0
39 #if !defined(GEOGRAPHICLIB_WORDS_BIGENDIAN)
40 # define GEOGRAPHICLIB_WORDS_BIGENDIAN 0
43 #if !defined(GEOGRAPHICLIB_HAVE_LONG_DOUBLE)
44 # define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 0
47 #if !defined(GEOGRAPHICLIB_PRECISION)
57 # define GEOGRAPHICLIB_PRECISION 2
64 #if GEOGRAPHICLIB_PRECISION == 4
65 #include <boost/multiprecision/float128.hpp>
66 #include <boost/math/special_functions/hypot.hpp>
67 #include <boost/math/special_functions/expm1.hpp>
68 #include <boost/math/special_functions/log1p.hpp>
69 #include <boost/math/special_functions/atanh.hpp>
70 #include <boost/math/special_functions/asinh.hpp>
71 #include <boost/math/special_functions/cbrt.hpp>
72 #elif GEOGRAPHICLIB_PRECISION == 5
76 #if GEOGRAPHICLIB_PRECISION > 3
78 #define GEOGRAPHICLIB_VOLATILE
81 #define GEOGRAPHICLIB_PANIC \
82 (throw GeographicLib::GeographicErr("Convergence failure"), false)
84 #define GEOGRAPHICLIB_VOLATILE volatile
87 #define GEOGRAPHICLIB_PANIC false
107 "Bad value of precision");
112 #if GEOGRAPHICLIB_HAVE_LONG_DOUBLE
122 #if GEOGRAPHICLIB_PRECISION == 2
130 #elif GEOGRAPHICLIB_PRECISION == 1
132 #elif GEOGRAPHICLIB_PRECISION == 3
133 typedef extended
real;
134 #elif GEOGRAPHICLIB_PRECISION == 4
135 typedef boost::multiprecision::float128
real;
136 #elif GEOGRAPHICLIB_PRECISION == 5
137 typedef mpfr::mpreal
real;
146 #if GEOGRAPHICLIB_PRECISION != 5
147 return std::numeric_limits<real>::digits;
149 return std::numeric_limits<real>::digits();
162 #if GEOGRAPHICLIB_PRECISION != 5
165 mpfr::mpreal::set_default_prec(ndigits >= 2 ? ndigits : 2);
174 #if GEOGRAPHICLIB_PRECISION != 5
175 return std::numeric_limits<real>::digits10;
177 return std::numeric_limits<real>::digits10();
187 digits10() > std::numeric_limits<double>::digits10 ?
188 digits10() - std::numeric_limits<double>::digits10 : 0;
191 #if GEOGRAPHICLIB_PRECISION <= 3
198 static const int extradigits =
199 std::numeric_limits<real>::digits10 >
200 std::numeric_limits<double>::digits10 ?
201 std::numeric_limits<real>::digits10 -
202 std::numeric_limits<double>::digits10 : 0;
214 template<
typename T>
static inline T
pi() {
216 static const T pi = atan2(T(0), T(-1));
222 static inline real
pi() {
return pi<real>(); }
228 template<
typename T>
static inline T
degree() {
229 static const T degree = pi<T>() / 180;
235 static inline real
degree() {
return degree<real>(); }
244 template<
typename T>
static inline T
sq(T x)
255 template<
typename T>
static inline T
hypot(T x, T y) {
256 #if GEOGRAPHICLIB_CXX11_MATH
257 using std::hypot;
return hypot(x, y);
259 using std::abs;
using std::sqrt;
260 x = abs(x); y = abs(y);
261 if (x < y) std::swap(x, y);
263 return x * sqrt(1 + y * y);
277 template<
typename T>
static inline T
expm1(T x) {
278 #if GEOGRAPHICLIB_CXX11_MATH
279 using std::expm1;
return expm1(x);
281 using std::exp;
using std::abs;
using std::log;
289 return abs(x) > 1 ? z : (z == 0 ? x : x * z / log(y));
300 template<
typename T>
static inline T
log1p(T x) {
301 #if GEOGRAPHICLIB_CXX11_MATH
302 using std::log1p;
return log1p(x);
312 return z == 0 ? x : x * log(y) / z;
323 template<
typename T>
static inline T
asinh(T x) {
324 #if GEOGRAPHICLIB_CXX11_MATH
325 using std::asinh;
return asinh(x);
327 using std::abs; T y = abs(x);
328 y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
329 return x < 0 ? -y : y;
340 template<
typename T>
static inline T
atanh(T x) {
341 #if GEOGRAPHICLIB_CXX11_MATH
342 using std::atanh;
return atanh(x);
344 using std::abs; T y = abs(x);
345 y = log1p(2 * y/(1 - y))/2;
346 return x < 0 ? -y : y;
357 template<
typename T>
static inline T
cbrt(T x) {
358 #if GEOGRAPHICLIB_CXX11_MATH
359 using std::cbrt;
return cbrt(x);
361 using std::abs;
using std::pow;
362 T y = pow(abs(x), 1/T(3));
363 return x < 0 ? -y : y;
379 template<
typename T>
static inline T
sum(T u, T v, T& t) {
401 {
return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); }
413 {
using std::fmod;
return AngNormalize<T>(fmod(x, T(360))); }
430 template<
typename T>
static inline T
AngDiff(T x, T y) {
431 T t, d = sum(-x, y, t);
432 if ((d - T(180)) + t > T(0))
434 else if ((d + T(180)) + t <= T(0))
446 template<
typename T>
static inline bool isfinite(T x) {
447 #if GEOGRAPHICLIB_CXX11_MATH
448 using std::isfinite;
return isfinite(x);
451 return abs(x) <= (std::numeric_limits<T>::max)();
461 template<
typename T>
static inline T
NaN() {
462 return std::numeric_limits<T>::has_quiet_NaN ?
463 std::numeric_limits<T>::quiet_NaN() :
464 (std::numeric_limits<T>::max)();
469 static inline real
NaN() {
return NaN<real>(); }
478 template<
typename T>
static inline bool isnan(T x) {
479 #if GEOGRAPHICLIB_CXX11_MATH
480 using std::isnan;
return isnan(x);
493 return std::numeric_limits<T>::has_infinity ?
494 std::numeric_limits<T>::infinity() :
495 (std::numeric_limits<T>::max)();
500 static inline real
infinity() {
return infinity<real>(); }
509 template<
typename T>
static inline T
swab(T x) {
512 unsigned char c[
sizeof(T)];
515 for (
int i =
sizeof(T)/2; i--; )
516 std::swap(b.c[i], b.c[
sizeof(T) - 1 - i]);
520 #if GEOGRAPHICLIB_PRECISION == 4
521 typedef boost::math::policies::policy
522 < boost::math::policies::domain_error
523 <boost::math::policies::errno_on_error>,
524 boost::math::policies::pole_error
525 <boost::math::policies::errno_on_error>,
526 boost::math::policies::overflow_error
527 <boost::math::policies::errno_on_error>,
528 boost::math::policies::evaluation_error
529 <boost::math::policies::errno_on_error> >
530 boost_special_functions_policy;
532 static inline real hypot(real x, real y)
533 {
return boost::math::hypot(x, y, boost_special_functions_policy()); }
535 static inline real expm1(real x)
536 {
return boost::math::expm1(x, boost_special_functions_policy()); }
538 static inline real log1p(real x)
539 {
return boost::math::log1p(x, boost_special_functions_policy()); }
541 static inline real asinh(real x)
542 {
return boost::math::asinh(x, boost_special_functions_policy()); }
544 static inline real atanh(real x)
545 {
return boost::math::atanh(x, boost_special_functions_policy()); }
547 static inline real cbrt(real x)
548 {
return boost::math::cbrt(x, boost_special_functions_policy()); }
550 static inline bool isnan(real x) {
return boost::math::isnan(x); }
552 static inline bool isfinite(real x) {
return boost::math::isfinite(x); }
558 #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)