Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

Re: Edge case conversions, exceptions to IEEE FPA



On (Thu, 13 Nov 2008 23:07:19 -0100) Siegfried Rump wrote:
> Let me make it clear again, my only question (and this seems to be the
> only point of disagreement, is the following:
>
> Given the interval constructor "intval" mapping floats into intervals
> and the call
>     y = intval(x),
> what is the interval result y for input x=inf?
>
> I see three possibilities for the user's program to produce this situation:
>
> 1)  y = intval(inf)         the input argument is true infinity
> 2)  y = intval(1e400)       a constant causing overflow
> 3)  y = intval(expression)  an expression with result inf.


Ok, now we've indeed isolated the main point of contention -- but not
quite.  I think Siegfried left out a fourth case, which is in fact the
one I've been most concerned with:

  4)  y = intval(variable)    a floating-point variable with value Inf

The subtle difference with 1-3 is that, in an IA-aware language, 1-3 have
all relevant information available locally.

For (1), the explicit Inf is not a member of any interval (in the model
with non-extended Reals, which we are discussing here, I hope we all
agree), so y = Empty is the correct result.

For (2), we clearly have a finite number that is too large, so y = Tail
is the correct result.  ("Tail" is my name for [realmax,Inf].)

For (3), the implementation can clear IEEE flags, evaluate the expression,
then check the flags when the result is Inf.  If DivideByZero is set, we
left the domain of non-extended Reals, and Empty is an appropriate result.
If DZ is clear but Overflow is set, we have a totally unknown finite value,
so Entire would be the correct result, as I suggested earlier.  However,
if neither flag is set, the Inf must have come from a variable used in the
expression, and we must treat it like case (4).

So case (4) is the only interesting case.  The language processor has
essentially no idea what the source of the infinity is, and so the proper
(i.e. safe) course of action is to use Empty, the worst-case assumption.
That is, unless the *programmer* knows the context, and has the means to
tell this to the language processor.

Earlier I had suggested that intval() itself check the flags and decide
between Empty and Tail, but I can see myself that this is not the right
way to proceed.

Arnold may however given given us a way out.  In his latest 1788.proposal,
now up to version 2.3, and perhaps still circulating only privately while a
subset of us are tossing corrections and suggestions back and forth, there
is a realHull(x,x) operation that converts Inf to Tail, while Interval(x)
converts it to Empty.  (Both convert finite x to the singleton [x,x].)

What we don't have is a function that converts Inf to Entire -- but I'm
not quite sure what the point of that would be.  Perhaps it would deal
with cases where x=Inf can happen in that place only when the rest of the
computation does not depend on x anymore.  That situation should be rare
enough that coding
  if (abs(x) == Inf)  y = Entire;  else y = interval(x);
should be acceptable.  (Defensive coding like this could of course handle
the other cases too, but generally we want to avoid conditionals.)

> > In the computation  (realmax/2)*3 - (realmax) the multiplication
> > triggers overflow and returns Inf.  The subtraction that follows
> > then propagates that Inf quietly.  If this computation is actually
> > carried out in separate steps, with other things in-between, the
> > overflow indication could have been cleared before the subtraction
> > is reached, and at that point no further flags or exceptions would
> > result from the subtraction: the Inf propagates quietly.  In the
> > absence of overflow (e.g. in a wider format, but using the realmax
> > of the narrower format as an ordinary float) the result would of
> > course have been -realmax/2 (again referring to the smaller realmax).
>
> Yes, but Arnold's "empty" is as mathematically incorrect as my "Tail".
> But again, it is an expression.  Accidentally the result realmax/2 is
> a float, I guess Michel constructed it that way; I think this is not
> typical.

I explicitly described it as a diffuse piece of a program and NOT as a
compact expression that is visible to the compiler all at once.  Also,
Siegfried left out my description of situations where this IS possible,
if not typical:  code written for reduction operations where the wider
intermediate precision is not wide enough, or badly-implemented register
spill when the computation was expected to be carried out in extended
precision registers.  Another example occurs in some multiplicative
series evaluations, where there is a long sequence of multiplications
and divisions that balance out in the end, but can lead to overflow in
the middle if the sequence is computed in an unfortunate order.

> But for x=1/0 ... a long computation clearing flags ... y=intval(x)
> the result "Entire" would be incorrect as well.  Again, these are
> expressions which can't be treated satisfactorily anyway.


Right -- and I never seriously suggested that intval(Inf) should return
Entire.  In this case, the DZ flag would have been set, and that is a
clear indication that something is outside the model, so Empty would be
the appropriate result.

By now it should be clear to everybody that there is no single correct
way to convert an anonymous Inf to an interval, so the IA environment
must provide the means for the programmer (who may know) to choose, and
in the absence of any knowledge, Empty is the only sensible choice for
the "ordinary" conversion function, intval(x) (called interval(x) in
Arnold's 1788.proposal).

Perhaps Siegfried can make a case that intval(x) should be the one that
converts Inf to Tail, and propose a different function that returns Empty,
or perhaps intval(x,m) should have a second "mode" argument that does the
selection -- but then one still has to define implicit conversions.

Sorry, but at this point I still prefer Arnold's approch, though I welcome
the arrival of the realHull() function.

Michel.
Sent: 2008-11-14 04:55:41 UTC