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 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 T
pi() {
204 static const T pi = atan2(T(0), T(-1));
217 static const T degree = pi<T>() / 180;
232 template<
typename T>
static T
sq(T x)
243 template<
typename T>
static 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 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 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 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 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 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 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 void norm(T& x, T& y)
385 { T h = hypot(x, y); x /= h; y /= h; }
399 template<
typename T>
static T
sum(T u, T v, T& t) {
425 template<
typename T>
static T
polyval(
int N,
const T p[], T x)
429 { T y = N < 0 ? 0 : *p++;
while (--N >= 0) y = y * x + *p++;
return y; }
441 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 4 442 using std::remainder;
443 x = remainder(x, T(360));
return x != -180 ? x : 180;
446 T y = fmod(x, T(360));
447 #if defined(_MSC_VER) && _MSC_VER < 1900 455 return y <= -180 ? y + 360 : (y <= 180 ? y : y - 360);
467 template<
typename T>
static T
LatFix(T x)
468 {
using std::abs;
return abs(x) > 90 ? NaN<T>() : x; }
486 template<
typename T>
static T
AngDiff(T x, T y, T& e) {
487 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 4 488 using std::remainder;
489 T t, d = AngNormalize(sum(remainder(-x, T(360)),
490 remainder( y, T(360)), t));
492 T t, d = AngNormalize(sum(AngNormalize(-x), AngNormalize(y), t));
500 return sum(d == 180 && t > 0 ? -180 : d, t, e);
517 template<
typename T>
static T
AngDiff(T x, T y)
518 { T e;
return AngDiff(x, y, e); }
537 static const T z = 1/T(16);
538 if (x == 0)
return 0;
541 y = y < z ? z - (z - y) : y;
542 return x < 0 ? -y : y;
558 template<
typename T>
static void sincosd(T x, T& sinx, T& cosx) {
561 using std::sin;
using std::cos;
563 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 572 r = remquo(x, T(90), &q);
574 using std::fmod;
using std::floor;
576 q = int(floor(r / 90 + T(0.5)));
582 T s = sin(r), c = cos(r);
583 #if defined(_MSC_VER) && _MSC_VER < 1900 592 switch (
unsigned(q) & 3U) {
593 case 0U: sinx = s; cosx = c;
break;
594 case 1U: sinx = c; cosx = -s;
break;
595 case 2U: sinx = -s; cosx = -c;
break;
596 default: sinx = -c; cosx = s;
break;
599 if (x != 0) { sinx += T(0); cosx += T(0); }
609 template<
typename T>
static T
sind(T x) {
611 using std::sin;
using std::cos;
613 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 616 r = remquo(x, T(90), &q);
618 using std::fmod;
using std::floor;
620 q = int(floor(r / 90 + T(0.5)));
625 unsigned p = unsigned(q);
626 r = p & 1U ? cos(r) : sin(r);
628 if (x != 0) r += T(0);
639 template<
typename T>
static T
cosd(T x) {
641 using std::sin;
using std::cos;
643 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \ 646 r = remquo(x, T(90), &q);
648 using std::fmod;
using std::floor;
650 q = int(floor(r / 90 + T(0.5)));
655 unsigned p = unsigned(q + 1);
656 r = p & 1U ? cos(r) : sin(r);
671 template<
typename T>
static T
tand(T x) {
672 static const T overflow = 1 / sq(std::numeric_limits<T>::epsilon());
675 return c != 0 ? s / c : (s < 0 ? -overflow : overflow);
691 template<
typename T>
static T
atan2d(T y, T x) {
696 using std::atan2;
using std::abs;
698 if (abs(y) > abs(x)) {
std::swap(x, y); q = 2; }
699 if (x < 0) { x = -x; ++q; }
701 T ang = atan2(y, x) / degree();
709 case 1: ang = (y >= 0 ? 180 : -180) - ang;
break;
710 case 2: ang = 90 - ang;
break;
711 case 3: ang = -90 + ang;
break;
723 template<
typename T>
static T
atand(T x)
724 {
return atan2d(x, T(1)); }
738 template<
typename T>
static T eatanhe(T x, T es);
752 #if GEOGRAPHICLIB_CXX11_MATH 753 using std::copysign;
return copysign(x, y);
757 return abs(x) * (y < 0 || (y == 0 && 1/y < 0) ? -1 : 1);
778 template<
typename T>
static T taupf(T tau, T es);
797 template<
typename T>
static T tauf(T taup, T es);
807 #if GEOGRAPHICLIB_CXX11_MATH 808 using std::isfinite;
return isfinite(x);
811 #if defined(_MSC_VER) 812 return abs(x) <= (std::numeric_limits<T>::max)();
819 return abs(x) <= std::numeric_limits<T>::max();
830 template<
typename T>
static T
NaN() {
831 #if defined(_MSC_VER) 832 return std::numeric_limits<T>::has_quiet_NaN ?
833 std::numeric_limits<T>::quiet_NaN() :
834 (std::numeric_limits<T>::max)();
836 return std::numeric_limits<T>::has_quiet_NaN ?
837 std::numeric_limits<T>::quiet_NaN() :
838 std::numeric_limits<T>::max();
853 template<
typename T>
static bool isnan(T x) {
854 #if GEOGRAPHICLIB_CXX11_MATH 855 using std::isnan;
return isnan(x);
868 #if defined(_MSC_VER) 869 return std::numeric_limits<T>::has_infinity ?
870 std::numeric_limits<T>::infinity() :
871 (std::numeric_limits<T>::max)();
873 return std::numeric_limits<T>::has_infinity ?
874 std::numeric_limits<T>::infinity() :
875 std::numeric_limits<T>::max();
890 template<
typename T>
static T
swab(T x) {
893 unsigned char c[
sizeof(T)];
896 for (
int i =
sizeof(T)/2; i--; )
897 std::swap(b.c[i], b.c[
sizeof(T) - 1 - i]);
901 #if GEOGRAPHICLIB_PRECISION == 4 902 typedef boost::math::policies::policy
903 < boost::math::policies::domain_error
904 <boost::math::policies::errno_on_error>,
905 boost::math::policies::pole_error
906 <boost::math::policies::errno_on_error>,
907 boost::math::policies::overflow_error
908 <boost::math::policies::errno_on_error>,
909 boost::math::policies::evaluation_error
910 <boost::math::policies::errno_on_error> >
911 boost_special_functions_policy;
914 {
return boost::math::hypot(x, y, boost_special_functions_policy()); }
917 {
return boost::math::expm1(x, boost_special_functions_policy()); }
920 {
return boost::math::log1p(x, boost_special_functions_policy()); }
923 {
return boost::math::asinh(x, boost_special_functions_policy()); }
926 {
return boost::math::atanh(x, boost_special_functions_policy()); }
929 {
return boost::math::cbrt(x, boost_special_functions_policy()); }
932 {
return fmaq(__float128(x), __float128(y), __float128(z)); }
935 {
return boost::math::copysign(x, y); }
937 static bool isnan(
real x) {
return boost::math::isnan(x); }
939 static bool isfinite(
real x) {
return boost::math::isfinite(x); }
945 #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)