Automatic Differentiation
 
Loading...
Searching...
No Matches
sd.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUN_SD_HPP
2#define STAN_MATH_REV_FUN_SD_HPP
3
10#include <cmath>
11#include <vector>
12
13namespace stan {
14namespace math {
15
25template <typename T, require_eigen_st<is_var, T>* = nullptr>
26var sd(const T& x) {
27 using std::sqrt;
28 using T_vi = promote_scalar_t<vari*, T>;
30
31 check_nonzero_size("sd", "x", x);
32
33 if (x.size() == 1) {
34 return 0.0;
35 }
36
37 vari** varis
39 double* partials
41 Eigen::Map<T_vi> varis_map(varis, x.rows(), x.cols());
42 Eigen::Map<T_d> partials_map(partials, x.rows(), x.cols());
43
44 varis_map = x.vi();
45 T_d dtrs_val = x.val();
46 double mean = dtrs_val.mean();
47 T_d diff = dtrs_val.array() - mean;
48 double sum_of_squares = diff.squaredNorm();
49 double size_m1 = x.size() - 1;
50 double sd = sqrt(sum_of_squares / size_m1);
51
52 if (sum_of_squares < 1e-20) {
53 partials_map.fill(inv_sqrt(static_cast<double>(x.size())));
54 } else {
55 partials_map = diff.array() / (sd * size_m1);
56 }
57 return var(new stored_gradient_vari(sd, x.size(), varis, partials));
58}
59
68template <typename T, require_var_matrix_t<T>* = nullptr>
69var sd(const T& x) {
70 check_nonzero_size("sd", "x", x);
71
72 if (x.size() == 1) {
73 return 0.0;
74 }
75
76 auto arena_diff = to_arena((x.val().array() - x.val().mean()).matrix());
77 double sum_of_squares = arena_diff.squaredNorm();
78 double sd = std::sqrt(sum_of_squares / (x.size() - 1));
79
80 return make_callback_vari(sd, [x, arena_diff](const auto& res) mutable {
81 x.adj() += (res.adj() / (res.val() * (x.size() - 1))) * arena_diff;
82 });
83}
84
94template <typename T, require_std_vector_st<is_var, T>* = nullptr>
95auto sd(const T& m) {
96 return apply_vector_unary<T>::reduce(m, [](const auto& x) { return sd(x); });
97}
98
99} // namespace math
100} // namespace stan
101#endif
T * alloc_array(size_t n)
Allocate an array on the arena of the specified size to hold values of the specified template paramet...
A var implementation that stores the daughter variable implementation pointers and the partial deriva...
scalar_type_t< T > mean(const T &m)
Returns the sample mean (i.e., average) of the coefficients in the specified std vector,...
Definition mean.hpp:20
static constexpr double e()
Return the base of the natural logarithm.
Definition constants.hpp:20
typename promote_scalar_type< std::decay_t< T >, std::decay_t< S > >::type promote_scalar_t
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 > sqrt(const fvar< T > &x)
Definition sqrt.hpp:17
var_value< double > var
Definition var.hpp:1187
void check_nonzero_size(const char *function, const char *name, const T_y &y)
Check if the specified matrix/vector is of non-zero size.
constexpr auto & partials(internal::partials_propagator< Types... > &x) noexcept
Access the partials for an edge of an partials_propagator
double sd(const T &a)
Returns the unbiased sample standard deviation of the coefficients in the specified std vector,...
Definition sd.hpp:26
fvar< T > inv_sqrt(const fvar< T > &x)
Definition inv_sqrt.hpp:12
internal::callback_vari< plain_type_t< T >, F > * make_callback_vari(T &&value, F &&functor)
Creates a new vari with given value and a callback that implements the reverse pass (chain).
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
static thread_local AutodiffStackStorage * instance_