Boost logo

Boost :

From: Gennadiy Rozental (gennadiy_at_[hidden])
Date: 2002-09-08 20:21:56


"Guillaume Melquiond" <gmelquio_at_[hidden]> wrote in message
news:Pine.GSO.4.21.0209090026220.7207-100000_at_brise...
> On Sun, 8 Sep 2002, Gennadiy Rozental wrote:
>
> > > > In general I think that your may struggle here because of the
problems
> > in
> > > > Rounding policy design (see my review): it's to big and unite in one
> > bottle
> > > > several implementation dependent but independent from user
prospective
> > > > policies. This one would be The ConvertionPolicy. And though it may
need
> > > > some staff from other rounding policies it still independent
decision.
> > Once
> > > > it become independent player it will more easy to work with it,
> > particularly
> > > > to change it.
> > >
> > > Why do you think they are independent? Is there a good reason a user
would
> > > like to use precise computations and unprecise conversions (or the
other
> > > way around)?
> >
> > Under "They" I meant rounding abstraction "levels". Do you?
> >
> > > And you say they are "implementation dependent". I would have said
they
> > > are implementation inter-dependent.
> >
> > No. Every rounding abstraction "level" only depends on lower level for
it's
> > implementation.
>
> So you seem to think there are more than one level?

No. It's you who seems to state that. Here is from docs:
"A lot of classes are provided. The classes are organized by level. At the
bottom is the class rounding_control. At the next level come
rounded_arith_exact, rounded_arith_std and rounded_arith_opp. Then there are
rounded_transc_dummy, rounded_transc_exact, rounded_transc_std and
rounded_transc_opp. And finally are save_state and save_state_nothing. Each
of these classes provide a set of members that are required by the classes
of the next level. For example, a rounded_transc_... class needs the members
of a rounded_arith_... class."

> Here is a part of the 'Rounding' policy for an interval type based on
MPFR:
> struct mpfr_rounded_math {
> mpfr_t add_down(const mpfr_t& x, const mpfr_t& y) {
> mpfr_t z;
> mpfr_add(&z, &x, &y, GMP_RNDD); // a function of MPFR
> return z;
> }
> };

And how mpfr_rounded_math is dependent on mpfr_t? What prevent you from
using template member functions and provide specialization for mprf_t? But
in fact there is more generic concern. See below?
> You think the part of the library responsible of the computations (the
> rounding policy) is not flexible enough. May I ask you what is the extent
> of your knowledge of interval arithmetic libraries, multi-precision
> arithmetic libraries and floating-point internals of various processors?

As I mentioned before I am not an expert in numeric computation but my
comments were based on my knowledge and experience in C++ language not a
specific domain. And they lay namely in generic domain. When I sad "is not
flexible enough" I meant namely "is not generic from C++ user stand point".
As an example let's try to answer following question:
What if I want to change only one function in rounded_arithmetic logic and
keep other existent levels implementation? rounded_math would not be of any
help here, while with simple change it could.
> > > > As I mention in my review I do not see the reason why Rounding
policies
> > depend on T as a template parameter. Once you exclude T problem
disappear by
> > itself. If policies defines conversions, intervals are convertible
either.
[...]
> I never said it was in the code. I just wanted to say that, in some cases,
> the lowest level of rounding (in the case there is more than one rounding
> level) needed to be type-dependent. And I was providing you the example of
> a processor where the rounding mode can be set to be precision-dependent.
>
> If you really want some code, just take a look at the file
> boost/interval/ext/x86_fast_rounding_control.hpp in the boost-sandbox
> cvs. The content and the usage of this file are not documented, but you
> will find some code that sets the FPU accordingly to the floating-point
> type used for computations.

Before I will proceed with reply I want to make one generic statement, based
in which we much more easily find a consensus. Here it is.
*********************************************************
IMO following rule/ recommendation is correct: Never use template parameter
in sole purpose of introducing specialization later on in design of generic
library.
*********************************************************
There could be an exclusions but it is good as a generic rule.

Once we agree on this everything become more clear. Let's apply it to you
current example. x86_fast_rounding_control.hpp introduce 3 specializations
for x86_fast_rounding_control template:

x86_fast_rounding_control<float>
x86_fast_rounding_control<double>
x86_fast_rounding_control<long double>

As far as I understand they are supposed to be (or may be if supposed to be
picked up automatically) used for explicit specialization of
interval<float>,interval<double>, and interval<long double>. But with the
same success you could have implemented x86_fast_rounding_control_for_float,
x86_fast_rounding_control_for_double,
x86_fast_rounding_control_for_long_double and use them in above
specializations.
 You yourself sad that only rounding_control level in "some cases" needs to
be specialized for some types. Once you make every level as independent
player you will be able introduce whatever class you want in its place
keeping all other decisions as default. The interface may look like this (if
we would use NTP):
typedef interval<float,
rounding_control_is<x86_fast_rounding_control_for_float> >
my_float_interval;

>
> Regards,
>
> Guillaume

Regards,

Gennadiy.


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