Automatic Differentiation
 
Loading...
Searching...
No Matches
finite_diff_gradient_auto.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_FUNCTOR_FINITE_DIFF_GRADIENT_AUTO_HPP
2#define STAN_MATH_PRIM_FUNCTOR_FINITE_DIFF_GRADIENT_AUTO_HPP
3
6#include <cmath>
7
8namespace stan {
9namespace math {
10
49template <typename F, typename VectorT, typename GradVectorT,
50 typename ScalarT = return_type_t<VectorT>>
51void finite_diff_gradient_auto(const F& f, VectorT&& x, ScalarT& fx,
52 GradVectorT& grad_fx) {
53 using EigT = Eigen::Matrix<ScalarT, -1, 1>;
54 static constexpr int h_scale[6] = {3, 2, 1, -3, -2, -1};
55 static constexpr int mults[6] = {1, -9, 45, -1, 9, -45};
56
57 fx = f(x);
58 grad_fx.resize(x.size());
59 Eigen::Map<EigT> grad_map(grad_fx.data(), grad_fx.size());
60
61 grad_map = EigT::NullaryExpr(x.size(), [&f, &x](Eigen::Index i) {
62 double h = finite_diff_stepsize(value_of_rec(x[i]));
63 ScalarT delta_f = 0;
64 for (int j = 0; j < 6; ++j) {
65 auto x_temp
66 = EigT::NullaryExpr(x.size(), [&x, &i, &h, &j](Eigen::Index k) {
67 return k == i ? x[i] + h * h_scale[j] : x[k];
68 });
69 delta_f += f(std::move(x_temp)) * mults[j];
70 }
71 return delta_f / (60 * h);
72 });
73}
74
75} // namespace math
76} // namespace stan
77#endif
void finite_diff_gradient_auto(const F &f, VectorT &&x, ScalarT &fx, GradVectorT &grad_fx)
Calculate the value and the gradient of the specified function at the specified argument using finite...
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...