1 #ifndef STAN_MATH_PRIM_FUN_VARIANCE_HPP
2 #define STAN_MATH_PRIM_FUN_VARIANCE_HPP
3 
4 #include <stan/math/prim/err.hpp>
5 #include <stan/math/prim/fun/Eigen.hpp>
6 #include <stan/math/prim/fun/mean.hpp>
7 #include <vector>
8 
9 namespace stan {
10 namespace math {
11 
12 /**
13  * Returns the sample variance (divide by length - 1) of the
14  * coefficients in the specified matrix
15  *
16  * @tparam EigMat type inheriting from `EigenBase` that does not have an `var`
17  *  scalar type.
18  *
19  * @param m matrix
20  * @return sample variance of coefficients
21  * @throw <code>std::invalid_argument</code> if the matrix has size zero
22  */
23 template <typename EigMat, require_eigen_t<EigMat>* = nullptr,
24           require_not_vt_var<EigMat>* = nullptr>
variance(const EigMat & m)25 inline value_type_t<EigMat> variance(const EigMat& m) {
26   using value_t = value_type_t<EigMat>;
27   const auto& mat = to_ref(m);
28   check_nonzero_size("variance", "m", mat);
29   if (mat.size() == 1) {
30     return value_t{0.0};
31   }
32   return (mat.array() - mat.mean()).square().sum() / value_t(mat.size() - 1.0);
33 }
34 
35 /**
36  * Returns the sample variance (divide by length - 1) of the
37  * coefficients in the specified standard vector.
38  *
39  * @tparam StdVec A standard library vector that does not contain a var.
40  * @param v specified vector
41  * @return sample variance of vector
42  * @throw <code>std::invalid_argument</code> if the vector has size zero
43  */
44 template <typename StdVec, require_std_vector_t<StdVec>* = nullptr,
45           require_not_vt_var<StdVec>* = nullptr>
variance(const StdVec & v)46 inline value_type_t<StdVec> variance(const StdVec& v) {
47   using eigen_t = Eigen::Matrix<value_type_t<StdVec>, -1, 1>;
48   return variance(Eigen::Map<const eigen_t>(v.data(), v.size()));
49 }
50 
51 }  // namespace math
52 }  // namespace stan
53 
54 #endif
55