1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
7 // This file was modified by Oracle on 2014, 2015.
8 // Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
20 #ifndef BOOST_GEOMETRY_UTIL_MATH_HPP
21 #define BOOST_GEOMETRY_UTIL_MATH_HPP
26 #include <boost/core/ignore_unused.hpp>
28 #include <boost/math/constants/constants.hpp>
29 #include <boost/math/special_functions/fpclassify.hpp>
30 //#include <boost/math/special_functions/round.hpp>
31 #include <boost/numeric/conversion/cast.hpp>
32 #include <boost/type_traits/is_fundamental.hpp>
33 #include <boost/type_traits/is_integral.hpp>
35 #include <boost/geometry/core/cs.hpp>
37 #include <boost/geometry/util/select_most_precise.hpp>
39 namespace boost { namespace geometry
45 #ifndef DOXYGEN_NO_DETAIL
50 inline T const& greatest(T const& v1, T const& v2)
52 return (std::max)(v1, v2);
56 inline T const& greatest(T const& v1, T const& v2, T const& v3)
58 return (std::max)(greatest(v1, v2), v3);
62 inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4)
64 return (std::max)(greatest(v1, v2, v3), v4);
68 inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4, T const& v5)
70 return (std::max)(greatest(v1, v2, v3, v4), v5);
75 inline T bounded(T const& v, T const& lower, T const& upper)
77 return (std::min)((std::max)(v, lower), upper);
81 inline T bounded(T const& v, T const& lower)
83 return (std::max)(v, lower);
88 bool IsFloatingPoint = boost::is_floating_point<T>::value>
91 static inline T apply(T const& value)
94 return value < zero ? -value : value;
101 static inline T apply(T const& value)
104 using std::fabs; // for long double
111 struct equals_default_policy
113 template <typename T>
114 static inline T apply(T const& a, T const& b)
116 // See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
117 return greatest(abs<T>::apply(a), abs<T>::apply(b), T(1));
121 template <typename T,
122 bool IsFloatingPoint = boost::is_floating_point<T>::value>
123 struct equals_factor_policy
125 equals_factor_policy()
127 explicit equals_factor_policy(T const& v)
128 : factor(greatest(abs<T>::apply(v), T(1)))
130 equals_factor_policy(T const& v0, T const& v1, T const& v2, T const& v3)
131 : factor(greatest(abs<T>::apply(v0), abs<T>::apply(v1),
132 abs<T>::apply(v2), abs<T>::apply(v3),
136 T const& apply(T const&, T const&) const
144 template <typename T>
145 struct equals_factor_policy<T, false>
147 equals_factor_policy() {}
148 explicit equals_factor_policy(T const&) {}
149 equals_factor_policy(T const& , T const& , T const& , T const& ) {}
151 static inline T apply(T const&, T const&)
157 template <typename Type,
158 bool IsFloatingPoint = boost::is_floating_point<Type>::value>
161 template <typename Policy>
162 static inline bool apply(Type const& a, Type const& b, Policy const&)
168 template <typename Type>
169 struct equals<Type, true>
171 template <typename Policy>
172 static inline bool apply(Type const& a, Type const& b, Policy const& policy)
174 boost::ignore_unused(policy);
181 if (boost::math::isfinite(a) && boost::math::isfinite(b))
183 // If a is INF and b is e.g. 0, the expression below returns true
184 // but the values are obviously not equal, hence the condition
185 return abs<Type>::apply(a - b)
186 <= std::numeric_limits<Type>::epsilon() * policy.apply(a, b);
195 template <typename T1, typename T2, typename Policy>
196 inline bool equals_by_policy(T1 const& a, T2 const& b, Policy const& policy)
198 return detail::equals
200 typename select_most_precise<T1, T2>::type
201 >::apply(a, b, policy);
204 template <typename Type,
205 bool IsFloatingPoint = boost::is_floating_point<Type>::value>
208 static inline bool apply(Type const& a, Type const& b)
214 template <typename Type>
215 struct smaller<Type, true>
217 static inline bool apply(Type const& a, Type const& b)
219 if (!(a < b)) // a >= b
224 return ! equals<Type, true>::apply(b, a, equals_default_policy());
228 template <typename Type,
229 bool IsFloatingPoint = boost::is_floating_point<Type>::value>
230 struct smaller_or_equals
232 static inline bool apply(Type const& a, Type const& b)
238 template <typename Type>
239 struct smaller_or_equals<Type, true>
241 static inline bool apply(Type const& a, Type const& b)
248 return equals<Type, true>::apply(a, b, equals_default_policy());
253 template <typename Type,
254 bool IsFloatingPoint = boost::is_floating_point<Type>::value>
255 struct equals_with_epsilon
256 : public equals<Type, IsFloatingPoint>
262 bool IsFundemantal = boost::is_fundamental<T>::value /* false */
266 typedef T return_type;
268 static inline T apply(T const& value)
270 // for non-fundamental number types assume that sqrt is
272 // 1) at T's scope, or
273 // 2) at global scope, or
274 // 3) in namespace std
282 template <typename FundamentalFP>
283 struct square_root_for_fundamental_fp
285 typedef FundamentalFP return_type;
287 static inline FundamentalFP apply(FundamentalFP const& value)
289 #ifdef BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
290 // This is a workaround for some 32-bit platforms.
291 // For some of those platforms it has been reported that
292 // std::sqrt(nan) and/or std::sqrt(-nan) returns a finite value.
293 // For those platforms we need to define the macro
294 // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS so that the argument
295 // to std::sqrt is checked appropriately before passed to std::sqrt
296 if (boost::math::isfinite(value))
298 return std::sqrt(value);
300 else if (boost::math::isinf(value) && value < 0)
302 return -std::numeric_limits<FundamentalFP>::quiet_NaN();
306 // for fundamental floating point numbers use std::sqrt
307 return std::sqrt(value);
308 #endif // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
313 struct square_root<float, true>
314 : square_root_for_fundamental_fp<float>
319 struct square_root<double, true>
320 : square_root_for_fundamental_fp<double>
325 struct square_root<long double, true>
326 : square_root_for_fundamental_fp<long double>
330 template <typename T>
331 struct square_root<T, true>
333 typedef double return_type;
335 static inline double apply(T const& value)
337 // for all other fundamental number types use also std::sqrt
339 // Note: in C++98 the only other possibility is double;
340 // in C++11 there are also overloads for integral types;
341 // this specialization works for those as well.
342 return square_root_for_fundamental_fp
345 >::apply(boost::numeric_cast<double>(value));
354 bool IsFundemantal = boost::is_fundamental<T>::value /* false */
358 typedef T return_type;
360 static inline T apply(T const& value1, T const& value2)
362 // for non-fundamental number types assume that a free
363 // function mod() is defined either:
364 // 1) at T's scope, or
365 // 2) at global scope
366 return mod(value1, value2);
372 typename Fundamental,
373 bool IsIntegral = boost::is_integral<Fundamental>::value
375 struct modulo_for_fundamental
377 typedef Fundamental return_type;
379 static inline Fundamental apply(Fundamental const& value1,
380 Fundamental const& value2)
382 return value1 % value2;
386 // specialization for floating-point numbers
387 template <typename Fundamental>
388 struct modulo_for_fundamental<Fundamental, false>
390 typedef Fundamental return_type;
392 static inline Fundamental apply(Fundamental const& value1,
393 Fundamental const& value2)
395 return std::fmod(value1, value2);
399 // specialization for fundamental number type
400 template <typename Fundamental>
401 struct modulo<Fundamental, true>
402 : modulo_for_fundamental<Fundamental>
408 \brief Short constructs to enable partial specialization for PI, 2*PI
409 and PI/2, currently not possible in Math.
411 template <typename T>
414 static inline T apply()
416 // Default calls Boost.Math
417 return boost::math::constants::pi<T>();
421 template <typename T>
424 static inline T apply()
426 // Default calls Boost.Math
427 return boost::math::constants::two_pi<T>();
431 template <typename T>
432 struct define_half_pi
434 static inline T apply()
436 // Default calls Boost.Math
437 return boost::math::constants::half_pi<T>();
441 template <typename T>
442 struct relaxed_epsilon
444 static inline T apply(const T& factor)
446 return factor * std::numeric_limits<T>::epsilon();
450 // This must be consistent with math::equals.
451 // By default math::equals() scales the error by epsilon using the greater of
452 // compared values but here is only one value, though it should work the same way.
453 // (a-a) <= max(a, a) * EPS -> 0 <= a*EPS
454 // (a+da-a) <= max(a+da, a) * EPS -> da <= (a+da)*EPS
455 template <typename T, bool IsFloat = boost::is_floating_point<T>::value>
456 struct scaled_epsilon
458 static inline T apply(T const& val)
460 return (std::max)(abs<T>::apply(val), T(1))
461 * std::numeric_limits<T>::epsilon();
465 template <typename T>
466 struct scaled_epsilon<T, false>
468 static inline T apply(T const&)
475 template <typename Result, typename Source,
476 bool ResultIsInteger = std::numeric_limits<Result>::is_integer,
477 bool SourceIsInteger = std::numeric_limits<Source>::is_integer>
480 static inline Result apply(Source const& v)
482 return boost::numeric_cast<Result>(v);
487 template <typename Source, bool ResultIsInteger, bool SourceIsInteger>
488 struct rounding_cast<Source, Source, ResultIsInteger, SourceIsInteger>
490 static inline Source apply(Source const& v)
497 template <typename Result, typename Source>
498 struct rounding_cast<Result, Source, true, false>
500 static inline Result apply(Source const& v)
502 return boost::numeric_cast<Result>(v < Source(0) ?
508 } // namespace detail
512 template <typename T>
513 inline T pi() { return detail::define_pi<T>::apply(); }
515 template <typename T>
516 inline T two_pi() { return detail::define_two_pi<T>::apply(); }
518 template <typename T>
519 inline T half_pi() { return detail::define_half_pi<T>::apply(); }
521 template <typename T>
522 inline T relaxed_epsilon(T const& factor)
524 return detail::relaxed_epsilon<T>::apply(factor);
527 template <typename T>
528 inline T scaled_epsilon(T const& value)
530 return detail::scaled_epsilon<T>::apply(value);
534 // Maybe replace this by boost equals or so
537 \brief returns true if both arguments are equal.
539 \param a first argument
540 \param b second argument
541 \return true if a == b
542 \note If both a and b are of an integral type, comparison is done by ==.
543 If one of the types is floating point, comparison is done by abs and
544 comparing with epsilon. If one of the types is non-fundamental, it might
545 be a high-precision number and comparison is done using the == operator
549 template <typename T1, typename T2>
550 inline bool equals(T1 const& a, T2 const& b)
552 return detail::equals
554 typename select_most_precise<T1, T2>::type
555 >::apply(a, b, detail::equals_default_policy());
558 template <typename T1, typename T2>
559 inline bool equals_with_epsilon(T1 const& a, T2 const& b)
561 return detail::equals_with_epsilon
563 typename select_most_precise<T1, T2>::type
564 >::apply(a, b, detail::equals_default_policy());
567 template <typename T1, typename T2>
568 inline bool smaller(T1 const& a, T2 const& b)
570 return detail::smaller
572 typename select_most_precise<T1, T2>::type
576 template <typename T1, typename T2>
577 inline bool larger(T1 const& a, T2 const& b)
579 return detail::smaller
581 typename select_most_precise<T1, T2>::type
585 template <typename T1, typename T2>
586 inline bool smaller_or_equals(T1 const& a, T2 const& b)
588 return detail::smaller_or_equals
590 typename select_most_precise<T1, T2>::type
594 template <typename T1, typename T2>
595 inline bool larger_or_equals(T1 const& a, T2 const& b)
597 return detail::smaller_or_equals
599 typename select_most_precise<T1, T2>::type
604 template <typename T>
607 static T const conversion_coefficient = geometry::math::pi<T>() / T(180.0);
608 return conversion_coefficient;
611 template <typename T>
614 static T const conversion_coefficient = T(180.0) / geometry::math::pi<T>();
615 return conversion_coefficient;
619 #ifndef DOXYGEN_NO_DETAIL
622 template <typename DegreeOrRadian>
625 template <typename T>
626 static inline T apply(T const& value)
633 struct as_radian<degree>
635 template <typename T>
636 static inline T apply(T const& value)
638 return value * d2r<T>();
642 template <typename DegreeOrRadian>
645 template <typename T>
646 static inline T apply(T const& value)
653 struct from_radian<degree>
655 template <typename T>
656 static inline T apply(T const& value)
658 return value * r2d<T>();
662 } // namespace detail
665 template <typename DegreeOrRadian, typename T>
666 inline T as_radian(T const& value)
668 return detail::as_radian<DegreeOrRadian>::apply(value);
671 template <typename DegreeOrRadian, typename T>
672 inline T from_radian(T const& value)
674 return detail::from_radian<DegreeOrRadian>::apply(value);
679 \brief Calculates the haversine of an angle
681 \note See http://en.wikipedia.org/wiki/Haversine_formula
682 haversin(alpha) = sin2(alpha/2)
684 template <typename T>
685 inline T hav(T const& theta)
687 T const half = T(0.5);
688 T const sn = sin(half * theta);
693 \brief Short utility to return the square
695 \param value Value to calculate the square from
696 \return The squared value
698 template <typename T>
699 inline T sqr(T const& value)
701 return value * value;
705 \brief Short utility to return the square root
707 \param value Value to calculate the square root from
708 \return The square root value
710 template <typename T>
711 inline typename detail::square_root<T>::return_type
714 return detail::square_root
716 T, boost::is_fundamental<T>::value
721 \brief Short utility to return the modulo of two values
723 \param value1 First value
724 \param value2 Second value
725 \return The result of the modulo operation on the (ordered) pair
728 template <typename T>
729 inline typename detail::modulo<T>::return_type
730 mod(T const& value1, T const& value2)
732 return detail::modulo
734 T, boost::is_fundamental<T>::value
735 >::apply(value1, value2);
739 \brief Short utility to workaround gcc/clang problem that abs is converting to integer
740 and that older versions of MSVC does not support abs of long long...
744 inline T abs(T const& value)
746 return detail::abs<T>::apply(value);
750 \brief Short utility to calculate the sign of a number: -1 (negative), 0 (zero), 1 (positive)
753 template <typename T>
754 inline int sign(T const& value)
757 return value > zero ? 1 : value < zero ? -1 : 0;
761 \brief Short utility to cast a value possibly rounding it to the nearest
764 \note If the source T is NOT an integral type and Result is an integral type
765 the value is rounded towards the closest integral value. Otherwise it's
766 casted without rounding.
768 template <typename Result, typename T>
769 inline Result rounding_cast(T const& v)
771 return detail::rounding_cast<Result, T>::apply(v);
777 }} // namespace boost::geometry
779 #endif // BOOST_GEOMETRY_UTIL_MATH_HPP