From 988c1f8870435bac8fb097e4d6a8aad62f84d19e Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 5 Mar 2014 13:12:16 +0100 Subject: [PATCH 1/3] Improve conversion of complex numbers to PARI --- src/sage/rings/complex_double.pyx | 15 +++++++++++---- src/sage/rings/complex_number.pyx | 12 +++++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 3ca3ca1811b..5dc88b8d77a 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -1054,14 +1054,19 @@ cdef class ComplexDoubleElement(FieldElement): cdef GEN _gen(self): cdef GEN y - y = cgetg(3, t_COMPLEX) # allocate space for a complex number - set_gel(y, 1, pari.double_to_GEN(self._complex.dat[0])) - set_gel(y, 2, pari.double_to_GEN(self._complex.dat[1])) + if self._complex.dat[1] == 0: + # Return t_REAL + y = pari.double_to_GEN(self._complex.dat[0]) + else: + # Return t_COMPLEX + y = cgetg(3, t_COMPLEX) + set_gel(y, 1, pari.double_to_GEN(self._complex.dat[0])) + set_gel(y, 2, pari.double_to_GEN(self._complex.dat[1])) return y def _pari_(self): """ - Return PARI version of ``self``. + Return PARI version of ``self``, as ``t_COMPLEX`` or ``t_REAL``. EXAMPLES:: @@ -1069,6 +1074,8 @@ cdef class ComplexDoubleElement(FieldElement): 1.00000000000000 + 2.00000000000000*I sage: pari(CDF(1,2)) 1.00000000000000 + 2.00000000000000*I + sage: pari(CDF(2.0)) + 2.00000000000000 """ pari_catch_sig_on() return pari.new_gen(self._gen()) diff --git a/src/sage/rings/complex_number.pyx b/src/sage/rings/complex_number.pyx index 5fb02097125..45f2e93b029 100644 --- a/src/sage/rings/complex_number.pyx +++ b/src/sage/rings/complex_number.pyx @@ -544,7 +544,8 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def _pari_(self): r""" - Coerces ``self`` into a Pari ``complex`` object. + Coerces ``self`` into a PARI ``t_COMPLEX`` object, + or a ``t_REAL`` if ``self`` is real. EXAMPLES: @@ -553,13 +554,22 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: a = ComplexNumber(2,1) sage: pari(a) 2.00000000000000 + 1.00000000000000*I + sage: pari(a).type() + 't_COMPLEX' sage: type(pari(a)) sage: a._pari_() 2.00000000000000 + 1.00000000000000*I sage: type(a._pari_()) + sage: a = CC(pi) + sage: pari(a) + 3.14159265358979 + sage: pari(a).type() + 't_REAL' """ + if self.is_real(): + return self.real()._pari_() return sage.libs.pari.all.pari.complex(self.real()._pari_(), self.imag()._pari_()) def _mpmath_(self, prec=None, rounding=None): From d6fdd0c38bb021e6002154023ac3e64e3b910cf4 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 6 Mar 2014 10:43:26 +0100 Subject: [PATCH 2/3] CC->PARI: convert purely imaginary numbers to t_COMPLEX with real part exactly 0 --- src/sage/rings/complex_double.pyx | 7 ++++++- src/sage/rings/complex_number.pyx | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 5dc88b8d77a..f3e0bc40c9a 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -1060,7 +1060,10 @@ cdef class ComplexDoubleElement(FieldElement): else: # Return t_COMPLEX y = cgetg(3, t_COMPLEX) - set_gel(y, 1, pari.double_to_GEN(self._complex.dat[0])) + if self._complex.dat[0] == 0: + set_gel(y, 1, gen_0) + else: + set_gel(y, 1, pari.double_to_GEN(self._complex.dat[0])) set_gel(y, 2, pari.double_to_GEN(self._complex.dat[1])) return y @@ -1076,6 +1079,8 @@ cdef class ComplexDoubleElement(FieldElement): 1.00000000000000 + 2.00000000000000*I sage: pari(CDF(2.0)) 2.00000000000000 + sage: pari(CDF(I)) + 1.00000000000000*I """ pari_catch_sig_on() return pari.new_gen(self._gen()) diff --git a/src/sage/rings/complex_number.pyx b/src/sage/rings/complex_number.pyx index 45f2e93b029..df3d007d49a 100644 --- a/src/sage/rings/complex_number.pyx +++ b/src/sage/rings/complex_number.pyx @@ -567,10 +567,13 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): 3.14159265358979 sage: pari(a).type() 't_REAL' + sage: a = CC(-2).sqrt() + sage: pari(a) + 1.41421356237310*I """ if self.is_real(): return self.real()._pari_() - return sage.libs.pari.all.pari.complex(self.real()._pari_(), self.imag()._pari_()) + return sage.libs.pari.all.pari.complex(self.real() or 0, self.imag()) def _mpmath_(self, prec=None, rounding=None): """ From 70672995f7b2e1b87d4d365396370e62ba10ae0a Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 6 Mar 2014 15:37:36 +0100 Subject: [PATCH 3/3] CC->PARI conversion: fix doctest failures --- src/sage/libs/pari/gen.pyx | 6 +++--- src/sage/schemes/elliptic_curves/heegner.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/libs/pari/gen.pyx b/src/sage/libs/pari/gen.pyx index 8cffecfbef1..2c797108cd8 100644 --- a/src/sage/libs/pari/gen.pyx +++ b/src/sage/libs/pari/gen.pyx @@ -4833,7 +4833,7 @@ cdef class gen(sage.structure.element.RingElement): -2.18503986326152 sage: C. = ComplexField() sage: pari(i).tan() - 0.E-19 + 0.761594155955765*I + 0.761594155955765*I """ pari_catch_sig_on() return P.new_gen(gtan(x.g, prec_bits_to_words(precision))) @@ -4853,7 +4853,7 @@ cdef class gen(sage.structure.element.RingElement): 0.761594155955765 sage: C. = ComplexField() sage: z = pari(i); z - 0.E-19 + 1.00000000000000*I + 1.00000000000000*I sage: result = z.tanh() sage: result.real() <= 1e-18 True @@ -4938,7 +4938,7 @@ cdef class gen(sage.structure.element.RingElement): 1.18920711500272 + 0.E-19*I # 32-bit 1.18920711500272 + 2.71050543121376 E-20*I # 64-bit sage: pari(i).weber(1) - 1.09050773266526 + 0.E-19*I + 1.09050773266526 sage: pari(i).weber(2) 1.09050773266526 """ diff --git a/src/sage/schemes/elliptic_curves/heegner.py b/src/sage/schemes/elliptic_curves/heegner.py index bc8aa49e9e0..0fdac33313a 100644 --- a/src/sage/schemes/elliptic_curves/heegner.py +++ b/src/sage/schemes/elliptic_curves/heegner.py @@ -3152,7 +3152,7 @@ def numerical_approx(self, prec=53): sage: E = EllipticCurve('37a'); P = E.heegner_point(-40); P Heegner point of discriminant -40 on elliptic curve of conductor 37 sage: P.numerical_approx() - (-6.68...e-16 + 1.41421356237310*I : 1.00000000000000 - 1.41421356237309*I : 1.00000000000000) + (-6.6...e-16 + 1.41421356237310*I : 1.00000000000000 - 1.41421356237309*I : 1.00000000000000) A rank 2 curve, where all Heegner points of conductor 1 are 0::