OSVR-Core
EigenTestHelpers.h
Go to the documentation of this file.
1 
11 // Copyright 2016 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 #ifndef INCLUDED_EigenTestHelpers_h_GUID_9C8A67BA_D846_4F94_8020_885E858600E3
26 #define INCLUDED_EigenTestHelpers_h_GUID_9C8A67BA_D846_4F94_8020_885E858600E3
27 
28 // Internal Includes
30 
31 // Library/third-party includes
32 #include "gtest/gtest.h"
33 
34 // Standard includes
35 // - none
36 
37 namespace Eigen {
38 void PrintTo(Eigen::Quaterniond const &quat, ::std::ostream *os) {
39  (*os) << "[(" << quat.vec().transpose() << "), " << quat.w() << "]";
40 }
41 void PrintTo(Eigen::Vector3d const &vec, ::std::ostream *os) {
42  (*os) << vec.transpose();
43 }
44 
46 inline std::string to_string(Eigen::Quaterniond const &quat) {
47  std::stringstream ss;
48  PrintTo(quat, &ss);
49  return ss.str();
50 }
51 
53 inline std::string to_string(Eigen::Vector3d const &vec) {
54  std::stringstream ss;
55  PrintTo(vec, &ss);
56  return ss.str();
57 }
58 }
59 namespace EigenGTestCompareHelpers {
60 template <typename Scalar, std::size_t SIZE, typename Derived1,
61  typename Derived2>
62 inline bool compareVecsEq_impl(Eigen::MatrixBase<Derived1> const &expected,
63  Eigen::MatrixBase<Derived2> const &actual) {
64  for (std::size_t i = 0; i < SIZE; ++i) {
66  rhs(actual[i]);
67  if (!lhs.AlmostEquals(rhs)) {
68  return false;
69  }
70  }
71  return true;
72 }
73 template <typename Scalar, typename T>
74 inline void formatStreamableValOrRowForMessage(std::ostream &os, T &&val) {
75  os << std::setprecision(std::numeric_limits<Scalar>::digits10 + 2)
76  << std::forward<T>(val);
77 }
78 
79 template <typename Derived>
80 inline std::string
81 formatVectorForMessage(Eigen::DenseBase<Derived> const &vec) {
82  using Scalar = typename Derived::Scalar;
83  ::std::stringstream ss;
84  if (1 == vec.rows()) {
85  formatStreamableValOrRowForMessage<Scalar>(ss, vec);
86  } else {
87  formatStreamableValOrRowForMessage<Scalar>(ss, vec.transpose());
88  }
89  return ss.str();
90 }
91 
92 template <typename Derived>
93 inline std::string
94 formatQuatForMessage(Eigen::QuaternionBase<Derived> const &quat) {
95  using Scalar = typename Derived::Scalar;
96  ::std::stringstream ss;
97  ss << "[(";
98  formatStreamableValOrRowForMessage<Scalar>(ss, quat.vec().transpose());
99  ss << "), ";
100  formatStreamableValOrRowForMessage<Scalar>(ss, quat.w());
101  ss << "]";
102  return ss.str();
103 }
104 
106 template <typename Scalar>
108 compareQuatsEq(const char *expected_expression, const char *actual_expression,
109  Eigen::Quaternion<Scalar> const &expected,
110  Eigen::Quaternion<Scalar> const &actual) {
111  if (compareVecsEq_impl<Scalar, 4>(expected.coeffs(), actual.coeffs())) {
112  return ::testing::AssertionSuccess();
113  }
114  return ::testing::internal::EqFailure(
115  expected_expression, actual_expression, formatQuatForMessage(expected),
116  formatQuatForMessage(actual), false);
117 }
118 
120 template <typename Scalar>
122 compareQuatsNe(const char *expected_expression, const char *actual_expression,
123  Eigen::Quaternion<Scalar> const &expected,
124  Eigen::Quaternion<Scalar> const &actual) {
125  if (!compareVecsEq_impl<Scalar, 4>(expected.coeffs(), actual.coeffs())) {
126  return ::testing::AssertionSuccess();
127  }
128  return ::testing::AssertionFailure()
129  << " Expected " << expected_expression << " ( "
130  << formatQuatForMessage(expected) << ") != " << actual_expression
131  << "\n Got " << actual_expression << " = "
132  << formatQuatForMessage(actual) << " instead.";
133 }
134 
135 template <typename Derived1, typename Derived2>
136 inline void
137 checkVecStaticAssertions(Eigen::MatrixBase<Derived1> const &expected,
138  Eigen::MatrixBase<Derived2> const &actual) {
139 
140  static_assert(
141  Derived1::IsVectorAtCompileTime,
142  "Expected must be a vector at compile time to use this assertion.");
143  static_assert(
144  Derived2::IsVectorAtCompileTime,
145  "Actual must be a vector at compile time to use this assertion.");
146  static_assert(Derived1::SizeAtCompileTime == Derived2::SizeAtCompileTime,
147  "Expected and Actual must be the same size vector at compile "
148  "time to use this assertion.");
149 }
151 template <typename Scalar, typename Derived1, typename Derived2>
153 compareVecsEq(const char *expected_expression, const char *actual_expression,
154  Eigen::MatrixBase<Derived1> const &expected,
155  Eigen::MatrixBase<Derived2> const &actual) {
156  checkVecStaticAssertions(expected, actual);
157  if (compareVecsEq_impl<Scalar, Derived1::SizeAtCompileTime>(expected,
158  actual)) {
159  return ::testing::AssertionSuccess();
160  }
161 
162  return ::testing::internal::EqFailure(
163  expected_expression, actual_expression,
164  formatVectorForMessage(expected), formatVectorForMessage(actual),
165  false);
166 }
167 
168 template <typename Scalar, typename Derived1, typename Derived2>
170 compareVecsNe(const char *expected_expression, const char *actual_expression,
171  Eigen::MatrixBase<Derived1> const &expected,
172  Eigen::MatrixBase<Derived2> const &actual) {
173  checkVecStaticAssertions(expected, actual);
174  if (!compareVecsEq_impl<Scalar, Derived1::SizeAtCompileTime>(expected,
175  actual)) {
176  return ::testing::AssertionSuccess();
177  }
178 
179  return ::testing::AssertionFailure()
180  << " Expected " << expected_expression << " ( "
181  << formatVectorForMessage(expected) << ") != " << actual_expression
182  << "\n Got " << actual_expression << " = "
183  << formatVectorForMessage(actual) << " instead.";
184 #if 0
185  ::testing::internal::EqFailure(
186  expected_expression, actual_expression,
187  ::testing::internal::StringStreamToString(&expected_ss),
188  ::testing::internal::StringStreamToString(&actual_ss), false);
189 #endif
190 }
191 } // namespace EigenGTestCompareHelpers
192 
193 #define ASSERT_QUAT_DOUBLE_EQ(expected, actual) \
194  ASSERT_PRED_FORMAT2(::EigenGTestCompareHelpers::compareQuatsEq<double>, \
195  expected, actual)
196 
197 #define ASSERT_QUAT_DOUBLE_NE(expected, actual) \
198  ASSERT_PRED_FORMAT2(::EigenGTestCompareHelpers::compareQuatsNe<double>, \
199  expected, actual)
200 #define ASSERT_VEC_DOUBLE_EQ(expected, actual) \
201  ASSERT_PRED_FORMAT2(::EigenGTestCompareHelpers::compareVecsEq<double>, \
202  expected, actual)
203 #define ASSERT_VEC_DOUBLE_NE(expected, actual) \
204  ASSERT_PRED_FORMAT2(::EigenGTestCompareHelpers::compareVecsNe<double>, \
205  expected, actual)
206 
207 #endif // INCLUDED_EigenTestHelpers_h_GUID_9C8A67BA_D846_4F94_8020_885E858600E3
::testing::AssertionResult compareQuatsEq(const char *expected_expression, const char *actual_expression, Eigen::Quaternion< Scalar > const &expected, Eigen::Quaternion< Scalar > const &actual)
based on CmpHelperFloatingPointEQ
Definition: EigenTestHelpers.h:108
const Coefficients & coeffs() const
Definition: Quaternion.h:93
iterative scaling algorithm to equilibrate rows and column norms in matrices
Definition: TestIMU_Common.h:87
Header wrapping include of <Eigen/Core> and <Eigen/Geometry> for warning quieting.
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:41
const Block< const Coefficients, 3, 1 > vec() const
Definition: Quaternion.h:87
Eigen::Transpose< Derived > transpose()
Definition: Transpose.h:199
std::string to_string(Eigen::Quaterniond const &quat)
Helper to convert to string for messages.
Definition: EigenTestHelpers.h:46
const VectorBlock< const Coefficients, 3 > vec() const
Definition: Quaternion.h:78
Definition: ForwardDeclarations.h:233
Scalar w() const
Definition: Quaternion.h:75
Definition: gtest.h:7192
::testing::AssertionResult compareVecsEq(const char *expected_expression, const char *actual_expression, Eigen::MatrixBase< Derived1 > const &expected, Eigen::MatrixBase< Derived2 > const &actual)
based on CmpHelperFloatingPointEQ
Definition: EigenTestHelpers.h:153
Definition: Quaternion.h:47
Definition: gtest.h:17669
::testing::AssertionResult compareQuatsNe(const char *expected_expression, const char *actual_expression, Eigen::Quaternion< Scalar > const &expected, Eigen::Quaternion< Scalar > const &actual)
based on CmpHelperFloatingPointEQ
Definition: EigenTestHelpers.h:122
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
Scalar w() const
Definition: Quaternion.h:66
double Scalar
Common scalar type.
Definition: FlexibleKalmanBase.h:48
Definition: EigenTestHelpers.h:59