Chris@16: // Copyright John Maddock 2006. Chris@16: // Use, modification and distribution are subject to the Chris@16: // Boost Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // distributions.hpp provides definitions of the concept of a distribution Chris@16: // and non-member accessor functions that must be implemented by all distributions. Chris@16: // This is used to verify that Chris@16: // all the features of a distributions have been fully implemented. Chris@16: Chris@16: #ifndef BOOST_MATH_DISTRIBUTION_CONCEPT_HPP Chris@16: #define BOOST_MATH_DISTRIBUTION_CONCEPT_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(push) Chris@16: #pragma warning(disable: 4100) Chris@16: #pragma warning(disable: 4510) Chris@16: #pragma warning(disable: 4610) Chris@16: #pragma warning(disable: 4189) // local variable is initialized but not referenced. Chris@16: #endif Chris@16: #include Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: #include Chris@16: Chris@16: namespace boost{ Chris@16: namespace math{ Chris@16: Chris@16: namespace concepts Chris@16: { Chris@16: // Begin by defining a concept archetype Chris@16: // for a distribution class: Chris@16: // Chris@16: template Chris@16: class distribution_archetype Chris@16: { Chris@16: public: Chris@16: typedef RealType value_type; Chris@16: Chris@16: distribution_archetype(const distribution_archetype&); // Copy constructible. Chris@16: distribution_archetype& operator=(const distribution_archetype&); // Assignable. Chris@16: Chris@16: // There is no default constructor, Chris@16: // but we need a way to instantiate the archetype: Chris@16: static distribution_archetype& get_object() Chris@16: { Chris@16: // will never get caled: Chris@16: return *reinterpret_cast(0); Chris@16: } Chris@16: }; // template class distribution_archetype Chris@16: Chris@16: // Non-member accessor functions: Chris@16: // (This list defines the functions that must be implemented by all distributions). Chris@16: Chris@16: template Chris@16: RealType pdf(const distribution_archetype& dist, const RealType& x); Chris@16: Chris@16: template Chris@16: RealType cdf(const distribution_archetype& dist, const RealType& x); Chris@16: Chris@16: template Chris@16: RealType quantile(const distribution_archetype& dist, const RealType& p); Chris@16: Chris@16: template Chris@16: RealType cdf(const complemented2_type, RealType>& c); Chris@16: Chris@16: template Chris@16: RealType quantile(const complemented2_type, RealType>& c); Chris@16: Chris@16: template Chris@16: RealType mean(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType standard_deviation(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType variance(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType hazard(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType chf(const distribution_archetype& dist); Chris@16: // http://en.wikipedia.org/wiki/Characteristic_function_%28probability_theory%29 Chris@16: Chris@16: template Chris@16: RealType coefficient_of_variation(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType mode(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType skewness(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType kurtosis_excess(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType kurtosis(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: RealType median(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: std::pair range(const distribution_archetype& dist); Chris@16: Chris@16: template Chris@16: std::pair support(const distribution_archetype& dist); Chris@16: Chris@16: // Chris@16: // Next comes the concept checks for verifying that a class Chris@16: // fullfils the requirements of a Distribution: Chris@16: // Chris@16: template Chris@16: struct DistributionConcept Chris@16: { Chris@16: typedef typename Distribution::value_type value_type; Chris@16: Chris@16: void constraints() Chris@16: { Chris@16: function_requires >(); Chris@16: function_requires >(); Chris@16: Chris@16: const Distribution& dist = DistributionConcept::get_object(); Chris@16: Chris@16: value_type x = 0; Chris@16: // The result values are ignored in all these checks. Chris@16: value_type v = cdf(dist, x); Chris@16: v = cdf(complement(dist, x)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = pdf(dist, x); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(dist, x); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(complement(dist, x)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = mean(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = mode(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = standard_deviation(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = variance(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = hazard(dist, x); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = chf(dist, x); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = coefficient_of_variation(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = skewness(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = kurtosis(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = kurtosis_excess(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = median(dist); Chris@16: suppress_unused_variable_warning(v); Chris@16: std::pair pv; Chris@16: pv = range(dist); Chris@16: suppress_unused_variable_warning(pv); Chris@16: pv = support(dist); Chris@16: suppress_unused_variable_warning(pv); Chris@16: Chris@16: float f = 1; Chris@16: v = cdf(dist, f); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = cdf(complement(dist, f)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = pdf(dist, f); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(dist, f); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(complement(dist, f)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = hazard(dist, f); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = chf(dist, f); Chris@16: suppress_unused_variable_warning(v); Chris@16: double d = 1; Chris@16: v = cdf(dist, d); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = cdf(complement(dist, d)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = pdf(dist, d); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(dist, d); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(complement(dist, d)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = hazard(dist, d); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = chf(dist, d); Chris@16: suppress_unused_variable_warning(v); Chris@16: #ifndef TEST_MPFR Chris@16: long double ld = 1; Chris@16: v = cdf(dist, ld); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = cdf(complement(dist, ld)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = pdf(dist, ld); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(dist, ld); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(complement(dist, ld)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = hazard(dist, ld); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = chf(dist, ld); Chris@16: suppress_unused_variable_warning(v); Chris@16: #endif Chris@16: int i = 1; Chris@16: v = cdf(dist, i); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = cdf(complement(dist, i)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = pdf(dist, i); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(dist, i); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(complement(dist, i)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = hazard(dist, i); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = chf(dist, i); Chris@16: suppress_unused_variable_warning(v); Chris@16: unsigned long li = 1; Chris@16: v = cdf(dist, li); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = cdf(complement(dist, li)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = pdf(dist, li); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(dist, li); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = quantile(complement(dist, li)); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = hazard(dist, li); Chris@16: suppress_unused_variable_warning(v); Chris@16: v = chf(dist, li); Chris@16: suppress_unused_variable_warning(v); Chris@16: test_extra_members(dist); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const D&) Chris@16: {} Chris@16: template Chris@16: static void test_extra_members(const boost::math::bernoulli_distribution& d) Chris@16: { Chris@16: value_type r = d.success_fraction(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::beta_distribution& d) Chris@16: { Chris@16: value_type r1 = d.alpha(); Chris@16: value_type r2 = d.beta(); Chris@16: r1 = boost::math::beta_distribution::find_alpha(r1, r2); Chris@16: suppress_unused_variable_warning(r1); Chris@16: r1 = boost::math::beta_distribution::find_beta(r1, r2); Chris@16: suppress_unused_variable_warning(r1); Chris@16: r1 = boost::math::beta_distribution::find_alpha(r1, r2, r1); Chris@16: suppress_unused_variable_warning(r1); Chris@16: r1 = boost::math::beta_distribution::find_beta(r1, r2, r1); Chris@16: suppress_unused_variable_warning(r1); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::binomial_distribution& d) Chris@16: { Chris@16: value_type r = d.success_fraction(); Chris@16: r = d.trials(); Chris@16: r = Distribution::find_lower_bound_on_p(r, r, r); Chris@16: r = Distribution::find_lower_bound_on_p(r, r, r, Distribution::clopper_pearson_exact_interval); Chris@16: r = Distribution::find_lower_bound_on_p(r, r, r, Distribution::jeffreys_prior_interval); Chris@16: r = Distribution::find_upper_bound_on_p(r, r, r); Chris@16: r = Distribution::find_upper_bound_on_p(r, r, r, Distribution::clopper_pearson_exact_interval); Chris@16: r = Distribution::find_upper_bound_on_p(r, r, r, Distribution::jeffreys_prior_interval); Chris@16: r = Distribution::find_minimum_number_of_trials(r, r, r); Chris@16: r = Distribution::find_maximum_number_of_trials(r, r, r); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::cauchy_distribution& d) Chris@16: { Chris@16: value_type r = d.location(); Chris@16: r = d.scale(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::chi_squared_distribution& d) Chris@16: { Chris@16: value_type r = d.degrees_of_freedom(); Chris@16: r = Distribution::find_degrees_of_freedom(r, r, r, r); Chris@16: r = Distribution::find_degrees_of_freedom(r, r, r, r, r); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::exponential_distribution& d) Chris@16: { Chris@16: value_type r = d.lambda(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::extreme_value_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.location(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::fisher_f_distribution& d) Chris@16: { Chris@16: value_type r = d.degrees_of_freedom1(); Chris@16: r = d.degrees_of_freedom2(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::gamma_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.shape(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::inverse_chi_squared_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.degrees_of_freedom(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::inverse_gamma_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.shape(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::hypergeometric_distribution& d) Chris@16: { Chris@16: unsigned u = d.defective(); Chris@16: u = d.sample_count(); Chris@16: u = d.total(); Chris@16: suppress_unused_variable_warning(u); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::laplace_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.location(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::logistic_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.location(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::lognormal_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.location(); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::negative_binomial_distribution& d) Chris@16: { Chris@16: value_type r = d.success_fraction(); Chris@16: r = d.successes(); Chris@16: r = Distribution::find_lower_bound_on_p(r, r, r); Chris@16: r = Distribution::find_upper_bound_on_p(r, r, r); Chris@16: r = Distribution::find_minimum_number_of_trials(r, r, r); Chris@16: r = Distribution::find_maximum_number_of_trials(r, r, r); Chris@16: suppress_unused_variable_warning(r); Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::non_central_beta_distribution& d) Chris@16: { Chris@16: value_type r1 = d.alpha(); Chris@16: value_type r2 = d.beta(); Chris@16: r1 = d.non_centrality(); Chris@16: (void)r1; // warning suppression Chris@16: (void)r2; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::non_central_chi_squared_distribution& d) Chris@16: { Chris@16: value_type r = d.degrees_of_freedom(); Chris@16: r = d.non_centrality(); Chris@16: r = Distribution::find_degrees_of_freedom(r, r, r); Chris@16: r = Distribution::find_degrees_of_freedom(boost::math::complement(r, r, r)); Chris@16: r = Distribution::find_non_centrality(r, r, r); Chris@16: r = Distribution::find_non_centrality(boost::math::complement(r, r, r)); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::non_central_f_distribution& d) Chris@16: { Chris@16: value_type r = d.degrees_of_freedom1(); Chris@16: r = d.degrees_of_freedom2(); Chris@16: r = d.non_centrality(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::non_central_t_distribution& d) Chris@16: { Chris@16: value_type r = d.degrees_of_freedom(); Chris@16: r = d.non_centrality(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::normal_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.location(); Chris@16: r = d.mean(); Chris@16: r = d.standard_deviation(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::pareto_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.shape(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::poisson_distribution& d) Chris@16: { Chris@16: value_type r = d.mean(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::rayleigh_distribution& d) Chris@16: { Chris@16: value_type r = d.sigma(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::students_t_distribution& d) Chris@16: { Chris@16: value_type r = d.degrees_of_freedom(); Chris@16: r = d.find_degrees_of_freedom(r, r, r, r); Chris@16: r = d.find_degrees_of_freedom(r, r, r, r, r); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::triangular_distribution& d) Chris@16: { Chris@16: value_type r = d.lower(); Chris@16: r = d.mode(); Chris@16: r = d.upper(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::weibull_distribution& d) Chris@16: { Chris@16: value_type r = d.scale(); Chris@16: r = d.shape(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: template Chris@16: static void test_extra_members(const boost::math::uniform_distribution& d) Chris@16: { Chris@16: value_type r = d.lower(); Chris@16: r = d.upper(); Chris@16: (void)r; // warning suppression Chris@16: } Chris@16: private: Chris@16: static Distribution* pd; Chris@16: static Distribution& get_object() Chris@16: { Chris@16: // In reality this will never get called: Chris@16: return *pd; Chris@16: } Chris@16: }; // struct DistributionConcept Chris@16: Chris@16: template Chris@16: Distribution* DistributionConcept::pd = 0; Chris@16: Chris@16: } // namespace concepts Chris@16: } // namespace math Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_MATH_DISTRIBUTION_CONCEPT_HPP Chris@16: