test_formula.hpp 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Boost.Geometry
  2. // Unit Test
  3. // Copyright (c) 2016-2019 Oracle and/or its affiliates.
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Use, modification and distribution is subject to the Boost Software License,
  6. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. #ifndef BOOST_GEOMETRY_TEST_FORMULA_HPP
  9. #define BOOST_GEOMETRY_TEST_FORMULA_HPP
  10. #include <geometry_test_common.hpp>
  11. #include <boost/geometry/util/math.hpp>
  12. void normalize_deg(double & deg)
  13. {
  14. while (deg > 180.0)
  15. deg -= 360.0;
  16. while (deg <= -180.0)
  17. deg += 360.0;
  18. }
  19. #define BOOST_GEOMETRY_CHECK_CLOSE( L, R, T, M ) BOOST_TEST_TOOL_IMPL( 0, \
  20. ::boost::test_tools::check_is_close_t(), M, CHECK, CHECK_MSG, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
  21. void check_one(std::string const& name, double result, double expected)
  22. {
  23. std::string id = name.empty() ? "" : (name + " : ");
  24. double eps = std::numeric_limits<double>::epsilon();
  25. double abs_result = bg::math::abs(result);
  26. double abs_expected = bg::math::abs(expected);
  27. double res_max = (std::max)(abs_result, abs_expected);
  28. double res_min = (std::min)(abs_result, abs_expected);
  29. if (res_min <= eps) // including 0
  30. {
  31. bool is_close = abs_result <= 30 * eps && abs_expected <= 30 * eps;
  32. BOOST_CHECK_MESSAGE((is_close),
  33. id << std::setprecision(20) << "result {" << result << "} different than expected {" << expected << "}.");
  34. }
  35. else if (res_max > 100 * eps)
  36. {
  37. BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 0.1,
  38. id << std::setprecision(20) << "result {" << result << "} different than expected {" << expected << "}.");
  39. }
  40. else if (res_max > 10 * eps)
  41. {
  42. BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 10,
  43. id << std::setprecision(20) << "result {" << result << "} different than expected {" << expected << "}.");
  44. }
  45. else if (res_max > eps)
  46. {
  47. BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 1000,
  48. id << std::setprecision(20) << "result {" << result << "} different than expected {" << expected << "}.");
  49. }
  50. }
  51. void check_one(std::string const& name,
  52. double result, double expected, double reference, double reference_error,
  53. bool normalize = false, bool check_reference_only = false)
  54. {
  55. std::string id = name.empty() ? "" : (name + " : ");
  56. if (normalize)
  57. {
  58. normalize_deg(result);
  59. normalize_deg(expected);
  60. normalize_deg(reference);
  61. }
  62. if (! check_reference_only)
  63. {
  64. check_one(name, result, expected);
  65. }
  66. // NOTE: in some cases it probably will be necessary to normalize
  67. // the differences between the result and expected result
  68. double ref_diff = bg::math::abs(result - reference);
  69. double ref_max = (std::max)(bg::math::abs(result), bg::math::abs(reference));
  70. bool is_ref_close = ref_diff <= reference_error || ref_diff <= reference_error * ref_max;
  71. BOOST_CHECK_MESSAGE((is_ref_close),
  72. id << std::setprecision(20) << "result {" << result << "} and reference {" << reference << "} not close enough.");
  73. }
  74. void check_one(double result, double expected, double reference, double reference_error,
  75. bool normalize = false, bool check_reference_only = false)
  76. {
  77. check_one("", result, expected, reference, reference_error, normalize, check_reference_only);
  78. }
  79. #endif // BOOST_GEOMETRY_TEST_FORMULA_HPP