1 #ifndef STAN_MATH_REV_FUN_OWENS_T_HPP
2 #define STAN_MATH_REV_FUN_OWENS_T_HPP
3
4 #include <stan/math/rev/meta.hpp>
5 #include <stan/math/rev/core.hpp>
6 #include <stan/math/prim/fun/constants.hpp>
7 #include <stan/math/prim/fun/erf.hpp>
8 #include <stan/math/prim/fun/owens_t.hpp>
9 #include <stan/math/prim/fun/square.hpp>
10 #include <cmath>
11
12 namespace stan {
13 namespace math {
14
15 namespace internal {
16 class owens_t_vv_vari : public op_vv_vari {
17 public:
owens_t_vv_vari(vari * avi,vari * bvi)18 owens_t_vv_vari(vari* avi, vari* bvi)
19 : op_vv_vari(owens_t(avi->val_, bvi->val_), avi, bvi) {}
chain()20 void chain() {
21 const double neg_avi_sq_div_2 = -square(avi_->val_) * 0.5;
22 const double one_p_bvi_sq = 1.0 + square(bvi_->val_);
23
24 avi_->adj_ += adj_ * erf(bvi_->val_ * avi_->val_ * INV_SQRT_TWO)
25 * std::exp(neg_avi_sq_div_2) * INV_SQRT_TWO_PI * -0.5;
26 bvi_->adj_ += adj_ * std::exp(neg_avi_sq_div_2 * one_p_bvi_sq)
27 / (one_p_bvi_sq * TWO_PI);
28 }
29 };
30
31 class owens_t_vd_vari : public op_vd_vari {
32 public:
owens_t_vd_vari(vari * avi,double b)33 owens_t_vd_vari(vari* avi, double b)
34 : op_vd_vari(owens_t(avi->val_, b), avi, b) {}
chain()35 void chain() {
36 avi_->adj_ += adj_ * erf(bd_ * avi_->val_ * INV_SQRT_TWO)
37 * std::exp(-square(avi_->val_) * 0.5) * INV_SQRT_TWO_PI
38 * -0.5;
39 }
40 };
41
42 class owens_t_dv_vari : public op_dv_vari {
43 public:
owens_t_dv_vari(double a,vari * bvi)44 owens_t_dv_vari(double a, vari* bvi)
45 : op_dv_vari(owens_t(a, bvi->val_), a, bvi) {}
chain()46 void chain() {
47 const double one_p_bvi_sq = 1.0 + square(bvi_->val_);
48 bvi_->adj_ += adj_ * std::exp(-0.5 * square(ad_) * one_p_bvi_sq)
49 / (one_p_bvi_sq * TWO_PI);
50 }
51 };
52 } // namespace internal
53
54 /**
55 * The Owen's T function of h and a.
56 *
57 * Used to compute the cumulative density function for the skew normal
58 * distribution.
59 *
60 * @param h var parameter.
61 * @param a var parameter.
62 * @return The Owen's T function.
63 */
owens_t(const var & h,const var & a)64 inline var owens_t(const var& h, const var& a) {
65 return var(new internal::owens_t_vv_vari(h.vi_, a.vi_));
66 }
67
68 /**
69 * The Owen's T function of h and a.
70 *
71 * Used to compute the cumulative density function for the skew normal
72 * distribution.
73 *
74 * @param h var parameter.
75 * @param a double parameter.
76 * @return The Owen's T function.
77 */
owens_t(const var & h,double a)78 inline var owens_t(const var& h, double a) {
79 return var(new internal::owens_t_vd_vari(h.vi_, a));
80 }
81
82 /**
83 * The Owen's T function of h and a.
84 *
85 * Used to compute the cumulative density function for the skew normal
86 * distribution.
87 *
88 * @param h double parameter.
89 * @param a var parameter.
90 * @return The Owen's T function.
91 */
owens_t(double h,const var & a)92 inline var owens_t(double h, const var& a) {
93 return var(new internal::owens_t_dv_vari(h, a.vi_));
94 }
95
96 } // namespace math
97 } // namespace stan
98 #endif
99