Automatic Differentiation
 
Loading...
Searching...
No Matches
positive_ordered_constrain.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_CONSTRAINT_POSITIVE_ORDERED_CONSTRAIN_HPP
2#define STAN_MATH_REV_CONSTRAINT_POSITIVE_ORDERED_CONSTRAIN_HPP
3
9#include <cmath>
10#include <tuple>
11#include <vector>
12
13namespace stan {
14namespace math {
15
24template <typename T, require_rev_col_vector_t<T>* = nullptr>
25inline auto positive_ordered_constrain(const T& x) {
26 using ret_type = plain_type_t<T>;
27
28 size_t N = x.size();
29
30 if (unlikely(N == 0)) {
31 return ret_type(x);
32 }
33
34 arena_t<T> arena_x = x;
35 Eigen::VectorXd y_val(N);
37
38 exp_x(0) = std::exp(value_of(arena_x)(0));
39 y_val(0) = exp_x.coeff(0);
40 for (int n = 1; n < N; ++n) {
41 exp_x(n) = std::exp(value_of(arena_x)(n));
42 y_val(n) = y_val.coeff(n - 1) + exp_x.coeff(n);
43 }
44
45 arena_t<ret_type> y = y_val;
46
47 reverse_pass_callback([arena_x, exp_x, y]() mutable {
48 const size_t N = arena_x.size();
49 double rolling_adjoint_sum = 0.0;
50
51 for (int n = N; --n >= 0;) {
52 rolling_adjoint_sum += y.adj().coeff(n);
53 arena_x.adj().coeffRef(n) += exp_x.coeff(n) * rolling_adjoint_sum;
54 }
55 });
56
57 return ret_type(y);
58}
59
60} // namespace math
61} // namespace stan
62#endif
#define unlikely(x)
void reverse_pass_callback(F &&functor)
Puts a callback on the autodiff stack to be called in reverse pass.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition value_of.hpp:18
auto positive_ordered_constrain(const EigVec &x)
Return an increasing positive ordered vector derived from the specified free vector.
typename plain_type< T >::type plain_type_t
typename internal::arena_type_impl< std::decay_t< T > >::type arena_t
Determines a type that can be used in place of T that does any dynamic allocations on the AD stack.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...