Boost logo

Boost-Commit :

From: john_at_[hidden]
Date: 2007-08-03 09:14:30


Author: johnmaddock
Date: 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
New Revision: 38415
URL: http://svn.boost.org/trac/boost/changeset/38415

Log:
Minor fix to previous policy update.
Lots of warning suppression.
Updated docs, and added the start of a policy tutorial.
Removed:
   sandbox/math_toolkit/policy/
Text files modified:
   sandbox/math_toolkit/boost/math/concepts/distributions.hpp | 9 +
   sandbox/math_toolkit/boost/math/policy/error_handling.hpp | 2
   sandbox/math_toolkit/boost/math/special_functions/detail/bessel_kn.hpp | 33 +++--
   sandbox/math_toolkit/boost/math/special_functions/detail/bessel_yn.hpp | 41 ++++--
   sandbox/math_toolkit/boost/math/special_functions/ellint_rc.hpp | 8
   sandbox/math_toolkit/boost/math/special_functions/ellint_rd.hpp | 6
   sandbox/math_toolkit/boost/math/special_functions/ellint_rf.hpp | 6
   sandbox/math_toolkit/boost/math/special_functions/ellint_rj.hpp | 6
   sandbox/math_toolkit/libs/math/doc/math.qbk | 2
   sandbox/math_toolkit/libs/math/doc/policy.qbk | 235 +++++++++++++++++++++++++++++++++++++++
   sandbox/math_toolkit/libs/math/test/Jamfile.v2 | 5
   sandbox/math_toolkit/libs/math/test/test_instantiate1.cpp | 2
   12 files changed, 310 insertions(+), 45 deletions(-)

Modified: sandbox/math_toolkit/boost/math/concepts/distributions.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/concepts/distributions.hpp (original)
+++ sandbox/math_toolkit/boost/math/concepts/distributions.hpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -12,7 +12,16 @@
 #define BOOST_MATH_DISTRIBUTION_CONCEPT_HPP
 
 #include <boost/math/distributions/complement.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4100)
+#pragma warning(disable: 4510)
+#pragma warning(disable: 4610)
+#endif
 #include <boost/concept_check.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
 #include <utility>
 
 namespace boost{

Modified: sandbox/math_toolkit/boost/math/policy/error_handling.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/policy/error_handling.hpp (original)
+++ sandbox/math_toolkit/boost/math/policy/error_handling.hpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -295,7 +295,7 @@
 inline T raise_denorm_error(
            const char* ,
            const char* ,
- const T& /* val */,
+ const T& val,
            const ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&)
 {
    errno = ERANGE;

Modified: sandbox/math_toolkit/boost/math/special_functions/detail/bessel_kn.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/detail/bessel_kn.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/detail/bessel_kn.hpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -34,28 +34,33 @@
        return policies::raise_overflow_error<T>(function, 0, pol);
     }
 
- if (n == 0)
+ if (n < 0)
     {
- return bessel_k0(x, pol);
+ n = -n; // K_{-n}(z) = K_n(z)
     }
- if (n == 1)
+ if (n == 0)
     {
- return bessel_k1(x, pol);
+ value = bessel_k0(x, pol);
     }
- if (n < 0)
+ else if (n == 1)
     {
- n = -n; // K_{-n}(z) = K_n(z)
+ value = bessel_k1(x, pol);
     }
-
- prev = bessel_k0(x, pol);
- current = bessel_k1(x, pol);
- for (int k = 1; k < n; k++) // n >= 2
+ else
     {
- value = 2 * k * current / x + prev;
- prev = current;
- current = value;
+ prev = bessel_k0(x, pol);
+ current = bessel_k1(x, pol);
+ int k = 1;
+ BOOST_ASSERT(k < n);
+ do
+ {
+ value = 2 * k * current / x + prev;
+ prev = current;
+ current = value;
+ ++k;
+ }
+ while(k < n);
     }
-
     return value;
 }
 

Modified: sandbox/math_toolkit/boost/math/special_functions/detail/bessel_yn.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/detail/bessel_yn.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/detail/bessel_yn.hpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -34,14 +34,9 @@
             "Got x = %1%, but x must be > 0, complex result not supported.", x, pol);
     }
 
- if (n == 0)
- {
- return bessel_y0(x, pol);
- }
- if (n == 1)
- {
- return bessel_y1(x, pol);
- }
+ //
+ // Reflection comes first:
+ //
     if (n < 0)
     {
         factor = (n & 0x1) ? -1 : 1; // Y_{-n}(z) = (-1)^n Y_n(z)
@@ -52,16 +47,30 @@
         factor = 1;
     }
 
- prev = bessel_y0(x, pol);
- current = bessel_y1(x, pol);
- for (int k = 1; k < n; k++) // n >= 2
+ if (n == 0)
     {
- value = 2 * k * current / x - prev;
- prev = current;
- current = value;
+ value = bessel_y0(x, pol);
+ }
+ else if (n == 1)
+ {
+ value = factor * bessel_y1(x, pol);
+ }
+ else
+ {
+ prev = bessel_y0(x, pol);
+ current = bessel_y1(x, pol);
+ int k = 1;
+ BOOST_ASSERT(k < n);
+ do
+ {
+ value = 2 * k * current / x - prev;
+ prev = current;
+ current = value;
+ ++k;
+ }
+ while(k < n);
+ value *= factor;
     }
- value *= factor;
-
     return value;
 }
 

Modified: sandbox/math_toolkit/boost/math/special_functions/ellint_rc.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/ellint_rc.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/ellint_rc.hpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -58,8 +58,9 @@
     else
        prefix = 1;
 
- // duplication
- for (k = 1; k < BOOST_MATH_MAX_ITER; k++)
+ // duplication:
+ k = 1;
+ do
     {
         u = (x + y + y) / 3;
         S = y / u - 1; // 1 - x / u = 2 * S
@@ -72,7 +73,8 @@
         lambda = 2 * sx * sy + y;
         x = (x + lambda) / 4;
         y = (y + lambda) / 4;
- }
+ ++k;
+ }while(k < BOOST_MATH_MAX_ITER);
     // Check to see if we gave up too soon:
     policies::check_series_iterations(function, k, pol);
 

Modified: sandbox/math_toolkit/boost/math/special_functions/ellint_rd.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/ellint_rd.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/ellint_rd.hpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -60,7 +60,8 @@
     // duplication
     sigma = 0;
     factor = 1;
- for (k = 1; k < BOOST_MATH_MAX_ITER; k++)
+ k = 1;
+ do
     {
         u = (x + y + z + z + z) / 5;
         X = (u - x) / u;
@@ -77,7 +78,10 @@
         x = (x + lambda) / 4;
         y = (y + lambda) / 4;
         z = (z + lambda) / 4;
+ ++k;
     }
+ while(k < BOOST_MATH_MAX_ITER);
+
     // Check to see if we gave up too soon:
     policies::check_series_iterations(function, k, pol);
 

Modified: sandbox/math_toolkit/boost/math/special_functions/ellint_rf.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/ellint_rf.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/ellint_rf.hpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -64,7 +64,8 @@
     }
 
     // duplication
- for (k = 1; k < BOOST_MATH_MAX_ITER; k++)
+ k = 1;
+ do
     {
         u = (x + y + z) / 3;
         X = (u - x) / u;
@@ -82,7 +83,10 @@
         x = (x + lambda) / 4;
         y = (y + lambda) / 4;
         z = (z + lambda) / 4;
+ ++k;
     }
+ while(k < BOOST_MATH_MAX_ITER);
+
     // Check to see if we gave up too soon:
     policies::check_series_iterations(function, k, pol);
     BOOST_MATH_INSTRUMENT_CODE(k);

Modified: sandbox/math_toolkit/boost/math/special_functions/ellint_rj.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/ellint_rj.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/ellint_rj.hpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -98,7 +98,8 @@
     // duplication
     sigma = 0;
     factor = 1;
- for (k = 1; k < BOOST_MATH_MAX_ITER; k++)
+ k = 1;
+ do
     {
         u = (x + y + z + p + p) / 5;
         X = (u - x) / u;
@@ -123,7 +124,10 @@
         y = (y + lambda) / 4;
         z = (z + lambda) / 4;
         p = (p + lambda) / 4;
+ ++k;
     }
+ while(k < BOOST_MATH_MAX_ITER);
+
     // Check to see if we gave up too soon:
     policies::check_series_iterations(function, k, pol);
 

Modified: sandbox/math_toolkit/libs/math/doc/math.qbk
==============================================================================
--- sandbox/math_toolkit/libs/math/doc/math.qbk (original)
+++ sandbox/math_toolkit/libs/math/doc/math.qbk 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -196,6 +196,8 @@
 [template floorlr[x][lfloor][x][rfloor]]
 [template ceil[x] '''&#x2308;'''[x]'''&#x2309;''']
 
+[template header_file[file] [@../../../../[file] [file]]]
+
 [template optional_policy[]
 The final __Policy argument is optional and can be used to
 control the behaviour of the function: how it handles errors,

Modified: sandbox/math_toolkit/libs/math/doc/policy.qbk
==============================================================================
--- sandbox/math_toolkit/libs/math/doc/policy.qbk (original)
+++ sandbox/math_toolkit/libs/math/doc/policy.qbk 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -35,7 +35,232 @@
 [endsect][/section:pol_overview Policy Overview]
 
 [section:pol_tutorial Policy Tutorial]
-TODO??
+
+[heading So Just What is a Policy Anyway?]
+
+A policy is a compile-time mechanism for customising the behaviour of a
+special function, or a statistical distribution. With Policies you can
+control:
+
+* What action to take when an error occurs.
+* What happens when you call a function that is mathematically undefined
+( for example if you ask for the mean of a Cauchy distribution).
+* What happens when you ask for a quantile of a discrete distribution.
+* Whether the library is allowed to internally promote `float` to `double`
+and `double` to `long double` in order to improve precision.
+* What precision to use when calculating the result.
+
+Some of these policies could arguably be runtime variables, but then we couldn't
+use compile-time dispatch internally to select the best evaluation method
+for the given policies.
+
+For this reason a Policy is a /type/: in fact it's an instance of the
+class template `boost::math::policies::policy<>`. This class is just a
+compile-time-container of user defined policies (sometimes called a typelist):
+
+ using namespace boost::math::policies;
+ //
+ // Define a policy that sets ::errno on overflow, and does
+ // not promote double to long double internally:
+ //
+ typedef policy<domain_error<errno_on_error>, promote_double<false> > mypolicy;
+
+[heading Policies Have Sensible Defaults]
+
+Most of the time you can just ignore the policy framework, the defaults for
+the various policies are as follows, if these work OK for you then you can
+stop reading now!
+
+[variablelist
+[[Domain Error][Throws a `std::domain_error` exception.]]
+[[Pole Error][Occurs when a function is evaluated at a pole: throws a `std::domain_error` exception.]]
+[[Overflow Error][Throws a `std::overflow_error` exception.]]
+[[Underflow][Ignores the underflow, and returns zero.]]
+[[Denormalised Result][Ignores the fact that the result is denormalised, and returns it]]
+[[Internal Evaluation Error][Throws a `boost::math::evaluation_error` exception.]]
+[[Promotion of float to double][Does occur by default - gives full float precision results.]]
+[[Promotion of double to long double][Does occur by default if long double offers
+ more precision than double.]]
+[[Precision of Approximation Used][By default uses an approximation that
+ will result in the lowest level of error for the type of the result.]]
+[[Behaviour of Discrete Quantiles][Returns an integer result that is rounded
+ down for lower quantiles and rounded up for upper quantiles - see TODO LINK HERE!!]]
+]
+
+What's more if you define you're own policy type, then it automatically
+inherits the defaults for any policies not explicitly set, so given:
+
+ using namespace boost::math::policies;
+ //
+ // Define a policy that sets ::errno on overflow, and does
+ // not promote double to long double internally:
+ //
+ typedef policy<domain_error<errno_on_error>, promote_double<false> > mypolicy;
+
+then `mypolicy` defines a policy where only the overflow error handling and
+`double`-promotion policies differ from the defaults.
+
+[heading So How are Policies Used Anyway?]
+
+The details follow later, but basically policies can be set by either:
+
+* Defining some macros that change the default behaviour: this is the
+ recomended method for setting installation-wide policies.
+* By instantiating a distribution object with an explicit policy:
+ this is mainly reserved for add-hock policy changes.
+* By passing a policy to a special function as an optional final argument:
+ this is mainly reserved for add-hock policy changes.
+* By using some helper macros to define a set of functions or distributions
+in the current namespace that use a specific policy: this is the
+recomended method for setting policies on a project- or translation-unit-wide
+basis.
+
+The following sections introduce these methods in more detail.
+
+[heading Changing the Policy Defaults]
+
+The default policies used by the library are changed by the usual
+configuration macro method.
+
+For example passing `-DBOOST_MATH_DOMAIN_ERROR_POLICY=errno_on_error` to
+your compiler will cause domain errors to set `::errno` and return a NaN
+rather than the usual default behaviour of throwing a `std::domain_error`
+exception. There is however a very important caveat to this:
+
+[important
+[*['Default policies changed by setting configuration macros must be changed
+uniformly in every translation unit in the program.]]
+
+Failure to follow this rule may result in violations of the "one
+definition rule" and result in unpredictable program behaviour.]
+
+That means there are only two safe ways to use these macros:
+
+* Edit them in [@../../../../boost/math/tools/user.hpp boost/math/tools/user.hpp], so that the defaults are set
+on an installation-wide basis. Unfortunately this may not be convenient if
+you are using a pre-installed Boost distribution (on Linux for example).
+* Set the defines in your project's makefile or build environment, so that they
+are set uniformly across all translation units.
+
+What you should not do is:
+
+* Set the defines in the source file using `#define` as doing so
+almost certainly will break your program, unless you're absolutely
+certain that the program is restricted to a single translation unit.
+
+And, yes you will find examples in our test programs where we break this
+rule: but only because we know they are will will always be a single
+translation unit only: don't say that you weren't warned!
+
+[heading Setting Policies for Distributions on an Ad-Hock Basis]
+
+All of the statistical distributions in this library are class templates
+that accept two template parameters, both with sensible defaults, for
+example:
+
+ namespace boost{ namespace math{
+
+ template <class RealType = double, class Policy = policies::policy<> >
+ class fisher_f_distribution;
+
+ typedef fisher_f_distribution<> fisher_f;
+
+ }}
+
+So if you use the shorthand-typedef for the distribution, then you get
+`double` precision arithmetic and all the default policies.
+
+However, say for example we wanted to evaluate the quantile
+of the binomial distribution at float precision, without internal
+promotion to double, and with the result rounded to the /nearest/
+integer, then here's how it can be done:
+
+[import ../example/policy_eg_3.cpp]
+
+[policy_eg_3]
+
+Which outputs:
+
+[pre quantile is: 40]
+
+[heading Changing the Policy on an Ad-Hock Basis for the Special Functions]
+
+All of the special functions in this library come in two overloaded forms,
+one with a final "policy" parameter, and one without. For example:
+
+ namespace boost{ namespace math{
+
+ template <class RealType, class Policy>
+ RealType tgamma(RealType, const Policy&);
+
+ template <class RealType>
+ RealType tgamma(RealType);
+
+ }} // namespaces
+
+Normally the second version is just a forwarding wrapper to the first
+like this:
+
+ template <class RealType>
+ inline RealType tgamma(RealType x)
+ {
+ return tgamma(x, policies::policy<>());
+ }
+
+So calling a special function with a specific policy
+is just a matter of defining the policy type to use
+and passing it as the final parameter. For example,
+suppose we want tgamma to behave in a C-compatible
+fashion and set errno when an error occurs, and never
+throw an exception:
+
+[import ../example/policy_eg_1.cpp]
+
+[policy_eg_1]
+
+Which outputs:
+
+[pre
+Result of tgamma(30000) is: 1.#INF
+errno = 34
+Result of tgamma(-10) is: 1.#QNAN
+errno = 33
+]
+
+Alternatively, for ad-hock use, we can use the `make_policy`
+helper function to create a policy for us, this useage is more
+verbose, so is probably only of use when a policy is going
+to be used once only:
+
+[import ../example/policy_eg_2.cpp]
+
+[policy_eg_2]
+
+[heading Setting Policies at Namespace or Translation Unit Scope]
+
+Sometimes what you want to do is just change a set of policies within
+the current scope: the one thing you should not do in this situation
+is use the configuration macros, as this can lead to "One Definition
+Rule" violations. Instead this library provides a pair of macros
+especially for this purpose.
+
+Let's consider the special functions first: we can declare a set of
+forwarding functions that all use a specific policy using the
+macro BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(['Policy]). This
+macro should be used either inside a unique namespace set aside for the
+purpose, or an unnamed namespace if you just want the functions
+visible in global scope for the current file only.
+
+[import ../example/policy_eg_4.cpp]
+
+[policy_eg_4]
+
+The same mechanism works well at file scope as well:
+
+[import ../example/policy_eg_5.cpp]
+
+[policy_eg_5]
+
 [endsect][/section:pol_Tutorial Policy Tutorial]
 
 [section:pol_ref Policy Reference]
@@ -111,7 +336,7 @@
 [h5 user_error]
 
 Will call a user defined error handler: these are forward declared
-in boost/math/policy/error_handling.hpp, but the actual definitions
+in boost/math/policies/error_handling.hpp, but the actual definitions
 must be provided by the user:
 
    template <class T>
@@ -526,7 +751,7 @@
  - but can be set to other values to cause lower levels of precision
 to be used.
 
- namespace boost{ namespace math{ namespace policy{
+ namespace boost{ namespace math{ namespace policies{
    
    template <int N>
    digits10;
@@ -790,12 +1015,12 @@
 There's very little to say here, the `policy` class is just a rag-bag
 compile-time container for a collection of policies:
 
-```#include <boost/math/policy/policy.hpp>```
+```#include <boost/math/policies/policy.hpp>```
 
 
    namespace boost{
    namespace math{
- namespace policy
+ namespace policies
    
    template <class A1 = default_policy,
              class A2 = default_policy,

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-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -13,9 +13,9 @@
       <toolset>darwin:<cxxflags>-Wno-missing-braces
       <toolset>acc:<cxxflags>+W2068,2461,2236,4070
       <toolset>intel:<cxxflags>-Qwd264,239
- <toolset>msvc:<cxxflags>/EHa
+ <toolset>msvc:<warnings>all
+ <toolset>msvc:<asynch-exceptions>on
       <toolset>msvc:<cxxflags>/wd4996
- <toolset>msvc:<cxxflags>/W4
       <toolset>msvc:<cxxflags>/wd4512
       <toolset>msvc:<cxxflags>/wd4610
       <toolset>msvc:<cxxflags>/wd4510
@@ -182,3 +182,4 @@
 
 
 
+

Modified: sandbox/math_toolkit/libs/math/test/test_instantiate1.cpp
==============================================================================
--- sandbox/math_toolkit/libs/math/test/test_instantiate1.cpp (original)
+++ sandbox/math_toolkit/libs/math/test/test_instantiate1.cpp 2007-08-03 09:14:29 EDT (Fri, 03 Aug 2007)
@@ -7,7 +7,7 @@
 
 extern void other_test();
 
-int main(int argc, char* argv[])
+int main(int argc, char* [])
 {
    if(argc > 10000)
    {


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