# Ticket #11726: trac_11726.patch

File trac_11726.patch, 45.9 KB (added by boothby, 10 years ago)
• ## sage/algebras/iwahori_hecke_algebra.py

# HG changeset patch

diff -r 2a2abbcad325 sage/algebras/iwahori_hecke_algebra.py
 a sage: [V1,V2]=H1.algebra_generators() sage: [W1,W2]=H1.inverse_generators() sage: [W1,W2] [(q^-1)*V1 + (-1+q^-1), (q^-1)*V2 + (-1+q^-1)] [(q^-1)*V1 + (q^-1-1), (q^-1)*V2 + (q^-1-1)] sage: V1*W1, W2*V2 (1, 1) sage: H = IwahoriHeckeAlgebraT("A2",q) sage: [T1,T2]=H.algebra_generators() sage: x = (T1*T2).inverse(); x (q^-2)*T2*T1 + (-q^-1+q^-2)*T1 + (-q^-1+q^-2)*T2 + (1-2*q^-1+q^-2) (q^-2)*T2*T1 + (q^-2-q^-1)*T1 + (q^-2-q^-1)*T2 + (q^-2-2*q^-1+1) sage: x*T1*T2 1
• ## sage/categories/pushout.py

diff -r 2a2abbcad325 sage/categories/pushout.py
 a Defn: x |--> x + 2*y y |--> 3*x - y sage: F(f)(x*F(P).gen()^-2+y*F(P).gen()^3) (3*x - y)*t^3 + (x + 2*y)*t^-2 (x + 2*y)*t^-2 + (3*x - y)*t^3 """ rank = 9
• ## sage/combinat/kazhdan_lusztig.py

diff -r 2a2abbcad325 sage/combinat/kazhdan_lusztig.py
 a sage: R.=LaurentPolynomialRing(QQ) sage: KL=KazhdanLusztigPolynomial(W,q) sage: KL.P(s2,s3*s2*s3*s1*s2) q + 1 1 + q """ self._coxeter_group = W return 0 p = sum(-self.R(x,t)*self.P(t,y) for t in self._coxeter_group.bruhat_interval(x,y) if t != x) tr = floor((y.length()-x.length()+1)/2) try: ret = p.truncate(tr) except: ret = laurent_polynomial_truncate(p, tr) ret = p.truncate(tr) if self._trace: print "    P(%s,%s)=%s"%(x, y, ret) return ret def laurent_polynomial_truncate(p, n): """ Truncates the Laurent polynomial p, returning only terms of degree = LaurentPolynomialRing(QQ) sage: laurent_polynomial_truncate((q+q^-1)^3+q^2*(q+q^-1)^4,3) 6*q^2 + 3*q + 4 + 3*q^-1 + q^-2 + q^-3 """ pdict = p._dict() dict = {} for k in pdict: if k[0] < n: dict[k] = pdict[k] return p.parent()(dict)
• ## sage/rings/laurent_series_ring.py

diff -r 2a2abbcad325 sage/rings/laurent_series_ring.py
 a laurent_series = {} def LaurentSeriesRing(base_ring, name=None, names=None, sparse=False): def LaurentSeriesRing(base_ring, name=None, names=None, sparse=False, default_prec=None): """ EXAMPLES:: else: raise TypeError, "base_ring must be a commutative ring" laurent_series[key] = weakref.ref(R) if default_prec is not None: R.set_default_prec(default_prec) return R def is_LaurentSeriesRing(x): sage: I = sqrt(-1) sage: K. = QQ[I] sage: P. = PolynomialRing(K) sage: L. = LaurentSeriesRing(QQ[I]) sage: L. = LaurentSeriesRing(QQ[I], default_prec = 20) sage: L((t*I)/(t^3+I*2*t)) 1/2 + 1/4*I*u^2 - 1/8*u^4 - 1/16*I*u^6 + 1/32*u^8 + 1/64*I*u^10 - 1/128*u^12 - 1/256*I*u^14 + 1/512*u^16 + from sage.rings.fraction_field_element import is_FractionFieldElement from sage.rings.polynomial.polynomial_element import is_Polynomial from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial if isinstance(x, laurent_series_ring_element.LaurentSeries) and n==0 and self is x.parent(): return x  # ok, since Laurent series are immutable (no need to make a copy) elif isinstance(x, pari_gen):
• ## sage/rings/laurent_series_ring_element.pyx

diff -r 2a2abbcad325 sage/rings/laurent_series_ring_element.pyx
 a import sage.misc.latex import sage.rings.ring_element as ring_element from sage.rings.integer import Integer from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_univariate from sage.structure.element cimport Element, ModuleElement, RingElement, AlgebraElement """ AlgebraElement.__init__(self, parent) if PY_TYPE_CHECK(f, LaurentSeries): if isinstance(f, LaurentSeries): n += (f).__n if (f).__u._parent is parent.power_series_ring(): f = (f).__u else: f = parent.power_series_ring()((f).__u) elif not PY_TYPE_CHECK(f, PowerSeries): elif isinstance(f, LaurentPolynomial_univariate): f = f(parent.gen()) elif not isinstance(f, PowerSeries): f = parent.power_series_ring()(f) ## now this is a power series, over a different ring ... ## requires that power series rings with same vars over the def shift(self, k): r""" Returns this laurent series multiplied by the power t^n. Returns this Laurent series multiplied by the power t^n. Does not change this series. .. note::
• ## sage/rings/polynomial/laurent_polynomial.pxd

diff -r 2a2abbcad325 sage/rings/polynomial/laurent_polynomial.pxd
 a from sage.rings.polynomial.multi_polynomial cimport MPolynomial from sage.rings.polynomial.polynomial_element cimport Polynomial cdef class LaurentPolynomial_univariate(CommutativeAlgebraElement): cpdef ModuleElement __u cdef long __n cdef class LaurentPolynomial_mpair(CommutativeAlgebraElement): cdef ETuple _mon cdef MPolynomial _poly
• ## sage/rings/polynomial/laurent_polynomial.pyx

diff -r 2a2abbcad325 sage/rings/polynomial/laurent_polynomial.pyx
 a """ include "../../ext/stdsage.pxi" import re #from infinity import infinity from sage.rings.integer import Integer from sage.structure.element import is_Element from sage.misc.latex import latex import sage.misc.latex from sage.misc.misc import union from sage.structure.factorization import Factorization from sage.misc.derivative import multi_derivative from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.laurent_series_ring_element import LaurentSeries cdef class LaurentPolynomial_univariate(CommutativeAlgebraElement): """ Univariate Laurent Polynomial AUTHORS:: Tom Boothby (2011) copied this class almost verbatim from laurent_series_ring_element.pyx, so most of the credit goes to William Stein, David Joyner, and Robert Bradshaw """ def __init__(self, parent, f, n=0): r""" Create the Laurent polynomial t^n \cdot f. The default is n=0. INPUT: -  parent - a Laurent polynomial ring -  f - a polynomial (or something can be coerced to one) -  n - integer (default 0) OUTPUT: a Laurent polynomial EXAMPLES:: sage: R. = LaurentPolynomialRing(ZZ) sage: R([1,2,3]) 1 + 2*q + 3*q^2 :: sage: S. = LaurentPolynomialRing(GF(5)) sage: T. = PolynomialRing(pAdicRing(5)) sage: S(t) s sage: parent(S(t)) Univariate Laurent Polynomial Ring in s over Finite Field of size 5 sage: parent(S(t)[1]) Finite Field of size 5 """ CommutativeAlgebraElement.__init__(self, parent) if isinstance(f, LaurentPolynomial_univariate): n += (f).__n if (f).__u._parent is parent.polynomial_ring(): f = (f).__u else: f = parent.polynomial_ring()((f).__u) elif (not isinstance(f, Polynomial)) or (parent is not f.parent()): if isinstance(f, dict): v = min(f.keys()) f = dict((i-v,c) for i,c in f.items()) n+=v f = parent.polynomial_ring()(f) # self is that t^n * u: cdef long val self.__u = f self.__n = n self.__normalize() def __reduce__(self): return make_element_from_parent, (self._parent, self.__u, self.__n) def change_ring(self, R): """ Return a copy of this Laurent polynomial, with coefficients in R. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: a = x^2 + 3*x^3 + 5*x^-1 sage: a.change_ring(GF(3)) 2*x^-1 + x^2 """ return self.parent().change_ring(R)(self) def is_unit(self): """ Returns True if this Laurent polynomial is a unit in this ring. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: (2+t).is_unit() False sage: f = 2*t sage: f.is_unit() True sage: 1/f 1/2*t^-1 sage: R(0).is_unit() False sage: R. = LaurentPolynomialRing(ZZ) sage: g = 2*s sage: g.is_unit() False sage: 1/g Traceback (most recent call last): ... ArithmeticError: division not defined ALGORITHM: A Laurent polynomial is a unit if and only if its "unit part" is a unit. """ return self.__u.is_monomial() and self.__u.coefficients()[0].is_unit() def is_zero(self): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = 1/x + x + x^2 + 3*x^4 sage: f.is_zero() 0 sage: z = 0*f sage: z.is_zero() 1 """ return self.__u.is_zero() def __nonzero__(self): return not not self.__u def _im_gens_(self, codomain, im_gens): return codomain(self(im_gens[0])) def __normalize(self): r""" A Laurent series is a pair (u(t), n), where either u=0 (to some precision) or u is a unit. This pair corresponds to t^n\cdot u(t). """ from sage.rings.infinity import infinity if self.is_zero(): return v = self.__u.valuation() if v == 0: return if v != infinity: self.__n += v self.__u = self.__u >> v def _repr_(self): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: (2 + (2/3)*t^3).__repr__() '2 + 2/3*t^3' """ if self.is_zero(): return "0" s = " " v = self.__u.list() valuation = self.__n m = len(v) X = self._parent.variable_name() atomic_repr = self._parent.base_ring().is_atomic_repr() first = True for n in xrange(m): x = v[n] e = n + valuation x = str(x) if x != '0': if not first: s += " + " if not atomic_repr and (x[1:].find("+") != -1 or x[1:].find("-") != -1): x = "(%s)"%x if e == 1: var = "*%s"%X elif e == 0: var = "" else: var = "*%s^%s"%(X,e) s += "%s%s"%(x,var) first = False s = s.replace(" + -", " - ") s = s.replace(" 1*"," ") s = s.replace(" -1*", " -") return s[1:] def _latex_(self): r""" EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = (17/2)*x^-2 + x + x^2 + 3*x^4 sage: latex(f) \frac{\frac{17}{2}}{x^{2}} + x + x^{2} + 3x^{4} Verify that trac #6656 has been fixed:: sage: R.=PolynomialRing(QQ) sage: T.=LaurentPolynomialRing(R) sage: y = a*x+b*x sage: y._latex_() '\\left(a + b\\right)x' sage: latex(y) \left(a + b\right)x """ if self.is_zero(): return "0" s = " " v = self.__u.list() valuation = self.__n m = len(v) X = self._parent.latex_variable_names()[0] atomic_repr = self._parent.base_ring().is_atomic_repr() first = True for n in xrange(m): x = v[n] e = n + valuation x = sage.misc.latex.latex(x) if x != '0': if not first: s += " + " if not atomic_repr and e > 0 and (x[1:].find("+") != -1 or x[1:].find("-") != -1): x = "\\left(%s\\right)"%x if e == 1: var = "|%s"%X elif e == 0: var = "" elif e > 0: var = "|%s^{%s}"%(X,e) if e >= 0: s += "%s%s"%(x,var) else: # negative e if e == -1: s += "\\frac{%s}{%s}"%(x, X) else: s += "\\frac{%s}{%s^{%s}}"%(x, X,-e) first = False s = s.replace(" + -", " - ") s = s.replace(" 1|"," ") s = s.replace(" -1|", " -") s = s.replace("|","") return s[1:] def __hash__(self): return hash(self.__u) ^ self.__n def __getitem__(self, i): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = -5/t^(10) + t + t^2 - 10/3*t^3; f -5*t^-10 + t + t^2 - 10/3*t^3 sage: f[-10] -5 sage: f[1] 1 sage: f[3] -10/3 sage: f[-9] 0 """ return self.__u[i-self.__n] def __getslice__(self, i, j): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = -5/t^(10) + 1/3 + t + t^2 - 10/3*t^3; f -5*t^-10 + 1/3 + t + t^2 - 10/3*t^3 sage: f[-10:2] -5*t^-10 + 1/3 + t sage: f[0:] 1/3 + t + t^2 - 10/3*t^3 """ if j > self.__u.degree(): j = self.__u.degree() f = self.__u[i-self.__n:j-self.__n] return LaurentPolynomial_univariate(self._parent, f, self.__n) def __iter__(self): """ Iterate through the coefficients from the first nonzero one to the last nonzero one. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = -5/t^(2) + t + t^2 - 10/3*t^3; f -5*t^-2 + t + t^2 - 10/3*t^3 sage: for a in f: print a -5 0 0 1 1 -10/3 """ return iter(self.__u) def dict(self): """ Return a dictionary representing self. EXAMPLES:: sage: R. = ZZ[] sage: Q. = LaurentPolynomialRing(R) sage: f = (x^3 + y/t^3)^3 + t^2; f y^3*t^-9 + 3*x^3*y^2*t^-6 + 3*x^6*y*t^-3 + x^9 + t^2 sage: f.dict() {0: x^9, -6: 3*x^3*y^2, 2: 1, -3: 3*x^6*y, -9: y^3} """ return dict(zip(self.exponents(), self.coefficients())) def coefficients(self): """ Return the nonzero coefficients of self. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = -5/t^(2) + t + t^2 - 10/3*t^3 sage: f.coefficients() [-5, 1, 1, -10/3] """ return self.__u.coefficients() def exponents(self): """ Return the exponents appearing in self with nonzero coefficients. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = -5/t^(2) + t + t^2 - 10/3*t^3 sage: f.exponents() [-2, 1, 2, 3] """ return [i+self.__n for i in self.__u.exponents()] def __setitem__(self, n, value): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = t^2 + t^3 sage: f[2] = 5 Traceback (most recent call last): ... IndexError: Laurent polynomials are immutable """ raise IndexError, "Laurent polynomials are immutable" def _unsafe_mutate(self, i, value): """ Sage assumes throughout that commutative ring elements are immutable. This is relevant for caching, etc. But sometimes you need to change a Laurent polynomial and you really know what you're doing. That's when this function is for you. EXAMPLES: """ j = i - self.__n if j >= 0: self.__u._unsafe_mutate(j, value) else: # off to the left if value != 0: self.__n = self.__n + j R = self._parent.base_ring() coeffs = [value] + [R(0) for _ in range(1,-j)] + self.__u.list() self.__u = self.__u._parent(coeffs) self.__normalize() cpdef ModuleElement _add_(self, ModuleElement right_m): """ Add two Laurent polynomials with the same parent. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: t + t 2*t sage: f = 1/t + t^2 + t^3 - 17/3 * t^4 sage: g = 2/t + t^3 sage: f + g 3*t^-1 + t^2 + 2*t^3 - 17/3*t^4 sage: f + 0 t^-1 + t^2 + t^3 - 17/3*t^4 sage: 0 + f t^-1 + t^2 + t^3 - 17/3*t^4 sage: R(0) + R(0) 0 sage: t^3 + t^-3 t^-3 + t^3 ALGORITHM: Shift the unit parts to align them, then add. """ cdef LaurentPolynomial_univariate right = right_m cdef long m # 1. Special case when one or the other is 0. if not right: return self if not self: return right # 2. Align the unit parts. if self.__n < right.__n: m = self.__n f1 = self.__u f2 = right.__u << right.__n - m elif self.__n > right.__n: m = right.__n f1 = self.__u << self.__n - m f2 = right.__u else: m = self.__n f1 = self.__u f2 = right.__u # 3. Add return LaurentPolynomial_univariate(self._parent, f1 + f2, m) cpdef ModuleElement _iadd_(self, ModuleElement right_m): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = t+t sage: f += t; f 3*t sage: f += t*t; f 3*t + t^2 """ cdef LaurentPolynomial_univariate right = right_m if self.__n == right.__n: self.__u += right.__u return self else: return self._add_(right) cpdef ModuleElement _sub_(self, ModuleElement right_m): """ Subtract two Laurent polynomials with the same parent. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: t - t 0 sage: t^5 + 2 * t^-5 2*t^-5 + t^5 ALGORITHM: Shift the unit parts to align them, then subtract. """ cdef LaurentPolynomial_univariate right = right_m cdef long m # 1. Special case when one or the other is 0. if not right: return self if not self: return -right # 2. Align the unit parts. if self.__n < right.__n: m = self.__n f1 = self.__u f2 = right.__u << right.__n - m else: m = right.__n f1 = self.__u << self.__n - m f2 = right.__u # 3. Subtract return LaurentPolynomial_univariate(self._parent, f1 - f2, m) #    def add_bigoh(self, prec): #        """ #        EXAMPLES:: # #            sage: R. = LaurentPolynomialRing(QQ) #            sage: f = t^2 + t^3 + O(t^10); f #            t^2 + t^3 + O(t^10) #            sage: f.add_bigoh(5) #            t^2 + t^3 + O(t^5) #        """ #        if prec == infinity: #            return self #        u = self.__u.add_bigoh(prec - self.__n) #        return LaurentSeries(self._parent.completion(self._parent.gen()), u, self.__n) def degree(self): """ Return the degree of this polynomial. EXAMPLES:: sage: R. = LaurentPolynomialRing(ZZ) sage: g = x^2 - x^4 sage: g.degree() 4 sage: g = -10/x^5 + x^2 - x^7 sage: g.degree() 7 """ return self.__u.degree() + self.__n def __neg__(self): """ :: sage: R. = LaurentPolynomialRing(ZZ) sage: -(1+t^5) -1 - t^5 """ return LaurentPolynomial_univariate(self._parent, -self.__u, self.__n) cpdef RingElement _mul_(self, RingElement right_r): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(GF(2)) sage: f = 1/x^3 + x + x^2 + 3*x^4 sage: g = 1 - x + x^2 - x^4 sage: f*g x^-3 + x^-2 + x^-1 + x^8 """ cdef LaurentPolynomial_univariate right = right_r return LaurentPolynomial_univariate(self._parent, self.__u * right.__u, self.__n + right.__n) cpdef RingElement _imul_(self, RingElement right_r): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(ZZ) sage: f = 1/x^3 + x + x^2 + 3*x^4 sage: g = 1 - x + x^2 - x^4 sage: f *= g; f x^-3 - x^-2 + x^-1 + 4*x^4 - 4*x^5 + 2*x^6 - 3*x^8 """ cdef LaurentPolynomial_univariate right = right_r self.__u *= right.__u self.__n += right.__n return self cpdef ModuleElement _rmul_(self, RingElement c): return LaurentPolynomial_univariate(self._parent, self.__u._rmul_(c), self.__n) cpdef ModuleElement _lmul_(self, RingElement c): return LaurentPolynomial_univariate(self._parent, self.__u._lmul_(c), self.__n) cpdef ModuleElement _ilmul_(self, RingElement c): self.__u *= c return self def __pow__(_self, r, dummy): """ EXAMPLES:: sage: x = LaurentPolynomialRing(QQ,'x').0 sage: f = x + x^2 + 3*x^4 sage: g = 1/x^10 - x sage: f^3 x^3 + 3*x^4 + 3*x^5 + 10*x^6 + 18*x^7 + 9*x^8 + 27*x^9 + 27*x^10 + 27*x^12 sage: g^4 x^-40 - 4*x^-29 + 6*x^-18 - 4*x^-7 + x^4 """ cdef LaurentPolynomial_univariate self = _self right=int(r) if right != r: raise ValueError, "exponent must be an integer" return LaurentPolynomial_univariate(self._parent, self.__u**right, self.__n*right) def shift(self, k): r""" Returns this Laurent polynomial multiplied by the power t^n. Does not change this polynomial. .. note:: Despite the fact that higher order terms are printed to the right in a power series, right shifting decreases the powers of t, while left shifting increases them. This is to be consistent with polynomials, integers, etc. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ['y']) sage: f = (t+t^-1)^4; f t^-4 + 4*t^-2 + 6 + 4*t^2 + t^4 sage: f.shift(10) t^6 + 4*t^8 + 6*t^10 + 4*t^12 + t^14 sage: f >> 10 t^-14 + 4*t^-12 + 6*t^-10 + 4*t^-8 + t^-6 sage: t << 4 t^5 """ return LaurentPolynomial_univariate(self._parent, self.__u, self.__n + k) def __lshift__(LaurentPolynomial_univariate self, k): return LaurentPolynomial_univariate(self._parent, self.__u, self.__n + k) def __rshift__(LaurentPolynomial_univariate self, k): return LaurentPolynomial_univariate(self._parent, self.__u, self.__n - k) cpdef RingElement _div_(self, RingElement right_r): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = x + x^2 + 3*x^4 sage: g = 1/x^7 - x + x^2 - x^4 sage: f/x 1 + x + 3*x^3 sage: f/g Traceback (most recent call last): ... ArithmeticError: division not defined """ cdef LaurentPolynomial_univariate right = right_r if right.__u.is_zero(): raise ZeroDivisionError try: return LaurentPolynomial_univariate(self._parent, self.__u / right.__u, self.__n - right.__n) except TypeError, msg: # todo: this could also make something in the formal fraction field. raise ArithmeticError, "division not defined" def __richcmp__(left, right, int op): return (left)._richcmp(right, op) cdef int _cmp_c_impl(self, Element right_r) except -2: r""" Comparison of self and right. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = x^(-1) + 1 + x sage: g = x^(-1) + 1 sage: f == g False :: sage: f = x^(-1) + 1 + x sage: g = x^(-1) + 2 sage: f == g False sage: f < g True sage: f > g False :: sage: f = x^(-2) + 1 + x sage: g = x^(-1) + 2 sage: f == g False sage: f < g False sage: f > g True """ cdef LaurentPolynomial_univariate right = right_r zero = self.base_ring()(0) if not self and not right: if self.__n < right.__n: return cmp(self.__u[0], zero) elif self.__n > right.__n: return cmp(zero, right.__u[0]) # zero pad coefficients on the left, to line them up for comparison cdef long n = min(self.__n, right.__n) x = [zero] * (self.__n - n) + self.__u.list() y = [zero] * (right.__n - n) + right.__u.list() # zero pad on right to make the lists the same length # (this is necessary since the power series list() function just # returns the coefficients of the underlying polynomial, which may # have zeroes in the high coefficients) if len(x) < len(y): x.extend([zero] * (len(y) - len(x))) elif len(y) < len(x): y.extend([zero] * (len(x) - len(y))) return cmp(x,y) def valuation_zero_part(self): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = x + x^2 + 3*x^4 sage: f/x 1 + x + 3*x^3 sage: f.valuation_zero_part() 3*x^3 + x + 1 sage: g = 1/x^7 - x + x^2 - x^4 sage: g.valuation_zero_part() -x^11 + x^9 - x^8 + 1 """ return self.__u def valuation(self): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(ZZ) sage: f = 1/x + x^2 + 3*x^4 sage: g = 1 - x + x^2 - x^4 sage: f.valuation() -1 sage: g.valuation() 0 """ return self.__n def truncate(self, n): """ Return a polynomial with degree at most n-1 whose j-th coefficients agree with self for all j = LaurentPolynomialRing(QQ) sage: f = 1/x^12 + x^3 + x^5 + x^9 sage: f.truncate(10) x^-12 + x^3 + x^5 + x^9 sage: f.truncate(5) x^-12 + x^3 sage: f.truncate(-16) 0 """ if n <= self.valuation(): return self._parent(0) else: return LaurentPolynomial_univariate(self._parent, self.__u.truncate(n-self.__n), self.__n) def variable(self): """ EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = 1/x + x^2 + 3*x^4 sage: f.variable() 'x' """ return self._parent.variable_name() def __copy__(self): return LaurentPolynomial_univariate(self._parent, self.__u.copy(), self.__n) def derivative(self, *args): """ The formal derivative of this Laurent polynomial, with respect to variables supplied in args. Multiple variables and iteration counts may be supplied; see documentation for the global derivative() function for more details. .. seealso:: :meth:_derivative EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: g = 1/x^10 - x + x^2 - x^4 sage: g.derivative() -10*x^-11 - 1 + 2*x - 4*x^3 sage: g.derivative(x) -10*x^-11 - 1 + 2*x - 4*x^3 :: sage: R. = PolynomialRing(ZZ) sage: S. = LaurentPolynomialRing(R) sage: f = 2*t/x + (3*t^2 + 6*t)*x sage: f.derivative() -2*t*x^-2 + (3*t^2 + 6*t) sage: f.derivative(x) -2*t*x^-2 + (3*t^2 + 6*t) sage: f.derivative(t) 2*x^-1 + (6*t + 6)*x """ return multi_derivative(self, args) def _derivative(self, var=None): """ The formal derivative of this Laurent series with respect to var. If var is None or the generator of this ring, it's the formal derivative as expected. Otherwise, _derivative(var) gets called recursively on each coefficient. .. seealso:: :meth:derivative EXAMPLES:: sage: R. = LaurentPolynomialRing(ZZ) sage: f = x^2 + 3*x^4 sage: f._derivative() 2*x + 12*x^3 sage: f._derivative(x) 2*x + 12*x^3 sage: g = 1/x^10 - x + x^2 - x^4 sage: g._derivative() -10*x^-11 - 1 + 2*x - 4*x^3 Differentiating with respect to something other than the generator gets recursed into the base ring:: sage: R. = PolynomialRing(ZZ) sage: S. = LaurentPolynomialRing(R) sage: f = 2*t/x + (3*t^2 + 6*t)*x sage: f._derivative(t) 2*x^-1 + (6*t + 6)*x """ if var is not None and var is not self._parent.gen(): # call _derivative() recursively on coefficients u = [coeff._derivative(var) for coeff in self.__u.list()] u = self._parent.polynomial_ring()(u) return LaurentPolynomial_univariate(self._parent, u, self.__n) # compute formal derivative with respect to generator if self.is_zero(): return LaurentPolynomial_univariate(self._parent, 0) cdef long m, n = self.__n a = self.__u.list() v = [(n+m)*a[m] for m from 0 <= m < len(a)] u = self._parent.polynomial_ring()(v) return LaurentPolynomial_univariate(self._parent, u, n-1) def integral(self): r""" The formal integral of this Laurent series with 0 constant term. EXAMPLES: The integral may or may not be defined if the base ring is not a field. :: sage: t = LaurentPolynomialRing(ZZ, 't').0 sage: f = 2*t^-3 + 3*t^2 sage: f.integral() -t^-2 + t^3 :: sage: f = t^3 sage: f.integral() Traceback (most recent call last): ... ArithmeticError: Coefficients of integral cannot be coerced into the base ring The integral of 1/t is \log(t), which is not given by a Laurent polynomial:: sage: t = LaurentPolynomialRing(ZZ,'t').0 sage: f = -1/t^3 - 31/t sage: f.integral() Traceback (most recent call last): ... ArithmeticError: The integral of is not a Laurent polynomial, since t^-1 has nonzero coefficient. Another example with just one negative coefficient:: sage: A. = LaurentPolynomialRing(QQ) sage: f = -2*t^(-4) sage: f.integral() 2/3*t^-3 sage: f.integral().derivative() == f True """ cdef long i, n = self.__n a = self.__u.list() if self[-1] != 0: raise ArithmeticError, \ "The integral of is not a Laurent polynomial, since t^-1 has nonzero coefficient." if n < 0: v = [a[i]/(n+i+1) for i in range(min(-1-n,len(a)))] + [0] else: v = [] v += [a[i]/(n+i+1) for i in range(max(-n,0), len(a))] try: u = self._parent.polynomial_ring()(v) except TypeError: raise ArithmeticError, "Coefficients of integral cannot be coerced into the base ring" return LaurentPolynomial_univariate(self._parent, u, n+1) def __call__(self, *x): """ Compute value of this Laurent polynomial at x. EXAMPLES:: sage: R. = LaurentPolynomialRing(ZZ) sage: f = t^(-2) + t^2 sage: f(2) 17/4 sage: f(-1) 2 sage: f(1/3) 82/9 """ if isinstance(x[0], tuple): x = x[0] return self.__u(x) * (x[0]**self.__n) def make_element_from_parent(parent, *args): return parent(*args) cdef class LaurentPolynomial_mpair(CommutativeAlgebraElement): def __init__(self, parent, x, reduce=True): sage: L(1/2) 1/2 """ if isinstance(x, PolyDict): if isinstance(x, LaurentPolynomial_mpair): x = x.dict() elif isinstance(x, PolyDict): x = x.dict() if isinstance(x, dict): self._mon = ETuple({},int(parent.ngens())) term *= kwds[repr_g[i]]**mon[i] else: term *= g[i]**mon[i] out += term return out def is_univariate(self): """ Returns True if this is a univariate or constant Laurent polynomial, and False otherwise. EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) sage: f = (x^3 + y^-3)*z sage: f.is_univariate() False sage: g = f(1,y,4) sage: g.is_univariate() True sage: R(1).is_univariate() True """ return len(self.variables()) < 2 def univariate_polynomial(self, R=None): """ Returns a univariate polynomial associated to this multivariate polynomial. INPUT: - R - (default: None) PolynomialRing If this polynomial is not in at most one variable, then a ValueError exception is raised.  The new polynomial is over the same base ring as the given LaurentPolynomial and in the variable x if no ring R is provided. EXAMPLES:: sage: R. = LaurentPolynomialRing(ZZ) sage: f = 3*x^2 - 2*y^-1 + 7*x^2*y^2 + 5 sage: f.univariate_polynomial() Traceback (most recent call last): ... TypeError: polynomial must involve at most one variable sage: g = f(10,y); g 700*y^2 + 305 - 2*y^-1 sage: h = g.univariate_polynomial(); h -2*y^-1 + 305 + 700*y^2 sage: h.parent() Univariate Laurent Polynomial Ring in y over Rational Field sage: g.univariate_polynomial(LaurentPolynomialRing(QQ,'z')) -2*z^-1 + 305 + 700*z^2 Here's an example with a constant multivariate polynomial:: sage: g = R(1) sage: h = g.univariate_polynomial(); h 1 sage: h.parent() Univariate Laurent Polynomial Ring in x over Integer Ring """ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing v = self.variables() if len(v) > 1: raise TypeError, "polynomial must involve at most one variable" elif len(v) == 1: x = v[0] i = self._parent.gens().index(x) else: x = 'x' i = 0 #construct ring if none if R is None: R = LaurentPolynomialRing(self.base_ring(),x) return R(dict((m[i],c) for m,c in self.dict().items())) def factor(self): """
• ## sage/rings/polynomial/laurent_polynomial_ring.py

diff -r 2a2abbcad325 sage/rings/polynomial/laurent_polynomial_ring.py`
 a from sage.rings.polynomial.polynomial_ring_constructor import _single_variate as _single_variate_poly from sage.rings.polynomial.polynomial_ring_constructor import _multi_variate as _multi_variate_poly from sage.misc.latex import latex from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_mpair from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_mpair, LaurentPolynomial_univariate from sage.rings.ring import CommutativeRing from sage.structure.parent_gens import ParentWithGens sage: R. = LaurentPolynomialRing(QQ) sage: (1 + w)^3 w^3 + 3*w^2 + 3*w + 1 1 + 3*w + 3*w^2 + w^3 You must specify a name:: sage: _single_variate(QQ, ('x',), False) Univariate Laurent Polynomial Ring in x over Rational Field """ ############################################################ # This should later get moved to an actual single variate  # # implementation with valuation tracking,                  # # but I don't want to right now.                           # ############################################################ # We need to come up with a name for the inverse that is easy to search # for in a string *and* doesn't overlap with the name that we already have. # For now, I'm going to use a name mangling with checking method. names = normalize_names(1, names) key = (base_ring, names, sparse) P = _get_from_cache(key) prepend_string += 'k' else: break R = _multi_variate_poly(base_ring, names, 1, sparse, 'degrevlex', None) P = LaurentPolynomialRing_mpair(R, prepend_string, names) R = _single_variate_poly(base_ring, names, sparse, None) P = LaurentPolynomialRing_univariate(R, names) _save_in_cache(key, P) return P """ if i < 0 or i >= self._n: raise ValueError, "generator not defined" return self(self._R.gen(i)) try: return self.__generators[i] except AttributeError: self.__generators = tuple(self(x) for x in self._R.gens()) return self.__generators[i] def is_integral_domain(self, proof = True): """ else: return LaurentPolynomialFunctor(vars[-1], True), LaurentPolynomialRing(self.base_ring(), vars[:-1]) def completion(self, p, prec=20, extras=None): """ EXAMPLES:: sage: LaurentPolynomialRing(QQ,2,'x').completion(3) Traceback (most recent call last): ... NotImplementedError sage: P.=LaurentPolynomialRing(QQ) sage: P Univariate Laurent Polynomial Ring in x over Rational Field sage: PP=P.completion(x) sage: PP Laurent Series Ring in x over Rational Field sage: f=1-1/x sage: PP(f) -x^-1 + 1 sage: 1/PP(f) -x - x^2 - x^3 - x^4 - x^5 - x^6 - x^7 - x^8 - x^9 - x^10 - x^11 - x^12 - x^13 - x^14 - x^15 - x^16 - x^17 - x^18 - x^19 - x^20 + O(x^21) """ raise NotImplementedError if str(p) == self._names[0] and self._n == 1: from sage.rings.laurent_series_ring import LaurentSeriesRing return LaurentSeriesRing(self.base_ring(), name=self._names[0]) else: raise TypeError, "Cannot complete %s with respect to %s" % (self, p) def remove_var(self, var): """ from sage.structure.coerce_maps import CallableConvertMap return CallableConvertMap(R, self, self._element_constructor_, parent_as_first_arg=False) elif isinstance(R, LaurentPolynomialRing_generic) and \ R.variable_names() == self.variable_names() and \ self.base_ring().has_coerce_map_from(R.base_ring()): return True else: f = self._R.coerce_map_from(R) if f is not None: base_ring = self.base_ring() if names is None: names = self.variable_names() if order is None: order = self.polynomial_ring().term_order() if self._n == 1: return LaurentPolynomialRing(base_ring, names[0], sparse = sparse) else: if order is None: order = self.polynomial_ring().term_order() return LaurentPolynomialRing(base_ring, self._n, names, order = order) class LaurentPolynomialRing_univariate(LaurentPolynomialRing_generic): def __init__(self, R, names): """ EXAMPLES:: sage: L = LaurentPolynomialRing(QQ,'x') sage: type(L) sage: L == loads(dumps(L)) True """ if R.ngens() != 1: raise ValueError, "n must be 1" if not R.base_ring().is_integral_domain(): raise ValueError, "base ring must be an integral domain" LaurentPolynomialRing_generic.__init__(self, R, '', names) def _element_constructor_(self, x): """ EXAMPLES:: sage: L = LaurentPolynomialRing(QQ,2,'x') sage: L(1/2) 1/2 """ return LaurentPolynomial_univariate(self, x) def __reduce__(self): return LaurentPolynomialRing_univariate, (self._R, self._names) class LaurentPolynomialRing_mpair(LaurentPolynomialRing_generic): def __init__(self, R, prepend_string, names): """ """ return LaurentPolynomial_mpair(self, x) def __reduce__(self): return LaurentPolynomialRing_mpair, (self._R, self._prepend_string, self._names)