Stan  1.1
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
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 
266  template <typename T>
267  inline typename boost::math::tools::promote_args<T>::type
268  Phi_approx(T x) {
269  return inv_logit(0.07056 * std::pow(x,3.0) + 1.5976 * x);
270  }
271 
285  template <typename T>
286  inline typename boost::math::tools::promote_args<T>::type
287  inv_cloglog(T x) {
288  using std::exp;
289  return exp(-exp(x));
290  }
291 
307  template <typename T>
308  inline typename boost::math::tools::promote_args<T>::type
309  binary_log_loss(int y, T y_hat) {
310  using std::log;
311  return -log(y ? y_hat : (1.0 - y_hat));
312  }
313 
314  // hide helper for now; could use Eigen here
315  namespace {
316  template <typename Vector, typename Scalar>
317  Scalar maximum(const Vector& x) {
318  if(x.size() == 0)
319  BOOST_THROW_EXCEPTION(std::invalid_argument ("x must have at least one element"));
320  Scalar max_x(x[0]);
321  for (typename Vector::size_type i = 1; i < x.size(); ++i)
322  if (x[i] < max_x)
323  max_x = x[i];
324  return max_x;
325  }
326  }
327 
328 
378  template <typename Vector, typename Scalar>
379  void softmax(const Vector& x, Vector& simplex) {
380  using std::exp;
381  if (x.size() != simplex.size())
382  BOOST_THROW_EXCEPTION(std::invalid_argument ("x.size() != simplex.size()"));
383  Scalar sum(0.0);
384  Scalar max_x = maximum<Vector,Scalar>(x);
385  for (typename Vector::size_type i = 0; i < x.size(); ++i) {
386  simplex[i] = exp(x[i]-max_x);
387  sum += simplex[i];
388  }
389  for (typename Vector::size_type i = 0; i < x.size(); ++i)
390  simplex[i] /= sum;
391  }
392 
415  template <typename Vector>
416  void inverse_softmax(const Vector& simplex, Vector& y) {
417  using std::log;
418  if(simplex.size() != y.size())
419  BOOST_THROW_EXCEPTION(std::invalid_argument ("simplex.size() != y.size()"));
420  for (size_t i = 0; i < simplex.size(); ++i)
421  y[i] = log(simplex[i]);
422  }
423 
433  template <typename T>
434  inline typename boost::math::tools::promote_args<T>::type
435  log1p(T x) {
436  using std::log;
437  if (x < -1.0)
438  BOOST_THROW_EXCEPTION(std::domain_error ("x can not be less than -1"));
439 
440  if (x > 1e-9 || x < -1e-9)
441  return log(1.0 + x); // direct, if distant from 1
442  else if (x > 1e-16 || x < -1e-16)
443  return x - 0.5 * x * x; // 2nd order Taylor, if close to 1
444  else
445  return x; // 1st order Taylor, if very close to 1
446  }
447 
457  template <typename T>
458  inline typename boost::math::tools::promote_args<T>::type
459  log1m(T x) {
460  return log1p(-x);
461  }
462 
463  namespace {
464  const double LOG_PI_OVER_FOUR = std::log(boost::math::constants::pi<double>()) / 4.0;
465  }
466 
483  template <typename T>
484  inline typename boost::math::tools::promote_args<T>::type
485  lmgamma(unsigned int k, T x) {
486  typename boost::math::tools::promote_args<T>::type result
487  = k * (k - 1) * LOG_PI_OVER_FOUR;
488  for (unsigned int j = 1; j <= k; ++j)
489  result += lgamma(x + (1.0 - j) / 2.0);
490  return result;
491  }
492 
493 
508  inline double if_else(bool c, double y_true, double y_false) {
509  return c ? y_true : y_false;
510  }
511 
526  template <typename T>
527  inline T square(T x) {
528  return x * x;
529  }
530 
531  template <typename T_a, typename T_b>
532  inline typename boost::math::tools::promote_args<T_a,T_b>::type
533  multiply_log(T_a a, T_b b) {
534  using std::log;
535  if (b == 0.0 && a == 0.0)
536  return 0.0;
537  return a * log(b);
538  }
539 
554  inline double log1p_exp(const double& a) {
555  using std::exp;
556  // like log_sum_exp below with b=0.0; prevents underflow
557  if (a > 0.0)
558  return a + log1p(exp(-a));
559  return log1p(exp(a));
560  }
561 
570  template <typename T>
571  inline typename boost::math::tools::promote_args<T>::type
572  log_inv_logit(const T& u) {
573  using std::exp;
574  if (u < 0.0)
575  return u - log1p(exp(u)); // prevent underflow
576  return -log1p(exp(-u));
577  }
578 
579 
588  template <typename T>
589  inline typename boost::math::tools::promote_args<T>::type
590  log1m_inv_logit(const T& u) {
591  using std::exp;
592  if (u > 0.0)
593  return -u - log1p(exp(-u)); // prevent underflow
594  return -log1p(exp(u));
595  }
596 
597 
608  inline double log_sum_exp(const double& a, const double& b) {
609  using std::exp;
610  if (a > b)
611  return a + log1p(exp(b - a));
612  return b + log1p(exp(a - b));
613  }
614 
627  inline double ibeta(const double& a,
628  const double& b,
629  const double& x) {
630  return boost::math::ibeta(a, b, x);
631  }
632 
633 
634 
646  double log_sum_exp(const std::vector<double>& x) {
647  using std::numeric_limits;
648  using std::log;
649  using std::exp;
650  double max = -numeric_limits<double>::infinity();
651  for (size_t ii = 0; ii < x.size(); ii++)
652  if (x[ii] > max)
653  max = x[ii];
654 
655  double sum = 0.0;
656  for (size_t ii = 0; ii < x.size(); ii++)
657  if (x[ii] != -numeric_limits<double>::infinity())
658  sum += exp(x[ii] - max);
659 
660  return max + log(sum);
661  }
662 
671  template <typename T>
672  inline
673  int
675  return (x == 0);
676  }
677 
689  template <typename T1, typename T2>
690  inline
691  int
692  logical_or(T1 x1, T2 x2) {
693  return (x1 != 0) || (x2 != 0);
694  }
695 
708  template <typename T1, typename T2>
709  inline
710  int
711  logical_and(T1 x1, T2 x2) {
712  return (x1 != 0) && (x2 != 0);
713  }
714 
715 
716 
727  template <typename T1, typename T2>
728  inline
729  int
730  logical_eq(T1 x1, T2 x2) {
731  return x1 == x2;
732  }
733 
744  template <typename T1, typename T2>
745  inline
746  int
747  logical_neq(T1 x1, T2 x2) {
748  return x1 != x2;
749  }
750 
761  template <typename T1, typename T2>
762  inline
763  int
764  logical_lt(T1 x1, T2 x2) {
765  return x1 < x2;
766  }
767 
778  template <typename T1, typename T2>
779  inline
780  int
781  logical_lte(T1 x1, T2 x2) {
782  return x1 <= x2;
783  }
784 
795  template <typename T1, typename T2>
796  inline
797  int
798  logical_gt(T1 x1, T2 x2) {
799  return x1 > x2;
800  }
801 
812  template <typename T1, typename T2>
813  inline
814  int
815  logical_gte(T1 x1, T2 x2) {
816  return x1 >= x2;
817  }
818 
819 
820 
838  template <typename T1, typename T2, typename T3>
839  inline double simple_var(double v,
840  const T1& /*y1*/, const T1& /*dy1*/,
841  const T2& /*y2*/, const T2& /*dy2*/,
842  const T3& /*y3*/, const T3& /*dy3*/) {
843  return v;
844  }
845 
858  template <typename T>
859  inline double value_of(T x) {
860  return static_cast<double>(x);
861  }
862 
874  template <>
875  inline double value_of<double>(double x) {
876  return x;
877  }
878 
879  // CONSTANTS
880 
886  inline double pi() {
887  return boost::math::constants::pi<double>();
888  }
889 
895  inline double e() {
896  return E;
897  }
898 
904  inline double sqrt2() {
905  return SQRT_2;
906  }
907 
913  inline double log2() {
914  return LOG_2;
915  }
916 
922  inline double log10() {
923  return LOG_10;
924  }
925 
931  inline double positive_infinity() {
932  return INFTY;
933  }
934 
940  inline double negative_infinity() {
941  return NEGATIVE_INFTY;
942  }
943 
949  inline double not_a_number() {
950  return NOT_A_NUMBER;
951  }
952 
958  inline double epsilon() {
959  return EPSILON;
960  }
961 
968  inline double negative_epsilon() {
969  return NEGATIVE_EPSILON;
970  }
971 
979  inline int as_bool(int x) {
980  return x;
981  }
988  inline int as_bool(double x) {
989  return x != 0.0;
990  }
991 
992  }
993 
994 }
995 
996 #endif

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