Math.hpp
Go to the documentation of this file.
1 
10 // Constants.hpp includes Math.hpp. Place this include outside Math.hpp's
11 // include guard to enforce this ordering.
13 
14 #if !defined(GEOGRAPHICLIB_MATH_HPP)
15 #define GEOGRAPHICLIB_MATH_HPP 1
16 
20 #if !defined(GEOGRAPHICLIB_CXX11_MATH)
21 // Recent versions of g++ -std=c++11 (4.7 and later?) set __cplusplus to 201103
22 // and support the new C++11 mathematical functions, std::atanh, etc. However
23 // the Android toolchain, which uses g++ -std=c++11 (4.8 as of 2014-03-11,
24 // according to Pullan Lu), does not support std::atanh. Android toolchains
25 // might define __ANDROID__ or ANDROID; so need to check both. With OSX the
26 // version is GNUC version 4.2 and __cplusplus is set to 201103, so remove the
27 // version check on GNUC.
28 # if defined(__GNUC__) && __cplusplus >= 201103 && \
29  !(defined(__ANDROID__) || defined(ANDROID) || defined(__CYGWIN__))
30 # define GEOGRAPHICLIB_CXX11_MATH 1
31 // Visual C++ 12 supports these functions
32 # elif defined(_MSC_VER) && _MSC_VER >= 1800
33 # define GEOGRAPHICLIB_CXX11_MATH 1
34 # else
35 # define GEOGRAPHICLIB_CXX11_MATH 0
36 # endif
37 #endif
38 
39 #if !defined(GEOGRAPHICLIB_WORDS_BIGENDIAN)
40 # define GEOGRAPHICLIB_WORDS_BIGENDIAN 0
41 #endif
42 
43 #if !defined(GEOGRAPHICLIB_HAVE_LONG_DOUBLE)
44 # define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 0
45 #endif
46 
47 #if !defined(GEOGRAPHICLIB_PRECISION)
48 
57 # define GEOGRAPHICLIB_PRECISION 2
58 #endif
59 
60 #include <cmath>
61 #include <algorithm>
62 #include <limits>
63 
64 #if GEOGRAPHICLIB_PRECISION == 4
65 #include <boost/version.hpp>
66 #if BOOST_VERSION >= 105600
67 #include <boost/cstdfloat.hpp>
68 #endif
69 #include <boost/multiprecision/float128.hpp>
70 #include <boost/math/special_functions.hpp>
71 __float128 fmaq(__float128, __float128, __float128);
72 #elif GEOGRAPHICLIB_PRECISION == 5
73 #include <mpreal.h>
74 #endif
75 
76 #if GEOGRAPHICLIB_PRECISION > 3
77 // volatile keyword makes no sense for multiprec types
78 #define GEOGRAPHICLIB_VOLATILE
79 // Signal a convergence failure with multiprec types by throwing an exception
80 // at loop exit.
81 #define GEOGRAPHICLIB_PANIC \
82  (throw GeographicLib::GeographicErr("Convergence failure"), false)
83 #else
84 #define GEOGRAPHICLIB_VOLATILE volatile
85 // Ignore convergence failures with standard floating points types by allowing
86 // loop to exit cleanly.
87 #define GEOGRAPHICLIB_PANIC false
88 #endif
89 
90 namespace GeographicLib {
91 
103  private:
104  void dummy() {
105  GEOGRAPHICLIB_STATIC_ASSERT(GEOGRAPHICLIB_PRECISION >= 1 &&
107  "Bad value of precision");
108  }
109  Math(); // Disable constructor
110  public:
111 
112 #if GEOGRAPHICLIB_HAVE_LONG_DOUBLE
113 
117  typedef long double extended;
118 #else
119  typedef double extended;
120 #endif
121 
122 #if GEOGRAPHICLIB_PRECISION == 2
123 
129  typedef double real;
130 #elif GEOGRAPHICLIB_PRECISION == 1
131  typedef float real;
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;
138 #else
139  typedef double real;
140 #endif
141 
145  static int digits() {
146 #if GEOGRAPHICLIB_PRECISION != 5
147  return std::numeric_limits<real>::digits;
148 #else
149  return std::numeric_limits<real>::digits();
150 #endif
151  }
152 
163  static int set_digits(int ndigits) {
164 #if GEOGRAPHICLIB_PRECISION != 5
165  (void)ndigits;
166 #else
167  mpfr::mpreal::set_default_prec(ndigits >= 2 ? ndigits : 2);
168 #endif
169  return digits();
170  }
171 
175  static int digits10() {
176 #if GEOGRAPHICLIB_PRECISION != 5
177  return std::numeric_limits<real>::digits10;
178 #else
179  return std::numeric_limits<real>::digits10();
180 #endif
181  }
182 
187  static int extra_digits() {
188  return
189  digits10() > std::numeric_limits<double>::digits10 ?
190  digits10() - std::numeric_limits<double>::digits10 : 0;
191  }
192 
196  static const bool bigendian = GEOGRAPHICLIB_WORDS_BIGENDIAN;
197 
202  template<typename T> static T pi() {
203  using std::atan2;
204  static const T pi = atan2(T(0), T(-1));
205  return pi;
206  }
210  static real pi() { return pi<real>(); }
211 
216  template<typename T> static T degree() {
217  static const T degree = pi<T>() / 180;
218  return degree;
219  }
223  static real degree() { return degree<real>(); }
224 
232  template<typename T> static T sq(T x)
233  { return x * x; }
234 
243  template<typename T> static T hypot(T x, T y) {
244 #if GEOGRAPHICLIB_CXX11_MATH
245  using std::hypot; return hypot(x, y);
246 #else
247  using std::abs; using std::sqrt;
248  x = abs(x); y = abs(y);
249  if (x < y) std::swap(x, y); // Now x >= y >= 0
250  y /= (x ? x : 1);
251  return x * sqrt(1 + y * y);
252  // For an alternative (square-root free) method see
253  // C. Moler and D. Morrision (1983) https://doi.org/10.1147/rd.276.0577
254  // and A. A. Dubrulle (1983) https://doi.org/10.1147/rd.276.0582
255 #endif
256  }
257 
265  template<typename T> static T expm1(T x) {
266 #if GEOGRAPHICLIB_CXX11_MATH
267  using std::expm1; return expm1(x);
268 #else
269  using std::exp; using std::abs; using std::log;
271  y = exp(x),
272  z = y - 1;
273  // The reasoning here is similar to that for log1p. The expression
274  // mathematically reduces to exp(x) - 1, and the factor z/log(y) = (y -
275  // 1)/log(y) is a slowly varying quantity near y = 1 and is accurately
276  // computed.
277  return abs(x) > 1 ? z : (z == 0 ? x : x * z / log(y));
278 #endif
279  }
280 
288  template<typename T> static T log1p(T x) {
289 #if GEOGRAPHICLIB_CXX11_MATH
290  using std::log1p; return log1p(x);
291 #else
292  using std::log;
294  y = 1 + x,
295  z = y - 1;
296  // Here's the explanation for this magic: y = 1 + z, exactly, and z
297  // approx x, thus log(y)/z (which is nearly constant near z = 0) returns
298  // a good approximation to the true log(1 + x)/x. The multiplication x *
299  // (log(y)/z) introduces little additional error.
300  return z == 0 ? x : x * log(y) / z;
301 #endif
302  }
303 
311  template<typename T> static T asinh(T x) {
312 #if GEOGRAPHICLIB_CXX11_MATH
313  using std::asinh; return asinh(x);
314 #else
315  using std::abs; T y = abs(x); // Enforce odd parity
316  y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
317  return x < 0 ? -y : y;
318 #endif
319  }
320 
328  template<typename T> static T atanh(T x) {
329 #if GEOGRAPHICLIB_CXX11_MATH
330  using std::atanh; return atanh(x);
331 #else
332  using std::abs; T y = abs(x); // Enforce odd parity
333  y = log1p(2 * y/(1 - y))/2;
334  return x < 0 ? -y : y;
335 #endif
336  }
337 
345  template<typename T> static T cbrt(T x) {
346 #if GEOGRAPHICLIB_CXX11_MATH
347  using std::cbrt; return cbrt(x);
348 #else
349  using std::abs; using std::pow;
350  T y = pow(abs(x), 1/T(3)); // Return the real cube root
351  return x < 0 ? -y : y;
352 #endif
353  }
354 
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);
372 #else
373  return x * y + z;
374 #endif
375  }
376 
384  template<typename T> static void norm(T& x, T& y)
385  { T h = hypot(x, y); x /= h; y /= h; }
386 
399  template<typename T> static T sum(T u, T v, T& t) {
400  GEOGRAPHICLIB_VOLATILE T s = u + v;
401  GEOGRAPHICLIB_VOLATILE T up = s - v;
402  GEOGRAPHICLIB_VOLATILE T vpp = s - up;
403  up -= u;
404  vpp -= v;
405  t = -(up + vpp);
406  // u + v = s + t
407  // = round(u + v) + t
408  return s;
409  }
410 
425  template<typename T> static T polyval(int N, const T p[], T x)
426  // This used to employ Math::fma; but that's too slow and it seemed not to
427  // improve the accuracy noticeably. This might change when there's direct
428  // hardware support for fma.
429  { T y = N < 0 ? 0 : *p++; while (--N >= 0) y = y * x + *p++; return y; }
430 
440  template<typename T> static T AngNormalize(T x) {
441 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION != 4
442  using std::remainder;
443  x = remainder(x, T(360)); return x != -180 ? x : 180;
444 #else
445  using std::fmod;
446  T y = fmod(x, T(360));
447 #if defined(_MSC_VER) && _MSC_VER < 1900
448  // Before version 14 (2015), Visual Studio had problems dealing
449  // with -0.0. Specifically
450  // VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
451  // sincosd has a similar fix.
452  // python 2.7 on Windows 32-bit machines has the same problem.
453  if (x == 0) y = x;
454 #endif
455  return y <= -180 ? y + 360 : (y <= 180 ? y : y - 360);
456 #endif
457  }
458 
467  template<typename T> static T LatFix(T x)
468  { using std::abs; return abs(x) > 90 ? NaN<T>() : x; }
469 
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));
491 #else
492  T t, d = AngNormalize(sum(AngNormalize(-x), AngNormalize(y), t));
493 #endif
494  // Here y - x = d + t (mod 360), exactly, where d is in (-180,180] and
495  // abs(t) <= eps (eps = 2^-45 for doubles). The only case where the
496  // addition of t takes the result outside the range (-180,180] is d = 180
497  // and t > 0. The case, d = -180 + eps, t = -eps, can't happen, since
498  // sum would have returned the exact result in such a case (i.e., given t
499  // = 0).
500  return sum(d == 180 && t > 0 ? -180 : d, t, e);
501  }
502 
517  template<typename T> static T AngDiff(T x, T y)
518  { T e; return AngDiff(x, y, e); }
519 
535  template<typename T> static T AngRound(T x) {
536  using std::abs;
537  static const T z = 1/T(16);
538  if (x == 0) return 0;
540  // The compiler mustn't "simplify" z - (z - y) to y
541  y = y < z ? z - (z - y) : y;
542  return x < 0 ? -y : y;
543  }
544 
558  template<typename T> static void sincosd(T x, T& sinx, T& cosx) {
559  // In order to minimize round-off errors, this function exactly reduces
560  // the argument to the range [-45, 45] before converting it to radians.
561  using std::sin; using std::cos;
562  T r; int q;
563 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \
564  !defined(__GNUC__)
565  // Disable for gcc because of bug in glibc version < 2.22, see
566  // https://sourceware.org/bugzilla/show_bug.cgi?id=17569
567  // Once this fix is widely deployed, should insert a runtime test for the
568  // glibc version number. For example
569  // #include <gnu/libc-version.h>
570  // std::string version(gnu_get_libc_version()); => "2.22"
571  using std::remquo;
572  r = remquo(x, T(90), &q);
573 #else
574  using std::fmod; using std::floor;
575  r = fmod(x, T(360));
576  q = int(floor(r / 90 + T(0.5)));
577  r -= 90 * q;
578 #endif
579  // now abs(r) <= 45
580  r *= degree();
581  // Possibly could call the gnu extension sincos
582  T s = sin(r), c = cos(r);
583 #if defined(_MSC_VER) && _MSC_VER < 1900
584  // Before version 14 (2015), Visual Studio had problems dealing
585  // with -0.0. Specifically
586  // VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
587  // VC 12 and 64-bit compile: sin(-0.0) -> +0.0
588  // AngNormalize has a similar fix.
589  // python 2.7 on Windows 32-bit machines has the same problem.
590  if (x == 0) s = x;
591 #endif
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; // case 3U
597  }
598  // Set sign of 0 results. -0 only produced for sin(-0)
599  if (x != 0) { sinx += T(0); cosx += T(0); }
600  }
601 
609  template<typename T> static T sind(T x) {
610  // See sincosd
611  using std::sin; using std::cos;
612  T r; int q;
613 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \
614  !defined(__GNUC__)
615  using std::remquo;
616  r = remquo(x, T(90), &q);
617 #else
618  using std::fmod; using std::floor;
619  r = fmod(x, T(360));
620  q = int(floor(r / 90 + T(0.5)));
621  r -= 90 * q;
622 #endif
623  // now abs(r) <= 45
624  r *= degree();
625  unsigned p = unsigned(q);
626  r = p & 1U ? cos(r) : sin(r);
627  if (p & 2U) r = -r;
628  if (x != 0) r += T(0);
629  return r;
630  }
631 
639  template<typename T> static T cosd(T x) {
640  // See sincosd
641  using std::sin; using std::cos;
642  T r; int q;
643 #if GEOGRAPHICLIB_CXX11_MATH && GEOGRAPHICLIB_PRECISION <= 3 && \
644  !defined(__GNUC__)
645  using std::remquo;
646  r = remquo(x, T(90), &q);
647 #else
648  using std::fmod; using std::floor;
649  r = fmod(x, T(360));
650  q = int(floor(r / 90 + T(0.5)));
651  r -= 90 * q;
652 #endif
653  // now abs(r) <= 45
654  r *= degree();
655  unsigned p = unsigned(q + 1);
656  r = p & 1U ? cos(r) : sin(r);
657  if (p & 2U) r = -r;
658  return T(0) + r;
659  }
660 
671  template<typename T> static T tand(T x) {
672  static const T overflow = 1 / sq(std::numeric_limits<T>::epsilon());
673  T s, c;
674  sincosd(x, s, c);
675  return c != 0 ? s / c : (s < 0 ? -overflow : overflow);
676  }
677 
691  template<typename T> static T atan2d(T y, T x) {
692  // In order to minimize round-off errors, this function rearranges the
693  // arguments so that result of atan2 is in the range [-pi/4, pi/4] before
694  // converting it to degrees and mapping the result to the correct
695  // quadrant.
696  using std::atan2; using std::abs;
697  int q = 0;
698  if (abs(y) > abs(x)) { std::swap(x, y); q = 2; }
699  if (x < 0) { x = -x; ++q; }
700  // here x >= 0 and x >= abs(y), so angle is in [-pi/4, pi/4]
701  T ang = atan2(y, x) / degree();
702  switch (q) {
703  // Note that atan2d(-0.0, 1.0) will return -0. However, we expect that
704  // atan2d will not be called with y = -0. If need be, include
705  //
706  // case 0: ang = 0 + ang; break;
707  //
708  // and handle mpfr as in AngRound.
709  case 1: ang = (y >= 0 ? 180 : -180) - ang; break;
710  case 2: ang = 90 - ang; break;
711  case 3: ang = -90 + ang; break;
712  }
713  return ang;
714  }
715 
723  template<typename T> static T atand(T x)
724  { return atan2d(x, T(1)); }
725 
738  template<typename T> static T eatanhe(T x, T es);
739 
751  template<typename T> static T copysign(T x, T y) {
752 #if GEOGRAPHICLIB_CXX11_MATH
753  using std::copysign; return copysign(x, y);
754 #else
755  using std::abs;
756  // NaN counts as positive
757  return abs(x) * (y < 0 || (y == 0 && 1/y < 0) ? -1 : 1);
758 #endif
759  }
760 
778  template<typename T> static T taupf(T tau, T es);
779 
797  template<typename T> static T tauf(T taup, T es);
798 
806  template<typename T> static bool isfinite(T x) {
807 #if GEOGRAPHICLIB_CXX11_MATH
808  using std::isfinite; return isfinite(x);
809 #else
810  using std::abs;
811 #if defined(_MSC_VER)
812  return abs(x) <= (std::numeric_limits<T>::max)();
813 #else
814  // There's a problem using MPFR C++ 3.6.3 and g++ -std=c++14 (reported on
815  // 2015-05-04) with the parens around std::numeric_limits<T>::max. Of
816  // course, these parens are only needed to deal with Windows stupidly
817  // defining max as a macro. So don't insert the parens on non-Windows
818  // platforms.
819  return abs(x) <= std::numeric_limits<T>::max();
820 #endif
821 #endif
822  }
823 
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() :
835 #else
836  return std::numeric_limits<T>::has_quiet_NaN ?
837  std::numeric_limits<T>::quiet_NaN() :
839 #endif
840  }
844  static real NaN() { return NaN<real>(); }
845 
853  template<typename T> static bool isnan(T x) {
854 #if GEOGRAPHICLIB_CXX11_MATH
855  using std::isnan; return isnan(x);
856 #else
857  return x != x;
858 #endif
859  }
860 
867  template<typename T> static T infinity() {
868 #if defined(_MSC_VER)
869  return std::numeric_limits<T>::has_infinity ?
870  std::numeric_limits<T>::infinity() :
872 #else
873  return std::numeric_limits<T>::has_infinity ?
874  std::numeric_limits<T>::infinity() :
876 #endif
877  }
881  static real infinity() { return infinity<real>(); }
882 
890  template<typename T> static T swab(T x) {
891  union {
892  T r;
893  unsigned char c[sizeof(T)];
894  } b;
895  b.r = x;
896  for (int i = sizeof(T)/2; i--; )
897  std::swap(b.c[i], b.c[sizeof(T) - 1 - i]);
898  return b.r;
899  }
900 
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;
912 
913  static real hypot(real x, real y)
914  { return boost::math::hypot(x, y, boost_special_functions_policy()); }
915 
916  static real expm1(real x)
917  { return boost::math::expm1(x, boost_special_functions_policy()); }
918 
919  static real log1p(real x)
920  { return boost::math::log1p(x, boost_special_functions_policy()); }
921 
922  static real asinh(real x)
923  { return boost::math::asinh(x, boost_special_functions_policy()); }
924 
925  static real atanh(real x)
926  { return boost::math::atanh(x, boost_special_functions_policy()); }
927 
928  static real cbrt(real x)
929  { return boost::math::cbrt(x, boost_special_functions_policy()); }
930 
931  static real fma(real x, real y, real z)
932  { return fmaq(__float128(x), __float128(y), __float128(z)); }
933 
934  static real copysign(real x, real y)
935  { return boost::math::copysign(x, y); }
936 
937  static bool isnan(real x) { return boost::math::isnan(x); }
938 
939  static bool isfinite(real x) { return boost::math::isfinite(x); }
940 #endif
941  };
942 
943 } // namespace GeographicLib
944 
945 #endif // GEOGRAPHICLIB_MATH_HPP
static T AngNormalize(T x)
Definition: Math.hpp:440
EIGEN_DEVICE_FUNC const Log1pReturnType log1p() const
static T NaN()
Definition: Math.hpp:830
static T sum(T u, T v, T &t)
Definition: Math.hpp:399
static int digits10()
Definition: Math.hpp:175
#define max(a, b)
Definition: datatypes.h:20
static int set_digits(int ndigits)
Definition: Math.hpp:163
static T pi()
Definition: Math.hpp:202
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:91
Jet< T, N > cos(const Jet< T, N > &f)
Definition: jet.h:426
float real
Definition: datatypes.h:10
Scalar * y
Scalar * b
Definition: benchVecAdd.cpp:17
static T atand(T x)
Definition: Math.hpp:723
static T infinity()
Definition: Math.hpp:867
#define GEOGRAPHICLIB_WORDS_BIGENDIAN
Definition: Math.hpp:40
static real degree()
Definition: Math.hpp:223
static T cbrt(T x)
Definition: Math.hpp:345
static bool isfinite(T x)
Definition: Math.hpp:806
static bool isnan(T x)
Definition: Math.hpp:853
static T LatFix(T x)
Definition: Math.hpp:467
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
Jet< T, N > sin(const Jet< T, N > &f)
Definition: jet.h:439
Mathematical functions needed by GeographicLib.
Definition: Math.hpp:102
static T sind(T x)
Definition: Math.hpp:609
static void sincosd(T x, T &sinx, T &cosx)
Definition: Math.hpp:558
static T AngDiff(T x, T y, T &e)
Definition: Math.hpp:486
static T atanh(T x)
Definition: Math.hpp:328
#define isfinite(X)
Definition: main.h:95
#define N
Definition: gksort.c:12
static T expm1(T x)
Definition: Math.hpp:265
static void norm(T &x, T &y)
Definition: Math.hpp:384
#define GEOGRAPHICLIB_PRECISION
Definition: Math.hpp:57
EIGEN_DEVICE_FUNC const LogReturnType log() const
#define GEOGRAPHICLIB_VOLATILE
Definition: Math.hpp:84
static double epsilon
Definition: testRot3.cpp:37
static T asinh(T x)
Definition: Math.hpp:311
static int extra_digits()
Definition: Math.hpp:187
EIGEN_DEVICE_FUNC const ExpReturnType exp() const
EIGEN_DEVICE_FUNC const FloorReturnType floor() const
const double degree
EIGEN_DEVICE_FUNC const Expm1ReturnType expm1() const
static T hypot(T x, T y)
Definition: Math.hpp:243
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 fmod(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:567
static T sq(T x)
Definition: Math.hpp:232
static real pi()
Definition: Math.hpp:210
static T cosd(T x)
Definition: Math.hpp:639
Array< int, Dynamic, 1 > v
static T atan2d(T y, T x)
Definition: Math.hpp:691
Eigen::Triplet< double > T
static T polyval(int N, const T p[], T x)
Definition: Math.hpp:425
Namespace for GeographicLib.
Array< double, 1, 3 > e(1./3., 0.5, 2.)
RealScalar s
EIGEN_DEVICE_FUNC const Scalar & q
static T degree()
Definition: Math.hpp:216
static T AngDiff(T x, T y)
Definition: Math.hpp:517
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)
static real NaN()
Definition: Math.hpp:844
AnnoyingScalar atan2(const AnnoyingScalar &y, const AnnoyingScalar &x)
static T log1p(T x)
Definition: Math.hpp:288
static T tand(T x)
Definition: Math.hpp:671
const double h
static T copysign(T x, T y)
Definition: Math.hpp:751
static T swab(T x)
Definition: Math.hpp:890
static real infinity()
Definition: Math.hpp:881
Header for GeographicLib::Constants class.
float * p
EigenSolver< MatrixXf > es
static T fma(T x, T y, T z)
Definition: Math.hpp:369
Jet< T, N > sqrt(const Jet< T, N > &f)
Definition: jet.h:418
Jet< T, N > pow(const Jet< T, N > &f, double g)
Definition: jet.h:570
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
#define abs(x)
Definition: datatypes.h:17
static T AngRound(T x)
Definition: Math.hpp:535
static int digits()
Definition: Math.hpp:145
Point2 t(10, 10)
#define isnan(X)
Definition: main.h:93


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:45