7#include <gtsam/linear/VectorValues.h>
8#include <gtsam/nonlinear/NonlinearFactor.h>
10namespace gtsam_points {
43template <
typename GenerateFactor,
typename GenerateValues>
44bool test_factor_jacobian(std::mt19937& mt,
const GenerateFactor& generate_factor,
const GenerateValues& generate_values) {
45 auto factor = generate_factor(mt);
46 gtsam::Values values = generate_values(mt);
48 std::vector<gtsam::Matrix> Hs_a(factor->keys().size());
49 std::vector<gtsam::Matrix> Hs_d(factor->keys().size());
50 gtsam::Vector x0 = factor->unwhitenedError(values, Hs_a);
52 const double eps = 1e-6;
54 for (
int i = 0; i < factor->keys().size(); i++) {
55 const auto key = factor->keys()[i];
56 gtsam::VectorValues delta = values.zeroVectors();
57 const int D = delta[key].size();
59 gtsam::Matrix Hd(x0.size(), D);
60 for (
int j = 0; j < D; j++) {
64 gtsam::Vector xi = factor->unwhitenedError(values.retract(delta));
65 Hd.col(j) = (xi - x0) / eps;
72 for (
int i = 0; i < factor->keys().size(); i++) {
73 ok &= ((Hs_a[i] - Hs_d[i]).array().abs() < 1e-3).all();
77 std::cout <<
"OK (x0=" << x0.transpose() <<
")" << std::endl;
79 std::cout <<
"Failed (x0=" << x0.transpose() <<
")" << std::endl;
81 for (
int i = 0; i < factor->keys().size(); i++) {
82 std::cout <<
"*** key " << i <<
" ***" << std::endl;
83 std::cerr <<
"--- Ha ---" << std::endl << Hs_a[i] << std::endl;
84 std::cerr <<
"--- Hd ---" << std::endl << Hs_d[i] << std::endl;
85 std::cerr <<
"--- err ---" << std::endl << Hs_a[i] - Hs_d[i] << std::endl;