Automatic Differentiation
 
Loading...
Searching...
No Matches
lub_free.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_CONSTRAINT_LUB_FREE_HPP
2#define STAN_MATH_PRIM_CONSTRAINT_LUB_FREE_HPP
3
12
13namespace stan {
14namespace math {
15
40
43template <typename T, typename L, typename U,
44 require_not_std_vector_t<T>* = nullptr,
45 require_all_stan_scalar_t<L, U>* = nullptr>
46inline auto lub_free(T&& y, L&& lb, U&& ub) {
47 const bool is_lb_inf = value_of(lb) == NEGATIVE_INFTY;
48 const bool is_ub_inf = value_of(ub) == INFTY;
49 if (unlikely(is_ub_inf && is_lb_inf)) {
50 return identity_free(y, lb, ub);
51 } else if (unlikely(is_ub_inf)) {
52 return lb_free(identity_free(y, ub), lb);
53 } else if (unlikely(is_lb_inf)) {
54 return ub_free(identity_free(y, lb), ub);
55 } else {
56 auto&& y_ref = to_ref(std::forward<T>(y));
57 check_bounded("lub_free", "Bounded variable", value_of(y_ref), value_of(lb),
58 value_of(ub));
59 return eval(logit(divide(subtract(std::forward<decltype(y_ref)>(y_ref), lb),
60 subtract(ub, lb))));
61 }
62}
63
68template <typename T, typename L, typename U,
70 require_stan_scalar_t<U>* = nullptr>
71inline auto lub_free(T&& y, L&& lb, U&& ub) {
72 check_matching_dims("lub_free", "y", y, "lb", lb);
73 auto&& y_ref = to_ref(std::forward<T>(y));
74 auto&& lb_ref = to_ref(std::forward<L>(lb));
75 promote_scalar_t<return_type_t<T, L, U>, T> ret(y.rows(), y.cols());
76 for (Eigen::Index j = 0; j < y.cols(); ++j) {
77 for (Eigen::Index i = 0; i < y.rows(); ++i) {
78 ret.coeffRef(i, j) = lub_free(y_ref.coeff(i, j), lb_ref.coeff(i, j), ub);
79 }
80 }
81 return ret;
82}
83
88template <typename T, typename L, typename U,
89 require_all_eigen_t<T, U>* = nullptr,
90 require_stan_scalar_t<L>* = nullptr>
91inline auto lub_free(T&& y, L&& lb, U&& ub) {
92 check_matching_dims("lub_free", "y", y, "ub", ub);
93 auto&& y_ref = to_ref(std::forward<T>(y));
94 auto&& ub_ref = to_ref(std::forward<U>(ub));
95 promote_scalar_t<return_type_t<T, L, U>, T> ret(y.rows(), y.cols());
96 for (Eigen::Index j = 0; j < y.cols(); ++j) {
97 for (Eigen::Index i = 0; i < y.rows(); ++i) {
98 ret.coeffRef(i, j) = lub_free(y_ref.coeff(i, j), lb, ub_ref.coeff(i, j));
99 }
100 }
101 return ret;
102}
103
108template <typename T, typename L, typename U,
109 require_all_eigen_t<T, L, U>* = nullptr>
110inline auto lub_free(T&& y, L&& lb, U&& ub) {
111 check_matching_dims("lub_free", "y", y, "lb", lb);
112 check_matching_dims("lub_free", "y", y, "ub", ub);
113 auto&& y_ref = to_ref(std::forward<T>(y));
114 auto&& lb_ref = to_ref(std::forward<L>(lb));
115 auto&& ub_ref = to_ref(std::forward<U>(ub));
116 promote_scalar_t<return_type_t<T, L, U>, T> ret(y.rows(), y.cols());
117 for (Eigen::Index j = 0; j < y.cols(); ++j) {
118 for (Eigen::Index i = 0; i < y.rows(); ++i) {
119 ret.coeffRef(i, j)
120 = lub_free(y_ref.coeff(i, j), lb_ref.coeff(i, j), ub_ref.coeff(i, j));
121 }
122 }
123 return ret;
124}
125
129template <typename T, typename L, typename U,
131inline auto lub_free(const std::vector<T> y, const L& lb, const U& ub) {
132 std::vector<decltype(lub_free(y[0], lb, ub))> ret(y.size());
133 for (Eigen::Index i = 0; i < y.size(); ++i) {
134 ret[i] = lub_free(y[i], lb, ub);
135 }
136 return ret;
137}
138
142template <typename T, typename L, typename U,
144inline auto lub_free(const std::vector<T> y, const L& lb,
145 const std::vector<U>& ub) {
146 check_matching_dims("lub_free", "y", y, "ub", ub);
147 std::vector<decltype(lub_free(y[0], lb, ub[0]))> ret(y.size());
148 for (Eigen::Index i = 0; i < y.size(); ++i) {
149 ret[i] = lub_free(y[i], lb, ub[i]);
150 }
151 return ret;
152}
153
157template <typename T, typename L, typename U,
159inline auto lub_free(const std::vector<T> y, const std::vector<L>& lb,
160 const U& ub) {
161 check_matching_dims("lub_free", "y", y, "lb", lb);
162 std::vector<decltype(lub_free(y[0], lb[0], ub))> ret(y.size());
163 for (Eigen::Index i = 0; i < y.size(); ++i) {
164 ret[i] = lub_free(y[i], lb[i], ub);
165 }
166 return ret;
167}
168
172template <typename T, typename L, typename U>
173inline auto lub_free(const std::vector<T> y, const std::vector<L>& lb,
174 const std::vector<U>& ub) {
175 check_matching_dims("lub_free", "y", y, "lb", lb);
176 check_matching_dims("lub_free", "y", y, "ub", ub);
177 std::vector<decltype(lub_free(y[0], lb[0], ub[0]))> ret(y.size());
178 for (Eigen::Index i = 0; i < y.size(); ++i) {
179 ret[i] = lub_free(y[i], lb[i], ub[i]);
180 }
181 return ret;
182}
183
187template <typename T, typename L, typename U>
188inline auto lub_free(T&& y, const std::tuple<L, U>& bounds) {
189 return lub_free(std::forward<T>(y), std::get<0>(bounds), std::get<1>(bounds));
190}
192
193} // namespace math
194} // namespace stan
195#endif
#define unlikely(x)
require_all_t< is_eigen< std::decay_t< Types > >... > require_all_eigen_t
Require all of the types satisfy is_eigen.
Definition is_eigen.hpp:120
subtraction_< as_operation_cl_t< T_a >, as_operation_cl_t< T_b > > subtract(T_a &&a, T_b &&b)
auto divide(T_a &&a, double d)
Returns the elementwise division of the kernel generator expression.
Definition divide.hpp:20
require_t< is_stan_scalar< std::decay_t< T > > > require_stan_scalar_t
Require type satisfies is_stan_scalar.
require_not_t< is_std_vector< std::decay_t< T > > > require_not_std_vector_t
Require type does not satisfy is_std_vector.
require_all_not_t< is_std_vector< std::decay_t< Types > >... > require_all_not_std_vector_t
Require none of the types satisfy is_std_vector.
fvar< T > logit(const fvar< T > &x)
Definition logit.hpp:14
void check_bounded(const char *function, const char *name, const T_y &y, const T_low &low, const T_high &high)
Check if the value is between the low and high values, inclusively.
typename promote_scalar_type< std::decay_t< T >, std::decay_t< S > >::type promote_scalar_t
T eval(T &&arg)
Inputs which have a plain_type equal to the own time are forwarded unmodified (for Eigen expressions ...
Definition eval.hpp:20
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition value_of.hpp:18
auto identity_free(T &&x, Types &&...)
Returns the result of applying the inverse of the identity constraint transform to the input.
static constexpr double NEGATIVE_INFTY
Negative infinity.
Definition constants.hpp:51
void check_matching_dims(const char *function, const char *name1, const T1 &y1, const char *name2, const T2 &y2)
Check if the two containers have the same dimensions.
auto ub_free(T &&y, U &&ub)
Return the free scalar that corresponds to the specified upper-bounded value with respect to the spec...
Definition ub_free.hpp:35
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
Definition to_ref.hpp:17
auto lub_free(T &&y, L &&lb, U &&ub)
lub_free Return the unconstrained variable that transforms to the y given the specified bounds.
Definition lub_free.hpp:46
auto lb_free(T &&y, L &&lb)
Return the unconstrained value that produces the specified lower-bound constrained value.
Definition lb_free.hpp:30
static constexpr double INFTY
Positive infinity.
Definition constants.hpp:46
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...