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_VALUES_NEAR_HPP
18 #define OPENKALMAN_VALUES_NEAR_HPP
19 
20 #include <limits>
21 #include "basics/basics.hpp"
26 #include "values/math/real.hpp"
27 #include "values/math/imag.hpp"
28 
30 {
38 #ifdef __cpp_concepts
39  template<unsigned int epsilon_factor = 2, value Arg1, value Arg2>
40  constexpr OpenKalman::internal::boolean_testable auto
41 #else
42  template<unsigned int epsilon_factor = 2, typename Arg1, typename Arg2,
43  std::enable_if_t<value<Arg1> and value<Arg2>, int> = 0>
44  constexpr auto
45 #endif
46  near(const Arg1& arg1, const Arg2& arg2)
47  {
48  if constexpr (fixed<Arg1> or fixed<Arg2>)
49  {
50  struct Op { constexpr auto operator()(const value_type_of_t<Arg1>& a1, const value_type_of_t<Arg2>& a2) const
51  { return near<epsilon_factor>(a1, a2); } };
52  return values::operation(Op{}, arg1, arg2);
53  }
54  else if constexpr (complex<Arg1> or complex<Arg2>)
55  {
56  return operation(
57  std::logical_and{},
58  near<epsilon_factor>(real(arg1), real(arg2)),
59  near<epsilon_factor>(imag(arg1), imag(arg2)));
60  }
61  else
62  {
63  auto diff = arg1 - arg2;
64  using Diff = decltype(diff);
65  auto ep = static_cast<Diff>(epsilon_factor * std::numeric_limits<Diff>::epsilon());
66  return -ep <= diff and diff <= ep;
67  }
68  }
69 
70 
78 #ifdef __cpp_concepts
79  template<value Arg1, value Arg2, value Err>
80  constexpr OpenKalman::internal::boolean_testable auto
81 #else
82  template<typename Arg1, typename Arg2, typename Err,
83  std::enable_if_t<value<Arg1> and value<Arg2> and value<Err>, int> = 0>
84  constexpr auto
85 #endif
86  near(const Arg1& arg1, const Arg2& arg2, const Err& err)
87  {
88  if constexpr (fixed<Arg1> or fixed<Arg2>)
89  {
90  struct Op { constexpr auto operator()(
91  const value_type_of_t<Arg1>& a1,
92  const value_type_of_t<Arg2>& a2,
93  const value_type_of_t<Err>& e) const
94  { return near(a1, a2, e); } };
95  return values::operation(Op{}, arg1, arg2, err);
96  }
97  else if constexpr (complex<Arg1> or complex<Arg2> or complex<Err>)
98  {
99  auto dr = real(arg2) - real(arg1);
100  auto di = imag(arg2) - imag(arg1);
101  auto er = real(err);
102  auto ei = imag(err);
103  return dr * dr + di * di <= er * er + ei * ei;
104  }
105  else
106  {
107  auto diff = arg1 - arg2;
108  using Diff = decltype(diff);
109  auto ep = static_cast<Diff>(err);
110  return -ep <= diff and diff <= ep;
111  }
112 
113  }
114 
115 
116 }
117 
118 #endif
typename value_type_of< T >::type value_type_of_t
Helper template for value_type_of.
Definition: value_type_of.hpp:52
constexpr auto imag(const Arg &arg)
A constexpr function to obtain the imaginary part of a (complex) number.
Definition: imag.hpp:40
Definition for values::imag.
constexpr auto near(const Arg1 &arg1, const Arg2 &arg2)
Determine whether two numbers are within a rounding tolerance.
Definition: near.hpp:46
Definition of utilities for atan functions.
Definition: fixed.hpp:24
Definition for value:value_type_of and value:value_type_of_t.
constexpr auto real(const Arg &arg)
A constexpr function to obtain the real part of a (complex) number.
Definition: real.hpp:40
Basic definitions for OpenKalman as a whole.
Definition for values::real.
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98
Definition for values::complex.
Definition for values::value.