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/version.hpp> 66 #if BOOST_VERSION >= 105600 67 #include <boost/cstdfloat.hpp> 69 #include <boost/multiprecision/float128.hpp> 70 #include <boost/math/special_functions.hpp> 71 __float128 fmaq(__float128, __float128, __float128);
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();
164 #if GEOGRAPHICLIB_PRECISION != 5 167 mpfr::mpreal::set_default_prec(ndigits >= 2 ? ndigits : 2);
176 #if GEOGRAPHICLIB_PRECISION != 5 177 return std::numeric_limits<real>::digits10;
179 return std::numeric_limits<real>::digits10();
189 digits10() > std::numeric_limits<double>::digits10 ?
190 digits10() - std::numeric_limits<double>::digits10 : 0;
202 template<
typename T>
static inline T
pi() {
204 static const T pi = atan2(T(0), T(-1));
210 static inline real
pi() {
return pi<real>(); }
216 template<
typename T>
static inline T
degree() {
217 static const T degree = pi<T>() / 180;
223 static inline real
degree() {
return degree<real>(); }
232 template<
typename T>
static inline T
sq(T x)
243 template<
typename T>
static inline T
hypot(T x, T y) {
244 #if GEOGRAPHICLIB_CXX11_MATH 245 using std::hypot;
return hypot(x, y);
247 using std::abs;
using std::sqrt;
248 x = abs(x); y = abs(y);
251 return x * sqrt(1 + y * y);
265 template<
typename T>
static inline T
expm1(T x) {
266 #if GEOGRAPHICLIB_CXX11_MATH 267 using std::expm1;
return expm1(x);
269 using std::exp;
using std::abs;
using std::log;
277 return abs(x) > 1 ? z : (z == 0 ? x : x * z / log(y));
288 template<
typename T>
static inline T
log1p(T x) {
289 #if GEOGRAPHICLIB_CXX11_MATH 290 using std::log1p;
return log1p(x);
300 return z == 0 ? x : x * log(y) / z;
311 template<
typename T>
static inline T
asinh(T x) {
312 #if GEOGRAPHICLIB_CXX11_MATH 313 using std::asinh;
return asinh(x);
315 using std::abs; T y = abs(x);
316 y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
317 return x < 0 ? -y : y;
328 template<
typename T>
static inline T
atanh(T x) {
329 #if GEOGRAPHICLIB_CXX11_MATH 330 using std::atanh;
return atanh(x);
332 using std::abs; T y = abs(x);
333 y = log1p(2 * y/(1 - y))/2;
334 return x < 0 ? -y : y;
345 template<
typename T>
static inline T
cbrt(T x) {
346 #if GEOGRAPHICLIB_CXX11_MATH 347 using std::cbrt;
return cbrt(x);
349 using std::abs;
using std::pow;
350 T y = pow(abs(x), 1/T(3));
351 return x < 0 ? -y : y;
369 template<
typename T>
static inline T
fma(T x, T y, T z) {
370 #if GEOGRAPHICLIB_CXX11_MATH 371 using std::fma;
return fma(x, y, z);
384 template<
typename T>
static inline void norm(T& x, T& y)
385 { T h = hypot(x, y); x /= h; y /= h; }
399 template<
typename T>
static inline T
sum(T u, T v, T& t) {
425 template<
typename T>
static inline T
polyval(
int N,
const T p[], T x)
426 { T y = N < 0 ? 0 : *p++;
while (--N >= 0) y = y * x + *p++;
return y; }
438 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 4 439 using std::remainder;
440 x = remainder(x, T(360));
return x != -180 ? x : 180;
443 T y = fmod(x, T(360));
444 #if defined(_MSC_VER) && _MSC_VER < 1900 452 return y <= -180 ? y + 360 : (y <= 180 ? y : y - 360);
464 template<
typename T>
static inline T
LatFix(T x)
465 {
using std::abs;
return abs(x) > 90 ? NaN<T>() : x; }
483 template<
typename T>
static inline T
AngDiff(T x, T y, T& e) {
484 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 4 485 using std::remainder;
486 T t, d = AngNormalize(sum(remainder(-x, T(360)),
487 remainder( y, T(360)), t));
489 T t, d = AngNormalize(sum(AngNormalize(-x), AngNormalize(y), t));
497 return sum(d == 180 && t > 0 ? -180 : d, t, e);
514 template<
typename T>
static inline T
AngDiff(T x, T y)
515 { T e;
return AngDiff(x, y, e); }
532 template<
typename T>
static inline T
AngRound(T x) {
534 static const T z = 1/T(16);
535 if (x == 0)
return 0;
538 y = y < z ? z - (z - y) : y;
539 return x < 0 ? -y : y;
555 template<
typename T>
static inline void sincosd(T x, T& sinx, T& cosx) {
558 using std::sin;
using std::cos;
560 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 569 r = remquo(x, T(90), &q);
571 using std::fmod;
using std::floor;
573 q = int(floor(r / 90 + T(0.5)));
579 T s = sin(r), c = cos(r);
580 #if defined(_MSC_VER) && _MSC_VER < 1900 589 switch (
unsigned(q) & 3U) {
590 case 0U: sinx = s; cosx = c;
break;
591 case 1U: sinx = c; cosx = -s;
break;
592 case 2U: sinx = -s; cosx = -c;
break;
593 default: sinx = -c; cosx = s;
break;
596 if (x) { sinx += T(0); cosx += T(0); }
606 template<
typename T>
static inline T
sind(T x) {
608 using std::sin;
using std::cos;
610 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 613 r = remquo(x, T(90), &q);
615 using std::fmod;
using std::floor;
617 q = int(floor(r / 90 + T(0.5)));
622 unsigned p = unsigned(q);
623 r = p & 1U ? cos(r) : sin(r);
636 template<
typename T>
static inline T
cosd(T x) {
638 using std::sin;
using std::cos;
640 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 643 r = remquo(x, T(90), &q);
645 using std::fmod;
using std::floor;
647 q = int(floor(r / 90 + T(0.5)));
652 unsigned p = unsigned(q + 1);
653 r = p & 1U ? cos(r) : sin(r);
668 template<
typename T>
static inline T
tand(T x) {
669 static const T overflow = 1 / sq(std::numeric_limits<T>::epsilon());
672 return c ? s / c : (s < 0 ? -overflow : overflow);
688 template<
typename T>
static inline T
atan2d(T y, T x) {
693 using std::atan2;
using std::abs;
695 if (abs(y) > abs(x)) {
std::swap(x, y); q = 2; }
696 if (x < 0) { x = -x; ++q; }
698 T ang = atan2(y, x) / degree();
706 case 1: ang = (y >= 0 ? 180 : -180) - ang;
break;
707 case 2: ang = 90 - ang;
break;
708 case 3: ang = -90 + ang;
break;
720 template<
typename T>
static inline T
atand(T x)
721 {
return atan2d(x, T(1)); }
735 template<
typename T>
static T eatanhe(T x, T es);
748 template<
typename T>
static inline T
copysign(T x, T y) {
749 #if GEOGRAPHICLIB_CXX11_MATH 750 using std::copysign;
return copysign(x, y);
754 return abs(x) * (y < 0 || (y == 0 && 1/y < 0) ? -1 : 1);
774 template<
typename T>
static T taupf(T tau, T es);
792 template<
typename T>
static T tauf(T taup, T es);
801 template<
typename T>
static inline bool isfinite(T x) {
802 #if GEOGRAPHICLIB_CXX11_MATH 803 using std::isfinite;
return isfinite(x);
806 #if defined(_MSC_VER) 807 return abs(x) <= (std::numeric_limits<T>::max)();
814 return abs(x) <= std::numeric_limits<T>::max();
825 template<
typename T>
static inline T
NaN() {
826 #if defined(_MSC_VER) 827 return std::numeric_limits<T>::has_quiet_NaN ?
828 std::numeric_limits<T>::quiet_NaN() :
829 (std::numeric_limits<T>::max)();
831 return std::numeric_limits<T>::has_quiet_NaN ?
832 std::numeric_limits<T>::quiet_NaN() :
833 std::numeric_limits<T>::max();
839 static inline real
NaN() {
return NaN<real>(); }
848 template<
typename T>
static inline bool isnan(T x) {
849 #if GEOGRAPHICLIB_CXX11_MATH 850 using std::isnan;
return isnan(x);
863 #if defined(_MSC_VER) 864 return std::numeric_limits<T>::has_infinity ?
865 std::numeric_limits<T>::infinity() :
866 (std::numeric_limits<T>::max)();
868 return std::numeric_limits<T>::has_infinity ?
869 std::numeric_limits<T>::infinity() :
870 std::numeric_limits<T>::max();
876 static inline real
infinity() {
return infinity<real>(); }
885 template<
typename T>
static inline T
swab(T x) {
888 unsigned char c[
sizeof(T)];
891 for (
int i =
sizeof(T)/2; i--; )
892 std::swap(b.c[i], b.c[
sizeof(T) - 1 - i]);
896 #if GEOGRAPHICLIB_PRECISION == 4 897 typedef boost::math::policies::policy
898 < boost::math::policies::domain_error
899 <boost::math::policies::errno_on_error>,
900 boost::math::policies::pole_error
901 <boost::math::policies::errno_on_error>,
902 boost::math::policies::overflow_error
903 <boost::math::policies::errno_on_error>,
904 boost::math::policies::evaluation_error
905 <boost::math::policies::errno_on_error> >
906 boost_special_functions_policy;
908 static inline real hypot(real x, real y)
909 {
return boost::math::hypot(x, y, boost_special_functions_policy()); }
911 static inline real expm1(real x)
912 {
return boost::math::expm1(x, boost_special_functions_policy()); }
914 static inline real log1p(real x)
915 {
return boost::math::log1p(x, boost_special_functions_policy()); }
917 static inline real asinh(real x)
918 {
return boost::math::asinh(x, boost_special_functions_policy()); }
920 static inline real atanh(real x)
921 {
return boost::math::atanh(x, boost_special_functions_policy()); }
923 static inline real cbrt(real x)
924 {
return boost::math::cbrt(x, boost_special_functions_policy()); }
926 static inline real fma(real x, real y, real z)
927 {
return fmaq(__float128(x), __float128(y), __float128(z)); }
929 static inline real copysign(real x, real y)
930 {
return boost::math::copysign(x, y); }
932 static inline bool isnan(real x) {
return boost::math::isnan(x); }
934 static inline bool isfinite(real x) {
return boost::math::isfinite(x); }
940 #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.
static void sincosd(T x, T &sinx, T &cosx)
static T AngDiff(T x, T y, T &e)
static void norm(T &x, T &y)
#define GEOGRAPHICLIB_PRECISION
#define GEOGRAPHICLIB_VOLATILE
static int extra_digits()
static T atan2d(T y, T x)
static T polyval(int N, const T p[], T x)
Namespace for GeographicLib.
static T AngDiff(T x, T y)
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)
static T copysign(T x, T y)
Header for GeographicLib::Constants class.
static T fma(T x, T y, T z)