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