#pragma once #include #include "gtest/gtest.h" template struct TestConstants; template <> struct TestConstants { static constexpr double epsilon = 1e-8; static constexpr double max_norm = 1e-3; }; template <> struct TestConstants { static constexpr double epsilon = 1e-2; static constexpr double max_norm = 1e-2; }; template void test_jacobian( const std::string &name, const Eigen::MatrixBase &Ja, F func, const Eigen::MatrixBase &x0, double eps = TestConstants::epsilon, double max_norm = TestConstants::max_norm) { typedef typename Derived1::Scalar Scalar; Eigen::Matrix Jn = Ja; Jn.setZero(); Eigen::Matrix inc = x0; for (int i = 0; i < Jn.cols(); i++) { inc.setZero(); inc[i] += eps; Eigen::Matrix fpe = func(x0 + inc); Eigen::Matrix fme = func(x0 - inc); Jn.col(i) = (fpe - fme); } Jn /= (2 * eps); EXPECT_TRUE(Ja.allFinite()) << name << ": Ja not finite\n " << Ja; EXPECT_TRUE(Jn.allFinite()) << name << ": Jn not finite\n " << Jn; if (Jn.isZero(max_norm) && Ja.isZero(max_norm)) { EXPECT_TRUE((Jn - Ja).isZero(max_norm)) << name << ": Ja not equal to Jn(diff norm:" << (Jn - Ja).norm() << ")\nJa: (norm: " << Ja.norm() << ")\n" << Ja << "\nJn: (norm: " << Jn.norm() << ")\n" << Jn; //<< "\ndiff:\n" << Jn - Ja; } else { EXPECT_TRUE(Jn.isApprox(Ja, max_norm)) << name << ": Ja not equal to Jn (diff norm:" << (Jn - Ja).norm() << ")\nJa: (norm: " << Ja.norm() << ")\n" << Ja << "\nJn: (norm: " << Jn.norm() << ")\n" << Jn; //<< "\ndiff:\n" << Jn - Ja; } }