1 #ifndef __STAN__MATH__SPECIAL_FUNCTIONS_HPP__
2 #define __STAN__MATH__SPECIAL_FUNCTIONS_HPP__
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>
33 inline typename boost::math::tools::promote_args<T>::type
50 template <
typename T1,
typename T2>
51 inline typename boost::math::tools::promote_args<T1, T2>::type
53 return (a > b) ? (a - b) : 0.0;
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) {
86 inline typename boost::math::tools::promote_args<T>::type
89 const static double LOG2 =
std::log(2.0);
102 template <
typename T>
119 template <
typename T>
121 return y < 0.0 ? 0 : 1;
148 template <
typename T1,
typename T2>
149 inline typename boost::math::tools::promote_args<T1,T2>::type
174 template <
typename T_N,
typename T_n>
175 inline typename boost::math::tools::promote_args<T_N, T_n>::type
179 const double cutoff = 1000;
180 if ((N < cutoff) || (N - n < cutoff)) {
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);
203 template <
typename T>
204 inline typename boost::math::tools::promote_args<T>::type
207 return 1.0 / (1.0 +
exp(-a));
224 template <
typename T>
225 inline typename boost::math::tools::promote_args<T>::type
228 return log(a / (1.0 - a));
248 template <
typename T>
249 inline typename boost::math::tools::promote_args<T>::type
251 static const double INV_SQRT_TWO = 1.0 /
std::sqrt(2.0);
266 template <
typename T>
267 inline typename boost::math::tools::promote_args<T>::type
285 template <
typename T>
286 inline typename boost::math::tools::promote_args<T>::type
307 template <
typename T>
308 inline typename boost::math::tools::promote_args<T>::type
311 return -
log(y ? y_hat : (1.0 - y_hat));
316 template <
typename Vector,
typename Scalar>
317 Scalar maximum(
const Vector& x) {
319 BOOST_THROW_EXCEPTION(std::invalid_argument (
"x must have at least one element"));
378 template <
typename Vector,
typename Scalar>
379 void softmax(
const Vector& x, Vector& simplex) {
381 if (x.size() != simplex.size())
382 BOOST_THROW_EXCEPTION(std::invalid_argument (
"x.size() != simplex.size()"));
384 Scalar max_x = maximum<Vector,Scalar>(x);
386 simplex[i] =
exp(x[i]-max_x);
415 template <
typename Vector>
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]);
433 template <
typename T>
434 inline typename boost::math::tools::promote_args<T>::type
438 BOOST_THROW_EXCEPTION(std::domain_error (
"x can not be less than -1"));
440 if (x > 1
e-9 || x < -1
e-9)
442 else if (x > 1
e-16 || x < -1
e-16)
443 return x - 0.5 * x * x;
457 template <
typename T>
458 inline typename boost::math::tools::promote_args<T>::type
464 const double LOG_PI_OVER_FOUR =
std::log(boost::math::constants::pi<double>()) / 4.0;
483 template <
typename T>
484 inline typename boost::math::tools::promote_args<T>::type
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);
508 inline double if_else(
bool c,
double y_true,
double y_false) {
509 return c ? y_true : y_false;
526 template <
typename T>
531 template <
typename T_a,
typename T_b>
532 inline typename boost::math::tools::promote_args<T_a,T_b>::type
535 if (b == 0.0 && a == 0.0)
570 template <
typename T>
571 inline typename boost::math::tools::promote_args<T>::type
588 template <
typename T>
589 inline typename boost::math::tools::promote_args<T>::type
627 inline double ibeta(
const double& a,
647 using std::numeric_limits;
650 double max = -numeric_limits<double>::infinity();
651 for (
size_t ii = 0; ii < x.size(); ii++)
656 for (
size_t ii = 0; ii < x.size(); ii++)
657 if (x[ii] != -numeric_limits<double>::infinity())
658 sum +=
exp(x[ii] - max);
660 return max +
log(sum);
671 template <
typename T>
689 template <
typename T1,
typename T2>
693 return (x1 != 0) || (x2 != 0);
708 template <
typename T1,
typename T2>
712 return (x1 != 0) && (x2 != 0);
727 template <
typename T1,
typename T2>
744 template <
typename T1,
typename T2>
761 template <
typename T1,
typename T2>
778 template <
typename T1,
typename T2>
795 template <
typename T1,
typename T2>
812 template <
typename T1,
typename T2>
838 template <
typename T1,
typename T2,
typename T3>
840 const T1& ,
const T1& ,
841 const T2& ,
const T2& ,
842 const T3& ,
const T3& ) {
858 template <
typename T>
860 return static_cast<double>(x);
887 return boost::math::constants::pi<double>();