Re: min / max and empty intervals (was: Friendly amendment to Motion 25)
> Subject: Re: min / max and empty intervals (was: Friendly amendment to Motion 25)
> From: John Pryce <j.d.pryce@xxxxxxxxxxxx>
> Date: Mon, 6 Jun 2011 21:06:32 +0100
> To: "stds-1788@xxxxxxxx" <stds-1788@xxxxxxxx>
>
> All
>
> . . .
> >>> From discussions I've witnessed between you and Nick, I gather
> >>> that in IEEE 754 the correctness of such a result is topic of a
> >>> longstanding debate. I'm not taking sides as it pertains to IEEE
> >>> 754. In regards to IEEE 1788, though, this would certainly lead to
> >>> failure of certain important interval algorithms. So just to be
> >>> clear: the description given in Motion 25 is really designed to
> >>> ensure the result of interval min and max is empty if at least one
> >>> operand is empty, just as it is for addition.
> >>
> >> I understand but disagree.
> >>
> >> Still, that might not be a problem. Given that it has
> >> no relation to the rest of your motion, may I suggest you
> >> remove references to min & max so that we may have this
> >> discussion at some later date & avoid needless conflict
> >> with the rest of your motion.
> >
> > I completely agree with Nate here. I think that min and max should
> > first be seen as functions over the real numbers (thus necessarily
> > 2-ary, at least with a fixed ariness).
>
> I agree with Nate too. This discussion seems to have introduced
> extraneous ideas such as treating NaN and Empty as on the same
> level as real point-values. Such ideas were removed by motions
> early in our work.
>
> There's no reason to object to max(x,y) and min(x,y) being ordinary
> point-functions of _real_ arguments and having interval extensions
> defined in the normal way as Nate and Vincent write.
>
> BTW Arnold points out they should allow any number of arguments, as
> in Fortran. I have included this in the current draft v03.2 out shortly.
>
> This is nothing to do with handling lists of intervals. It simply
> means max represents an (in principle infinite) family of functions
> max(x1,x2), max(x1,x2,x3), max(x1,x2,x3,x4), ...
> each being of fixed arity known at compile time. No big deal.
>
> John
Perhaps you consider this a question of arity then. Rather
than one of default value. I'm not sure.
Let me describe the thinking we went through in 754 on this
question & see if it can be applied to 1788.
The dyadic functions minNum, maxNum, et al are defined on
page 19 clause 5.3.1. Let me quote one:
sourceFormat maxNum(source,source)
maxNum(x,y) is the canonicalized number y if x < y,
x if y < x, the canonicalized number if one operand
is a number and the other a quiet NaN. Otherwise it
is either x or y, canonicalized (this means results
differ among implementations). When either x or y
is a signaling NaN, then the result is according to
6.2.
You can ignore the references to 'canonicalized' & 'signaling'
as they deal with issues that have no meaning for 1788.
The key is that the dyadic minNum & maxNum functions return
a number if at all possible. The thinking here was that the
variable arity functions min & max would be derived from these
dyadic functions in the following manner:
max(list) = if length(list) = 0 then return -infinity
else if length(list) = 1
then return maxNum(first(list),-infinity)
else return maxNum(first(list),max(rest(list))).
That is, any function of a list of things must have a value
when that list is empty. In the case of max, that value must
be -infinity if it is to be compatible with any later list that
comes along.
And why do this?
Well, the thinking here was that these functions are used to
select from among a list of things that which is largest. As
NaNs always fail the test NaN > number (because NaNs fail ALL
comparisons) the largest of a list of things should always be
a number if at all possible.
There is a practical reason for this. When one is choosing a
pivot element (using maxNumMag) for a gaussian elimination
from a column of a matrix that contains NaN elements, it is
much to be preferred that one pivot on a number rather than
filling the whole matrix with NaNs that need not be there.
You should know that this was not without controversy. There
were those that were in the "thou shalt be STRICTLY NaN
preserving" camp for reasons having to do with debugging where
the NaN came from in the first place. The feeling among them
was "let the NaNs fall where they may but do NOT hide them".
It is a reasonable argument. And its interval counterpart is
to be strictly empty preserving as is the case with things
like add & the like.
The counter argument is that, in the 21st century, problems
have become so large as to be intractable to human scrutiny for
debugging. Indeed, as far back as the 80s, code that produces
NaNs on some machines & not on others (& ALL thought to be
correct 754 implementations) has resisted debugging to this
day with MERELY 10^6 elements involved. Today's problems run
into the 10^9 range & beyond.
So even if we cannot "do no harm" it was felt that our best
strategy was to "do as little harm as possible" & return the
more meaningful answer rather than filling a matrix with
meaningless NaNs. The NaNs are still there. They just don't
infect the entire matrix.
So we pick the number when we can & return -infinity for max
when there are none to choose from.
What does this all mean for 1788?
John is correct when he says we need to define a (possibly
infinite) class of functions that look like:
max(x1,x2), max(x1,x2,x3), max(x1,x2,x3,x4), ...
More completely, the class starts with:
max(), max(x1), max(x1,x2), max(x1,x2,x3), ...
So what is the result of the niladic max()?
We cannot return the interval [-oo,-oo] as we have defined
that to be outside our set of intervals. I believe the only
sensible answer that remains to us is to return empty in this
case.
One can look at it in analogy to the point function case if
not in complete interval generalization to it.
The point function max returns the largest number if any are
to be found otherwise it returns -infinity as the number that
has the property that the dyadic maxNum(-infinity,x) is x for
all cases that x is a number.
Similarly, the interval function max needs to return the
'largest' interval if any are to be found otherwise it needs
to return empty on the grounds that empty has the property
that the dyadic max(empty,xx) is xx for all cases that xx is
an interval.
Always assuming, of course, that we DEFINE max(empty,xx) to
be xx.
This seems to me to be the 'do the least possible harm'
definition for 1788. It is not strictly empty perserving.
But that is not always the most meaningful thing to do.
What do you think?
Dan