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
12#include <cmath>
13#include <vector>
14
15namespace stan {
16namespace math {
17
27template <typename T, require_eigen_st<is_var, T>* = nullptr>
28var sd(const T& x) {
29 using std::sqrt;
30 using T_vi = promote_scalar_t<vari*, T>;
32
33 check_nonzero_size("sd", "x", x);
34
35 if (x.size() == 1) {
36 return 0.0;
37 }
38
39 vari** varis
41 double* partials
43 Eigen::Map<T_vi> varis_map(varis, x.rows(), x.cols());
44 Eigen::Map<T_d> partials_map(partials, x.rows(), x.cols());
45
46 varis_map = x.vi();
47 T_d dtrs_val = x.val();
48 double mean = dtrs_val.mean();
49 T_d diff = dtrs_val.array() - mean;
50 double sum_of_squares = diff.squaredNorm();
51 double size_m1 = x.size() - 1;
52 double sd = sqrt(sum_of_squares / size_m1);
53
54 if (sum_of_squares < 1e-20) {
55 partials_map.fill(inv_sqrt(static_cast<double>(x.size())));
56 } else {
57 partials_map = diff.array() / (sd * size_m1);
58 }
59 return var(new stored_gradient_vari(sd, x.size(), varis, partials));
60}
61
70template <typename T, require_var_matrix_t<T>* = nullptr>
71var sd(const T& x) {
72 check_nonzero_size("sd", "x", x);
73
74 if (x.size() == 1) {
75 return 0.0;
76 }
77
78 auto arena_diff = to_arena((x.val().array() - x.val().mean()).matrix());
79 double sum_of_squares = arena_diff.squaredNorm();
80 double sd = std::sqrt(sum_of_squares / (x.size() - 1));
81
82 return make_callback_vari(sd, [x, arena_diff](const auto& res) mutable {
83 x.adj() += (res.adj() / (res.val() * (x.size() - 1))) * arena_diff;
84 });
85}
86
96template <typename T, require_std_vector_st<is_var, T>* = nullptr>
97auto sd(const T& m) {
98 return apply_vector_unary<T>::reduce(m, [](const auto& x) { return sd(x); });
99}
100
101} // namespace math
102} // namespace stan
103#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:18
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:14
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_