octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: imag () function detail regarding -0.0000


From: Daniel J Sebald
Subject: Re: imag () function detail regarding -0.0000
Date: Wed, 12 Sep 2012 14:11:53 -0500
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111108 Fedora/3.1.16-1.fc14 Thunderbird/3.1.16

On 09/12/2012 02:51 AM, John W. Eaton wrote:
On 11-Sep-2012, Daniel J Sebald wrote:

| Well, not in this case, no, unless one wants to think of rounding to
| zero from the negative direction.  But I prefer the single additive
| identity rule of a field in the case of computations.
|
| I would think the CPU naturally doesn't use -0 for multiplies if it is
| following some standard, unless there is some configuration (compile
| option?) saying to maintain sign through multiplication by zero.  I'm
| guessing Octave is implementing the rule.

I don't think we should change Octave so that the '-' is not
displayed, and I would definitely be against checking for and dropping
the sign of zero every time we do some computation.  If -0 can be
generated, it should be displayed.  Consider things like

   1/(1/-Inf)

if you drop the - from (1/-Inf) == -0, this expression would result in
Inf -- how does that make sense?  If you decide to not display it (as
Matlab does) then things become somewhat confusing if you break the
expression into parts and evaluate them separately: x = 1/-Inf
produces -0 but it is displayed as 0, so you think, OK, I have 0.
Then you use that result in the expression 1/x and you get -Inf.
What?

I think there is utility to + and - 0. That's why I said it complicates matters because then -0 has to be displayed whenever it appears. So, to address, say the example

octave:28> [1 -1 -0]' * i
ans =

   0 + 1i
  -0 - 1i
  -0 - 0i

would require a change to the arithmetic rules, not merely dropping the minus sign in front of the zero when displaying.

...

I'm going to ruminate here a bit and leave the matter open...

There are the machine rules for extended number arithmetic, 1/Inf = 0, 1/-Inf = 0, 1/0 = Inf, 1/-0 = -Inf, but these are slightly different than the rules of the extended real number "field".

In the extended number system there is 1/Inf = 0 and 1/-Inf = 0, i.e., just one additive identity, 0. 1/+-0 is undefined. It's because Inf and -Inf represent the concept of limit, and any function that tends to unboundedness whether it be on the positive or negative side of the real line has an inverse which does in fact tend to 0 in a legitimate way. However, a function that tends to zero but alternates between positive and negative does not have an inverse that properly diverge to Inf or -Inf.

[One might argue I'm comparing apples and oranges, real numbers and floating point. But Kahan appears to do this as well when making statements like this (the ¥ symbol is infinity symbol in the paper): "For example, expressions 0/0, ¥/¥, ¥-¥ and ¥*0 are distinguished because, to produce anything of more use than a NaN, they require different versions of l'Hospital's rule for the removal of removable singularities." l'Hospital's rule is a purely real number concept. Finite precision number systems can't converge in the proper sense.]

Given that, I would say that

1/-Inf = -0
1/Inf = 0

are OK results and carry some meaningful information. One can think of 1/-Inf as approaching 0 from the left, and 1/Inf as approaching 0 from the right.

The following make *plausible* candidates for NaN:

1/0        (Octave calls this Inf)
1/-0       (Octave calls this -Inf)
1/(1/-Inf) (Octave calls this -Inf)
1/(1/Inf)  (Octave calls this Inf)
Inf - Inf  (Octave does call this NaN)
Inf / Inf  (Octave does call this NaN)
0 * -0     (Octave calls this -0)

These are up in the air:

0 * Inf (Octave calls this NaN, but measure theorists invoke the rule of fields saying 0 * a = 0 for any a, so would call this 0.)
0 * -Inf   (Same deal, some but not all think of this as 0.)
-0 * Inf (Octave calls this NaN, and that is probably correct because it represents (1/-Inf)*Inf which depends on the way things converge.)
-0 * -Inf  (Same deal.)

...

Now, as for the occurrence of -0 as the result of *multiplication*, that's a different matter. Consider the simple example:

octave:32> 0 * -1
ans = -0

That may be a valid IEEE 754 definition, but that's a violation of the field rule for the normal (and extended) real number system. 0 * a = 0 for all a in the field. Sure, one could think of this as 1/Inf * -1 or -1/Inf, but honestly the real number system sort of takes precedence over the extended real number system for me. So, I guess I'd prefer to see 0 * -1 = 0. Kahan doesn't discuss this 0 * -1 = -0 behavior anywhere in the paper (everything but).

Should anyone introduce in Octave -0 either explicitly or implicitly with 1/-Inf then I think that should hang around. In other words, whenever a -0 shows up in the results we know it was the result of something unusual.

If there is any change to try it would be:

1) 0 * a = 0 for all a except a = -0, NaN, -NaN, (possibly Inf, -Inf)
2) 0 * -0 = NaN  (Or, leave it as 0 * -0 = -0)
3) 1/0 = NaN
4) 1/-0 = NaN  (Or, possibly -NaN if such a thing exists)

My point is that normal field theory rules take precedent for me, and that -0 should be used sparingly for instances where it makes sense to have it.

...

Is there a reason to stick to IEEE 754 floating point math, at least in Octave? Kahan doesn't make a real compelling case. The section of "Digression on Division-by-Zero" gives some examples, and they are quite interesting. The eigenvalue problem, fairly commonly used, can avoid a test for division by zero and thereby become 25% more efficient. BUT, we're talking C-program (i.e., a library function) and not Octave. If one were to program the eigenvalue solver in Octave m-script there would be losses due to interpreting that far surpass a 25% loss due to a division-by-zero check.

...

So, I'm still open to IEEE 754 behavior. But when it comes to a couple basic questions, the answers aren't real satisfying. Is it important that Octave have 0 * -1 = -0? Is -0 conveying some information? If the answer is "no", then a followup is, Why display -0 then? If the answer is "yes", then the followup is, Shouldn't narrowing be disallowed because that information can be lost:

octave:20> z = complex([1 -0 -1],[-0 0 -0])
z =

   1 - 0i  -0 + 0i  -1 - 0i

octave:21> z*1
ans =

   1  -0  -1

...

So, Octave appears to be fairly adherent to the IEEE 754 standard. I can get used to having the -0 floating about, but it is kind of annoying in arithmetic operations seeing this as I really only think of +/-0 related to convergence.

If there is any shortcoming, it might be IEEE 754 for not introducing a third zero, i.e.,, m0 = 0 = p0 whereby

1/-Inf = m0
1/Inf = p0
0 * a = 0
m0 * a = m0, a>0
m0 * a = p0, a<0
p0 * a = p0, a>0
p0 * a = m0, a<0

Dan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]