Boost logo

Boost-Commit :

From: john_at_[hidden]
Date: 2007-08-30 13:08:49


Author: johnmaddock
Date: 2007-08-30 13:08:46 EDT (Thu, 30 Aug 2007)
New Revision: 39076
URL: http://svn.boost.org/trac/boost/changeset/39076

Log:
Added some type traits so we can do concept checking where required.
Updated find_location to use the traits.
Added tests for traits.hpp.
Updated Jamfile.v2 with new tests.
Added:
   sandbox/math_toolkit/boost/math/tools/traits.hpp (contents, props changed)
   sandbox/math_toolkit/libs/math/test/compile_test/test_traits.cpp (contents, props changed)
Text files modified:
   sandbox/math_toolkit/boost/math/distributions/find_location.hpp | 34 +++++++++++++++++++---------------
   sandbox/math_toolkit/libs/math/test/Jamfile.v2 | 3 +++
   2 files changed, 22 insertions(+), 15 deletions(-)

Modified: sandbox/math_toolkit/boost/math/distributions/find_location.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/distributions/find_location.hpp (original)
+++ sandbox/math_toolkit/boost/math/distributions/find_location.hpp 2007-08-30 13:08:46 EDT (Thu, 30 Aug 2007)
@@ -11,6 +11,8 @@
 #include <boost/math/distributions/fwd.hpp> // for all distribution signatures.
 #include <boost/math/distributions/complement.hpp>
 #include <boost/math/policies/policy.hpp>
+#include <boost/math/tools/traits.hpp>
+#include <boost/static_assert.hpp>
 // using boost::math::policies::policy;
 // using boost::math::complement; // will be needed by users who want complement,
 // but NOT placed here to avoid putting it in global scope.
@@ -24,17 +26,6 @@
   // Apply to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular).
   // TODO use concepts to enforce this.
 
- template <class Dist>
- inline // with default policy.
- typename Dist::value_type find_location( // For example, normal mean.
- typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p.
- // For example, a nominal minimum acceptable z, so that p * 100 % are > z
- typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z.
- typename Dist::value_type scale) // scale parameter, for example, normal standard deviation.
- { // Forward to find_location with default policy.
- return (find_location<Dist>(z, p, scale, policies::policy<>()));
- } // find_location
-
     template <class Dist, class Policy>
     inline
       typename Dist::value_type find_location( // For example, normal mean.
@@ -45,21 +36,23 @@
       const Policy& pol
       )
     {
+ BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<Dist>::value);
+ BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<Dist>::value);
       static const char* function = "boost::math::find_location<%1%>&, %1%)";
 
       if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
       {
- return policies::raise_domain_error<Dist::value_type>(
+ return policies::raise_domain_error<typename Dist::value_type>(
            function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol);
       }
       if(!(boost::math::isfinite)(z))
       {
- return policies::raise_domain_error<Dist::value_type>(
+ return policies::raise_domain_error<typename Dist::value_type>(
            function, "z parameter was %1%, but must be finite!", z, pol);
       }
- if(!(boost::math::isfinite)(z))
+ if(!(boost::math::isfinite)(scale))
       {
- return policies::raise_domain_error<Dist::value_type>(
+ return policies::raise_domain_error<typename Dist::value_type>(
            function, "scale parameter was %1%, but must be finite!", scale, pol);
       }
         
@@ -68,6 +61,17 @@
       return z - (quantile(Dist(), p) * scale);
     } // find_location
 
+ template <class Dist>
+ inline // with default policy.
+ typename Dist::value_type find_location( // For example, normal mean.
+ typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p.
+ // For example, a nominal minimum acceptable z, so that p * 100 % are > z
+ typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z.
+ typename Dist::value_type scale) // scale parameter, for example, normal standard deviation.
+ { // Forward to find_location with default policy.
+ return (find_location<Dist>(z, p, scale, policies::policy<>()));
+ } // find_location
+
     // So the user can start from the complement q = (1 - p) of the probability p,
     // for example, l = find_location<normal>(complement(z, q, sd));
 

Added: sandbox/math_toolkit/boost/math/tools/traits.hpp
==============================================================================
--- (empty file)
+++ sandbox/math_toolkit/boost/math/tools/traits.hpp 2007-08-30 13:08:46 EDT (Thu, 30 Aug 2007)
@@ -0,0 +1,92 @@
+// Copyright John Maddock 2007.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_STATS_IS_DISTRIBUTION_HPP
+#define BOOST_STATS_IS_DISTRIBUTION_HPP
+
+#include <boost/mpl/has_xxx.hpp>
+// should be the last #include
+#include <boost/type_traits/detail/bool_trait_def.hpp>
+
+namespace boost{ namespace math{ namespace tools{
+
+namespace detail{
+
+BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_value_type, value_type, true);
+BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_policy_type, policy_type, true);
+
+template<class D>
+char cdf(const D& ...);
+template<class D>
+char quantile(const D& ...);
+
+template <class D>
+struct has_cdf
+{
+ static D d;
+ BOOST_STATIC_CONSTANT(bool, value = sizeof(cdf(d, 0.0f)) != 1);
+};
+
+template <class D>
+struct has_quantile
+{
+ static D d;
+ BOOST_STATIC_CONSTANT(bool, value = sizeof(quantile(d, 0.0f)) != 1);
+};
+
+template <class D>
+struct is_distribution_imp
+{
+ BOOST_STATIC_CONSTANT(bool, value =
+ has_quantile<D>::value
+ && has_cdf<D>::value
+ && has_value_type<D>::value
+ && has_policy_type<D>::value);
+};
+
+template <class sig, sig val>
+struct result_tag{};
+
+template <class D>
+double test_has_location(const volatile result_tag<typename D::value_type (D::*)()const, &D::location>*);
+template <class D>
+char test_has_location(...);
+
+template <class D>
+double test_has_scale(const volatile result_tag<typename D::value_type (D::*)()const, &D::scale>*);
+template <class D>
+char test_has_scale(...);
+
+template <class D, bool b>
+struct is_scaled_distribution_helper
+{
+ BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template <class D>
+struct is_scaled_distribution_helper<D, true>
+{
+ BOOST_STATIC_CONSTANT(bool, value =
+ (sizeof(test_has_location<D>(0)) != 1)
+ &&
+ (sizeof(test_has_scale<D>(0)) != 1));
+};
+
+template <class D>
+struct is_scaled_distribution_imp
+{
+ BOOST_STATIC_CONSTANT(bool, value = (::boost::math::tools::detail::is_scaled_distribution_helper<D, ::boost::math::tools::detail::is_distribution_imp<D>::value>::value));
+};
+
+} // namespace detail
+
+BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_distribution,T,::boost::math::tools::detail::is_distribution_imp<T>::value)
+BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_scaled_distribution,T,::boost::math::tools::detail::is_scaled_distribution_imp<T>::value)
+
+}}}
+
+#endif
+

Modified: sandbox/math_toolkit/libs/math/test/Jamfile.v2
==============================================================================
--- sandbox/math_toolkit/libs/math/test/Jamfile.v2 (original)
+++ sandbox/math_toolkit/libs/math/test/Jamfile.v2 2007-08-30 13:08:46 EDT (Thu, 30 Aug 2007)
@@ -54,6 +54,7 @@
 run test_exponential_dist.cpp ;
 run test_extreme_value.cpp ;
 run test_factorials.cpp ;
+run test_find_location.cpp ;
 run test_fisher_f.cpp ;
 run test_gamma.cpp ;
 run test_gamma_dist.cpp ;
@@ -166,6 +167,7 @@
 compile compile_test/sf_sph_harm_incl_test.cpp ;
 compile compile_test/sf_sqrt1pm1_incl_test.cpp ;
 compile compile_test/std_real_concept_check.cpp ;
+compile compile_test/test_traits.cpp ;
 compile compile_test/tools_config_inc_test.cpp ;
 compile compile_test/tools_fraction_inc_test.cpp ;
 compile compile_test/tools_minima_inc_test.cpp ;
@@ -189,3 +191,4 @@
 
 
 
+

Added: sandbox/math_toolkit/libs/math/test/compile_test/test_traits.cpp
==============================================================================
--- (empty file)
+++ sandbox/math_toolkit/libs/math/test/compile_test/test_traits.cpp 2007-08-30 13:08:46 EDT (Thu, 30 Aug 2007)
@@ -0,0 +1,56 @@
+// Copyright John Maddock 2007.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/math/tools/traits.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/math/distributions.hpp>
+
+using namespace boost::math;
+
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<double>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<int>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<bernoulli>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<beta_distribution<> >::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<binomial>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<cauchy>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<chi_squared>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<exponential>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<extreme_value>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<fisher_f>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<gamma_distribution<> >::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<lognormal>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<negative_binomial>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<normal>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<pareto>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<poisson>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<rayleigh>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<students_t>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<triangular>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<uniform>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_distribution<weibull>::value);
+
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<double>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<int>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<bernoulli>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<beta_distribution<> >::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<binomial>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<cauchy>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<chi_squared>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<exponential>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<extreme_value>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<fisher_f>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<gamma_distribution<> >::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<lognormal>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<negative_binomial>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<normal>::value);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<pareto>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<poisson>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<rayleigh>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<students_t>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<triangular>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<uniform>::value == false);
+BOOST_STATIC_ASSERT(::boost::math::tools::is_scaled_distribution<weibull>::value == false);
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk