Stan Math Library  2.20.0
reverse mode automatic differentiation
lub_constrain.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_PRIM_SCAL_FUN_LUB_CONSTRAIN_HPP
2 #define STAN_MATH_PRIM_SCAL_FUN_LUB_CONSTRAIN_HPP
3 
9 #include <boost/math/tools/promotion.hpp>
10 #include <cmath>
11 #include <limits>
12 
13 namespace stan {
14 namespace math {
15 
43 template <typename T, typename L, typename U>
44 inline typename boost::math::tools::promote_args<T, L, U>::type lub_constrain(
45  const T& x, const L& lb, const U& ub) {
46  using std::exp;
47  check_less("lub_constrain", "lb", lb, ub);
48  if (lb == NEGATIVE_INFTY)
49  return ub_constrain(x, ub);
50  if (ub == INFTY)
51  return lb_constrain(x, lb);
52 
53  T inv_logit_x;
54  if (x > 0) {
55  inv_logit_x = inv_logit(x);
56  // Prevent x from reaching one unless it really really should.
57  if ((x < INFTY) && (inv_logit_x == 1))
58  inv_logit_x = 1 - 1e-15;
59  } else {
60  inv_logit_x = inv_logit(x);
61  // Prevent x from reaching zero unless it really really should.
62  if ((x > NEGATIVE_INFTY) && (inv_logit_x == 0))
63  inv_logit_x = 1e-15;
64  }
65  return fma((ub - lb), inv_logit_x, lb);
66 }
67 
109 template <typename T, typename L, typename U>
110 inline typename boost::math::tools::promote_args<T, L, U>::type lub_constrain(
111  const T& x, const L& lb, const U& ub, T& lp) {
112  using std::exp;
113  using std::log;
114  check_less("lub_constrain", "lb", lb, ub);
115  if (lb == NEGATIVE_INFTY)
116  return ub_constrain(x, ub, lp);
117  if (ub == INFTY)
118  return lb_constrain(x, lb, lp);
119  T inv_logit_x;
120  if (x > 0) {
121  T exp_minus_x = exp(-x);
122  inv_logit_x = inv_logit(x);
123  lp += log(ub - lb) - x - 2 * log1p(exp_minus_x);
124  // Prevent x from reaching one unless it really really should.
125  if ((x < INFTY) && (inv_logit_x == 1))
126  inv_logit_x = 1 - 1e-15;
127  } else {
128  T exp_x = exp(x);
129  inv_logit_x = inv_logit(x);
130  lp += log(ub - lb) + x - 2 * log1p(exp_x);
131  // Prevent x from reaching zero unless it really really should.
132  if ((x > NEGATIVE_INFTY) && (inv_logit_x == 0))
133  inv_logit_x = 1e-15;
134  }
135  return fma((ub - lb), inv_logit_x, lb);
136 }
137 
138 } // namespace math
139 } // namespace stan
140 #endif
fvar< T > log(const fvar< T > &x)
Definition: log.hpp:12
fvar< T > inv_logit(const fvar< T > &x)
Returns the inverse logit function applied to the argument.
Definition: inv_logit.hpp:20
boost::math::tools::promote_args< T, U >::type ub_constrain(const T &x, const U &ub)
Return the upper-bounded value for the specified unconstrained scalar and upper bound.
boost::math::tools::promote_args< T, L >::type lb_constrain(const T &x, const L &lb)
Return the lower-bounded value for the specified unconstrained input and specified lower bound...
boost::math::tools::promote_args< T, L, U >::type lub_constrain(const T &x, const L &lb, const U &ub)
Return the lower- and upper-bounded scalar derived by transforming the specified free scalar given th...
fvar< T > exp(const fvar< T > &x)
Definition: exp.hpp:11
fvar< typename stan::return_type< T1, T2, T3 >::type > fma(const fvar< T1 > &x1, const fvar< T2 > &x2, const fvar< T3 > &x3)
The fused multiply-add operation (C99).
Definition: fma.hpp:59
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:87
fvar< T > log1p(const fvar< T > &x)
Definition: log1p.hpp:12
const double INFTY
Positive infinity.
Definition: constants.hpp:48
const double NEGATIVE_INFTY
Negative infinity.
Definition: constants.hpp:53
void check_less(const char *function, const char *name, const T_y &y, const T_high &high)
Check if y is strictly less than high.
Definition: check_less.hpp:63

     [ Stan Home Page ] © 2011–2018, Stan Development Team.