Stan Math Library  2.14.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 
7 #include <boost/math/tools/promotion.hpp>
8 #include <cmath>
9 #include <limits>
10 
11 namespace stan {
12  namespace math {
13 
41  template <typename T, typename TL, typename TU>
42  inline
43  typename boost::math::tools::promote_args<T, TL, TU>::type
44  lub_constrain(const T x, TL lb, TU ub) {
45  using std::exp;
46  check_less("lub_constrain", "lb", lb, ub);
47  if (lb == -std::numeric_limits<double>::infinity())
48  return ub_constrain(x, ub);
49  if (ub == std::numeric_limits<double>::infinity())
50  return lb_constrain(x, lb);
51 
52  T inv_logit_x;
53  if (x > 0) {
54  T exp_minus_x = exp(-x);
55  inv_logit_x = 1.0 / (1.0 + exp_minus_x);
56  // Prevent x from reaching one unless it really really should.
57  if ((x < std::numeric_limits<double>::infinity())
58  && (inv_logit_x == 1))
59  inv_logit_x = 1 - 1e-15;
60  } else {
61  T exp_x = exp(x);
62  inv_logit_x = 1.0 - 1.0 / (1.0 + exp_x);
63  // Prevent x from reaching zero unless it really really should.
64  if ((x > -std::numeric_limits<double>::infinity())
65  && (inv_logit_x== 0))
66  inv_logit_x = 1e-15;
67  }
68  return lb + (ub - lb) * inv_logit_x;
69  }
70 
112  template <typename T, typename TL, typename TU>
113  typename boost::math::tools::promote_args<T, TL, TU>::type
114  lub_constrain(const T x, const TL lb, const TU ub, T& lp) {
115  using std::log;
116  using std::exp;
117  check_less("lub_constrain", "lb", lb, ub);
118  if (lb == -std::numeric_limits<double>::infinity())
119  return ub_constrain(x, ub, lp);
120  if (ub == std::numeric_limits<double>::infinity())
121  return lb_constrain(x, lb, lp);
122  T inv_logit_x;
123  if (x > 0) {
124  T exp_minus_x = exp(-x);
125  inv_logit_x = 1.0 / (1.0 + exp_minus_x);
126  lp += log(ub - lb) - x - 2 * log1p(exp_minus_x);
127  // Prevent x from reaching one unless it really really should.
128  if ((x < std::numeric_limits<double>::infinity())
129  && (inv_logit_x == 1))
130  inv_logit_x = 1 - 1e-15;
131  } else {
132  T exp_x = exp(x);
133  inv_logit_x = 1.0 - 1.0 / (1.0 + exp_x);
134  lp += log(ub - lb) + x - 2 * log1p(exp_x);
135  // Prevent x from reaching zero unless it really really should.
136  if ((x > -std::numeric_limits<double>::infinity())
137  && (inv_logit_x== 0))
138  inv_logit_x = 1e-15;
139  }
140  return lb + (ub - lb) * inv_logit_x;
141  }
142 
143  }
144 }
145 #endif
fvar< T > log(const fvar< T > &x)
Definition: log.hpp:14
T lb_constrain(const T x, const TL lb)
Return the lower-bounded value for the specified unconstrained input and specified lower bound...
fvar< T > exp(const fvar< T > &x)
Definition: exp.hpp:10
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:94
fvar< T > log1p(const fvar< T > &x)
Definition: log1p.hpp:11
boost::math::tools::promote_args< T, TU >::type ub_constrain(const T x, const TU ub)
Return the upper-bounded value for the specified unconstrained scalar and upper bound.
boost::math::tools::promote_args< T, TL, TU >::type lub_constrain(const T x, TL lb, TU ub)
Return the lower- and upper-bounded scalar derived by transforming the specified free scalar given th...
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:78

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