Ticket #10532: trac_1956_faster_MPowerSeries_mul2.patch

File trac_1956_faster_MPowerSeries_mul2.patch, 4.4 KB (added by pernici, 8 years ago)
  • sage/rings/multi_power_series_ring.py

    # HG changeset patch
    # User Mario Pernici <mario.pernici@gmail.com>
    # Date 1295456545 -3600
    # Node ID e0d02abc6dca0215ea783fc42404684403e1a3b2
    # Parent  bc05e5342eeff321fe1eb0de2199e23c3c689863
    Generic multiplication used for multiplication of multivariate series.
    
    diff -r bc05e5342eef -r e0d02abc6dca sage/rings/multi_power_series_ring.py
    a b  
    989989            f = self._poly_ring(f)
    990990        except TypeError:
    991991            raise TypeError("Cannot coerce input to polynomial ring.")
    992         fg_to_bg_dict = dict((v,v*self._bg_ps_ring().gen())
    993                              for v in self._poly_ring().gens())
    994         return self._bg_ps_ring(f.subs(fg_to_bg_dict))
     992        degs = f.degrees()
     993        if degs:
     994            emax = 0
     995            f1 = [0]*(sum(degs)+1)
     996            for x in f:
     997                e = sum(x[1].degrees())
     998                if e > emax:
     999                    emax = e
     1000                f1[e] += x[0]*x[1]
     1001            f1 = f1[:emax+1]
     1002        else:
     1003            f1 = f
     1004        return self._bg_ps_ring(f1)
    9951005
    9961006    def _send_to_fg(self,f):
    9971007        """
     
    10171027            4 + 4*f0 + 4*f2
    10181028        """
    10191029       
    1020         return self._poly_ring(f.subs({self.__bg_indeterminate:1}))
     1030        return self._poly_ring(sum(f.list()))
    10211031
    10221032   
    10231033   
  • sage/rings/multi_power_series_ring_element.py

    diff -r bc05e5342eef -r e0d02abc6dca sage/rings/multi_power_series_ring_element.py
    a b  
    172172from sage.structure.nonexact import Nonexact
    173173from sage.structure.parent_gens import ParentWithGens
    174174from sage.structure.category_object import CategoryObject
     175from sage.rings.polynomial.polynomial_element import Polynomial_generic_dense
     176from sage.rings.power_series_poly import PowerSeries_poly
    175177
    176178
    177179def is_MPowerSeries(f):
     
    658660            sage: all(S >= g.prec() for S in [sum(e) for e in diff.exponents()])
    659661            True
    660662        """
    661         f = left._bg_value * right._bg_value
    662         return MPowerSeries(left.parent(), f, prec=f.prec())
     663        prec = left._bg_value._mul_prec(right._bg_value)
     664        if not isinstance(left._bg_value.polynomial(), Polynomial_generic_dense) or  not isinstance(right._bg_value.polynomial(), Polynomial_generic_dense):
     665          f = left._bg_value*right._bg_value
     666        elif prec is infinity:
     667          f = left._bg_value.polynomial()._mul_generic(right._bg_value.polynomial())
     668          f = PowerSeries_poly(left._bg_value.parent(),f,prec,check = False)
     669        else:
     670          f = left._bg_value.polynomial()._mul_trunc_generic(right._bg_value.polynomial(),prec)
     671          f = PowerSeries_poly(left._bg_value.parent(),f,prec,check = True)
     672        return MPowerSeries(left.parent(), f, prec)
     673
    663674   
    664675#    def _rmul_(self, c):
    665676#        # multivariate power series rings are assumed to be commutative
  • sage/rings/polynomial/polynomial_element.pyx

    diff -r bc05e5342eef -r e0d02abc6dca sage/rings/polynomial/polynomial_element.pyx
    a b  
    17231723            coeffs.append(sum)
    17241724        return self._parent(coeffs)
    17251725       
     1726    def _mul_trunc_generic(self, right, prec):
     1727        # TODO optimize case self is right
     1728        # merge with _mul_generic?
     1729        x = self.list()
     1730        y = right.list()
     1731        cdef Py_ssize_t i, k, start, end
     1732        cdef Py_ssize_t d1 = len(x)-1, d2 = len(y)-1
     1733        if d1 == -1:
     1734            return self
     1735        elif d2 == -1:
     1736            return right
     1737        elif d1 == 0:
     1738            c = x[0]
     1739            return self._parent([c*a for a in y])
     1740        elif d2 == 0:
     1741            c = y[0]
     1742            return self._parent([a*c for a in x])
     1743        coeffs = []
     1744        for k from 0 <= k <= min(d1+d2,prec-1):
     1745            start = 0 if k <= d2 else k-d2 # max(0, k-d2)
     1746            end =   k if k <= d1 else d1    # min(k, d1)
     1747            sum = x[start] * y[k-start]
     1748            for i from start < i <= end:
     1749                sum += x[i] * y[k-i]
     1750            coeffs.append(sum)
     1751        return self._parent(coeffs)
     1752       
    17261753    def _square_generic(self):
    17271754        x = self.list()
    17281755        cdef Py_ssize_t i, j