LCOV - code coverage report
Current view: top level - src/common/autoware_auto_common/include/helper_functions - float_comparisons.hpp (source / functions) Hit Total Coverage
Test: coverage.filtered Lines: 21 21 100.0 %
Date: 2022-02-08 20:14:05 Functions: 8 8 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 12 12 100.0 %

           Branch data     Line data    Source code
       1                 :            : // Copyright 2020 Mapless AI, Inc.
       2                 :            : //
       3                 :            : // Permission is hereby granted, free of charge, to any person obtaining a copy
       4                 :            : // of this software and associated documentation files (the "Software"), to
       5                 :            : // deal in the Software without restriction, including without limitation the
       6                 :            : // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
       7                 :            : // sell copies of the Software, and to permit persons to whom the Software is
       8                 :            : // furnished to do so, subject to the following conditions:
       9                 :            : //
      10                 :            : // The above copyright notice and this permission notice shall be included in
      11                 :            : // all copies or substantial portions of the Software.
      12                 :            : //
      13                 :            : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      14                 :            : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      15                 :            : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      16                 :            : //  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      17                 :            : //  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      18                 :            : // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      19                 :            : // IN THE SOFTWARE.
      20                 :            : 
      21                 :            : #ifndef HELPER_FUNCTIONS__FLOAT_COMPARISONS_HPP_
      22                 :            : #define HELPER_FUNCTIONS__FLOAT_COMPARISONS_HPP_
      23                 :            : 
      24                 :            : #include <algorithm>
      25                 :            : #include <cmath>
      26                 :            : #include <limits>
      27                 :            : 
      28                 :            : namespace autoware
      29                 :            : {
      30                 :            : namespace common
      31                 :            : {
      32                 :            : namespace helper_functions
      33                 :            : {
      34                 :            : namespace comparisons
      35                 :            : {
      36                 :            : 
      37                 :            : /**
      38                 :            :  * @brief Check for approximate equality in absolute terms.
      39                 :            :  * @pre eps >= 0
      40                 :            :  * @return True iff 'a' and 'b' are within 'eps' of each other.
      41                 :            :  */
      42                 :            : template<typename T>
      43                 :         56 : bool abs_eq(const T & a, const T & b, const T & eps)
      44                 :            : {
      45                 :            :   static_assert(
      46                 :            :     std::is_floating_point<T>::value,
      47                 :            :     "Float comparisons only support floating point types.");
      48                 :            : 
      49                 :         56 :   return std::abs(a - b) <= eps;
      50                 :            : }
      51                 :            : 
      52                 :            : /**
      53                 :            :  * @brief Check for approximate less than in absolute terms.
      54                 :            :  * @pre eps >= 0
      55                 :            :  * @return True iff 'a' is less than 'b' minus 'eps'.
      56                 :            :  */
      57                 :            : template<typename T>
      58                 :         13 : bool abs_lt(const T & a, const T & b, const T & eps)
      59                 :            : {
      60   [ +  +  +  + ]:         13 :   return !abs_eq(a, b, eps) && (a < b);
      61                 :            : }
      62                 :            : 
      63                 :            : /**
      64                 :            :  * @brief Check for approximate less than or equal in absolute terms.
      65                 :            :  * @pre eps >= 0
      66                 :            :  * @return True iff 'a' is less than or equal to 'b' plus 'eps'.
      67                 :            :  */
      68                 :            : template<typename T>
      69                 :         16 : bool abs_lte(const T & a, const T & b, const T & eps)
      70                 :            : {
      71   [ +  +  +  + ]:         16 :   return abs_eq(a, b, eps) || (a < b);
      72                 :            : }
      73                 :            : 
      74                 :            : /**
      75                 :            :  * @brief Check for approximate greater than or equal in absolute terms.
      76                 :            :  * @pre eps >= 0
      77                 :            :  * @return True iff 'a' is greater than or equal to 'b' minus 'eps'.
      78                 :            :  */
      79                 :            : template<typename T>
      80                 :          8 : bool abs_gte(const T & a, const T & b, const T & eps)
      81                 :            : {
      82                 :          8 :   return !abs_lt(a, b, eps);
      83                 :            : }
      84                 :            : 
      85                 :            : /**
      86                 :            :  * @brief Check for approximate greater than in absolute terms.
      87                 :            :  * @pre eps >= 0
      88                 :            :  * @return True iff 'a' is greater than 'b' minus 'eps'.
      89                 :            :  */
      90                 :            : template<typename T>
      91                 :          6 : bool abs_gt(const T & a, const T & b, const T & eps)
      92                 :            : {
      93                 :          6 :   return !abs_lte(a, b, eps);
      94                 :            : }
      95                 :            : 
      96                 :            : /**
      97                 :            :  * @brief Check whether a value is within epsilon of zero.
      98                 :            :  * @pre eps >= 0
      99                 :            :  * @return True iff 'a' is within 'eps' of zero.
     100                 :            :  */
     101                 :            : template<typename T>
     102                 :          5 : bool abs_eq_zero(const T & a, const T & eps)
     103                 :            : {
     104                 :          5 :   return abs_eq(a, static_cast<T>(0), eps);
     105                 :            : }
     106                 :            : 
     107                 :            : /**
     108                 :            :  * @brief
     109                 :            :  * https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
     110                 :            :  * @pre rel_eps >= 0
     111                 :            :  * @return True iff 'a' and 'b' are within relative 'rel_eps' of each other.
     112                 :            :  */
     113                 :            : template<typename T>
     114                 :         23 : bool rel_eq(const T & a, const T & b, const T & rel_eps)
     115                 :            : {
     116                 :            :   static_assert(
     117                 :            :     std::is_floating_point<T>::value,
     118                 :            :     "Float comparisons only support floating point types.");
     119                 :            : 
     120                 :         23 :   const auto delta = std::abs(a - b);
     121                 :         23 :   const auto larger = std::max(std::abs(a), std::abs(b));
     122                 :         23 :   const auto max_rel_delta = (larger * rel_eps);
     123                 :         23 :   return delta <= max_rel_delta;
     124                 :            : }
     125                 :            : 
     126                 :            : // TODO(jeff): As needed, add relative variants of <, <=, >, >=
     127                 :            : 
     128                 :            : /**
     129                 :            :  * @brief Check for approximate equality in absolute and relative terms.
     130                 :            :  *
     131                 :            :  * @note This method should be used only if an explicit relative or absolute
     132                 :            :  * comparison is not appropriate for the particular use case.
     133                 :            :  *
     134                 :            :  * @pre abs_eps >= 0
     135                 :            :  * @pre rel_eps >= 0
     136                 :            :  * @return True iff 'a' and 'b' are within 'eps' or 'rel_eps' of each other
     137                 :            :  */
     138                 :            : template<typename T>
     139                 :         14 : bool approx_eq(const T & a, const T & b, const T & abs_eps, const T & rel_eps)
     140                 :            : {
     141                 :         14 :   const auto are_absolute_eq = abs_eq(a, b, abs_eps);
     142                 :         14 :   const auto are_relative_eq = rel_eq(a, b, rel_eps);
     143   [ +  +  +  + ]:         14 :   return are_absolute_eq || are_relative_eq;
     144                 :            : }
     145                 :            : 
     146                 :            : }  // namespace comparisons
     147                 :            : }  // namespace helper_functions
     148                 :            : }  // namespace common
     149                 :            : }  // namespace autoware
     150                 :            : 
     151                 :            : #endif  // HELPER_FUNCTIONS__FLOAT_COMPARISONS_HPP_

Generated by: LCOV version 1.14