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

Re: text2interval again /



Thanks for your patience!




On 3/7/2013 12:51 AM, Arnold Neumaier wrote:
On 03/07/2013 02:03 AM, Richard Fateman wrote:
I am curious about your note because I agree with your final paragraph, but
dosagree with much of the earlier material!


On 3/6/2013 10:16 AM, Michel Hack wrote:
Richard Fateman wrote:
If you can serialize numbers, you can serialize intervals.
(arguably therefore you don't need text2interval)
On the contrary -- it means that you don't need nums2interval()!
Hardly the case, since nums2interval() would be need whenever the endpoints
are computed  as scalars rather than read in as literal constants.

This would not be enough as the error in a computed scalar can be arbitrarily large, depending on how it was computed.
If the error in a computed scalar can be arbitrarily large, then no such number whatsoever should be permitted as
an endpoint to an interval ever.   I can understand a system in which every number from birth to death is an interval, but is
this the system being proposed?  I  was assuming that the interval system interoperates with the host system essentially
by treating any number x in the host system as an interval with two exact endpoints [x,x].

If we treat a number x in the host system as  "any interval of unknown width that includes x"  then I suppose I should rethink my
objections, and probably get off the mailing list.

It would be enough only if it were known that the computation was just an optimally rounded conversion. But in this case it is better to do the two steps at once with a single call to text2interval (which even gives more accurate results in case the conversion was exact).
I think I understand this argument, and I have a more significant issue about language design later.

 but first I'd like to run through a perhaps tangential concern...
I think there may be a flaw in it, having to do with large numbers, or integers.

I think we agree that double_text2interval("[0.5,0.5]")  
could return an interval of zero width since 0.5 is an exactly represented number.

q=100000000000000000 can be represented exactly also in double,  (that's 10^17)
but not q+1.  It seems then that if q is used as both  endpoints, no rounding is required.
 But what about 100000000000000000.00000  which seems to require more bits,
but really does it??  Certainly 100000000000000000.1 requires up/down rounding,
but does adding zeros change the number? 

This is a slightly different issue than distinguishing between 0.5 and 0.50  both of which are
well represented in double-float.

  A more extreme version --- consider 2^1023 which is
89884656743115795386465259539451236680898848947
11532863671504057886633790275048156635423866120
37680105600569399356966788293948844072083112464
23715319737062188883946712432742638151109800623
04705972654147604250288441907534117123144073695
65552704136185816752553422931491199736229692398
58152417678164812112068608
also exactly representable as a double-float.  (it is about 8.99d307 )

what happens if we add .000  at the end of that, and it causes us to
round down and up.  The endpoints of the original zero-width interval
would be known to about 307 decimal places, but the endpoints of
the widened interval would be known to about 16 decimal places.

Perhaps this is all nonsense though, and/or has been discussed
and dismissed.  I recall, but cannot spot some discussion of 0.5 vs 0.50.



Your recipe also loses accuracy when the first rounding was without error. For example when processing 1.0 with your procedure it would produce [0.9999999999999,1.000000000001]
My  proposal regarding nums2 interval is that nums2interval(1.0d0, 1.0d0) produce exactly
[1.000000...0, 1.0000000000...0.].  that is, inf=sup= the number that is the argument to
nums2interval.


rather than the wanted result [1.0000000000000,1.0000000000000] produced by text2interval.
In addition to producing an inferior result, it is more complicated to write in a program and is error prone (as an inexperienced user may forget the second step).
I do not see it as more complicated, but merely relating to "facts on the ground" in a computer..
that 1.0 is the number 1.0 not   0.9999....
and that  (in binary)
  0.1  is slightly different from 1/10.

In any case, starting from [1,1] and dividing by 10.0d0, I get the following (from using a lisp
system that allows setting of IEEE rounding modes),   two different  results which (to specify
precisely ) I write in ratios:
rounding downward  7205759403792793/72057594037927936
rounding upward      3602879701896397/36028797018963968
rounding nearest      3602879701896397/36028797018963968  naturally one of the two above ...

The difference in value between the two round modes is 1/2^56 which looks like one ULP.
This looks like an optimal enclosure to me.

the number 1/10 is between these two values, about 5.55d-18 from one and about 8.33d-18 from the other.




As mentioned many times already, interval bounds have to be derived
using appropriate rounding directions, so when a literal is used to
derive an interval endpoint, the literal has to be interpreted in
the appropriate context.
OK, I think this is where I disagree.  The result of OPERATIONS like +
and *
require attention to rounding directions.  When a literal is used to
initialize
a value, and that value is used as an endpoint, why not use that value?

The value is determined by the mathematical problem posed, which is usually in text format.
I really don't see this the same way you do. There are applications in which some physical
problem starts with some uncertainty.  A scientist will not know the uncertainly exactly and
so will add some "slop" to it.  There should be no need to add an epsilonic extra slop.
I think the IEEE community understands this.  A program may be written to determine
if some critical value is reached by a sequence of calculations starting with one or more
intervals.  For example, the question might be:  Is z:= f(x_interval)  always less than y.
One answer might be:   if sup(z) < y,  you are safe.   If sup(z)> y, you might not be safe,
but we can't tell for sure because maybe a tighter calculation of f(x_interval) is possible.
If inf(z)>y then you are certainly in danger, because ANY value of x  makes f(x) exceed
the critical value.

But now you are saying that if z is the result of a machine computation, or even if it
is a literal number like 0.1 entered into the program as a constant outside of an interval,
then the comparison simply cannot be made because the mathematical problem is
not posed in a text form.   Yes, one could enter y  as    y:=text2interval("[0.1,0.1]")
and then instead of asking if  sup(z)<y,  one can ask whether the intersection of y and z
is empty or not.  Is it the intention for the standard to push all computations into such a
form?   I note that there is no required function that answers the question "is this scalar
in the interior of this interval", so maybe that is the plan.   I think that from an
engineering perspective this is unattractive, and that an interval_member(e,X) predicate
would be very handy.  It could be constructed by  interval_member(e,x):== Interior(nums2interval(e,e),x)
but that might not be quite right if nums2interval inflates the enclosure.

Some applications presumably do not have an engineering basis.


There are problems that come from pure mathematics. 
It seems to me that a mathematician approaching
a computer should understand how numbers are represented in a computer, and how
to construct, using integers, etc.  any exact numbers he or she needs
to be represented in the computer.

An improperly rounded conversion changes the mathematical problem.
  It is certainly the case that a mathematician could be disappointed by
some expectation that differed from reality.  I would not call that an improperly
rounded conversion.  Being ungenerous toward the mathematician, I would
call that "user error".  Attempting to be generous toward the mathematician,
I would call it "poor design of user interface"  which could be either
the programming language or possibly the interval package.


If we want to prove the theorem that x in [0.1,0.2] implies f(x) in [result], we need to be sure that the computer does not prove
    x in [0.10000000000001,0.199999999999999] implies
                                              f(x) in [approx_result]
(which is useless as it might be that f(0.1) \not in [approx_result]).
Instead we want it to prove
    x in [0.0,9999999999999,0.2]0000000000001 implies
                                            f(x) in [enclosed_result]
which guarantees x in [0.1,0.2] implies f(x) in [enclosed_result]
So far I entirely agree. (modulo typo).  Of course it might be false, whereas the
theorem that x in [1/10,2/10]  implies f(x) in [result],

or there may be another theorem   (and it can certainly happen if one is
trying to prove theorems concerned with representation of floating point number!)
that  x  is the interval from [3602879701896397/36028797018963968,
3602879701896397/18014398509481984] exactly.  (that's IEEE754-speak for
the two numbers 0.1d0 and 0.2d0)  and so from that perspective you
and I have different theorems to prove.  They may both be true, both be false,
or one of each.  Is one of the theorems the right theorem?



This is the main reason why an outward rounding text2interval routine is needed.

If the mathematician was so inclined to prove something about x in [1/10, 2/10] 
with a computer, then he (or she) should
first make sure that [0.1,0.2]  meant the same as [1/10,2/10].
Are we going to protect the mathematician from all possible representation-related
issues in the scalar world outside intervals?

I suspect that the mathematician, at least in the world of proof-by-computer
will have to be aware of the gap between most-positive-double-float and
infinity,  Or between  double-float epsilon and zero.  This is not to say the
interval calculations per se would fail TFIA  but
it does get tedious to replace in every statement in a programming language that
involves a numeric constant, say 3.0  by its equivalent  double_text2inteval("[3.0d0,3.0d0]").

  I think that as a user interface issue, this is a bad design if the user must make
that substitution.  you could argue that the programming language should make
that substitution.  (Indeed this is easiest enough to do by macroexpansion in Lisp,
but I think would be difficult in most other languages).  It is perhaps a valid
but ultimately troubling contention that it is not a design problem
 in the interval standard but a failure of every programming language
to not provide a mechanism to implicitly wrap every floating-point constant literal in a "text2interval".

However, I may just be prejudiced by the fact that the programming language
I am using  is perfectly happy with exact constants like 1/10.

It does seem hazardous to have the string "0.1" mean two different things in
a programming language statement like x:= 0.1-double_text2interval("[0.1,0.1]").
 In particular, note that your interpretation of text2interval gives a value for x of
 [-1.387778780781446d-17,4.163336342344338d-17]

but my equivalent, namely  0.1-interval(0.1,0.1) gives the substantially tighter

[0,  1.387778780781446d-17]




  This context is lost if the literal is
first converted to a number, and then used later to construct an
interval.
The context for the literal is "This number has previousl been computed or
  read in by the normal input routine
for the programming language".  It ceases to have meaning as 0.1 or 0.3
and now
only has meaning  3FB999999999999A  or 3FD3333333333333 and is devoid of
history or rounding mode.

Precisely this is the problem. The semantics changes when going from text to float, and this must be avoided if we want to solve a problem which is defined by the semantics of the underlying text.
It seems to me that if the mathematical semantics is to be determined by exactly the text and in particular not affected by the underlying representation,  then there must be no way by calculation for the programmer to determine any aspect of the underlying floating point
representation.  That is, no calculation using intervals should be able to figure out the number of bits in the fraction of the format, and the maximum and minimum exponent, and the radix.  Am I overstating the case?  



text2interval ensures that the floating-point computations in an interval context will not change the meaning of the originally posed problem in spite of the change in semantics for the underlying floating point processing.
This seems to suggest that I am not overstating the case .. but then
 there is no reason to support double_float because the meaning  would be the same in single_float.  While both
presumably would support TFIA., I think that the meaning (i.e. the RESULT in terms of size of enclosure) would change.

My apologies for being argumentative, but I think there really is a different viewpoint, perhaps one could call it
an engineering viewpoint or perhaps computer-architecture viewpoint, worth considering.

 In part, I think a more engineering approach could
substantially simplify the description of the standard and make
 it possible to produce a reference implementation
that is substantially more complete with respect to that standard,
as well as transportable to a variety of host systems.
I also think it would be more appealing to the IEEE.

Thanks again for the explanations.  I hope I am contributing at least
a small amount of light here.

In the meantime I'll go back to my programming of tight upper and lower bounds on log, exp, sin, pi.



Richard Fateman