WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
NumericalJacobian.hpp
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
8
9namespace wpi::math {
10
11/**
12 * Returns numerical Jacobian with respect to x for f(x).
13 *
14 * @tparam Rows Number of rows in result of f(x).
15 * @tparam Cols Number of columns in result of f(x).
16 * @param f Vector-valued function from which to compute Jacobian.
17 * @param x Vector argument.
18 */
19template <int Rows, int Cols, typename F>
20auto NumericalJacobian(F&& f, const Vectord<Cols>& x) {
21 constexpr double kEpsilon = 1e-5;
23 result.setZero();
24
25 // It's more expensive, but +- epsilon will be more accurate
26 for (int i = 0; i < Cols; ++i) {
27 Vectord<Cols> dX_plus = x;
28 dX_plus(i) += kEpsilon;
29 Vectord<Cols> dX_minus = x;
30 dX_minus(i) -= kEpsilon;
31 result.col(i) = (f(dX_plus) - f(dX_minus)) / (kEpsilon * 2.0);
32 }
33
34 return result;
35}
36
37/**
38 * Returns numerical Jacobian with respect to x for f(x).
39 *
40 * @param f Vector-valued function from which to compute Jacobian.
41 * @param x Vector argument.
42 */
43template <typename F>
44Eigen::MatrixXd NumericalJacobian(F&& f, const Eigen::VectorXd& x) {
45 constexpr double kEpsilon = 1e-5;
46 Eigen::MatrixXd result;
47
48 // It's more expensive, but +- epsilon will be more accurate
49 for (int i = 0; i < x.rows(); ++i) {
50 Eigen::VectorXd dX_plus = x;
51 dX_plus(i) += kEpsilon;
52 Eigen::VectorXd dX_minus = x;
53 dX_minus(i) -= kEpsilon;
54 Eigen::VectorXd partialDerivative =
55 (f(dX_plus) - f(dX_minus)) / (kEpsilon * 2.0);
56 if (i == 0) {
57 result.resize(partialDerivative.rows(), x.rows());
58 result.setZero();
59 }
60 result.col(i) = partialDerivative;
61 }
62
63 return result;
64}
65
66/**
67 * Returns numerical Jacobian with respect to x for f(x, u, ...).
68 *
69 * @tparam Rows Number of rows in result of f(x, u, ...).
70 * @tparam States Number of rows in x.
71 * @tparam Inputs Number of rows in u.
72 * @tparam F Function object type.
73 * @tparam Args... Types of remaining arguments to f(x, u, ...).
74 * @param f Vector-valued function from which to compute Jacobian.
75 * @param x State vector.
76 * @param u Input vector.
77 * @param args Remaining arguments to f(x, u, ...).
78 */
79template <int Rows, int States, int Inputs, typename F, typename... Args>
81 const Vectord<Inputs>& u, Args&&... args) {
83 [&](const Vectord<States>& x) { return f(x, u, args...); }, x);
84}
85
86/**
87 * Returns numerical Jacobian with respect to x for f(x, u, ...).
88 *
89 * @tparam F Function object type.
90 * @tparam Args... Types of remaining arguments to f(x, u, ...).
91 * @param f Vector-valued function from which to compute Jacobian.
92 * @param x State vector.
93 * @param u Input vector.
94 * @param args Remaining arguments to f(x, u, ...).
95 */
96template <typename F, typename... Args>
97auto NumericalJacobianX(F&& f, const Eigen::VectorXd& x,
98 const Eigen::VectorXd& u, Args&&... args) {
99 return NumericalJacobian(
100 [&](const Eigen::VectorXd& x) { return f(x, u, args...); }, x);
101}
102
103/**
104 * Returns numerical Jacobian with respect to u for f(x, u, ...).
105 *
106 * @tparam Rows Number of rows in result of f(x, u, ...).
107 * @tparam States Number of rows in x.
108 * @tparam Inputs Number of rows in u.
109 * @tparam F Function object type.
110 * @tparam Args... Types of remaining arguments to f(x, u, ...).
111 * @param f Vector-valued function from which to compute Jacobian.
112 * @param x State vector.
113 * @param u Input vector.
114 * @param args Remaining arguments to f(x, u, ...).
115 */
116template <int Rows, int States, int Inputs, typename F, typename... Args>
118 const Vectord<Inputs>& u, Args&&... args) {
120 [&](const Vectord<Inputs>& u) { return f(x, u, args...); }, u);
121}
122
123/**
124 * Returns numerical Jacobian with respect to u for f(x, u, ...).
125 *
126 * @tparam F Function object type.
127 * @tparam Args... Types of remaining arguments to f(x, u, ...).
128 * @param f Vector-valued function from which to compute Jacobian.
129 * @param x State vector.
130 * @param u Input vector.
131 * @param args Remaining arguments to f(x, u, ...).
132 */
133template <typename F, typename... Args>
134auto NumericalJacobianU(F&& f, const Eigen::VectorXd& x,
135 const Eigen::VectorXd& u, Args&&... args) {
136 return NumericalJacobian(
137 [&](const Eigen::VectorXd& u) { return f(x, u, args...); }, u);
138}
139
140} // namespace wpi::math
Definition LinearSystem.hpp:20
auto NumericalJacobianU(F &&f, const Vectord< States > &x, const Vectord< Inputs > &u, Args &&... args)
Returns numerical Jacobian with respect to u for f(x, u, ...).
Definition NumericalJacobian.hpp:117
auto NumericalJacobian(F &&f, const Vectord< Cols > &x)
Returns numerical Jacobian with respect to x for f(x).
Definition NumericalJacobian.hpp:20
Eigen::Matrix< double, Rows, Cols, Options, MaxRows, MaxCols > Matrixd
Definition EigenCore.hpp:21
auto NumericalJacobianX(F &&f, const Vectord< States > &x, const Vectord< Inputs > &u, Args &&... args)
Returns numerical Jacobian with respect to x for f(x, u, ...).
Definition NumericalJacobian.hpp:80
Eigen::Vector< double, Size > Vectord
Definition EigenCore.hpp:12