Boost logo

Boost :

From: Guillaume Melquiond (gmelquio_at_[hidden])
Date: 2003-04-15 07:32:36


On Mon, 14 Apr 2003, Paul A. Bristow wrote:

> > All these results are deduced from the inclusion property, which is
> > already in the documentation. Maybe some more examples of this property
> > should be added.
>
> But I doubt if I am alone in this sad state :-) So Yes.

It will be done, but not this week unfortunately.

> > Expressions like T mean/integer count failed when T was an interval type.
> > I half_x = x/2; // fails
>
> > In order for the user to access integer functions, I can add this
> > kind of code:
> >
> > template<class T, class Policies>
> > interval<T, Policies> operator* (int x, interval<T, Policies> y) {
> > return static_cast<T>(x) * y;
> > }
> >
> > It will solve the issue. But it may induce some strange behavior when int
> > is not exactly convertible to T. For example, x is not always equal to
> > float(x) (for some big integers).
>
> I think users using the library to handle measurement or computational
> uncertainty will decide the utility is worth the risk. For more mathematical
> uses, it may not be. So
>
> > to put these helper functions in a separate header that would not be included
> by default sounds a sensible compromise.

Good.

> > The display of intervals is something we didn't want to do. It's up to the
> > user to define its own display. The header interval/io.hpp is merely
> > provided as a debug facilities (it isn't included by default).
>
> Some warnings/examples would help the naive user.

Maybe the best solution would be to simply remove interval/io.hpp from the
library since it seems to induce more problems than it solves. And to add
a bit of documentation to explain the situation.

> > So you are free to do whatever you want for the display of intervals, it's
> > outside the scope of the library.
>
> OK, I understand the limitations. For handling measurements, the ideal is to
> use the interval 'width' to chose the right precision (number of significant
> digits). I have found this gives a great improvement in clarity of display (in
> other programs) and may be able to offer an alternative to your simple
> interval/io.hpp.
>
> > x1 = exp(x); // fails - exp_up and exp_down not a member ...
>
> > So it isn't enough to only compute [exp(lower),exp(upper)], the
> > function needs to compute [exp_down(lower),exp_up(upper)] in order for the
> > result to correctly contain all possible results.
> > The user needs to rely on an external mathematical library
> > which provides them. And it's the reason why the library doesn't do
> > anything by default.
>
> > I will try to add an example which uses an external library.
>
> Thanks. exp and log are likely to most useful because some math library
> implementations introduce more than a few eps of computation 'error'.

I have added a file examples/transc.cpp which shows how to complete the
rounding policy in order to get an interval<double> class that provides
the transcendental functions. The example relies on the MPFR subset of GMP
to do the floating-point computations.

> Do I understand correctly that it is deliberate that (if cout.precision(17))
>
> I x = 2.; // exactly representable as 2.00000000000000000
> outputs:
> [1.9999999999999993, 2.0000000000000004]
>
> despite
> 2. is singleton true
>
> [3.9999999999999991,4]
> square(x) is singleton true
>
> [1.9999999999999993,2.0000000000000004]
> sqrt(square(-2.)) is singleton true
> [3.9999999999999991,4]
>
> Thus there is a ulp or eps/2 widening, even of a singleton.

Yes, it's what interval/io.hpp does. The reason is that, even for a
singleton, depending on the output precision some information may be
lost. For example, let's consider the double x = 1 + 2**(-53) (the
floating-point succesor of 1 in fact). If you now try to display the
interval [x,x] (it's a singleton) with the real bounds, you need
something like precision(53) for the bounds to be correctly displayed. If
the precision is less then you will get [1,1], which does not even contain
the interval [x,x].

It's the reason why interval/io.hpp widen the interval depending on the
precision. By doing that, we are sure the displayed version contains the
initial interval. For the previous example, the answer will be something
like [0.999999,1.000002] (I didn't try). This answer is not a singleton
but at least it contains [x,x], and so it is a better answer than [1,1]
(or [1] if it uses your notation) in our opinion.

So, as I said before, maybe it's better to just remove io.hpp.

> If one wanted to show singletons explicitly, I presume I could test and only
> output one central value?

Why not. But as I explained, the answer will not be mathematically
satisfying since the result will be biased. So it's really up to the user
to define its own display methods depending on the expected results.

> > This code:
> > using boost::numeric::interval_lib::pi;
> > I a = pi<I>();
> > works with GCC and Intel CC.,
> but MSVC 7.0 says:
>
> typedef boost::numeric::interval<double> I;
> using boost::numeric::interval_lib::pi;
> a = pi<I>();
>
> testInterval.cpp(65) : error C2275: 'I' : illegal use of this type as an
> expression
> testInterval.cpp(59) : see declaration of 'I'
> testInterval.cpp(65) : error C2059: syntax error : ')'
>
> but
>
> I pi_d = boost::numeric::interval_lib::pi< boost::numeric::interval<double> >();
> I pi_d1 = boost::numeric::interval_lib::pi<I>();
>
> are OK,
>
> so am I in bad company in my (lack of) understanding of C++ :-(

If MSVC complains on the first three lines, there is a problem with the
compiler.

Guillaume


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk