Automatic Differentiation
 
Loading...
Searching...
No Matches
owens_t.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUN_OWENS_T_HPP
2#define STAN_MATH_REV_FUN_OWENS_T_HPP
3
11#include <cmath>
12
13namespace stan {
14namespace math {
15
28template <typename Var1, typename Var2,
29 require_all_st_var<Var1, Var2>* = nullptr,
30 require_all_not_std_vector_t<Var1, Var2>* = nullptr>
31inline auto owens_t(const Var1& h, const Var2& a) {
32 auto h_arena = to_arena(h);
33 auto a_arena = to_arena(a);
34 using return_type
35 = return_var_matrix_t<decltype(owens_t(h_arena.val(), a_arena.val())),
36 Var1, Var2>;
37 arena_t<return_type> ret = owens_t(h_arena.val(), a_arena.val());
38 reverse_pass_callback([h_arena, a_arena, ret]() mutable {
39 const auto& h_val = as_value_array_or_scalar(h_arena);
40 const auto& a_val = as_value_array_or_scalar(a_arena);
41 const auto neg_h_sq_div_2 = stan::math::eval(-square(h_val) * 0.5);
42 const auto one_p_a_sq = stan::math::eval(1.0 + square(a_val));
43 as_array_or_scalar(h_arena).adj() += possibly_sum<is_stan_scalar<Var1>>(
44 as_array_or_scalar(ret.adj()) * erf(a_val * h_val * INV_SQRT_TWO)
45 * exp(neg_h_sq_div_2) * INV_SQRT_TWO_PI * -0.5);
46 as_array_or_scalar(a_arena).adj() += possibly_sum<is_stan_scalar<Var2>>(
47 as_array_or_scalar(ret.adj()) * exp(neg_h_sq_div_2 * one_p_a_sq)
48 / (one_p_a_sq * TWO_PI));
49 });
50 return return_type(ret);
51}
52
65template <typename Var, typename Arith, require_st_arithmetic<Arith>* = nullptr,
66 require_all_not_std_vector_t<Var, Arith>* = nullptr,
67 require_st_var<Var>* = nullptr>
68inline auto owens_t(const Var& h, const Arith& a) {
69 auto h_arena = to_arena(h);
70 auto a_arena = to_arena(a);
71 using return_type
72 = return_var_matrix_t<decltype(owens_t(h_arena.val(), a_arena)), Var,
73 Arith>;
74 arena_t<return_type> ret = owens_t(h_arena.val(), a_arena);
75 reverse_pass_callback([h_arena, a_arena, ret]() mutable {
76 const auto& h_val = as_value_array_or_scalar(h_arena);
77 as_array_or_scalar(h_arena).adj() += possibly_sum<is_stan_scalar<Var>>(
78 as_array_or_scalar(ret.adj())
79 * erf(as_array_or_scalar(a_arena) * h_val * INV_SQRT_TWO)
80 * exp(-square(h_val) * 0.5) * INV_SQRT_TWO_PI * -0.5);
81 });
82 return return_type(ret);
83}
84
97template <typename Arith, typename Var, require_st_arithmetic<Arith>* = nullptr,
98 require_all_not_std_vector_t<Var, Arith>* = nullptr,
99 require_st_var<Var>* = nullptr>
100inline auto owens_t(const Arith& h, const Var& a) {
101 auto h_arena = to_arena(h);
102 auto a_arena = to_arena(a);
103 using return_type
104 = return_var_matrix_t<decltype(owens_t(h_arena, a_arena.val())), Var,
105 Arith>;
106 arena_t<return_type> ret = owens_t(h_arena, a_arena.val());
107 reverse_pass_callback([h_arena, a_arena, ret]() mutable {
108 const auto one_p_a_sq
109 = eval(1.0 + square(as_value_array_or_scalar(a_arena)));
110 as_array_or_scalar(a_arena).adj() += possibly_sum<is_stan_scalar<Var>>(
111 as_array_or_scalar(ret.adj())
112 * exp(-0.5 * square(as_array_or_scalar(h_arena)) * one_p_a_sq)
113 / (one_p_a_sq * TWO_PI));
114 });
115 return return_type(ret);
116}
117
118} // namespace math
119} // namespace stan
120#endif
T as_array_or_scalar(T &&v)
Returns specified input value.
void reverse_pass_callback(F &&functor)
Puts a callback on the autodiff stack to be called in reverse pass.
T eval(T &&arg)
Inputs which have a plain_type equal to the own time are forwarded unmodified (for Eigen expressions ...
Definition eval.hpp:20
fvar< T > erf(const fvar< T > &x)
Definition erf.hpp:16
static constexpr double INV_SQRT_TWO
The value of 1 over the square root of 2, .
static constexpr double INV_SQRT_TWO_PI
The value of 1 over the square root of , .
arena_t< T > to_arena(const T &a)
Converts given argument into a type that either has any dynamic allocation on AD stack or schedules i...
Definition to_arena.hpp:25
fvar< T > owens_t(const fvar< T > &x1, const fvar< T > &x2)
Return Owen's T function applied to the specified arguments.
Definition owens_t.hpp:26
static constexpr double TWO_PI
Twice the value of , .
Definition constants.hpp:62
auto as_value_array_or_scalar(T &&v)
Extract the value from an object.
fvar< T > square(const fvar< T > &x)
Definition square.hpp:12
fvar< T > exp(const fvar< T > &x)
Definition exp.hpp:15
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.
std::conditional_t< is_any_var_matrix< ReturnType, Types... >::value, stan::math::var_value< stan::math::promote_scalar_t< double, plain_type_t< ReturnType > > >, stan::math::promote_scalar_t< stan::math::var_value< double >, plain_type_t< ReturnType > > > return_var_matrix_t
Given an Eigen type and several inputs, determine if a matrix should be var<Matrix> or Matrix<var>.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
Template metaprogram to calculate the base scalar return type resulting from promoting all the scalar...