Stan  1.0
probability, sampling & optimization
special_functions.hpp
Go to the documentation of this file.
1 #ifndef __STAN__MATH__SPECIAL_FUNCTIONS_HPP__
2 #define __STAN__MATH__SPECIAL_FUNCTIONS_HPP__
3 
4 #include <stdexcept>
5 
6 #include <boost/math/special_functions/gamma.hpp>
7 #include <boost/math/special_functions/beta.hpp>
8 #include <boost/math/tools/promotion.hpp>
9 #include <boost/throw_exception.hpp>
10 
11 #include <stan/math/constants.hpp>
13 #include <stan/meta/traits.hpp>
14 
15 namespace stan {
16 
17  namespace math {
18 
19  // C99
20 
32  template <typename T>
33  inline typename boost::math::tools::promote_args<T>::type
34  exp2(T y) {
35  using std::pow;
36  return pow(2.0,y);
37  }
38 
50  template <typename T1, typename T2>
51  inline typename boost::math::tools::promote_args<T1, T2>::type
52  fdim(T1 a, T2 b) {
53  return (a > b) ? (a - b) : 0.0;
54  }
55 
68  template <typename T1, typename T2, typename T3>
69  inline typename boost::math::tools::promote_args<T1,T2,T3>::type
70  fma(T1 a, T2 b, T3 c) {
71  return (a * b) + c;
72  }
73 
85  template <typename T>
86  inline typename boost::math::tools::promote_args<T>::type
87  log2(T a) {
88  using std::log;
89  const static double LOG2 = std::log(2.0);
90  return log(a) / LOG2;
91  }
92 
93  // OTHER BASIC FUNCTIONS
94 
102  template <typename T>
103  unsigned int int_step(T y) {
104  return y > 0;
105  }
106 
119  template <typename T>
120  inline int step(T y) {
121  return y < 0.0 ? 0 : 1;
122  }
123 
124 
125  // PROBABILITY-RELATED FUNCTIONS
126 
148  template <typename T1, typename T2>
149  inline typename boost::math::tools::promote_args<T1,T2>::type
150  lbeta(T1 a, T2 b) {
151  return lgamma(a)
152  + lgamma(b)
153  - lgamma(a + b);
154  }
155 
174  template <typename T_N, typename T_n>
175  inline typename boost::math::tools::promote_args<T_N, T_n>::type
176  binomial_coefficient_log(T_N N, T_n n) {
177  using std::log;
178 
179  const double cutoff = 1000;
180  if ((N < cutoff) || (N - n < cutoff)) {
181  return lgamma(N + 1.0) - lgamma(n + 1.0) - lgamma(N - n + 1.0);
182  } else {
183  return n * log(N - n) + (N + 0.5) * log(N/(N-n))
184  + 1/(12*N) - n - 1/(12*(N-n)) - lgamma(n + 1.0);
185  }
186  }
187 
203  template <typename T>
204  inline typename boost::math::tools::promote_args<T>::type
205  inv_logit(T a) {
206  using std::exp;
207  return 1.0 / (1.0 + exp(-a));
208  }
209 
224  template <typename T>
225  inline typename boost::math::tools::promote_args<T>::type
226  logit(T a) {
227  using std::log;
228  return log(a / (1.0 - a));
229  }
230 
231 
232 
248  template <typename T>
249  inline typename boost::math::tools::promote_args<T>::type
250  Phi(T x) {
251  static const double INV_SQRT_TWO = 1.0 / std::sqrt(2.0);
252  return 0.5 * (1.0 + boost::math::erf(INV_SQRT_TWO * x));
253  }
254 
268  template <typename T>
269  inline typename boost::math::tools::promote_args<T>::type
270  inv_cloglog(T x) {
271  using std::exp;
272  return exp(-exp(x));
273  }
274 
290  template <typename T>
291  inline typename boost::math::tools::promote_args<T>::type
292  binary_log_loss(int y, T y_hat) {
293  using std::log;
294  return -log(y ? y_hat : (1.0 - y_hat));
295  }
296 
297  // hide helper for now; could use Eigen here
298  namespace {
299  template <typename Vector, typename Scalar>
300  Scalar maximum(const Vector& x) {
301  if(x.size() == 0)
302  BOOST_THROW_EXCEPTION(std::invalid_argument ("x must have at least one element"));
303  Scalar max_x(x[0]);
304  for (typename Vector::size_type i = 1; i < x.size(); ++i)
305  if (x[i] < max_x)
306  max_x = x[i];
307  return max_x;
308  }
309  }
310 
311 
361  template <typename Vector, typename Scalar>
362  void softmax(const Vector& x, Vector& simplex) {
363  using std::exp;
364  if (x.size() != simplex.size())
365  BOOST_THROW_EXCEPTION(std::invalid_argument ("x.size() != simplex.size()"));
366  Scalar sum(0.0);
367  Scalar max_x = maximum<Vector,Scalar>(x);
368  for (typename Vector::size_type i = 0; i < x.size(); ++i) {
369  simplex[i] = exp(x[i]-max_x);
370  sum += simplex[i];
371  }
372  for (typename Vector::size_type i = 0; i < x.size(); ++i)
373  simplex[i] /= sum;
374  }
375 
398  template <typename Vector>
399  void inverse_softmax(const Vector& simplex, Vector& y) {
400  using std::log;
401  if(simplex.size() != y.size())
402  BOOST_THROW_EXCEPTION(std::invalid_argument ("simplex.size() != y.size()"));
403  for (size_t i = 0; i < simplex.size(); ++i)
404  y[i] = log(simplex[i]);
405  }
406 
416  template <typename T>
417  inline typename boost::math::tools::promote_args<T>::type
418  log1p(T x) {
419  using std::log;
420  if (x < -1.0)
421  BOOST_THROW_EXCEPTION(std::domain_error ("x can not be less than -1"));
422 
423  if (x > 1e-9 || x < -1e-9)
424  return log(1.0 + x); // direct, if distant from 1
425  else if (x > 1e-16 || x < -1e-16)
426  return x - 0.5 * x * x; // 2nd order Taylor, if close to 1
427  else
428  return x; // 1st order Taylor, if very close to 1
429  }
430 
440  template <typename T>
441  inline typename boost::math::tools::promote_args<T>::type
442  log1m(T x) {
443  return log1p(-x);
444  }
445 
446  namespace {
447  const double LOG_PI_OVER_FOUR = std::log(boost::math::constants::pi<double>()) / 4.0;
448  }
449 
466  template <typename T>
467  inline typename boost::math::tools::promote_args<T>::type
468  lmgamma(unsigned int k, T x) {
469  typename boost::math::tools::promote_args<T>::type result
470  = k * (k - 1) * LOG_PI_OVER_FOUR;
471  for (unsigned int j = 1; j <= k; ++j)
472  result += lgamma(x + (1.0 - j) / 2.0);
473  return result;
474  }
475 
476 
491  inline double if_else(bool c, double y_true, double y_false) {
492  return c ? y_true : y_false;
493  }
494 
509  template <typename T>
510  inline T square(T x) {
511  return x * x;
512  }
513 
514  template <typename T_a, typename T_b>
515  inline typename boost::math::tools::promote_args<T_a,T_b>::type
516  multiply_log(T_a a, T_b b) {
517  using std::log;
518  if (b == 0.0 && a == 0.0)
519  return 0.0;
520  return a * log(b);
521  }
522 
537  inline double log1p_exp(const double& a) {
538  using std::exp;
539  // like log_sum_exp below with b=0.0; prevents underflow
540  if (a > 0.0)
541  return a + log1p(exp(-a));
542  return log1p(exp(a));
543  }
544 
553  template <typename T>
554  inline typename boost::math::tools::promote_args<T>::type
555  log_inv_logit(const T& u) {
556  using std::exp;
557  if (u < 0.0)
558  return u - log1p(exp(u)); // prevent underflow
559  return -log1p(exp(-u));
560  }
561 
562 
571  template <typename T>
572  inline typename boost::math::tools::promote_args<T>::type
573  log1m_inv_logit(const T& u) {
574  using std::exp;
575  if (u > 0.0)
576  return -u - log1p(exp(-u)); // prevent underflow
577  return -log1p(exp(u));
578  }
579 
580 
591  inline double log_sum_exp(const double& a, const double& b) {
592  using std::exp;
593  if (a > b)
594  return a + log1p(exp(b - a));
595  return b + log1p(exp(a - b));
596  }
597 
610  inline double ibeta(const double& a,
611  const double& b,
612  const double& x) {
613  return boost::math::ibeta(a, b, x);
614  }
615 
616 
617 
629  double log_sum_exp(const std::vector<double>& x) {
630  using std::numeric_limits;
631  using std::log;
632  using std::exp;
633  double max = -numeric_limits<double>::infinity();
634  for (size_t ii = 0; ii < x.size(); ii++)
635  if (x[ii] > max)
636  max = x[ii];
637 
638  double sum = 0.0;
639  for (size_t ii = 0; ii < x.size(); ii++)
640  if (x[ii] != -numeric_limits<double>::infinity())
641  sum += exp(x[ii] - max);
642 
643  return max + log(sum);
644  }
645 
654  template <typename T>
655  inline
656  int
658  return (x == 0);
659  }
660 
672  template <typename T1, typename T2>
673  inline
674  int
675  logical_or(T1 x1, T2 x2) {
676  return (x1 != 0) || (x2 != 0);
677  }
678 
691  template <typename T1, typename T2>
692  inline
693  int
694  logical_and(T1 x1, T2 x2) {
695  return (x1 != 0) && (x2 != 0);
696  }
697 
698 
699 
710  template <typename T1, typename T2>
711  inline
712  int
713  logical_eq(T1 x1, T2 x2) {
714  return x1 == x2;
715  }
716 
727  template <typename T1, typename T2>
728  inline
729  int
730  logical_neq(T1 x1, T2 x2) {
731  return x1 != x2;
732  }
733 
744  template <typename T1, typename T2>
745  inline
746  int
747  logical_lt(T1 x1, T2 x2) {
748  return x1 < x2;
749  }
750 
761  template <typename T1, typename T2>
762  inline
763  int
764  logical_lte(T1 x1, T2 x2) {
765  return x1 <= x2;
766  }
767 
778  template <typename T1, typename T2>
779  inline
780  int
781  logical_gt(T1 x1, T2 x2) {
782  return x1 > x2;
783  }
784 
795  template <typename T1, typename T2>
796  inline
797  int
798  logical_gte(T1 x1, T2 x2) {
799  return x1 >= x2;
800  }
801 
802 
803 
821  template <typename T1, typename T2, typename T3>
822  inline double simple_var(double v,
823  const T1& /*y1*/, const T1& /*dy1*/,
824  const T2& /*y2*/, const T2& /*dy2*/,
825  const T3& /*y3*/, const T3& /*dy3*/) {
826  return v;
827  }
828 
841  template <typename T>
842  inline double value_of(T x) {
843  return static_cast<double>(x);
844  }
845 
857  template <>
858  inline double value_of<double>(double x) {
859  return x;
860  }
861 
862  // CONSTANTS
863 
869  inline double pi() {
870  return boost::math::constants::pi<double>();
871  }
872 
878  inline double e() {
879  return E;
880  }
881 
887  inline double sqrt2() {
888  return SQRT_2;
889  }
890 
896  inline double log2() {
897  return LOG_2;
898  }
899 
905  inline double log10() {
906  return LOG_10;
907  }
908 
914  inline double positive_infinity() {
915  return INFTY;
916  }
917 
923  inline double negative_infinity() {
924  return NEGATIVE_INFTY;
925  }
926 
932  inline double not_a_number() {
933  return NOT_A_NUMBER;
934  }
935 
941  inline double epsilon() {
942  return EPSILON;
943  }
944 
951  inline double negative_epsilon() {
952  return NEGATIVE_EPSILON;
953  }
954 
962  inline int as_bool(int x) {
963  return x;
964  }
971  inline int as_bool(double x) {
972  return x != 0.0;
973  }
974 
975  }
976 
977 }
978 
979 #endif
internal::traits< Derived >::Index size_type
var sqrt(const var &a)
Return the square root of the specified variable (cmath).
Definition: agrad.hpp:1761
var lgamma(const stan::agrad::var &a)
The log gamma function for variables (C99).
var erf(const stan::agrad::var &a)
The error function for variables (C99).
var pow(const var &base, const var &exponent)
Return the base raised to the power of the exponent (cmath).
Definition: agrad.hpp:1778
var log(const var &a)
Return the natural log of the specified variable (cmath).
Definition: agrad.hpp:1730
var exp(const var &a)
Return the exponentiation of the specified variable (cmath).
Definition: agrad.hpp:1716
boost::math::tools::promote_args< T >::type inv_cloglog(T x)
The inverse complementary log-log function.
int logical_negation(T x)
The logical negation function which returns 1 if the input is equal to zero and 0 otherwise.
int logical_lt(T1 x1, T2 x2)
Return 1 if the first argument is strictly less than the second.
double value_of< double >(double x)
Return the specified argument.
boost::math::tools::promote_args< T >::type logit(T a)
Returns the logit function applied to the argument.
int logical_gt(T1 x1, T2 x2)
Return 1 if the first argument is strictly greater than the second.
double sqrt2()
Return the square root of two.
double epsilon()
Return minimum positive number representable.
const double NEGATIVE_EPSILON
Largest negative value (i.e., smallest absolute value).
Definition: constants.hpp:57
void inverse_softmax(const Vector &simplex, Vector &y)
Writes the inverse softmax of the simplex argument into the second argument.
T sum(const std::vector< T > &xs)
Return the sum of the values in the specified standard vector.
Definition: matrix.hpp:1131
double log10()
Return natural logarithm of ten.
double log_sum_exp(const double &a, const double &b)
Calculates the log sum of exponetials without overflow.
double positive_infinity()
Return positive infinity.
double negative_infinity()
Return negative infinity.
double not_a_number()
Return (quiet) not-a-number.
boost::math::tools::promote_args< T >::type lmgamma(unsigned int k, T x)
Return the natural logarithm of the multivariate gamma function with the speciifed dimensions and arg...
double e()
Return the base of the natural logarithm.
double ibeta(const double &a, const double &b, const double &x)
The normalized incomplete beta function of a, b, and x.
const double LOG_2
The natural logarithm of 2, .
Definition: constants.hpp:26
const double SQRT_2
The value of the square root of 2, .
Definition: constants.hpp:20
double simple_var(double v, const T1 &, const T1 &, const T2 &, const T2 &, const T3 &, const T3 &)
Return the scalar value and ignore the remaining arguments.
int logical_eq(T1 x1, T2 x2)
Return 1 if the first argument is equal to the second.
boost::math::tools::promote_args< T >::type log1m(T x)
Return the natural logarithm of one minus the specified value.
int as_bool(int x)
Return an integer with an equivalent boolean value to specified input.
int step(T y)
The step, or Heaviside, function.
boost::math::tools::promote_args< T >::type exp2(T y)
Return the exponent base 2 of the specified argument (C99).
int max(const std::vector< int > &x)
Returns the maximum coefficient in the specified column vector.
Definition: matrix.hpp:968
boost::math::tools::promote_args< T_a, T_b >::type multiply_log(T_a a, T_b b)
const double EPSILON
Smallest positive value.
Definition: constants.hpp:52
boost::math::tools::promote_args< T >::type log1p(T x)
Return the natural logarithm of one plus the specified value.
const double E
The base of the natural logarithm, .
Definition: constants.hpp:14
boost::math::tools::promote_args< T >::type log1m_inv_logit(const T &u)
Returns the natural logarithm of 1 minus the inverse logit of the specified argument.
boost::math::tools::promote_args< T >::type inv_logit(T a)
Returns the inverse logit function applied to the argument.
int logical_and(T1 x1, T2 x2)
The logical and function which returns 1 if both arguments are unequal to zero and 0 otherwise.
double negative_epsilon()
Return maximum negative number (i.e., negative number with smallest absolute value).
int logical_gte(T1 x1, T2 x2)
Return 1 if the first argument is greater than or equal to the second.
Eigen::Matrix< T, Eigen::Dynamic, 1 > softmax(const Eigen::Matrix< T, Eigen::Dynamic, 1 > &v)
Return the softmax of the specified vector.
Definition: matrix.hpp:1688
int logical_neq(T1 x1, T2 x2)
Return 1 if the first argument is unequal to the second.
boost::math::tools::promote_args< T >::type binary_log_loss(int y, T y_hat)
Returns the log loss function for binary classification with specified reference and response values.
boost::math::tools::promote_args< T1, T2, T3 >::type fma(T1 a, T2 b, T3 c)
The fused multiply-add operation (C99).
boost::math::tools::promote_args< T1, T2 >::type fdim(T1 a, T2 b)
The positive difference function (C99).
double value_of(T x)
Return the value of the specified scalar argument converted to a double value.
const double INFTY
Positive infinity.
Definition: constants.hpp:37
boost::math::tools::promote_args< T >::type Phi(T x)
The unit normal cumulative distribution function.
double if_else(bool c, double y_true, double y_false)
Return the second argument if the first argument is true and otherwise return the second argument.
T square(T x)
Return the square of the specified argument.
boost::math::tools::promote_args< T1, T2 >::type lbeta(T1 a, T2 b)
Return the log of the beta function applied to the specified arguments.
boost::math::tools::promote_args< T_N, T_n >::type binomial_coefficient_log(T_N N, T_n n)
Return the log of the binomial coefficient for the specified arguments.
double log1p_exp(const double &a)
Calculates the log of 1 plus the exponential of the specified value without overflow.
const double NOT_A_NUMBER
(Quiet) not-a-number value.
Definition: constants.hpp:47
boost::math::tools::promote_args< T >::type log2(T a)
Returns the base 2 logarithm of the argument (C99).
double pi()
Return the value of pi.
const double NEGATIVE_INFTY
Negative infinity.
Definition: constants.hpp:42
const double LOG_10
The natural logarithm of 10, .
Definition: constants.hpp:32
Eigen::Matrix< T, Rows, Cols > exp(const Eigen::Matrix< T, Rows, Cols > &m)
Return the element-wise exponentiation of the matrix or vector.
Definition: matrix.hpp:1209
int logical_lte(T1 x1, T2 x2)
Return 1 if the first argument is less than or equal to the second.
int logical_or(T1 x1, T2 x2)
The logical or function which returns 1 if either argument is unequal to zero and 0 otherwise.
boost::math::tools::promote_args< T >::type log_inv_logit(const T &u)
Returns the natural logarithm of the inverse logit of the specified argument.
unsigned int int_step(T y)
The integer step, or Heaviside, function.
Eigen::Matrix< T, Rows, Cols > log(const Eigen::Matrix< T, Rows, Cols > &m)
Return the element-wise logarithm of the matrix or vector.
Definition: matrix.hpp:1198
Probability, optimization and sampling library.
Definition: agrad.cpp:6

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