File indexing completed on 2025-01-18 09:39:43
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_STATS_NORMAL_HPP
0009 #define BOOST_STATS_NORMAL_HPP
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <boost/math/distributions/fwd.hpp>
0019 #include <boost/math/special_functions/erf.hpp> // for erf/erfc.
0020 #include <boost/math/distributions/complement.hpp>
0021 #include <boost/math/distributions/detail/common_error_handling.hpp>
0022
0023 #include <utility>
0024 #include <type_traits>
0025
0026 namespace boost{ namespace math{
0027
0028 template <class RealType = double, class Policy = policies::policy<> >
0029 class normal_distribution
0030 {
0031 public:
0032 using value_type = RealType;
0033 using policy_type = Policy;
0034
0035 explicit normal_distribution(RealType l_mean = 0, RealType sd = 1)
0036 : m_mean(l_mean), m_sd(sd)
0037 {
0038 static const char* function = "boost::math::normal_distribution<%1%>::normal_distribution";
0039
0040 RealType result;
0041 detail::check_scale(function, sd, &result, Policy());
0042 detail::check_location(function, l_mean, &result, Policy());
0043 }
0044
0045 RealType mean()const
0046 {
0047 return m_mean;
0048 }
0049
0050 RealType standard_deviation()const
0051 {
0052 return m_sd;
0053 }
0054
0055
0056 RealType location()const
0057 {
0058 return m_mean;
0059 }
0060 RealType scale()const
0061 {
0062 return m_sd;
0063 }
0064
0065 private:
0066
0067
0068
0069 RealType m_mean;
0070 RealType m_sd;
0071 };
0072
0073 using normal = normal_distribution<double>;
0074
0075
0076
0077
0078
0079
0080 #ifdef __cpp_deduction_guides
0081
0082 template <class RealType>
0083 normal_distribution(RealType, RealType)->normal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0084 template <class RealType>
0085 normal_distribution(RealType)->normal_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0086
0087 #endif
0088
0089 #ifdef _MSC_VER
0090 #pragma warning(push)
0091 #pragma warning(disable:4127)
0092 #endif
0093
0094 template <class RealType, class Policy>
0095 inline std::pair<RealType, RealType> range(const normal_distribution<RealType, Policy>& )
0096 {
0097 if (std::numeric_limits<RealType>::has_infinity)
0098 {
0099 return std::pair<RealType, RealType>(-std::numeric_limits<RealType>::infinity(), std::numeric_limits<RealType>::infinity());
0100 }
0101 else
0102 {
0103 using boost::math::tools::max_value;
0104 return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
0105 }
0106 }
0107
0108 template <class RealType, class Policy>
0109 inline std::pair<RealType, RealType> support(const normal_distribution<RealType, Policy>& )
0110 {
0111 if (std::numeric_limits<RealType>::has_infinity)
0112 {
0113 return std::pair<RealType, RealType>(-std::numeric_limits<RealType>::infinity(), std::numeric_limits<RealType>::infinity());
0114 }
0115 else
0116 {
0117 using boost::math::tools::max_value;
0118 return std::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>());
0119 }
0120 }
0121
0122 #ifdef _MSC_VER
0123 #pragma warning(pop)
0124 #endif
0125
0126 template <class RealType, class Policy>
0127 inline RealType pdf(const normal_distribution<RealType, Policy>& dist, const RealType& x)
0128 {
0129 BOOST_MATH_STD_USING
0130
0131 RealType sd = dist.standard_deviation();
0132 RealType mean = dist.mean();
0133
0134 static const char* function = "boost::math::pdf(const normal_distribution<%1%>&, %1%)";
0135
0136 RealType result = 0;
0137 if(false == detail::check_scale(function, sd, &result, Policy()))
0138 {
0139 return result;
0140 }
0141 if(false == detail::check_location(function, mean, &result, Policy()))
0142 {
0143 return result;
0144 }
0145 if((boost::math::isinf)(x))
0146 {
0147 return 0;
0148 }
0149 if(false == detail::check_x(function, x, &result, Policy()))
0150 {
0151 return result;
0152 }
0153
0154 RealType exponent = x - mean;
0155 exponent *= -exponent;
0156 exponent /= 2 * sd * sd;
0157
0158 result = exp(exponent);
0159 result /= sd * sqrt(2 * constants::pi<RealType>());
0160
0161 return result;
0162 }
0163
0164 template <class RealType, class Policy>
0165 inline RealType logpdf(const normal_distribution<RealType, Policy>& dist, const RealType& x)
0166 {
0167 BOOST_MATH_STD_USING
0168
0169 const RealType sd = dist.standard_deviation();
0170 const RealType mean = dist.mean();
0171
0172 static const char* function = "boost::math::logpdf(const normal_distribution<%1%>&, %1%)";
0173
0174 RealType result = -std::numeric_limits<RealType>::infinity();
0175 if(false == detail::check_scale(function, sd, &result, Policy()))
0176 {
0177 return result;
0178 }
0179 if(false == detail::check_location(function, mean, &result, Policy()))
0180 {
0181 return result;
0182 }
0183 if((boost::math::isinf)(x))
0184 {
0185 return result;
0186 }
0187 if(false == detail::check_x(function, x, &result, Policy()))
0188 {
0189 return result;
0190 }
0191
0192 const RealType pi = boost::math::constants::pi<RealType>();
0193 const RealType half = boost::math::constants::half<RealType>();
0194
0195 result = -log(sd) - half*log(2*pi) - (x-mean)*(x-mean)/(2*sd*sd);
0196
0197 return result;
0198 }
0199
0200 template <class RealType, class Policy>
0201 inline RealType cdf(const normal_distribution<RealType, Policy>& dist, const RealType& x)
0202 {
0203 BOOST_MATH_STD_USING
0204
0205 RealType sd = dist.standard_deviation();
0206 RealType mean = dist.mean();
0207 static const char* function = "boost::math::cdf(const normal_distribution<%1%>&, %1%)";
0208 RealType result = 0;
0209 if(false == detail::check_scale(function, sd, &result, Policy()))
0210 {
0211 return result;
0212 }
0213 if(false == detail::check_location(function, mean, &result, Policy()))
0214 {
0215 return result;
0216 }
0217 if((boost::math::isinf)(x))
0218 {
0219 if(x < 0) return 0;
0220 return 1;
0221 }
0222 if(false == detail::check_x(function, x, &result, Policy()))
0223 {
0224 return result;
0225 }
0226 RealType diff = (x - mean) / (sd * constants::root_two<RealType>());
0227 result = boost::math::erfc(-diff, Policy()) / 2;
0228 return result;
0229 }
0230
0231 template <class RealType, class Policy>
0232 inline RealType quantile(const normal_distribution<RealType, Policy>& dist, const RealType& p)
0233 {
0234 BOOST_MATH_STD_USING
0235
0236 RealType sd = dist.standard_deviation();
0237 RealType mean = dist.mean();
0238 static const char* function = "boost::math::quantile(const normal_distribution<%1%>&, %1%)";
0239
0240 RealType result = 0;
0241 if(false == detail::check_scale(function, sd, &result, Policy()))
0242 return result;
0243 if(false == detail::check_location(function, mean, &result, Policy()))
0244 return result;
0245 if(false == detail::check_probability(function, p, &result, Policy()))
0246 return result;
0247
0248 result= boost::math::erfc_inv(2 * p, Policy());
0249 result = -result;
0250 result *= sd * constants::root_two<RealType>();
0251 result += mean;
0252 return result;
0253 }
0254
0255 template <class RealType, class Policy>
0256 inline RealType cdf(const complemented2_type<normal_distribution<RealType, Policy>, RealType>& c)
0257 {
0258 BOOST_MATH_STD_USING
0259
0260 RealType sd = c.dist.standard_deviation();
0261 RealType mean = c.dist.mean();
0262 RealType x = c.param;
0263 static const char* function = "boost::math::cdf(const complement(normal_distribution<%1%>&), %1%)";
0264
0265 RealType result = 0;
0266 if(false == detail::check_scale(function, sd, &result, Policy()))
0267 return result;
0268 if(false == detail::check_location(function, mean, &result, Policy()))
0269 return result;
0270 if((boost::math::isinf)(x))
0271 {
0272 if(x < 0) return 1;
0273 return 0;
0274 }
0275 if(false == detail::check_x(function, x, &result, Policy()))
0276 return result;
0277
0278 RealType diff = (x - mean) / (sd * constants::root_two<RealType>());
0279 result = boost::math::erfc(diff, Policy()) / 2;
0280 return result;
0281 }
0282
0283 template <class RealType, class Policy>
0284 inline RealType quantile(const complemented2_type<normal_distribution<RealType, Policy>, RealType>& c)
0285 {
0286 BOOST_MATH_STD_USING
0287
0288 RealType sd = c.dist.standard_deviation();
0289 RealType mean = c.dist.mean();
0290 static const char* function = "boost::math::quantile(const complement(normal_distribution<%1%>&), %1%)";
0291 RealType result = 0;
0292 if(false == detail::check_scale(function, sd, &result, Policy()))
0293 return result;
0294 if(false == detail::check_location(function, mean, &result, Policy()))
0295 return result;
0296 RealType q = c.param;
0297 if(false == detail::check_probability(function, q, &result, Policy()))
0298 return result;
0299 result = boost::math::erfc_inv(2 * q, Policy());
0300 result *= sd * constants::root_two<RealType>();
0301 result += mean;
0302 return result;
0303 }
0304
0305 template <class RealType, class Policy>
0306 inline RealType mean(const normal_distribution<RealType, Policy>& dist)
0307 {
0308 return dist.mean();
0309 }
0310
0311 template <class RealType, class Policy>
0312 inline RealType standard_deviation(const normal_distribution<RealType, Policy>& dist)
0313 {
0314 return dist.standard_deviation();
0315 }
0316
0317 template <class RealType, class Policy>
0318 inline RealType mode(const normal_distribution<RealType, Policy>& dist)
0319 {
0320 return dist.mean();
0321 }
0322
0323 template <class RealType, class Policy>
0324 inline RealType median(const normal_distribution<RealType, Policy>& dist)
0325 {
0326 return dist.mean();
0327 }
0328
0329 template <class RealType, class Policy>
0330 inline RealType skewness(const normal_distribution<RealType, Policy>& )
0331 {
0332 return 0;
0333 }
0334
0335 template <class RealType, class Policy>
0336 inline RealType kurtosis(const normal_distribution<RealType, Policy>& )
0337 {
0338 return 3;
0339 }
0340
0341 template <class RealType, class Policy>
0342 inline RealType kurtosis_excess(const normal_distribution<RealType, Policy>& )
0343 {
0344 return 0;
0345 }
0346
0347 template <class RealType, class Policy>
0348 inline RealType entropy(const normal_distribution<RealType, Policy> & dist)
0349 {
0350 using std::log;
0351 RealType arg = constants::two_pi<RealType>()*constants::e<RealType>()*dist.standard_deviation()*dist.standard_deviation();
0352 return log(arg)/2;
0353 }
0354
0355 }
0356 }
0357
0358
0359
0360
0361 #include <boost/math/distributions/detail/derived_accessors.hpp>
0362
0363 #endif
0364
0365