annotate DEPENDENCIES/generic/include/boost/math/distributions/non_central_f.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // boost\math\distributions\non_central_f.hpp
Chris@16 2
Chris@16 3 // Copyright John Maddock 2008.
Chris@16 4
Chris@16 5 // Use, modification and distribution are subject to the
Chris@16 6 // Boost Software License, Version 1.0.
Chris@16 7 // (See accompanying file LICENSE_1_0.txt
Chris@16 8 // or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9
Chris@16 10 #ifndef BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP
Chris@16 11 #define BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP
Chris@16 12
Chris@16 13 #include <boost/math/distributions/non_central_beta.hpp>
Chris@16 14 #include <boost/math/distributions/detail/generic_mode.hpp>
Chris@16 15 #include <boost/math/special_functions/pow.hpp>
Chris@16 16
Chris@16 17 namespace boost
Chris@16 18 {
Chris@16 19 namespace math
Chris@16 20 {
Chris@16 21 template <class RealType = double, class Policy = policies::policy<> >
Chris@16 22 class non_central_f_distribution
Chris@16 23 {
Chris@16 24 public:
Chris@16 25 typedef RealType value_type;
Chris@16 26 typedef Policy policy_type;
Chris@16 27
Chris@16 28 non_central_f_distribution(RealType v1_, RealType v2_, RealType lambda) : v1(v1_), v2(v2_), ncp(lambda)
Chris@16 29 {
Chris@16 30 const char* function = "boost::math::non_central_f_distribution<%1%>::non_central_f_distribution(%1%,%1%)";
Chris@16 31 RealType r;
Chris@16 32 detail::check_df(
Chris@16 33 function,
Chris@16 34 v1, &r, Policy());
Chris@16 35 detail::check_df(
Chris@16 36 function,
Chris@16 37 v2, &r, Policy());
Chris@16 38 detail::check_non_centrality(
Chris@16 39 function,
Chris@16 40 lambda,
Chris@16 41 &r,
Chris@16 42 Policy());
Chris@16 43 } // non_central_f_distribution constructor.
Chris@16 44
Chris@16 45 RealType degrees_of_freedom1()const
Chris@16 46 {
Chris@16 47 return v1;
Chris@16 48 }
Chris@16 49 RealType degrees_of_freedom2()const
Chris@16 50 {
Chris@16 51 return v2;
Chris@16 52 }
Chris@16 53 RealType non_centrality() const
Chris@16 54 { // Private data getter function.
Chris@16 55 return ncp;
Chris@16 56 }
Chris@16 57 private:
Chris@16 58 // Data member, initialized by constructor.
Chris@16 59 RealType v1; // alpha.
Chris@16 60 RealType v2; // beta.
Chris@16 61 RealType ncp; // non-centrality parameter
Chris@16 62 }; // template <class RealType, class Policy> class non_central_f_distribution
Chris@16 63
Chris@16 64 typedef non_central_f_distribution<double> non_central_f; // Reserved name of type double.
Chris@16 65
Chris@16 66 // Non-member functions to give properties of the distribution.
Chris@16 67
Chris@16 68 template <class RealType, class Policy>
Chris@16 69 inline const std::pair<RealType, RealType> range(const non_central_f_distribution<RealType, Policy>& /* dist */)
Chris@16 70 { // Range of permissible values for random variable k.
Chris@16 71 using boost::math::tools::max_value;
Chris@16 72 return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
Chris@16 73 }
Chris@16 74
Chris@16 75 template <class RealType, class Policy>
Chris@16 76 inline const std::pair<RealType, RealType> support(const non_central_f_distribution<RealType, Policy>& /* dist */)
Chris@16 77 { // Range of supported values for random variable k.
Chris@16 78 // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
Chris@16 79 using boost::math::tools::max_value;
Chris@16 80 return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>());
Chris@16 81 }
Chris@16 82
Chris@16 83 template <class RealType, class Policy>
Chris@16 84 inline RealType mean(const non_central_f_distribution<RealType, Policy>& dist)
Chris@16 85 {
Chris@16 86 const char* function = "mean(non_central_f_distribution<%1%> const&)";
Chris@16 87 RealType v1 = dist.degrees_of_freedom1();
Chris@16 88 RealType v2 = dist.degrees_of_freedom2();
Chris@16 89 RealType l = dist.non_centrality();
Chris@16 90 RealType r;
Chris@16 91 if(!detail::check_df(
Chris@16 92 function,
Chris@16 93 v1, &r, Policy())
Chris@16 94 ||
Chris@16 95 !detail::check_df(
Chris@16 96 function,
Chris@16 97 v2, &r, Policy())
Chris@16 98 ||
Chris@16 99 !detail::check_non_centrality(
Chris@16 100 function,
Chris@16 101 l,
Chris@16 102 &r,
Chris@16 103 Policy()))
Chris@16 104 return r;
Chris@16 105 if(v2 <= 2)
Chris@16 106 return policies::raise_domain_error(
Chris@16 107 function,
Chris@16 108 "Second degrees of freedom parameter was %1%, but must be > 2 !",
Chris@16 109 v2, Policy());
Chris@16 110 return v2 * (v1 + l) / (v1 * (v2 - 2));
Chris@16 111 } // mean
Chris@16 112
Chris@16 113 template <class RealType, class Policy>
Chris@16 114 inline RealType mode(const non_central_f_distribution<RealType, Policy>& dist)
Chris@16 115 { // mode.
Chris@16 116 static const char* function = "mode(non_central_chi_squared_distribution<%1%> const&)";
Chris@16 117
Chris@16 118 RealType n = dist.degrees_of_freedom1();
Chris@16 119 RealType m = dist.degrees_of_freedom2();
Chris@16 120 RealType l = dist.non_centrality();
Chris@16 121 RealType r;
Chris@16 122 if(!detail::check_df(
Chris@16 123 function,
Chris@16 124 n, &r, Policy())
Chris@16 125 ||
Chris@16 126 !detail::check_df(
Chris@16 127 function,
Chris@16 128 m, &r, Policy())
Chris@16 129 ||
Chris@16 130 !detail::check_non_centrality(
Chris@16 131 function,
Chris@16 132 l,
Chris@16 133 &r,
Chris@16 134 Policy()))
Chris@16 135 return r;
Chris@101 136 RealType guess = m > 2 ? RealType(m * (n + l) / (n * (m - 2))) : RealType(1);
Chris@16 137 return detail::generic_find_mode(
Chris@16 138 dist,
Chris@101 139 guess,
Chris@16 140 function);
Chris@16 141 }
Chris@16 142
Chris@16 143 template <class RealType, class Policy>
Chris@16 144 inline RealType variance(const non_central_f_distribution<RealType, Policy>& dist)
Chris@16 145 { // variance.
Chris@16 146 const char* function = "variance(non_central_f_distribution<%1%> const&)";
Chris@16 147 RealType n = dist.degrees_of_freedom1();
Chris@16 148 RealType m = dist.degrees_of_freedom2();
Chris@16 149 RealType l = dist.non_centrality();
Chris@16 150 RealType r;
Chris@16 151 if(!detail::check_df(
Chris@16 152 function,
Chris@16 153 n, &r, Policy())
Chris@16 154 ||
Chris@16 155 !detail::check_df(
Chris@16 156 function,
Chris@16 157 m, &r, Policy())
Chris@16 158 ||
Chris@16 159 !detail::check_non_centrality(
Chris@16 160 function,
Chris@16 161 l,
Chris@16 162 &r,
Chris@16 163 Policy()))
Chris@16 164 return r;
Chris@16 165 if(m <= 4)
Chris@16 166 return policies::raise_domain_error(
Chris@16 167 function,
Chris@16 168 "Second degrees of freedom parameter was %1%, but must be > 4 !",
Chris@16 169 m, Policy());
Chris@16 170 RealType result = 2 * m * m * ((n + l) * (n + l)
Chris@16 171 + (m - 2) * (n + 2 * l));
Chris@16 172 result /= (m - 4) * (m - 2) * (m - 2) * n * n;
Chris@16 173 return result;
Chris@16 174 }
Chris@16 175
Chris@16 176 // RealType standard_deviation(const non_central_f_distribution<RealType, Policy>& dist)
Chris@16 177 // standard_deviation provided by derived accessors.
Chris@16 178
Chris@16 179 template <class RealType, class Policy>
Chris@16 180 inline RealType skewness(const non_central_f_distribution<RealType, Policy>& dist)
Chris@16 181 { // skewness = sqrt(l).
Chris@16 182 const char* function = "skewness(non_central_f_distribution<%1%> const&)";
Chris@16 183 BOOST_MATH_STD_USING
Chris@16 184 RealType n = dist.degrees_of_freedom1();
Chris@16 185 RealType m = dist.degrees_of_freedom2();
Chris@16 186 RealType l = dist.non_centrality();
Chris@16 187 RealType r;
Chris@16 188 if(!detail::check_df(
Chris@16 189 function,
Chris@16 190 n, &r, Policy())
Chris@16 191 ||
Chris@16 192 !detail::check_df(
Chris@16 193 function,
Chris@16 194 m, &r, Policy())
Chris@16 195 ||
Chris@16 196 !detail::check_non_centrality(
Chris@16 197 function,
Chris@16 198 l,
Chris@16 199 &r,
Chris@16 200 Policy()))
Chris@16 201 return r;
Chris@16 202 if(m <= 6)
Chris@16 203 return policies::raise_domain_error(
Chris@16 204 function,
Chris@16 205 "Second degrees of freedom parameter was %1%, but must be > 6 !",
Chris@16 206 m, Policy());
Chris@16 207 RealType result = 2 * constants::root_two<RealType>();
Chris@16 208 result *= sqrt(m - 4);
Chris@16 209 result *= (n * (m + n - 2) *(m + 2 * n - 2)
Chris@16 210 + 3 * (m + n - 2) * (m + 2 * n - 2) * l
Chris@16 211 + 6 * (m + n - 2) * l * l + 2 * l * l * l);
Chris@16 212 result /= (m - 6) * pow(n * (m + n - 2) + 2 * (m + n - 2) * l + l * l, RealType(1.5f));
Chris@16 213 return result;
Chris@16 214 }
Chris@16 215
Chris@16 216 template <class RealType, class Policy>
Chris@16 217 inline RealType kurtosis_excess(const non_central_f_distribution<RealType, Policy>& dist)
Chris@16 218 {
Chris@16 219 const char* function = "kurtosis_excess(non_central_f_distribution<%1%> const&)";
Chris@16 220 BOOST_MATH_STD_USING
Chris@16 221 RealType n = dist.degrees_of_freedom1();
Chris@16 222 RealType m = dist.degrees_of_freedom2();
Chris@16 223 RealType l = dist.non_centrality();
Chris@16 224 RealType r;
Chris@16 225 if(!detail::check_df(
Chris@16 226 function,
Chris@16 227 n, &r, Policy())
Chris@16 228 ||
Chris@16 229 !detail::check_df(
Chris@16 230 function,
Chris@16 231 m, &r, Policy())
Chris@16 232 ||
Chris@16 233 !detail::check_non_centrality(
Chris@16 234 function,
Chris@16 235 l,
Chris@16 236 &r,
Chris@16 237 Policy()))
Chris@16 238 return r;
Chris@16 239 if(m <= 8)
Chris@16 240 return policies::raise_domain_error(
Chris@16 241 function,
Chris@16 242 "Second degrees of freedom parameter was %1%, but must be > 8 !",
Chris@16 243 m, Policy());
Chris@16 244 RealType l2 = l * l;
Chris@16 245 RealType l3 = l2 * l;
Chris@16 246 RealType l4 = l2 * l2;
Chris@16 247 RealType result = (3 * (m - 4) * (n * (m + n - 2)
Chris@16 248 * (4 * (m - 2) * (m - 2)
Chris@16 249 + (m - 2) * (m + 10) * n
Chris@16 250 + (10 + m) * n * n)
Chris@16 251 + 4 * (m + n - 2) * (4 * (m - 2) * (m - 2)
Chris@16 252 + (m - 2) * (10 + m) * n
Chris@16 253 + (10 + m) * n * n) * l + 2 * (10 + m)
Chris@16 254 * (m + n - 2) * (2 * m + 3 * n - 4) * l2
Chris@16 255 + 4 * (10 + m) * (-2 + m + n) * l3
Chris@16 256 + (10 + m) * l4))
Chris@16 257 /
Chris@16 258 ((-8 + m) * (-6 + m) * boost::math::pow<2>(n * (-2 + m + n)
Chris@16 259 + 2 * (-2 + m + n) * l + l2));
Chris@16 260 return result;
Chris@16 261 } // kurtosis_excess
Chris@16 262
Chris@16 263 template <class RealType, class Policy>
Chris@16 264 inline RealType kurtosis(const non_central_f_distribution<RealType, Policy>& dist)
Chris@16 265 {
Chris@16 266 return kurtosis_excess(dist) + 3;
Chris@16 267 }
Chris@16 268
Chris@16 269 template <class RealType, class Policy>
Chris@16 270 inline RealType pdf(const non_central_f_distribution<RealType, Policy>& dist, const RealType& x)
Chris@16 271 { // Probability Density/Mass Function.
Chris@16 272 typedef typename policies::evaluation<RealType, Policy>::type value_type;
Chris@16 273 typedef typename policies::normalise<
Chris@16 274 Policy,
Chris@16 275 policies::promote_float<false>,
Chris@16 276 policies::promote_double<false>,
Chris@16 277 policies::discrete_quantile<>,
Chris@16 278 policies::assert_undefined<> >::type forwarding_policy;
Chris@16 279
Chris@16 280 value_type alpha = dist.degrees_of_freedom1() / 2;
Chris@16 281 value_type beta = dist.degrees_of_freedom2() / 2;
Chris@16 282 value_type y = x * alpha / beta;
Chris@16 283 value_type r = pdf(boost::math::non_central_beta_distribution<value_type, forwarding_policy>(alpha, beta, dist.non_centrality()), y / (1 + y));
Chris@16 284 return policies::checked_narrowing_cast<RealType, forwarding_policy>(
Chris@16 285 r * (dist.degrees_of_freedom1() / dist.degrees_of_freedom2()) / ((1 + y) * (1 + y)),
Chris@16 286 "pdf(non_central_f_distribution<%1%>, %1%)");
Chris@16 287 } // pdf
Chris@16 288
Chris@16 289 template <class RealType, class Policy>
Chris@16 290 RealType cdf(const non_central_f_distribution<RealType, Policy>& dist, const RealType& x)
Chris@16 291 {
Chris@16 292 const char* function = "cdf(const non_central_f_distribution<%1%>&, %1%)";
Chris@16 293 RealType r;
Chris@16 294 if(!detail::check_df(
Chris@16 295 function,
Chris@16 296 dist.degrees_of_freedom1(), &r, Policy())
Chris@16 297 ||
Chris@16 298 !detail::check_df(
Chris@16 299 function,
Chris@16 300 dist.degrees_of_freedom2(), &r, Policy())
Chris@16 301 ||
Chris@16 302 !detail::check_non_centrality(
Chris@16 303 function,
Chris@16 304 dist.non_centrality(),
Chris@16 305 &r,
Chris@16 306 Policy()))
Chris@16 307 return r;
Chris@16 308
Chris@16 309 if((x < 0) || !(boost::math::isfinite)(x))
Chris@16 310 {
Chris@16 311 return policies::raise_domain_error<RealType>(
Chris@16 312 function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy());
Chris@16 313 }
Chris@16 314
Chris@16 315 RealType alpha = dist.degrees_of_freedom1() / 2;
Chris@16 316 RealType beta = dist.degrees_of_freedom2() / 2;
Chris@16 317 RealType y = x * alpha / beta;
Chris@16 318 RealType c = y / (1 + y);
Chris@16 319 RealType cp = 1 / (1 + y);
Chris@16 320 //
Chris@16 321 // To ensure accuracy, we pass both x and 1-x to the
Chris@16 322 // non-central beta cdf routine, this ensures accuracy
Chris@16 323 // even when we compute x to be ~ 1:
Chris@16 324 //
Chris@16 325 r = detail::non_central_beta_cdf(c, cp, alpha, beta,
Chris@16 326 dist.non_centrality(), false, Policy());
Chris@16 327 return r;
Chris@16 328 } // cdf
Chris@16 329
Chris@16 330 template <class RealType, class Policy>
Chris@16 331 RealType cdf(const complemented2_type<non_central_f_distribution<RealType, Policy>, RealType>& c)
Chris@16 332 { // Complemented Cumulative Distribution Function
Chris@16 333 const char* function = "cdf(complement(const non_central_f_distribution<%1%>&, %1%))";
Chris@16 334 RealType r;
Chris@16 335 if(!detail::check_df(
Chris@16 336 function,
Chris@16 337 c.dist.degrees_of_freedom1(), &r, Policy())
Chris@16 338 ||
Chris@16 339 !detail::check_df(
Chris@16 340 function,
Chris@16 341 c.dist.degrees_of_freedom2(), &r, Policy())
Chris@16 342 ||
Chris@16 343 !detail::check_non_centrality(
Chris@16 344 function,
Chris@16 345 c.dist.non_centrality(),
Chris@16 346 &r,
Chris@16 347 Policy()))
Chris@16 348 return r;
Chris@16 349
Chris@16 350 if((c.param < 0) || !(boost::math::isfinite)(c.param))
Chris@16 351 {
Chris@16 352 return policies::raise_domain_error<RealType>(
Chris@16 353 function, "Random Variable parameter was %1%, but must be > 0 !", c.param, Policy());
Chris@16 354 }
Chris@16 355
Chris@16 356 RealType alpha = c.dist.degrees_of_freedom1() / 2;
Chris@16 357 RealType beta = c.dist.degrees_of_freedom2() / 2;
Chris@16 358 RealType y = c.param * alpha / beta;
Chris@16 359 RealType x = y / (1 + y);
Chris@16 360 RealType cx = 1 / (1 + y);
Chris@16 361 //
Chris@16 362 // To ensure accuracy, we pass both x and 1-x to the
Chris@16 363 // non-central beta cdf routine, this ensures accuracy
Chris@16 364 // even when we compute x to be ~ 1:
Chris@16 365 //
Chris@16 366 r = detail::non_central_beta_cdf(x, cx, alpha, beta,
Chris@16 367 c.dist.non_centrality(), true, Policy());
Chris@16 368 return r;
Chris@16 369 } // ccdf
Chris@16 370
Chris@16 371 template <class RealType, class Policy>
Chris@16 372 inline RealType quantile(const non_central_f_distribution<RealType, Policy>& dist, const RealType& p)
Chris@16 373 { // Quantile (or Percent Point) function.
Chris@16 374 RealType alpha = dist.degrees_of_freedom1() / 2;
Chris@16 375 RealType beta = dist.degrees_of_freedom2() / 2;
Chris@16 376 RealType x = quantile(boost::math::non_central_beta_distribution<RealType, Policy>(alpha, beta, dist.non_centrality()), p);
Chris@16 377 if(x == 1)
Chris@16 378 return policies::raise_overflow_error<RealType>(
Chris@16 379 "quantile(const non_central_f_distribution<%1%>&, %1%)",
Chris@16 380 "Result of non central F quantile is too large to represent.",
Chris@16 381 Policy());
Chris@16 382 return (x / (1 - x)) * (dist.degrees_of_freedom2() / dist.degrees_of_freedom1());
Chris@16 383 } // quantile
Chris@16 384
Chris@16 385 template <class RealType, class Policy>
Chris@16 386 inline RealType quantile(const complemented2_type<non_central_f_distribution<RealType, Policy>, RealType>& c)
Chris@16 387 { // Quantile (or Percent Point) function.
Chris@16 388 RealType alpha = c.dist.degrees_of_freedom1() / 2;
Chris@16 389 RealType beta = c.dist.degrees_of_freedom2() / 2;
Chris@16 390 RealType x = quantile(complement(boost::math::non_central_beta_distribution<RealType, Policy>(alpha, beta, c.dist.non_centrality()), c.param));
Chris@16 391 if(x == 1)
Chris@16 392 return policies::raise_overflow_error<RealType>(
Chris@16 393 "quantile(complement(const non_central_f_distribution<%1%>&, %1%))",
Chris@16 394 "Result of non central F quantile is too large to represent.",
Chris@16 395 Policy());
Chris@16 396 return (x / (1 - x)) * (c.dist.degrees_of_freedom2() / c.dist.degrees_of_freedom1());
Chris@16 397 } // quantile complement.
Chris@16 398
Chris@16 399 } // namespace math
Chris@16 400 } // namespace boost
Chris@16 401
Chris@16 402 // This include must be at the end, *after* the accessors
Chris@16 403 // for this distribution have been defined, in order to
Chris@16 404 // keep compilers that support two-phase lookup happy.
Chris@16 405 #include <boost/math/distributions/detail/derived_accessors.hpp>
Chris@16 406
Chris@16 407 #endif // BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP
Chris@16 408
Chris@16 409
Chris@16 410