OpenKalman
near.hpp
Go to the documentation of this file.
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2022-2023 Christopher Lee Ogden <ogden@gatech.edu>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
9  */
10 
17 #ifndef OPENKALMAN_ARE_WITHIN_TOLERANCE_HPP
18 #define OPENKALMAN_ARE_WITHIN_TOLERANCE_HPP
19 
20 #include <limits>
24 
25 
27 {
35  template<unsigned int epsilon_factor = 2, typename Arg1, typename Arg2>
36  constexpr bool near(const Arg1& arg1, const Arg2& arg2)
37  {
38  if constexpr (not values::number<Arg1> or not values::number<Arg2>)
39  {
40  return near(values::to_number<epsilon_factor>(arg1), values::to_number(arg2));
41  }
42  else if constexpr (values::complex<Arg1> or values::complex<Arg2>)
43  {
44  using std::real, std::imag;
45  return
46  near<epsilon_factor>(real(arg1), real(arg2)) and
47  near<epsilon_factor>(imag(arg1), imag(arg2));
48  }
49  else if (arg1 != arg1 or arg2 != arg2) return false; // in case either argument is NaN
50  else
51  {
52  auto diff = arg1 - arg2;
53  using Diff = decltype(diff);
54  constexpr auto ep = epsilon_factor * std::numeric_limits<Diff>::epsilon();
55  return -static_cast<Diff>(ep) <= diff and diff <= static_cast<Diff>(ep);
56  }
57  }
58 
59 
67  template<typename Arg1, typename Arg2, typename Err>
68  constexpr bool near(const Arg1& arg1, const Arg2& arg2, const Err& err)
69  {
70  if constexpr (not values::number<Arg1> or not values::number<Arg2> or not values::number<Err>)
71  {
72  return near(values::to_number(arg1), values::to_number(arg2), values::to_number(err));
73  }
74  else if constexpr (values::complex<Arg1> or values::complex<Arg2> or values::complex<Err>)
75  {
76  using std::real, std::imag;
77  auto dr = real(arg2) - real(arg1);
78  auto di = imag(arg2) - imag(arg1);
79  auto er = real(err);
80  auto ei = imag(err);
81  return dr * dr + di * di <= er * er + ei * ei;
82  }
83  else if (arg1 != arg1 or arg2 != arg2) return false; // in case either argument is NaN
84  else
85  {
86  auto diff = arg1 - arg2;
87  using Diff = decltype(diff);
88  return -static_cast<Diff>(err) <= diff and diff <= static_cast<Diff>(err);
89  }
90 
91  }
92 
93 
94 } // namespace OpenKalman::values::internal
95 
96 #endif //OPENKALMAN_ARE_WITHIN_TOLERANCE_HPP
Definition for values::to_number.
constexpr auto imag(Arg arg)
A constexpr function to obtain the imaginary part of a (complex) number.
Definition: imag.hpp:40
constexpr auto to_number(Arg arg)
Convert any values::value to a values::number.
Definition: to_number.hpp:34
Definition of utilities for atan functions.
Definition: dynamic.hpp:26
constexpr auto real(Arg arg)
A constexpr function to obtain the real part of a (complex) number.
Definition: real.hpp:40
constexpr bool near(const Arg1 &arg1, const Arg2 &arg2)
Determine whether two numbers are within a rounding tolerance.
Definition: near.hpp:36
Definition for values::number.
Definition for ::complex.