Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit a709d12

Browse files
committed
speed improvements for PARI power series
1 parent 07f5508 commit a709d12

File tree

1 file changed

+85
-5
lines changed

1 file changed

+85
-5
lines changed

src/sage/rings/power_series_pari.pyx

+85-5
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ cdef class PowerSeries_pari(PowerSeries):
5959
g = <pari_gen>f
6060
t = typ(g.g)
6161
if t == t_SER and varn(g.g) == pari.get_var(v):
62-
prec = g.length() + g._valp()
62+
prec = lg(g.g) - 2 + valp(g.g)
6363
elif t == t_RFRAC:
6464
prec = parent.default_prec()
6565
g = g.Ser(v, prec - g.valuation(v))
@@ -98,10 +98,10 @@ cdef class PowerSeries_pari(PowerSeries):
9898
if t == t_POL:
9999
g = P(g)._pari_()
100100
elif t == t_SER and varn(g.g) == pari.get_var(v):
101-
if g._valp() < 0:
101+
if valp(g.g) < 0:
102102
raise ValueError('series has negative valuation')
103103
if prec is infinity:
104-
prec = g.length() + g._valp()
104+
prec = lg(g.g) - 2 + valp(g.g)
105105
g = P(g.Pol(v))._pari_()
106106
elif t == t_RFRAC:
107107
if prec is infinity:
@@ -198,7 +198,7 @@ cdef class PowerSeries_pari(PowerSeries):
198198
6*t^3 + 3
199199
200200
"""
201-
return self._parent._poly_ring()(self.g)
201+
return self._parent._poly_ring()(self.list())
202202

203203
def valuation(self):
204204
"""
@@ -646,8 +646,88 @@ cdef class PowerSeries_pari(PowerSeries):
646646
[2 + O(5^20), 1 + O(5^20)]
647647
648648
"""
649+
cdef pari_gen g = self.g
650+
cdef long vn = pari.get_var(self._parent.variable_name())
649651
R = self.base_ring()
650-
return [R(a) for a in self.g.Pol(self._parent.variable_name()).list()]
652+
if typ(g.g) == t_SER and varn(g.g) == vn:
653+
g = g.truncate()
654+
if typ(g.g) == t_POL and varn(g.g) == vn:
655+
# t_POL has 2 codewords. Use new_ref instead of g[i] for speed.
656+
return [R(pari.new_ref(gel(g.g, i), g)) for i in xrange(2, lg(g.g))]
657+
else:
658+
return [R(g)]
659+
660+
def padded_list(self, n=None):
661+
"""
662+
Return a list of coefficients of ``self`` up to (but not
663+
including) `q^n`.
664+
665+
The list is padded with zeroes on the right so that it has
666+
length `n`.
667+
668+
INPUT:
669+
670+
- ``n`` - (optional) a non-negative integer. If `n` is not
671+
given, it will be taken to be the precision of self, unless
672+
this is +Infinity, in which case we just return
673+
``self.list()``.
674+
675+
EXAMPLES::
676+
677+
sage: R.<q> = PowerSeriesRing(QQ, implementation='pari')
678+
sage: f = 1 - 17*q + 13*q^2 + 10*q^4 + O(q^7)
679+
sage: f.list()
680+
[1, -17, 13, 0, 10]
681+
sage: f.padded_list(7)
682+
[1, -17, 13, 0, 10, 0, 0]
683+
sage: f.padded_list(10)
684+
[1, -17, 13, 0, 10, 0, 0, 0, 0, 0]
685+
sage: f.padded_list(3)
686+
[1, -17, 13]
687+
sage: f.padded_list()
688+
[1, -17, 13, 0, 10, 0, 0]
689+
sage: g = 1 - 17*q + 13*q^2 + 10*q^4
690+
sage: g.list()
691+
[1, -17, 13, 0, 10]
692+
sage: g.padded_list()
693+
[1, -17, 13, 0, 10]
694+
sage: g.padded_list(10)
695+
[1, -17, 13, 0, 10, 0, 0, 0, 0, 0]
696+
697+
"""
698+
if n is None:
699+
if self._prec is infinity:
700+
return self.list()
701+
else:
702+
n = self._prec
703+
if not n:
704+
return []
705+
706+
cdef pari_gen g = self.g
707+
cdef long l, m
708+
709+
R = self.base_ring()
710+
if typ(g.g) == t_POL and varn(g.g) == pari.get_var(self._parent.variable_name()):
711+
l = lg(g.g) - 2 # t_POL has 2 codewords
712+
if n <= l:
713+
return [R(pari.new_ref(gel(g.g, i + 2), g)) for i in xrange(n)]
714+
else:
715+
return ([R(pari.new_ref(gel(g.g, i + 2), g)) for i in xrange(l)]
716+
+ [R.zero_element()] * (n - l))
717+
elif typ(g.g) == t_SER and varn(g.g) == pari.get_var(self._parent.variable_name()):
718+
l = lg(g.g) - 2 # t_SER has 2 codewords
719+
m = valp(g.g)
720+
if n <= m:
721+
return [R.zero_element()] * n
722+
elif n <= l + m:
723+
return ([R.zero_element()] * m
724+
+ [R(pari.new_ref(gel(g.g, i + 2), g)) for i in xrange(n - m)])
725+
else:
726+
return ([R.zero_element()] * m
727+
+ [R(pari.new_ref(gel(g.g, i + 2), g)) for i in xrange(l)]
728+
+ [R.zero_element()] * (n - l - m))
729+
else:
730+
return [R(g)] + [R.zero_element()] * (n - 1)
651731

652732
def dict(self):
653733
"""

0 commit comments

Comments
 (0)