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);
268 template <
typename T>
269 inline typename boost::math::tools::promote_args<T>::type
290 template <
typename T>
291 inline typename boost::math::tools::promote_args<T>::type
294 return -
log(y ? y_hat : (1.0 - y_hat));
299 template <
typename Vector,
typename Scalar>
300 Scalar maximum(
const Vector& x) {
302 BOOST_THROW_EXCEPTION(std::invalid_argument (
"x must have at least one element"));
361 template <
typename Vector,
typename Scalar>
362 void softmax(
const Vector& x, Vector& simplex) {
364 if (x.size() != simplex.size())
365 BOOST_THROW_EXCEPTION(std::invalid_argument (
"x.size() != simplex.size()"));
367 Scalar max_x = maximum<Vector,Scalar>(x);
369 simplex[i] =
exp(x[i]-max_x);
398 template <
typename Vector>
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]);
416 template <
typename T>
417 inline typename boost::math::tools::promote_args<T>::type
421 BOOST_THROW_EXCEPTION(std::domain_error (
"x can not be less than -1"));
423 if (x > 1
e-9 || x < -1
e-9)
425 else if (x > 1
e-16 || x < -1
e-16)
426 return x - 0.5 * x * x;
440 template <
typename T>
441 inline typename boost::math::tools::promote_args<T>::type
447 const double LOG_PI_OVER_FOUR =
std::log(boost::math::constants::pi<double>()) / 4.0;
466 template <
typename T>
467 inline typename boost::math::tools::promote_args<T>::type
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);
491 inline double if_else(
bool c,
double y_true,
double y_false) {
492 return c ? y_true : y_false;
509 template <
typename T>
514 template <
typename T_a,
typename T_b>
515 inline typename boost::math::tools::promote_args<T_a,T_b>::type
518 if (b == 0.0 && a == 0.0)
553 template <
typename T>
554 inline typename boost::math::tools::promote_args<T>::type
571 template <
typename T>
572 inline typename boost::math::tools::promote_args<T>::type
610 inline double ibeta(
const double& a,
630 using std::numeric_limits;
633 double max = -numeric_limits<double>::infinity();
634 for (
size_t ii = 0; ii < x.size(); ii++)
639 for (
size_t ii = 0; ii < x.size(); ii++)
640 if (x[ii] != -numeric_limits<double>::infinity())
641 sum +=
exp(x[ii] - max);
643 return max +
log(sum);
654 template <
typename T>
672 template <
typename T1,
typename T2>
676 return (x1 != 0) || (x2 != 0);
691 template <
typename T1,
typename T2>
695 return (x1 != 0) && (x2 != 0);
710 template <
typename T1,
typename T2>
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>
821 template <
typename T1,
typename T2,
typename T3>
823 const T1& ,
const T1& ,
824 const T2& ,
const T2& ,
825 const T3& ,
const T3& ) {
841 template <
typename T>
843 return static_cast<double>(x);
870 return boost::math::constants::pi<double>();