Program Listing for File gtest_eigen.hpp
↰ Return to documentation for file (/tmp/ws/src/grid_map/grid_map_core/include/grid_map_core/gtest_eigen.hpp
)
#ifndef GRID_MAP_CORE__GTEST_EIGEN_HPP_
#define GRID_MAP_CORE__GTEST_EIGEN_HPP_
#include <gtest/gtest.h>
#include <Eigen/Core>
#include <iostream>
#include <cmath>
#include <string>
#include <algorithm>
namespace grid_map
{
template<int N>
Eigen::Matrix<double, N, N> randomCovariance()
{
Eigen::Matrix<double, N, N> U;
U.setRandom();
return U.transpose() * U + 5.0 * Eigen::Matrix<double, N, N>::Identity();
}
inline Eigen::MatrixXd randomCovarianceXd(int N)
{
Eigen::MatrixXd U(N, N);
U.setRandom();
return U.transpose() * U + 5.0 * Eigen::MatrixXd::Identity(N, N);
}
template<typename M1, typename M2>
void assertEqual(const M1 & A, const M2 & B, std::string const & message = "")
{
ASSERT_EQ(
(size_t)A.rows(),
(size_t)B.rows()) << message << "\nMatrix A:\n" << A << "\nand matrix B\n" << B <<
"\nare not the same\n";
ASSERT_EQ(
(size_t)A.cols(),
(size_t)B.cols()) << message << "\nMatrix A:\n" << A << "\nand matrix B\n" << B <<
"\nare not the same\n";
for (int r = 0; r < A.rows(); r++) {
for (int c = 0; c < A.cols(); c++) {
if (std::isnan(A(r, c))) {
ASSERT_TRUE(std::isnan(B(r, c)));
} else {
ASSERT_EQ(
A(r, c),
B(r, c)) << message << "\nEquality comparison failed at (" << r << "," << c << ")\n" <<
"\nMatrix A:\n" << A << "\nand matrix B\n" << B;
}
}
}
}
template<typename M1, typename M2, typename T>
void assertNear(const M1 & A, const M2 & B, T tolerance, std::string const & message = "")
{
// Note: If these assertions fail, they only abort this subroutine.
// see: http://code.google.com/p/googletest/wiki/AdvancedGuide#Using_Assertions_in_Sub-routines
// \todo better handling of this
ASSERT_EQ(
(size_t)A.rows(),
(size_t)B.rows()) << message << "\nMatrix A:\n" << A << "\nand matrix B\n" << B <<
"\nare not the same\n";
ASSERT_EQ(
(size_t)A.cols(),
(size_t)B.cols()) << message << "\nMatrix A:\n" << A << "\nand matrix B\n" << B <<
"\nare not the same\n";
for (int r = 0; r < A.rows(); r++) {
for (int c = 0; c < A.cols(); c++) {
if (std::isnan(A(r, c))) {
ASSERT_TRUE(std::isnan(B(r, c)));
} else {
ASSERT_NEAR(
A(r, c), B(r, c),
tolerance) << message << "\nTolerance comparison failed at (" << r << "," << c <<
")\n" <<
"\nMatrix A:\n" << A << "\nand matrix B\n" << B;
}
}
}
}
template<typename M1, typename M2, typename T>
void expectNear(const M1 & A, const M2 & B, T tolerance, std::string const & message = "")
{
EXPECT_EQ(
(size_t)A.rows(),
(size_t)B.rows()) << message << "\nMatrix A:\n" << A << "\nand matrix B\n" << B <<
"\nare not the same\n";
EXPECT_EQ(
(size_t)A.cols(),
(size_t)B.cols()) << message << "\nMatrix A:\n" << A << "\nand matrix B\n" << B <<
"\nare not the same\n";
for (int r = 0; r < A.rows(); r++) {
for (int c = 0; c < A.cols(); c++) {
if (std::isnan(A(r, c))) {
EXPECT_TRUE(std::isnan(B(r, c)));
} else {
EXPECT_NEAR(
A(r, c), B(r, c),
tolerance) << message << "\nTolerance comparison failed at (" << r << "," << c <<
")\n" <<
"\nMatrix A:\n" << A << "\nand matrix B\n" << B;
}
}
}
}
template<typename M1>
void assertFinite(const M1 & A, std::string const & /* message */)
{
for (int r = 0; r < A.rows(); r++) {
for (int c = 0; c < A.cols(); c++) {
ASSERT_TRUE(
std::isfinite(
A(
r,
c))) << std::endl << "Check for finite values failed at A(" << r << "," << c <<
"). Matrix A:" << std::endl << A << std::endl;
}
}
}
inline bool compareRelative(
double a, double b, double percentTolerance,
double * percentError = NULL)
{
// \todo: does anyone have a better idea?
double fa = fabs(a);
double fb = fabs(b);
if ( (fa < 1e-15 && fb < 1e-15) || // Both zero.
(fa == 0.0 && fb < 1e-6) || // One exactly zero and the other small
(fb == 0.0 && fa < 1e-6) ) // ditto
{
return true;
}
double diff = fabs(a - b) / std::max(fa, fb);
if (diff > percentTolerance * 1e-2) {
if (percentError) {
*percentError = diff * 100.0;
}
return false;
}
return true;
}
#define ASSERT_DOUBLE_MX_EQ(A, B, PERCENT_TOLERANCE, MSG) \
ASSERT_EQ( \
(size_t)(A).rows(), \
(size_t)(B).rows()) << MSG << "\nMatrix " << #A << ":\n" << A << "\nand matrix " << #B << \
"\n" << B << "\nare not the same size"; \
ASSERT_EQ( \
(size_t)(A).cols(), \
(size_t)(B).cols()) << MSG << "\nMatrix " << #A << ":\n" << A << "\nand matrix " << #B << \
"\n" << B << "\nare not the same size"; \
for (int r = 0; r < (A).rows(); r++) \
{ \
for (int c = 0; c < (A).cols(); c++) \
{ \
double percentError = 0.0; \
ASSERT_TRUE( \
grid_map::compareRelative( \
(A)(r, c), (B)(r, c), PERCENT_TOLERANCE, \
&percentError)) \
<< MSG << "\nComparing:\n" \
<< #A << "(" << r << "," << c << ") = " << (A)(r, c) << std::endl \
<< #B << "(" << r << "," << c << ") = " << (B)(r, c) << std::endl \
<< "Error was " << percentError << "% > " << PERCENT_TOLERANCE << "%\n" \
<< "\nMatrix " << #A << ":\n" << A << "\nand matrix " << #B << "\n" << B; \
} \
}
#define ASSERT_DOUBLE_SPARSE_MX_EQ(A, B, PERCENT_TOLERANCE, MSG) \
ASSERT_EQ( \
(size_t)(A).rows(), \
(size_t)(B).rows()) << MSG << "\nMatrix " << #A << ":\n" << A << "\nand matrix " << #B << \
"\n" << B << "\nare not the same size"; \
ASSERT_EQ( \
(size_t)(A).cols(), \
(size_t)(B).cols()) << MSG << "\nMatrix " << #A << ":\n" << A << "\nand matrix " << #B << \
"\n" << B << "\nare not the same size"; \
for (int r = 0; r < (A).rows(); r++) \
{ \
for (int c = 0; c < (A).cols(); c++) \
{ \
double percentError = 0.0; \
ASSERT_TRUE( \
grid_map::compareRelative( \
(A).coeff(r, c), (B).coeff(r, c), PERCENT_TOLERANCE, \
&percentError)) \
<< MSG << "\nComparing:\n" \
<< #A << "(" << r << "," << c << ") = " << (A).coeff(r, c) << std::endl \
<< #B << "(" << r << "," << c << ") = " << (B).coeff(r, c) << std::endl \
<< "Error was " << percentError << "% > " << PERCENT_TOLERANCE << "%\n" \
<< "\nMatrix " << #A << ":\n" << A << "\nand matrix " << #B << "\n" << B; \
} \
}
} // namespace grid_map
#endif // GRID_MAP_CORE__GTEST_EIGEN_HPP_