Automatic Differentiation
 
Loading...
Searching...
No Matches
Phi_approx.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUN_PHI_APPROX_HPP
2#define STAN_MATH_REV_FUN_PHI_APPROX_HPP
3
8
9namespace stan {
10namespace math {
11
47inline var Phi_approx(const var& a) {
48 double av_squared = a.val() * a.val();
49 double f = inv_logit(0.07056 * a.val() * av_squared + 1.5976 * a.val());
50 double da = f * (1 - f) * (3.0 * 0.07056 * av_squared + 1.5976);
51 return make_callback_var(
52 f, [a, da](auto& vi) mutable { a.adj() += vi.adj() * da; });
53}
54
55template <typename T, require_var_matrix_t<T>* = nullptr>
56inline auto Phi_approx(const T& a) {
57 arena_t<value_type_t<T>> f(a.rows(), a.cols());
58 arena_t<value_type_t<T>> da(a.rows(), a.cols());
59 for (Eigen::Index j = 0; j < a.cols(); ++j) {
60 for (Eigen::Index i = 0; i < a.rows(); ++i) {
61 const auto a_val = a.val().coeff(i, j);
62 const auto av_squared = a_val * a_val;
63 f.coeffRef(i, j) = inv_logit(0.07056 * a_val * av_squared
64 + 1.5976 * a.val().coeff(i, j));
65 da.coeffRef(i, j) = f.coeff(i, j) * (1 - f.coeff(i, j))
66 * (3.0 * 0.07056 * av_squared + 1.5976);
67 }
68 }
69 return make_callback_var(f, [a, da](auto& vi) mutable {
70 a.adj().array() += vi.adj().array() * da.array();
71 });
72}
73
74} // namespace math
75} // namespace stan
76#endif
var_value< plain_type_t< T > > make_callback_var(T &&value, F &&functor)
Creates a new var initialized with a callback_vari with a given value and reverse-pass callback funct...
fvar< T > Phi_approx(const fvar< T > &x)
Return an approximation of the unit normal cumulative distribution function (CDF).
fvar< T > inv_logit(const fvar< T > &x)
Returns the inverse logit function applied to the argument.
Definition inv_logit.hpp:20
typename internal::arena_type_impl< std::decay_t< T > >::type arena_t
Determines a type that can be used in place of T that does any dynamic allocations on the AD stack.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...