Karim Belabas on Sat, 27 Sep 2014 15:44:19 +0200

 Re: [PATCH] enable basic arithmetic with infinity

Hi Jeroen,

* Jeroen Demeyer [2014-09-23 17:03]:
> On 2014-09-23 16:03, Bill Allombert wrote:
> >Purposefully, we restricted the semantic attached to oo.
> >Most of the time such operations are the symptom of a bug.
> The usage quoted before [if (lambda > 2*valuation(x,p),...)] is not a bug,
> in fact it expresses something very natural and it would be a pity to force
> people to write
>
> if (x!=0 && lambda > 2*valuation(x,p),...)
>
> Why would you introduce t_INFINITY in the first place if you don't allow
> this? Surely, the philosophy of introducing t_INFINITY was to make code
> easier and less prone to errors.

It was originally meant as a special marker to use +/- oo as interval
bounds, for polsturm or numeric integration.

Then, after some hesitations, extended for degree and valuation, but
again meant as a special marker. I never wanted to go into a partial
implementation of \bar{R}-arithmetic. E.g. why allow 2 + oo but not
2^-oo ? 2^poldegree(T) is a sensible construction.

Lots of function to inspect and instrument, possibly elegant, but for
limited actual use-case...

> Now, on the contrary, you're making code more difficult.
>
> If you really think that people should write
>
> if (x!=0 && lambda > 2*valuation(x,p),...)

<aside>

In that particular case, x == 0 should be catered for earlier
(as it is in the C version, hidden in buch4.c and currently not
exported, unfortunately). The original code (lemma[67]{nf} in buch4.c)
is full of clever hacks allowing to use regular constructions
independent of special cases. But treating them specially actually
simplifies the code by making it clearer, if (arguably) less elegant.

N.B. The following works
if (lambda/2 > valuation(x,p),...)

</aside>

> then why not raise an error for valuation(0,p)?

I agree.

Unfortunately, I made the mistake of allowing valuation(0) a long time
ago (circa 1995). And poldegree(0) has been allowed since the dawn of
time (circa 1985). Thus lots of scripts depend on this behaviour.

> I think that's better than returning a useless t_INFINITY.

The new behaviour is IMHO saner than the old one (return a big integer,
either 2^63-1 or 2^32-1 depending on the architecture). And it avoids
breaking simple scripts. (It does break hackish code, granted.)

I introduced a new type t_INFINITY instead of (ab)using a t_REAL, say,
so that, by default, functions would do the right thing: raise a type error.

I really don't want to instrument essentially all numerical functions to
make sense of infinities-as-actual-numbers, including beasts such as
a+I*oo which make perfect sense for complex integrals. A related
former TODO item was to introduce IEEE754 special values as t_REALs
(infinities, signed 0s, NaN, etc.): I decided against it a long time ago.

I can revert the change letting poldegree() and valuation() return
t_INFINITYs. But, given the above, I don't see how to reach a situation
that would both be saner than the current one, and avoid breaking too
many scripts.

Denis's script is the only one I'm aware of that was broken by the change,
and there are various simple ways to fix it [ the easiest would be for
us to export the C function and replace the function call: been in the
TODO list for some time ].

I understand your point that a minor extension (= allow simple kinds of
add/sub/mul) is easy, unlikely to do any harm and possibly "useful", but
I prefer sticking to a clear infinity-is-not-a-number rule.

Cheers,

K.B.
--
Karim Belabas, IMB (UMR 5251)  Tel: (+33) (0)5 40 00 26 17
Universite de Bordeaux         Fax: (+33) (0)5 40 00 69 50
351, cours de la Liberation    http://www.math.u-bordeaux1.fr/~kbelabas/
F-33405 Talence (France)       http://pari.math.u-bordeaux1.fr/  [PARI/GP]

`