Stan Math Library  2.11.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 #include <stdexcept>
11 
12 namespace stan {
13 
14  namespace math {
42  template <typename T, typename TL, typename TU>
43  inline
44  typename boost::math::tools::promote_args<T, TL, TU>::type
45  lub_constrain(const T x, TL lb, TU ub) {
46  using std::exp;
47  stan::math::check_less("lub_constrain", "lb", lb, ub);
48  if (lb == -std::numeric_limits<double>::infinity())
49  return ub_constrain(x, ub);
50  if (ub == std::numeric_limits<double>::infinity())
51  return lb_constrain(x, lb);
52 
53  T inv_logit_x;
54  if (x > 0) {
55  T exp_minus_x = exp(-x);
56  inv_logit_x = 1.0 / (1.0 + exp_minus_x);
57  // Prevent x from reaching one unless it really really should.
58  if ((x < std::numeric_limits<double>::infinity())
59  && (inv_logit_x == 1))
60  inv_logit_x = 1 - 1e-15;
61  } else {
62  T exp_x = exp(x);
63  inv_logit_x = 1.0 - 1.0 / (1.0 + exp_x);
64  // Prevent x from reaching zero unless it really really should.
65  if ((x > -std::numeric_limits<double>::infinity())
66  && (inv_logit_x== 0))
67  inv_logit_x = 1e-15;
68  }
69  return lb + (ub - lb) * inv_logit_x;
70  }
71 
113  template <typename T, typename TL, typename TU>
114  typename boost::math::tools::promote_args<T, TL, TU>::type
115  lub_constrain(const T x, const TL lb, const TU ub, T& lp) {
116  using std::log;
117  using std::exp;
118  if (!(lb < ub)) {
119  std::stringstream s;
120  s << "domain error in lub_constrain; lower bound = " << lb
121  << " must be strictly less than upper bound = " << ub;
122  throw std::domain_error(s.str());
123  }
124  if (lb == -std::numeric_limits<double>::infinity())
125  return ub_constrain(x, ub, lp);
126  if (ub == std::numeric_limits<double>::infinity())
127  return lb_constrain(x, lb, lp);
128  T inv_logit_x;
129  if (x > 0) {
130  T exp_minus_x = exp(-x);
131  inv_logit_x = 1.0 / (1.0 + exp_minus_x);
132  lp += log(ub - lb) - x - 2 * log1p(exp_minus_x);
133  // Prevent x from reaching one unless it really really should.
134  if ((x < std::numeric_limits<double>::infinity())
135  && (inv_logit_x == 1))
136  inv_logit_x = 1 - 1e-15;
137  } else {
138  T exp_x = exp(x);
139  inv_logit_x = 1.0 - 1.0 / (1.0 + exp_x);
140  lp += log(ub - lb) + x - 2 * log1p(exp_x);
141  // Prevent x from reaching zero unless it really really should.
142  if ((x > -std::numeric_limits<double>::infinity())
143  && (inv_logit_x== 0))
144  inv_logit_x = 1e-15;
145  }
146  return lb + (ub - lb) * inv_logit_x;
147  }
148 
149  }
150 
151 }
152 
153 #endif
bool check_less(const char *function, const char *name, const T_y &y, const T_high &high)
Return true if y is strictly less than high.
Definition: check_less.hpp:81
fvar< T > log(const fvar< T > &x)
Definition: log.hpp:15
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
void domain_error(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
Throw a domain error with a consistently formatted message.
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:95
fvar< T > log1p(const fvar< T > &x)
Definition: log1p.hpp:16
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...

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