inline RealType pdf(const inverse_gaussian_distribution<RealType, Policy>& dist, const RealType& x) { // Probability Density Function BOOST_MATH_STD_USING // for ADL of std functions RealType scale = dist.scale(); RealType mean = dist.mean(); RealType result = 0; static const char* function = "boost::math::pdf(const inverse_gaussian_distribution<%1%>&, %1%)"; if(false == detail::check_scale(function, scale, &result, Policy())) { return result; } if(false == detail::check_location(function, mean, &result, Policy())) { return result; } if(false == detail::check_positive_x(function, x, &result, Policy())) { return result; } if (x == 0) { return 0; // Convenient, even if not defined mathematically. } result = sqrt(scale / (constants::two_pi<RealType>() * x * x * x)) * exp(-scale * (x - mean) * (x - mean) / (2 * x * mean * mean)); return result; } // pdf
inline RealType cdf(const inverse_gaussian_distribution<RealType, Policy>& dist, const RealType& x) { // Cumulative Density Function. BOOST_MATH_STD_USING // for ADL of std functions. RealType scale = dist.scale(); RealType mean = dist.mean(); static const char* function = "boost::math::cdf(const inverse_gaussian_distribution<%1%>&, %1%)"; RealType result = 0; if(false == detail::check_scale(function, scale, &result, Policy())) { return result; } if(false == detail::check_location(function, mean, &result, Policy())) { return result; } if (false == detail::check_x_gt0(function, mean, &result, Policy())) { return result; } if(false == detail::check_positive_x(function, x, &result, Policy())) { return result; } if (x == 0) { return 0; // Convenient, even if not defined mathematically. } // Problem with this formula for large scale > 1000 or small x, //result = 0.5 * (erf(sqrt(scale / x) * ((x / mean) - 1) / constants::root_two<RealType>(), Policy()) + 1) // + exp(2 * scale / mean) / 2 // * (1 - erf(sqrt(scale / x) * (x / mean + 1) / constants::root_two<RealType>(), Policy())); // so use normal distribution version: // Wikipedia CDF equation http://en.wikipedia.org/wiki/Inverse_Gaussian_distribution. normal_distribution<RealType> n01; RealType n0 = sqrt(scale / x); n0 *= ((x / mean) -1); RealType n1 = cdf(n01, n0); RealType expfactor = exp(2 * scale / mean); RealType n3 = - sqrt(scale / x); n3 *= (x / mean) + 1; RealType n4 = cdf(n01, n3); result = n1 + expfactor * n4; return result; } // cdf