gtsam_points
Loading...
Searching...
No Matches
numerical.hpp
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2021 Kenji Koide (k.koide@aist.go.jp)
3
4#pragma once
5
6#include <Eigen/Core>
7
8namespace gtsam_points {
9
10template <typename Func>
11Eigen::VectorXd numerical_jacobian(const Func& f, const Eigen::VectorXd& x, double eps = 1e-6) {
12 const int N = x.size();
13 Eigen::VectorXd j(N);
14
15 for (int i = 0; i < N; i++) {
16 Eigen::VectorXd dx = Eigen::VectorXd::Zero(N);
17 dx[i] = eps;
18
19 const double y0 = f(x - dx);
20 const double y1 = f(x + dx);
21 j[i] = (y1 - y0) / (2.0 * eps);
22 }
23
24 return j;
25}
26
27template <typename Func>
28Eigen::MatrixXd numerical_hessian(const Func& f, const Eigen::VectorXd& x, double eps = 1e-6) {
29 const int N = x.size();
30 Eigen::MatrixXd h(N, N);
31
32 for (int i = 0; i < N; i++) {
33 for (int j = 0; j < N; j++) {
34 Eigen::VectorXd dx = Eigen::VectorXd::Zero(N);
35 dx[i] = eps;
36
37 auto first = [&](const Eigen::VectorXd& dy) {
38 const double y0 = f(x - dx + dy);
39 const double y1 = f(x + dx + dy);
40 return (y1 - y0) / (2.0 * eps);
41 };
42
43 Eigen::VectorXd dy = Eigen::VectorXd::Zero(N);
44 dy[j] = eps;
45
46 const double dx0 = first(-dy);
47 const double dx1 = first(dy);
48
49 h(i, j) = (dx1 - dx0) / (2.0 * eps);
50 }
51 }
52
53 return h;
54}
55} // namespace gtsam_points