Example:
sage: E = EllipticCurve('37a')
sage: E_pari = E.pari_curve()
sage: om = E_pari.omega()[0]
sage: om
2.9934586462319596298320099794525081778
sage: om.precision()
19
sage: om.python()
2.99345864623195962983200997945250817779758379137013298534052337856325035698668290412039406739705147343584052710494728819414438723737202525437537667109326137530433325059652462521644730690726945107490578063656104457817258171351824279342631324889800869424380208704316693154446424015476558450847785954700795671977773461040730510763
sage: om.python().prec()
1088
sage: 1088 == (19-2)*64
True
The pari_curve object has been created with a *decimal* precision of
19 *decimal* digits, but the conversion back to python reals has
interpreted this as 19 *words*, which is 1088 bits.
This is behind #4064 and who knows what else...
John
---------- Forwarded message ----------
From: Bill Allombert <Bill.Al...@math.u-bordeaux1.fr>
Date: 2008/9/5
Subject: Re: precision() in pari
To: John Cremona <john.c...@gmail.com>
Cc: Karim Belabas <Karim....@math.u-bordeaux1.fr>
On Fri, Sep 05, 2008 at 03:13:44PM +0100, John Cremona wrote:
> Am I right in thinking that in the pari library, if x is a t_REAL,
> precision0(x) returns the decimal digit precision of x, just as the gp
> function precision (without the 0), while precision(x) returns the
> word length?
Yes! Actually there is the relation:
precision0(x)=(precision(x)-2)*log(2^32)/log(10)
(or 2^64 on a 64bit system)
Cheers,
Bill.
The pari library always and only measures precision in
number-of-codewords, and the prec parameter in pari library functions
always denotes this.
For the gp interface (to pari) decimal precisions are used, as they
are supposed to make more sense to humans (which they do).
Sage interfaces with *both* libpari and gp, in different places. When
it interfaces with libpari it needs to work with word lengths; for
example in a function like the elliptic curve function pari_curve(),
it makes no sense at all for the prec parameter of that function to be
in decimal in the belief that that is what the pari library wants.
It should be in bits, as in the rest of Sage, and that function can
convert it to word-precision before calling the pari library function.
It seems that #4064, which most of you ignored as it was about
elliptic curves ;) has some far-reaching consequences (since the pari
library is used all over the place). I think a new ticket is
therefore required (and I don't mind trying to take care of it). Or
am I making a mountain out of a molehill?
John
2008/9/5 John Cremona <john.c...@gmail.com>:
sage: pari(1.2345).precision() , pari('1.2345').precision()
(3, 4)
sage: pari(1.2345).python() , pari('1.2345').python()
(1.23449999999999993, 1.2345000000000000000000000000000000000)
sage: pari(1.2345).python().prec() , pari('1.2345').python().prec()
(64, 128)
not to mention this:
sage: pari((1.2345).str()).precision()
210
sage: pari((1.2345).str()).python().parent()
Real Field with 6656 bits of precision
-- that's right, you turn an honest 53-bit real to a string, it turns
into a pari real with precision 210 (words) which gets turned back
into 6656 bits (on 32 bits; for some reason on 64 bit machine it only
comes back with 128 bits precision).
-- and that's after I had become convinced that the mpfr -> pari real
conversion was done via strings!
Karim tells me that in the current (so-called) SVN version the
precision stuff is clearer and, more importantly, the documentation
for the whole of libpari is vastly better. I have not checked it out
yet. But that means that whatever we do now might have to change when
that unstable pari version becomes stable enough for Sage to adopt.
On the other hand, the current situation is so terrible that it just
has to be fixed properly. It would be better if more than one person
did it, perhaps? I don't think we can make this a blocker for 3.1.2
but surely it should be for 3.1.3?
John
2008/9/5 mabshoff <mabs...@googlemail.com>:
That may well be -- but there is a fundamental *mistake* in the way
precision in the pari library is handled in Sage. Internally pari
only uses word-precision (to convert to bits you subtract 2 and
multiply by 32 or 64), but the interface functions treat it as decimal
precision. It's only in pari's own gp interface that decimal
precision is used.
This totally explains this:
sage: pari.get_real_precision()
28
sage: E = EllipticCurve('37a1').pari_curve()
sage: E[14].python().prec()
256
The variable whose value is returned by pari.get_real_precision() is
the decimal precision which should only be used by the gp interface,
But the pari_curve function calls pari's ellinit0 function with (as
default) *this* number in its prec variable, while the prec variable
is expecting a word-precision value. So the ellinit uses 28 word
precision. Somehow that is changed to 10-word precision:
sage: [a.precision() for a in E]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10]
(the only floating point values are the ones at the end of the list)
and then the conversion back to python computes 32*(10-2)=256.
As you can see I have not quite traced everything through (where did
those 10s come from?).
Also, in a pevious posting in this thread I wrongly said that Sage
(mpfr) reals were converted to pari reals via strings; they are not.
In both directions the conversion is done properly using internal
formats. So once we get the precisions sorted out it will be perfect.
!
John
John
>
> Carl
>
> >
>
Yep, no doubt due to yours truly.
Excellent. I very very very much hope you will get this sorted out.
-- William
I am about to put up a patch at #4064 (I'm adding a couple more doctests). It
is not perfect (it does not have proper doctests for 64 bit machines since I
don't have access to one), but I hope we can make it work soon.
Basically, I spent two days reading the libs/pari code and despairing about
precision, and then I realized that it is actually mostly ok, but that we're
misusing it terribly from schemes/elliptic_curves. So I did my best to fix
this. Part of this was to make all sage functions on elliptic curves use real
precision in bits, with a default value of RealField.precision() (which
currently is 53 bits).
Here is the post-patch-behavior for the various things you ran into:
sage: E = EllipticCurve('37a1').pari_curve()
sage: E[14].python().prec()
64
[Explanation: pari_curve() uses the default value of 53 bits, which gets bumped
up to 64 (the nearest word on 32-bit machines) by pari. Then it gets sent back
to sage with a precision of 64 bits.]
sage: [a.precision() for a in E]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4]
[Explanation: the floats want default precision of 53 bits, pari bumps it up to
64 bits, which is 4 words = 2 for the float and 2 for the pari structure.]
sage: E = EllipticCurve('37a')
sage: E.period_lattice().basis(prec=30)[0].parent()
Real Field with 32 bits of precision
sage: E.period_lattice().basis(prec=100)[0].parent()
Real Field with 128 bits of precision
[Self-explanatory.]
Let me know what you think.
Alex
--
Alexandru Ghitza
Lecturer, Pure Mathematics
Department of Mathematics and Statistics
The University of Melbourne
Parkville, VIC, 3010
Australia
John
2008/9/5 William Stein <wst...@gmail.com>: