OpenKalman
eigen-tensor.gtest.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) 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 
19 #ifndef EIGEN_TENSOR_GTEST_HPP
20 #define EIGEN_TENSOR_GTEST_HPP
21 
24 
25 namespace OpenKalman::test
26 {
27 
28 #ifdef __cpp_concepts
29  template<Eigen3::eigen_tensor_general Arg1, Eigen3::eigen_tensor_general Arg2, typename Err> requires
30  (Eigen3::eigen_tensor_general<Arg1, true> or Eigen3::eigen_tensor_general<Arg2, true>) and
31  (std::is_arithmetic_v<Err> or Eigen3::eigen_tensor_general<Err>)
32  struct TestComparison<Arg1, Arg2, Err>
33 #else
34  template<typename Arg1, typename Arg2, typename Err>
35  struct TestComparison<Arg1, Arg2, Err, std::enable_if_t<
36  Eigen3::eigen_tensor_general<Arg1> and Eigen3::eigen_tensor_general<Arg2> and
37  (Eigen3::eigen_tensor_general<Arg1, true> or Eigen3::eigen_tensor_general<Arg2, true>) and
38  (std::is_arithmetic_v<Err> or Eigen3::eigen_tensor_general<Err>)>>
39 #endif
40  : ::testing::AssertionResult
41  {
42 
43  private:
44 
45  static ::testing::AssertionResult
46  compare(const Arg1& arg1, const Arg2& arg2, const Err& err)
47  {
48  using Scalar = scalar_type_of_t<Arg1>;
49  auto diff = arg1 - arg2;
50  using T0 = Eigen::Tensor<Scalar, 0>;
51  if constexpr (std::is_arithmetic_v<Err>)
52  {
53  auto lhs = T0{(diff.square()).sum()}.coeff(0);
54  auto sum1 = T0{(arg1.square()).sum()}.coeff(0);
55  auto sum2 = T0{(arg2.square()).sum()}.coeff(0);
56  auto err2 = err * err;
57  auto rhs = err2 * std::min(sum1, sum2);
58  if (lhs <= rhs or (sum1 <= err2 and sum2 <= err2))
59  {
60  return ::testing::AssertionSuccess();
61  }
62  }
63  else
64  {
65  if (T0{(diff.abs() - err).maximum()}.coeff(0) <= 0)
66  {
67  return ::testing::AssertionSuccess();
68  }
69  }
70 
71  return ::testing::AssertionFailure() << std::endl << arg1 << std::endl << "is not near" << std::endl <<
72  arg2 << std::endl;
73  }
74 
75  public:
76 
77  TestComparison(const Arg1& arg1, const Arg2& arg2, const Err& err)
78  : ::testing::AssertionResult {compare(arg1, arg2, err)} {};
79 
80  };
81 
82 
83 #ifdef __cpp_concepts
84  template<typename Arg1, typename Arg2, typename Err> requires
85  (not Eigen3::eigen_tensor_general<Arg1> or not Eigen3::eigen_tensor_general<Arg2>) and
86  (Eigen3::eigen_tensor_general<Arg1, true> or Eigen3::eigen_tensor_general<Arg2, true>) and
87  (Eigen3::eigen_tensor_general<Arg1> or Eigen3::eigen_general<Arg1>) and
88  (Eigen3::eigen_tensor_general<Arg2> or Eigen3::eigen_general<Arg2>) and
89  (std::is_arithmetic_v<Err> or Eigen3::eigen_tensor_general<Err>)
90  struct TestComparison<Arg1, Arg2, Err>
91 #else
92  template<typename Arg1, typename Arg2, typename Err>
93  struct TestComparison<Arg1, Arg2, Err, std::enable_if_t<
94  (not Eigen3::eigen_tensor_general<Arg1> or not Eigen3::eigen_tensor_general<Arg2>) and
95  (Eigen3::eigen_tensor_general<Arg1, true> or Eigen3::eigen_tensor_general<Arg2, true>) and
96  (Eigen3::eigen_tensor_general<Arg1> or Eigen3::eigen_general<Arg1>) and
97  (Eigen3::eigen_tensor_general<Arg2> or Eigen3::eigen_general<Arg2>) and
98  (std::is_arithmetic_v<Err> or Eigen3::eigen_tensor_general<Err>)>>
99 #endif
100  : ::testing::AssertionResult
101  {
102  private:
103 
104  using A = std::conditional_t<Eigen3::eigen_tensor_general<Arg1, true>, Arg1, Arg2>;
105 
106  public:
107  TestComparison(const Arg1& arg1, const Arg2& arg2, const Err& err)
108  : ::testing::AssertionResult {is_near(to_native_matrix<A>(arg1), to_native_matrix<A>(arg2), err)} {};
109 
110  };
111 
112 
113 } // namespace OpenKalman::test
114 
115 #endif //EIGEN_TENSOR_GTEST_HPP
constexpr partial_ordering compare(const Lhs &lhs, const Rhs &rhs)
Compare two collections.
Definition: compare.hpp:106
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
Definition: tuple_reverse.hpp:103
Definition: tests.hpp:41
Definition: tests.hpp:27
The comprehensive header file for OpenKalman&#39;s interface to the Eigen library.
decltype(auto) constexpr sum(Ts &&...ts)
Element-by-element sum of one or more objects.
Definition: sum.hpp:112
Header file for Eigen3 tests.
inline ::testing::AssertionResult is_near(const Arg1 &arg1, const Arg2 &arg2, const Err &err=1e-6)
Determine if two objects are "near" each other, within a margin of error.
Definition: tests.hpp:60