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)