Automatic Differentiation
 
Loading...
Searching...
No Matches
sum_to_zero_free.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_CONSTRAINT_SUM_TO_ZERO_FREE_HPP
2#define STAN_MATH_PRIM_CONSTRAINT_SUM_TO_ZERO_FREE_HPP
3
10#include <cmath>
11
12namespace stan {
13namespace math {
14
37template <typename Vec, require_eigen_vector_t<Vec>* = nullptr>
38inline plain_type_t<Vec> sum_to_zero_free(const Vec& z) {
39 const auto& z_ref = to_ref(z);
40 check_sum_to_zero("stan::math::sum_to_zero_free", "sum_to_zero variable",
41 z_ref);
42
43 const auto N = z.size() - 1;
44
45 plain_type_t<Vec> y = Eigen::VectorXd::Zero(N);
46 if (unlikely(N == 0)) {
47 return y;
48 }
49
50 y.coeffRef(N - 1) = -z_ref(N) * sqrt(N * (N + 1)) / N;
51
52 value_type_t<Vec> sum_w(0);
53
54 for (int i = N - 2; i >= 0; --i) {
55 double n = static_cast<double>(i + 1);
56 auto w = y(i + 1) / sqrt((n + 1) * (n + 2));
57 sum_w += w;
58 y.coeffRef(i) = (sum_w - z_ref(i + 1)) * sqrt(n * (n + 1)) / n;
59 }
60
61 return y;
62}
63
71template <typename T, require_std_vector_t<T>* = nullptr>
72auto sum_to_zero_free(const T& z) {
74 z, [](auto&& v) { return sum_to_zero_free(v); });
75}
76
77} // namespace math
78} // namespace stan
79
80#endif
#define unlikely(x)
typename value_type< T >::type value_type_t
Helper function for accessing underlying type.
plain_type_t< Vec > sum_to_zero_free(const Vec &z)
Return an unconstrained vector.
void check_sum_to_zero(const char *function, const char *name, const T &theta)
Throw an exception if the specified vector does not sum to 0.
fvar< T > sqrt(const fvar< T > &x)
Definition sqrt.hpp:17
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
Definition to_ref.hpp:17
typename plain_type< T >::type plain_type_t
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...