diff --git a/doc/checking.htm b/doc/checking.htm index 6e82af5..aedd40b 100644 --- a/doc/checking.htm +++ b/doc/checking.htm @@ -187,15 +187,14 @@ if the base type does not have corresponding values).

intervals, then checking_base<T> is a possibility.
  • If you do not want empty intervals to be created and are not sure all the numbers are valid, then checking_catch_nan<T, - checking_no_empty<T> > can help you. This is the default - policy and it is also called - interval_lib::checking_strict.
  • + checking_no_empty<T> > can help you.
  • If all the numbers will be valid and if no empty interval is supposed to be created (or if you do not want them to be created), then you can use checking_no_nan<T, checking_no_empty<T> >. Please note that if T does not have a way to represent invalid numbers, then this policy will behave the same way as - checking_no_empty<T>.
  • + checking_no_empty<T>. This is the default policy and + it is also called interval_lib::checking_strict.
  • If all numerical data are valid but the algorithm can produce and manipulate empty intervals, then checking_no_nan<T> should be used.
  • @@ -211,8 +210,9 @@ if the base type does not have corresponding values).


    -

    Revised: 2003-01-19
    -Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002.
    -Polytechnic University.

    +

    Revised: 2003-04-24
    +Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002. +Polytechnic University.
    +Copyright (c) Guillaume Melquiond, 2003.

    diff --git a/doc/comparisons.htm b/doc/comparisons.htm index a02dba7..250daca 100644 --- a/doc/comparisons.htm +++ b/doc/comparisons.htm @@ -35,7 +35,7 @@ return_type operator== (const interval<T, Policies1>&, const interval& template<class T, class Policies> return_type operator== (const interval<T, Policies>&, const T&); -

    Provided comparisons

    +

    vided comparisons

    Default comparison

    @@ -64,9 +64,9 @@ comparison was unsure and should have been rewritten.

    Other comparisons

    The other comparisons are selected by using a namespace. These namespaces -are located under boost::interval_lib::compare and are invoked -by:

    -
    using namespace boost::interval_lib::compare::the_comparison_to_select;
    +are located under boost::numeric::interval_lib::compare and are +invoked by:

    +
    using namespace boost::numeric::interval_lib::compare::the_comparison_to_select;

    After this line, the default meaning of the operators will have been replaced by the meaning located in the namespace. Please note that because of @@ -93,10 +93,18 @@ using namespace compare1;

    Now comes the list of the provided comparisons. They all are located in their respective header files under -<boost/numeric/interval/compare/>. And as for the default -comparison, the operators will generally complain by throwing an exception if -feed by invalid values.

    +<boost/numeric/interval/compare/...>. And as for the +default comparison, the operators will generally complain by throwing an +exception if feed by invalid values.

    @@ -117,12 +125,14 @@ feed by invalid values.

    namespace boost {
    -  namespace interval_lib {
    +namespace numeric {
    +namespace interval_lib {
     
     class comparison_error: std::runtime_error; // "boost::interval: uncertain comparison"
     
    -  }
    -}
    +} // namespace interval_lib +} // namespace numeric +} // namespace boost

    Explicit comparison functions

    @@ -135,12 +145,13 @@ true, the result is true) or pos (for "possible", if the default comparison is false, the result is false) followed by lt, le, gt, ge, eq or ne. They are located in -<boost/numeric/interval/compare/explicit.hpp>. Each of these -functions takes two parameters and returns a boolean; the parameters are -expected to be valid, undefined behavior may result otherwise. For example, -the definition of the "certainly less than" comparison is:

    +<boost/numeric/interval/compare/explicit.hpp>. Each of +these functions takes two parameters and returns a boolean; the parameters +are expected to be valid, undefined behavior may result otherwise. For +example, the definition of the "certainly less than" comparison is:

    namespace boost {
    -  namespace interval_lib {
    +namespace numeric {
    +namespace interval_lib {
     
     template<class T, class Policies1, class Policies2>
     bool cerlt(const interval<T, Policies1>& x, const interval<T, Policies2>& y);
    @@ -151,12 +162,14 @@ bool cerlt(const interval<T, Policies>& x, const T& y);
     template<class T, class Policies>
     bool cerlt(const T& x, const interval<T, Policies>& y);
     
    -  } // namespace interval_lib
    +} // namespace interval_lib
    +} // namespace numeric
     } // namespace boost

    -

    Revised: 2002-10-13
    -Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002.
    -Polytechnic University.

    +

    Revised: 2003-04-22
    +Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002. +Polytechnic University.
    +Copyright (c) Guillaume Melquiond, 2003.

    diff --git a/doc/examples.htm b/doc/examples.htm index ad6c563..59e9825 100644 --- a/doc/examples.htm +++ b/doc/examples.htm @@ -10,13 +10,93 @@

    Tests and Examples

    -

    In libs/interval/test/ and -libs/interval/examples/ are some test and example programs.. The -examples illustrate a few uses of intervals. For a general description and -considerations on using this library, and some potential domains of -application, please read this mini-guide.

    +

    A first example

    -

    Tests

    +

    This example shows how to design a function which takes a polynomial and a +value and returns the sign of this polynomial at this point. This function is +a filter: if the answer is not guaranteed, the functions says so. The reason +of using a filter rather than a simple evaluation function is: computations +with floating-point numbers will incur apporximations and it can be enough to +change the sign of the polynomial. So, in order to validate the result, the +function will use interval arithmetic.

    + +

    The first step is the inclusion of the appropriate headers. Because the +function will handle floating-point bounds, the easiest solution is:

    +
    #include <boost/numeric/interval.hpp>
    + +

    Now, let's begin the function. The polynomial is given by the array of its +coefficients and its size (strictly greater to its degree). In order to +simplify the code, two namespaces of the library are included.

    +
    int sign_polynomial(double x, double P[], int sz) {
    +  using namespace boost::numeric;
    +  using namespace interval_lib;
    + +

    Then we can define the interval type. Since no special behavior is +required, the default policies are enough:

    +
      typedef interval<double> I;
    + +

    For the evalutation, let's just use the Horner scheme with interval +arithmetic. The library overloads all the arithmetic operators and provides +mixed operations, so the only difference between the code with and without +interval arithmetic lies in the type of the iterated value y:

    +
      I y = P[sz - 1];
    +  for(int i = sz - 2; i >= 0; i--)
    +    y = y * x + P[i];
    + +

    The last step is the computation of the sign of y. It is done +by choosing an appropriate comparison scheme and then doing the comparison +with the usual operators:

    +
      using namespace compare::certain;
    +  if (y > 0.) return 1;
    +  if (y < 0.) return -1;
    +  return 0;
    +}
    + +

    The answer 0 does not mean the polynomial is zero at this +point. It only means the answer is not known since y contains +zero and thus does not have a precise sign.

    + +

    Now we have the expected function. However, due to the poor +implementations of floating-point rounding in most of the processors, it can +be useful to say to optimize the code; or rather, to let the library optimize +it. The main condition for this optimization is that the interval code should +not be mixed with floating-point code. In this example, it is the case, since +all the operations done in the functions involve the library. So the code can +be rewritten:

    +
    int sign_polynomial(double x, double P[], int sz) {
    +  using namespace boost::numeric;
    +  using namespace interval_lib;
    +  typedef interval<double> I_aux;
    +
    +  I_aux::traits_type::rounding rnd;
    +  typedef unprotect<I_aux>::type I;
    +
    +  I y = P[sz - 1];
    +  for(int i = sz - 2; i >= 0; i--) 
    +    y = y * x + P[i];
    +
    +  using namespace compare::certain;
    +  if (y > 0.) return 1;
    +  if (y < 0.) return -1;
    +  return 0;
    +}
    + +

    The difference between this code and the previous is the use of another +interval type. This new type I indicates to the library that all +the computations can be done without caring for the rounding mode. And +because of that, it is up to the function to care about it: a rounding object +need to be alive whenever the optimized type is used.

    + +

    Other tests and examples

    + +

    In libs/numeric/interval/test/ and +libs/numeric/interval/examples/ are some test and example +programs.. The examples illustrate a few uses of intervals. For a general +description and considerations on using this library, and some potential +domains of application, please read this mini-guide.

    + +

    Tests

    The test programs are as follows. Please note that they require the use of the Boost.test library and can be automatically tested by using @@ -56,8 +136,8 @@ subset of [π

    pow.cpp tests if the pow function behaves correctly on some simple test cases.

    -

    test_float.cpp exercises the arithmetic operations of the -library for floating point base types.

    +

    test_float.cpp exercises the arithmetic operations of the library +for floating point base types.

    interval_test.cpp tests if the interval library respects the inclusion property of interval arithmetic by computing some functions and @@ -66,6 +146,11 @@ operations for both double and

    Examples

    +

    filter.cpp contains filters for computational geometry able to find +the sign of a determinant. This example is inspired by the article +Interval arithmetic yields efficient dynamic filters for computational +geometry by Brönnimann, Burnikel and Pion, 2001.

    +

    findroot_demo.cpp finds zeros of some functions by using dichotomy and even produces gnuplot datas for one of them. The processor has to correctly handle elementary functions for this example to properly work.

    @@ -79,15 +164,14 @@ version of Newton-Raphson algorithm for finding the zeros of a function knowing its derivative. It exercises unprotecting, full division, some set operations and empty intervals.

    -

    interval_speed.cpp is not really an example but more like a -benchmark for testing performance of the library. It needs to be compiled -with -DUSE_BOOST. The compilation option --DUSE_BOOST_UNPROTECTED allows the program to use unprotected -local rounding, leading to better performance.

    +

    transc.cpp implements the transcendental part of the rounding +policy for double by using an external library (the MPFR subset +of GMP in this case).


    -

    Revised: 2002-12-15
    -Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002.
    -Polytechnic University.

    +

    Revised: 2003-04-22
    +Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002. +Polytechnic University.
    +Copyright (c) Guillaume Melquiond, 2003.

    diff --git a/doc/includes.htm b/doc/includes.htm index 376c502..5b8077a 100644 --- a/doc/includes.htm +++ b/doc/includes.htm @@ -17,12 +17,12 @@ header:

    This header will include almost all the other headers (except the ones listed as extensions). However, you may not want to access all the functionalities of the library. So this page stands as a reminder for the -whole structure of the library. <boost/numeric/interval.hpp> -is the only header to be located directly under boost/numeric/; -all the other headers are located in the subdirectory -boost/numeric/interval/. And each time this documentation will -refer to interval/something.hpp, it is -<boost/numeric/interval/something.hpp>.

    +whole structure of the library. +<boost/numeric/interval.hpp> is the only header to be +located directly under boost/numeric; all the other headers are +located in the subdirectory boost/numeric/interval. And each +time this documentation will refer to interval/something.hpp, it +is <boost/numeric/interval/something.hpp>.

    Please also note that all the following headers are independent and can easily be pre-compiled if necessary (for compilers which support pre-compiled @@ -69,14 +69,19 @@ functions: in, in_zero, empty,

    This header defines fmod, square, sqrt and pow.

    +

    interval/arith3.hpp

    + +

    The third arithmetic header: it provides the functions add, +sub, mul, div. The type of their +arguments is the base number type.

    +

    interval/transc.hpp

    -

    It is the last of the three headers with mathematical functions; it -provides the following functions: cos, sin, -tan, acos, asin, atan, -cosh, sinh, tanh, acosh, -asinh, atanh, exp and -log.

    +

    It is the last of the headers with mathematical functions; it provides the +following functions: cos, sin, tan, +acos, asin, atan, cosh, +sinh, tanh, acosh, asinh, +atanh, exp and log.

    Policies

    @@ -125,6 +130,14 @@ are the arithmetic functions of the rounding policy.

    This header includes all the following headers. They provide some predefined comparison namespaces.

    +

    interval/compare/certain.hpp

    + +

    Here is compare::certain.

    + +

    interval/compare/possible.hpp

    + +

    And here is its friend compare::possible.

    +

    interval/compare/explicit.hpp

    The explicit comparison functions cerlt, posge, @@ -154,16 +167,27 @@ be replaced by a customized version.

    This header provides a comparison namespace compare::tribool especially adapted to a tristate boolean.

    +

    interval/ext/integer.hpp

    + +

    This header provides mixed operations between intervals and integers. It +is done by converting the integer to the base number type. Because this +comparison is not always correct (for a big int may not be +exactly convertible to float), this header is not automatically +included and the user should ensure that this behavior is compatible with +what she wants to do (if it is only to multiply some intervals by 2, it +probably is a good thing to include this header).

    +

    interval/ext/x86_fast_rounding_control.hpp

    This header defines a new rounding policy allowing to workaround the precision problem of the x86 processors (and so speeding up the computations). However, it only is a partial solution and it shouldn't be -used when there is a possibility of underflow.

    +used when there is a possibility of underflow or overflow.


    -

    Revised: 2003-01-21
    -Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002.
    -Polytechnic University.

    +

    Revised: 2003-04-22
    +Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002. +Polytechnic University.
    +Copyright (c) Guillaume Melquiond, 2003.

    diff --git a/doc/interval.htm b/doc/interval.htm index 6c20839..5477dfd 100644 --- a/doc/interval.htm +++ b/doc/interval.htm @@ -678,6 +678,8 @@ template <class T, class Traits> bool posne(const T& x, const interva /* comparison namespaces */ namespace compare { + namespace certain; + namespace possible; namespace lexicographic; namespace set; namespace tribool; @@ -768,7 +770,7 @@ fixed-precision bigfloat library types (MPFR, etc.)

    Policy design. Although it was tempting to make it a class template with only one template argument, the diversity of uses for an interval arithmetic practically forced us to use policies. The behavior of -this class can be fixed by three policies. These policies are packaged into a +this class can be fixed by two policies. These policies are packaged into a single policy class, rather than making interval with three template parameters. This is both for ease of use (the policy class can be picked by default) and for readability.

    @@ -806,8 +808,8 @@ singleton, there is no use to widen the interval). We decided to drop those functions.

    Specialization of std::less. Since the -operator < depends on the comparison namespace chosen locally -chosen by the user, it is not possible to correctly specialize +operator < depends on the comparison namespace locally chosen +by the user, it is not possible to correctly specialize std::less. So you have to explicitely provide such a class to all the algorithms and templates that could require it (for example, std::map).

    @@ -841,6 +843,15 @@ instead, the result should be correctly rounded to ensure the inclusion property. So we decided not to provide the conversion and leave it up to the user to do it himself or herself.

    +

    Mixed operations with integers. When using and reusing +template codes, it is common there are operations like 2*x. +However, the library does not provide them by default because the conversion +from int to the base number type is not always correct. So the +functions have been put in a separate header and the user need to include +them explicitely if she wants to benefit from these mixed operators Another +point, there is no mixed comparison operators due to the technical way they +are defined..

    +

    History and Acknowledgments

    This library was mostly inspired by previous work from Jens Maurer. Some @@ -860,9 +871,9 @@ order for this library to be written. Herv the documentation based on Guillaume's great starting point.


    -

    Revised: 2003-02-05
    -Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, -2002-2003.
    -Polytechnic University, 2002.

    +

    Revised: 2003-04-22
    +Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002. +Polytechnic University.
    +Copyright (c) Guillaume Melquiond, 2003.

    diff --git a/include/boost/numeric/interval/arith3.hpp b/include/boost/numeric/interval/arith3.hpp index 8841165..6fbf82f 100644 --- a/include/boost/numeric/interval/arith3.hpp +++ b/include/boost/numeric/interval/arith3.hpp @@ -17,7 +17,6 @@ #define BOOST_NUMERIC_INTERVAL_ARITH3_HPP #include -#include #include namespace boost { diff --git a/include/boost/numeric/interval/checking.hpp b/include/boost/numeric/interval/checking.hpp index 86cf69c..cb38363 100644 --- a/include/boost/numeric/interval/checking.hpp +++ b/include/boost/numeric/interval/checking.hpp @@ -120,7 +120,7 @@ struct checking_catch_nan: Checking template struct checking_strict: - checking_catch_nan > + checking_no_nan > {}; namespace detail { diff --git a/include/boost/numeric/interval/compare.hpp b/include/boost/numeric/interval/compare.hpp index b813e41..c18088c 100644 --- a/include/boost/numeric/interval/compare.hpp +++ b/include/boost/numeric/interval/compare.hpp @@ -16,6 +16,8 @@ #ifndef BOOST_NUMERIC_INTERVAL_COMPARE_HPP #define BOOST_NUMERIC_INTERVAL_COMPARE_HPP +#include +#include #include #include #include diff --git a/include/boost/numeric/interval/compare/certain.hpp b/include/boost/numeric/interval/compare/certain.hpp new file mode 100644 index 0000000..ceb03b0 --- /dev/null +++ b/include/boost/numeric/interval/compare/certain.hpp @@ -0,0 +1,119 @@ +/* Boost interval/compare/certain.hpp template implementation file + * + * Copyright Guillaume Melquiond 2003 + * Permission to use, copy, modify, sell, and distribute this software + * is hereby granted without fee provided that the above copyright notice + * appears in all copies and that both that copyright notice and this + * permission notice appear in supporting documentation, + * + * None of the above authors make any representation about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * $Id$ + */ + +#ifndef BOOST_NUMERIC_INTERVAL_COMPARE_CERTAIN_HPP +#define BOOST_NUMERIC_INTERVAL_COMPARE_CERTAIN_HPP + +#include +#include + +namespace boost { +namespace numeric { +namespace interval_lib { +namespace compare { +namespace certain { + +template inline +bool operator<(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() < y.lower(); +} + +template inline +bool operator<(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() < y; +} + +template inline +bool operator<=(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() <= y.lower(); +} + +template inline +bool operator<=(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() <= y; +} + +template inline +bool operator>(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() > y.upper(); +} + +template inline +bool operator>(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() > y; +} + +template inline +bool operator>=(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() >= y.upper(); +} + +template inline +bool operator>=(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() >= y; +} + +template inline +bool operator==(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() == y.lower() && x.lower() == y.upper(); +} + +template inline +bool operator==(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() == y && x.lower() == y; +} + +template inline +bool operator!=(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() < y.lower() || x.lower() > y.upper(); +} + +template inline +bool operator!=(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() < y || x.lower() > y; +} + +} // namespace certain +} // namespace compare +} // namespace interval_lib +} // namespace numeric +} // namespace boost + + +#endif // BOOST_NUMERIC_INTERVAL_COMPARE_CERTAIN_HPP diff --git a/include/boost/numeric/interval/compare/possible.hpp b/include/boost/numeric/interval/compare/possible.hpp new file mode 100644 index 0000000..cc81a70 --- /dev/null +++ b/include/boost/numeric/interval/compare/possible.hpp @@ -0,0 +1,119 @@ +/* Boost interval/compare/possible.hpp template implementation file + * + * Copyright Guillaume Melquiond 2003 + * Permission to use, copy, modify, sell, and distribute this software + * is hereby granted without fee provided that the above copyright notice + * appears in all copies and that both that copyright notice and this + * permission notice appear in supporting documentation, + * + * None of the above authors make any representation about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * $Id$ + */ + +#ifndef BOOST_NUMERIC_INTERVAL_COMPARE_POSSIBLE_HPP +#define BOOST_NUMERIC_INTERVAL_COMPARE_POSSIBLE_HPP + +#include +#include + +namespace boost { +namespace numeric { +namespace interval_lib { +namespace compare { +namespace possible { + +template inline +bool operator<(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() < y.upper(); +} + +template inline +bool operator<(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() < y; +} + +template inline +bool operator<=(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() <= y.upper(); +} + +template inline +bool operator<=(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() <= y; +} + +template inline +bool operator>(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() > y.lower(); +} + +template inline +bool operator>(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() > y; +} + +template inline +bool operator>=(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() >= y.lower(); +} + +template inline +bool operator>=(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.upper() >= y; +} + +template inline +bool operator==(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() <= y.upper() && x.upper() >= y.lower(); +} + +template inline +bool operator==(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() <= y && x.upper() >= y; +} + +template inline +bool operator!=(const interval& x, const interval& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() != y.upper() || x.upper() != y.lower(); +} + +template inline +bool operator!=(const interval& x, const T& y) +{ + if (detail::test_input(x, y)) throw comparison_error(); + return x.lower() != y || x.upper() != y; +} + +} // namespace possible +} // namespace compare +} // namespace interval_lib +} // namespace numeric +} // namespace boost + + +#endif // BOOST_NUMERIC_INTERVAL_COMPARE_POSSIBLE_HPP diff --git a/include/boost/numeric/interval/ext/integer.hpp b/include/boost/numeric/interval/ext/integer.hpp new file mode 100644 index 0000000..4a32668 --- /dev/null +++ b/include/boost/numeric/interval/ext/integer.hpp @@ -0,0 +1,76 @@ +/* Boost interval/ext/integer.hpp template implementation file + * + * Copyright Guillaume Melquiond 2003 + * Permission to use, copy, modify, sell, and distribute this software + * is hereby granted without fee provided that the above copyright notice + * appears in all copies and that both that copyright notice and this + * permission notice appear in supporting documentation. + * + * None of the above authors make any representation about the suitability + * of this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * $Id$ + */ + +#ifndef BOOST_NUMERIC_INTERVAL_EXT_INTEGER_HPP +#define BOOST_NUMERIC_INTERVAL_EXT_INTEGER_HPP + +#include +#include + +namespace boost { +namespace numeric { + +template inline +interval operator+ (const interval& x, int y) +{ + return x + static_cast(y); +} + +template inline +interval operator+ (int x, const interval& y) +{ + return static_cast(x) + y; +} + +template inline +interval operator- (const interval& x, int y) +{ + return x - static_cast(y); +} + +template inline +interval operator- (int x, const interval& y) +{ + return static_cast(x) - y; +} + +template inline +interval operator* (const interval& x, int y) +{ + return x * static_cast(y); +} + +template inline +interval operator* (int x, const interval& y) +{ + return static_cast(x) * y; +} + +template inline +interval operator/ (const interval& x, int y) +{ + return x / static_cast(y); +} + +template inline +interval operator/ (int x, const interval& y) +{ + return static_cast(x) / y; +} + +} // namespace numeric +} // namespace boost + +#endif // BOOST_NUMERIC_INTERVAL_EXT_INTEGER_HPP diff --git a/test/Jamfile b/test/Jamfile index d82f7f5..1247feb 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -14,6 +14,8 @@ DEPENDS all : test ; local SEARCH_SOURCE = $(BOOST_ROOT) $(SEARCH_SOURCE) ; test-suite "interval" : + [ compile libs/numeric/interval/test/integer.cpp ] + [ run libs/numeric/interval/test/add.cpp ] [ run libs/numeric/interval/test/det.cpp ] [ run libs/numeric/interval/test/fmod.cpp ] diff --git a/test/det.cpp b/test/det.cpp index 361f066..4397232 100644 --- a/test/det.cpp +++ b/test/det.cpp @@ -1,4 +1,4 @@ -/* Boost test/det.hpp +/* Boost test/det.cpp * test protected and unprotected rounding on an unstable determinant * * Copyright Guillaume Melquiond 2002-2003 diff --git a/test/integer.cpp b/test/integer.cpp new file mode 100644 index 0000000..42ee18b --- /dev/null +++ b/test/integer.cpp @@ -0,0 +1,26 @@ +/* Boost test/integer.cpp + * test int extension + * + * Copyright Guillaume Melquiond 2003 + * Permission to use, copy, modify, sell, and distribute this software + * is hereby granted without fee provided that the above copyright notice + * appears in all copies and that both that copyright notice and this + * permission notice appear in supporting documentation. + * + * None of the above authors make any representation about the suitability + * of this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * $Id$ + */ + +#include +#include + +typedef boost::numeric::interval I; + +int main() { + I x, y; + x = 4 - (2 * y + 1) / 3; + return 0; +} diff --git a/test/test_float.cpp b/test/test_float.cpp index 08b09fd..bebcc54 100644 --- a/test/test_float.cpp +++ b/test/test_float.cpp @@ -45,16 +45,16 @@ void test_binary() { I rII = F::f_II(a, b); I rIT1 = F::f_IT(a, bl), rIT2 = F::f_IT(a, bu); I rTI1 = F::f_TI(al, b), rTI2 = F::f_TI(au, b); - T rTT1 = F::f_TT(al, bl), rTT2 = F::f_TT(al, bu); - T rTT3 = F::f_TT(au, bl), rTT4 = F::f_TT(au, bu); - BOOST_REQUIRE(in(rTT1, rIT1)); - BOOST_REQUIRE(in(rTT3, rIT1)); - BOOST_REQUIRE(in(rTT2, rIT2)); - BOOST_REQUIRE(in(rTT4, rIT2)); - BOOST_REQUIRE(in(rTT1, rTI1)); - BOOST_REQUIRE(in(rTT2, rTI1)); - BOOST_REQUIRE(in(rTT3, rTI2)); - BOOST_REQUIRE(in(rTT4, rTI2)); + I rTT1 = F::f_TT(al, bl), rTT2 = F::f_TT(al, bu); + I rTT3 = F::f_TT(au, bl), rTT4 = F::f_TT(au, bu); + BOOST_REQUIRE(subset(rTT1, rIT1)); + BOOST_REQUIRE(subset(rTT3, rIT1)); + BOOST_REQUIRE(subset(rTT2, rIT2)); + BOOST_REQUIRE(subset(rTT4, rIT2)); + BOOST_REQUIRE(subset(rTT1, rTI1)); + BOOST_REQUIRE(subset(rTT2, rTI1)); + BOOST_REQUIRE(subset(rTT3, rTI2)); + BOOST_REQUIRE(subset(rTT4, rTI2)); BOOST_REQUIRE(subset(rIT1, rII)); BOOST_REQUIRE(subset(rIT2, rII)); BOOST_REQUIRE(subset(rTI1, rII)); @@ -72,34 +72,37 @@ void test_binary() { static bool validate(const I& a) { return val; } \ } +using std::abs; + new_unary_bunch(bunch_pos, +, true); new_unary_bunch(bunch_neg, -, true); -//new_unary_bunch(bunch_sqrt, sqrt, a.lower() >= 0.); -//new_unary_bunch(bunch_abs, abs, true); +new_unary_bunch(bunch_sqrt, sqrt, a.lower() >= 0.); +new_unary_bunch(bunch_abs, abs, true); template void test_all_unaries() { BOOST_CHECKPOINT("pos"); test_unary >(); BOOST_CHECKPOINT("neg"); test_unary >(); - // BOOST_CHECKPOINT("sqrt"); test_unary >(); - // BOOST_CHECKPOINT("abs"); test_unary >(); + BOOST_CHECKPOINT("sqrt"); test_unary >(); + BOOST_CHECKPOINT("abs"); test_unary >(); } #define new_binary_bunch(name, op, val) \ template \ - struct name { \ + struct bunch_##name { \ typedef boost::numeric::interval I; \ static I f_II(const I& a, const I& b) { return a op b; } \ static I f_IT(const I& a, const T& b) { return a op b; } \ static I f_TI(const T& a, const I& b) { return a op b; } \ - static T f_TT(const T& a, const T& b) { return a op b; } \ + static I f_TT(const T& a, const T& b) \ + { return boost::numeric::interval_lib::name(a,b); } \ static bool validate(const I& a, const I& b) { return val; } \ } -new_binary_bunch(bunch_add, +, true); -new_binary_bunch(bunch_sub, -, true); -new_binary_bunch(bunch_mul, *, true); -new_binary_bunch(bunch_div, /, !in_zero(b)); +new_binary_bunch(add, +, true); +new_binary_bunch(sub, -, true); +new_binary_bunch(mul, *, true); +new_binary_bunch(div, /, !in_zero(b)); template void test_all_binaries() { @@ -116,8 +119,8 @@ int test_main(int, char *[]) { BOOST_CHECKPOINT("double tests"); test_all_unaries(); test_all_binaries(); - BOOST_CHECKPOINT("long double tests"); - test_all_unaries(); - test_all_binaries(); + //BOOST_CHECKPOINT("long double tests"); + //test_all_unaries(); + //test_all_binaries(); return 0; }