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