Automatic Differentiation
 
Loading...
Searching...
No Matches
finite_diff_hessian_auto.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUNCTOR_HESSIAN_HPP
2#define STAN_MATH_REV_FUNCTOR_HESSIAN_HPP
3
9#include <stdexcept>
10
11namespace stan {
12namespace math {
13namespace internal {
42template <typename F>
43void finite_diff_hessian_auto(const F& f, const Eigen::VectorXd& x, double& fx,
44 Eigen::VectorXd& grad_fx,
45 Eigen::MatrixXd& hess_fx) {
46 int d = x.size();
47
48 Eigen::VectorXd x_temp(x);
49 hess_fx.resize(d, d);
50
51 gradient(f, x, fx, grad_fx);
52
53 std::vector<Eigen::VectorXd> g_plus(d);
54 std::vector<Eigen::VectorXd> g_minus(d);
55 std::vector<double> epsilons(d);
56 double tmp;
57
58 // compute the gradient at x+eps_i*e_i
59 // such that eps_i is the step size and e_i is the unit vector
60 // in the i-th direction
61 for (size_t i = 0; i < d; ++i) {
62 Eigen::VectorXd x_temp(x);
63 epsilons[i] = finite_diff_stepsize(x(i));
64 x_temp(i) += epsilons[i];
65 gradient(f, x_temp, tmp, g_plus[i]);
66 }
67
68 // similarly, compute the gradient at x-eps_i*e_i
69 for (size_t i = 0; i < d; ++i) {
70 Eigen::VectorXd x_temp(x);
71 x_temp(i) -= epsilons[i];
72 gradient(f, x_temp, tmp, g_minus[i]);
73 }
74 // approximate the hessian as a finite difference of gradients
75 for (int i = 0; i < d; ++i) {
76 for (int j = i; j < d; ++j) {
77 hess_fx(j, i) = (g_plus[j](i) - g_minus[j](i)) / (4 * epsilons[j])
78 + (g_plus[i](j) - g_minus[i](j)) / (4 * epsilons[i]);
79 hess_fx(i, j) = hess_fx(j, i);
80 }
81 }
82}
83} // namespace internal
84} // namespace math
85} // namespace stan
86#endif
void finite_diff_hessian_auto(const F &f, const Eigen::VectorXd &x, double &fx, Eigen::VectorXd &grad_fx, Eigen::MatrixXd &hess_fx)
Calculate the value and the Hessian of the specified function at the specified argument using first-o...
void gradient(const F &f, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &x, T &fx, Eigen::Matrix< T, Eigen::Dynamic, 1 > &grad_fx)
Calculate the value and the gradient of the specified function at the specified argument.
Definition gradient.hpp:40
double finite_diff_stepsize(double u)
Return the stepsize for finite difference evaluations at the specified scalar.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...