From ef171f3acd83608431db7416bf671a62b08748e4 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Thu, 28 Jan 2016 15:21:02 +0100 Subject: [PATCH] Properly use typed math constants instead of impl. specific hacks PI is not in the stdlib, neither is 1/pi, pi*2 and so on. Instead of relying on implementations providing these, use properly typed math constants. Main benefits: - portable and - returns constexpr, for compile-time computation References: - http://www.boost.org/doc/libs/1_60_0/libs/math/doc/html/math_toolkit/constants_intro.html - http://www.boost.org/doc/libs/1_60_0/libs/math/doc/html/math_toolkit/constants.html --- CMakeLists.txt | 2 -- .../engine/map_matching/bayes_classifier.hpp | 6 ++++- .../map_matching/hidden_markov_model.hpp | 3 ++- include/util/trigonometry_table.hpp | 23 +++++++++------- include/util/typedefs.hpp | 8 ------ src/util/coordinate_calculation.cpp | 26 +++++++++++++++---- 6 files changed, 42 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f238c834..efc6d36bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,7 +163,6 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") # using GCC set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=1 -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC") if(WIN32) # using mingw - add_definitions(-D_USE_MATH_DEFINES) # define M_PI, M_1_PI etc. add_definitions(-DWIN32) set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32) endif() @@ -175,7 +174,6 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib) add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation - add_definitions(-D_USE_MATH_DEFINES) # define M_PI add_definitions(-D_WIN32_WINNT=0x0501) add_definitions(-DXML_STATIC) find_library(ws2_32_LIBRARY_PATH ws2_32) diff --git a/include/engine/map_matching/bayes_classifier.hpp b/include/engine/map_matching/bayes_classifier.hpp index f3c2e8eee..59b9fb5ae 100644 --- a/include/engine/map_matching/bayes_classifier.hpp +++ b/include/engine/map_matching/bayes_classifier.hpp @@ -6,6 +6,8 @@ #include #include +#include + namespace osrm { namespace engine @@ -23,8 +25,10 @@ struct NormalDistribution // FIXME implement log-probability version since its faster double density_function(const double val) const { + using namespace boost::math::constants; + const double x = val - mean; - return 1.0 / (std::sqrt(2. * M_PI) * standard_deviation) * + return 1.0 / (std::sqrt(two_pi()) * standard_deviation) * std::exp(-x * x / (standard_deviation * standard_deviation)); } diff --git a/include/engine/map_matching/hidden_markov_model.hpp b/include/engine/map_matching/hidden_markov_model.hpp index c387c1faf..91895b51e 100644 --- a/include/engine/map_matching/hidden_markov_model.hpp +++ b/include/engine/map_matching/hidden_markov_model.hpp @@ -4,6 +4,7 @@ #include "util/integer_range.hpp" #include +#include #include @@ -17,7 +18,7 @@ namespace engine namespace map_matching { -static const double log_2_pi = std::log(2. * M_PI); +static const double log_2_pi = std::log(2. * boost::math::constants::pi()); static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits::infinity(); static const double MINIMAL_LOG_PROB = std::numeric_limits::lowest(); static const std::size_t INVALID_STATE = std::numeric_limits::max(); diff --git a/include/util/trigonometry_table.hpp b/include/util/trigonometry_table.hpp index 69e0bb459..e66a52509 100644 --- a/include/util/trigonometry_table.hpp +++ b/include/util/trigonometry_table.hpp @@ -6,6 +6,8 @@ #include +#include + namespace osrm { namespace util @@ -356,19 +358,22 @@ constexpr unsigned short atan_table[4096] = { 0xffe0, 0xffea, 0xfff4, 0xffff}; // max value is pi/4 -constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF; +const constexpr double SCALING_FACTOR = 4. / boost::math::constants::pi() * 0xFFFF; inline double atan2_lookup(double y, double x) { + + using namespace boost::math::constants; + if (std::abs(x) < std::numeric_limits::epsilon()) { if (y >= 0.) { - return M_PI / 2.; + return half_pi(); } else { - return -M_PI / 2.; + return -half_pi(); } } @@ -399,25 +404,25 @@ inline double atan2_lookup(double y, double x) case 0: break; case 1: - angle = M_PI - angle; + angle = pi() - angle; break; case 2: angle = -angle; break; case 3: - angle = -M_PI + angle; + angle = -pi() + angle; break; case 4: - angle = M_PI / 2.0 - angle; + angle = half_pi() - angle; break; case 5: - angle = M_PI / 2.0 + angle; + angle = half_pi() + angle; break; case 6: - angle = -M_PI / 2.0 + angle; + angle = -half_pi() + angle; break; case 7: - angle = -M_PI / 2.0 - angle; + angle = -half_pi() - angle; break; } return angle; diff --git a/include/util/typedefs.hpp b/include/util/typedefs.hpp index 614e7ebd6..8dc417a41 100644 --- a/include/util/typedefs.hpp +++ b/include/util/typedefs.hpp @@ -6,14 +6,6 @@ #include #include -// Necessary workaround for Windows as VS doesn't implement C99 -#ifdef _MSC_VER -#define WIN32_LEAN_AND_MEAN -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif -#endif - // OpenStreetMap node ids are higher than 2^32 OSRM_STRONG_TYPEDEF(uint64_t, OSMNodeID) OSRM_STRONG_TYPEDEF(uint32_t, OSMWayID) diff --git a/src/util/coordinate_calculation.cpp b/src/util/coordinate_calculation.cpp index b54154fa6..61fd77cab 100644 --- a/src/util/coordinate_calculation.cpp +++ b/src/util/coordinate_calculation.cpp @@ -4,6 +4,7 @@ #include "util/trigonometry_table.hpp" #include +#include #include @@ -193,9 +194,17 @@ perpendicularDistanceFromProjectedCoordinate(const FixedPointCoordinate segment_ return approximate_distance; } -double degToRad(const double degree) { return degree * (static_cast(M_PI) / 180.0); } +double degToRad(const double degree) +{ + using namespace boost::math::constants; + return degree * (pi() / 180.0); +} -double radToDeg(const double radian) { return radian * (180.0 * static_cast(M_1_PI)); } +double radToDeg(const double radian) +{ + using namespace boost::math::constants; + return radian * (180.0 * (1. / pi())); +} double bearing(const FixedPointCoordinate first_coordinate, const FixedPointCoordinate second_coordinate) @@ -225,6 +234,7 @@ double computeAngle(const FixedPointCoordinate first, const FixedPointCoordinate second, const FixedPointCoordinate third) { + using namespace boost::math::constants; using namespace coordinate_calculation; const double v1x = (first.lon - second.lon) / COORDINATE_PRECISION; @@ -234,7 +244,7 @@ double computeAngle(const FixedPointCoordinate first, const double v2y = mercator::latToY(third.lat / COORDINATE_PRECISION) - mercator::latToY(second.lat / COORDINATE_PRECISION); - double angle = (atan2_lookup(v2y, v2x) - atan2_lookup(v1y, v1x)) * 180. / M_PI; + double angle = (atan2_lookup(v2y, v2x) - atan2_lookup(v1y, v1x)) * 180. / pi(); while (angle < 0.) { @@ -248,12 +258,18 @@ namespace mercator { double yToLat(const double value) { - return 180. * M_1_PI * (2. * std::atan(std::exp(value * M_PI / 180.)) - M_PI_2); + using namespace boost::math::constants; + + return 180. * (1. / pi()) * + (2. * std::atan(std::exp(value * pi() / 180.)) - half_pi()); } double latToY(const double latitude) { - return 180. * M_1_PI * std::log(std::tan(M_PI_4 + latitude * (M_PI / 180.) / 2.)); + using namespace boost::math::constants; + + return 180. * (1. / pi()) * + std::log(std::tan((pi() / 4.) + latitude * (pi() / 180.) / 2.)); } } // ns mercato // ns mercatorr } // ns coordinate_calculation