1 #ifndef STAN_MATH_REV_FUN_ERF_HPP
2 #define STAN_MATH_REV_FUN_ERF_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 <cmath>
9 
10 namespace stan {
11 namespace math {
12 
13 /**
14  * The error function for variables (C99).
15  *
16  * The derivative is
17  *
18  * \f$\frac{d}{dx} \mbox{erf}(x) = \frac{2}{\sqrt{\pi}} \exp(-x^2)\f$.
19  *
20  *
21    \f[
22    \mbox{erf}(x) =
23    \begin{cases}
24      \operatorname{erf}(x) & \mbox{if } -\infty\leq x \leq \infty \\[6pt]
25      \textrm{NaN} & \mbox{if } x = \textrm{NaN}
26    \end{cases}
27    \f]
28 
29    \f[
30    \frac{\partial\, \mbox{erf}(x)}{\partial x} =
31    \begin{cases}
32      \frac{\partial\, \operatorname{erf}(x)}{\partial x} & \mbox{if }
33  -\infty\leq x\leq \infty \\[6pt] \textrm{NaN} & \mbox{if } x = \textrm{NaN}
34    \end{cases}
35    \f]
36 
37    \f[
38    \operatorname{erf}(x)=\frac{2}{\sqrt{\pi}}\int_0^x e^{-t^2}dt
39    \f]
40 
41    \f[
42    \frac{\partial \, \operatorname{erf}(x)}{\partial x} = \frac{2}{\sqrt{\pi}}
43  e^{-x^2} \f]
44  *
45  * @param a The variable.
46  * @return Error function applied to the variable.
47  */
erf(const var & a)48 inline var erf(const var& a) {
49   auto precomp_erf = TWO_OVER_SQRT_PI * std::exp(-a.val() * a.val());
50   return make_callback_var(erf(a.val()), [a, precomp_erf](auto& vi) mutable {
51     a.adj() += vi.adj() * precomp_erf;
52   });
53 }
54 
55 template <typename T, require_matrix_t<T>* = nullptr>
erf(const var_value<T> & a)56 inline auto erf(const var_value<T>& a) {
57   auto precomp_erf
58       = to_arena(TWO_OVER_SQRT_PI * (-a.val().array().square()).exp());
59   return make_callback_var(erf(a.val()), [a, precomp_erf](auto& vi) mutable {
60     a.adj().array() += vi.adj().array() * precomp_erf;
61   });
62 }
63 
64 }  // namespace math
65 }  // namespace stan
66 #endif
67