def _element_constructor_(self, x, n=0): r""" Construct a Laurent series from `x`. INPUT: - ``x`` -- object that can be converted into a Laurent series - ``n`` -- (default: 0) multiply the result by `t^n` EXAMPLES:: sage: R.<u> = LaurentSeriesRing(Qp(5, 10)) sage: S.<t> = LaurentSeriesRing(RationalField()) sage: print R(t + t^2 + O(t^3)) (1 + O(5^10))*u + (1 + O(5^10))*u^2 + O(u^3) Note that coercing an element into its own parent just produces that element again (since Laurent series are immutable):: sage: u is R(u) True Rational functions are accepted:: sage: I = sqrt(-1) sage: K.<I> = QQ[I] sage: P.<t> = PolynomialRing(K) sage: L.<u> = LaurentSeriesRing(QQ[I]) 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 + 1/1024*I*u^18 + O(u^20) :: sage: L(t*I) / L(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 + 1/1024*I*u^18 + O(u^20) TESTS: When converting from `R((z))` to `R((z))((w))`, the variable `z` is sent to `z` rather than to `w` (see :trac:`7085`):: sage: A.<z> = LaurentSeriesRing(QQ) sage: B.<w> = LaurentSeriesRing(A) sage: B(z) z sage: z/w z*w^-1 Various conversions from PARI (see also :trac:`2508`):: sage: L.<q> = LaurentSeriesRing(QQ) sage: L.set_default_prec(10) doctest:...: DeprecationWarning: This method is deprecated. See http://trac.sagemath.org/16201 for details. sage: L(pari('1/x')) q^-1 sage: L(pari('polchebyshev(5)')) 5*q - 20*q^3 + 16*q^5 sage: L(pari('polchebyshev(5) - 1/x^4')) -q^-4 + 5*q - 20*q^3 + 16*q^5 sage: L(pari('1/polchebyshev(5)')) 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + O(q^9) sage: L(pari('polchebyshev(5) + O(x^40)')) 5*q - 20*q^3 + 16*q^5 + O(q^40) sage: L(pari('polchebyshev(5) - 1/x^4 + O(x^40)')) -q^-4 + 5*q - 20*q^3 + 16*q^5 + O(q^40) sage: L(pari('1/polchebyshev(5) + O(x^10)')) 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + 8192/125*q^9 + O(q^10) sage: L(pari('1/polchebyshev(5) + O(x^10)'), -10) # Multiply by q^-10 1/5*q^-11 + 4/5*q^-9 + 64/25*q^-7 + 192/25*q^-5 + 2816/125*q^-3 + 8192/125*q^-1 + O(1) sage: L(pari('O(x^-10)')) O(q^-10) """ 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 from sage.structure.element import parent P = parent(x) if isinstance(x, self.element_class) and n==0 and P is self: return x # ok, since Laurent series are immutable (no need to make a copy) elif P is self.base_ring(): # Convert x into a power series; if P is itself a Laurent # series ring A((t)), this prevents the implementation of # LaurentSeries.__init__() from effectively applying the # ring homomorphism A((t)) -> A((t))((u)) sending t to u # instead of the one sending t to t. We cannot easily # tell LaurentSeries.__init__() to be more strict, because # A((t)) -> B((u)) is expected to send t to u if A admits # a coercion to B but A((t)) does not, and this condition # would be inefficient to check there. x = self.power_series_ring()(x) elif isinstance(x, pari_gen): t = x.type() if t == "t_RFRAC": # Rational function x = self(self.polynomial_ring()(x.numerator())) / \ self(self.polynomial_ring()(x.denominator())) return (x << n) elif t == "t_SER": # Laurent series n += x._valp() bigoh = n + x.length() x = self(self.polynomial_ring()(x.Vec())) return (x << n).add_bigoh(bigoh) else: # General case, pretend to be a polynomial return self(self.polynomial_ring()(x)) << n elif is_FractionFieldElement(x) and \ (x.base_ring() is self.base_ring() or x.base_ring() == self.base_ring()) and \ (is_Polynomial(x.numerator()) or is_MPolynomial(x.numerator())): x = self(x.numerator())/self(x.denominator()) return (x << n) return self.element_class(self, x, n)
def __call__(self, x, n=0): r""" Coerces the element x into this Laurent series ring. INPUT: - ``x`` - the element to coerce - ``n`` - the result of the coercion will be multiplied by `t^n` (default: 0) EXAMPLES:: sage: R.<u> = LaurentSeriesRing(Qp(5, 10)) sage: S.<t> = LaurentSeriesRing(RationalField()) sage: print R(t + t^2 + O(t^3)) (1 + O(5^10))*u + (1 + O(5^10))*u^2 + O(u^3) Note that coercing an element into its own parent just produces that element again (since Laurent series are immutable):: sage: u is R(u) True Rational functions are accepted:: sage: I = sqrt(-1) sage: K.<I> = QQ[I] sage: P.<t> = PolynomialRing(K) sage: L.<u> = LaurentSeriesRing(QQ[I]) 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 + 1/1024*I*u^18 + O(u^20) :: sage: L(t*I) / L(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 + 1/1024*I*u^18 + O(u^20) Various conversions from PARI (see also #2508):: sage: L.<q> = LaurentSeriesRing(QQ) sage: L.set_default_prec(10) sage: L(pari('1/x')) q^-1 sage: L(pari('poltchebi(5)')) 5*q - 20*q^3 + 16*q^5 sage: L(pari('poltchebi(5) - 1/x^4')) -q^-4 + 5*q - 20*q^3 + 16*q^5 sage: L(pari('1/poltchebi(5)')) 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + O(q^9) sage: L(pari('poltchebi(5) + O(x^40)')) 5*q - 20*q^3 + 16*q^5 + O(q^40) sage: L(pari('poltchebi(5) - 1/x^4 + O(x^40)')) -q^-4 + 5*q - 20*q^3 + 16*q^5 + O(q^40) sage: L(pari('1/poltchebi(5) + O(x^10)')) 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + 8192/125*q^9 + O(q^10) sage: L(pari('1/poltchebi(5) + O(x^10)'), -10) # Multiply by q^-10 1/5*q^-11 + 4/5*q^-9 + 64/25*q^-7 + 192/25*q^-5 + 2816/125*q^-3 + 8192/125*q^-1 + O(1) sage: L(pari('O(x^-10)')) O(q^-10) """ 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): t = x.type() if t == "t_RFRAC": # Rational function x = self(self.polynomial_ring()(x.numerator())) / \ self(self.polynomial_ring()(x.denominator())) return (x << n) elif t == "t_SER": # Laurent series n += x._valp() bigoh = n + x.length() x = self(self.polynomial_ring()(x.Vec())) return (x << n).add_bigoh(bigoh) else: # General case, pretend to be a polynomial return self(self.polynomial_ring()(x)) << n elif is_FractionFieldElement(x) and \ (x.base_ring() is self.base_ring() or x.base_ring() == self.base_ring()) and \ (is_Polynomial(x.numerator()) or is_MPolynomial(x.numerator())): x = self(x.numerator()) / self(x.denominator()) return (x << n) else: return laurent_series_ring_element.LaurentSeries(self, x, n)
def _element_constructor_(self, x, n=0): r""" Construct a Laurent series from `x`. INPUT: - ``x`` -- object that can be converted into a Laurent series - ``n`` -- (default: 0) multiply the result by `t^n` EXAMPLES:: sage: R.<u> = LaurentSeriesRing(Qp(5, 10)) sage: S.<t> = LaurentSeriesRing(RationalField()) sage: print R(t + t^2 + O(t^3)) (1 + O(5^10))*u + (1 + O(5^10))*u^2 + O(u^3) Note that coercing an element into its own parent just produces that element again (since Laurent series are immutable):: sage: u is R(u) True Rational functions are accepted:: sage: I = sqrt(-1) sage: K.<I> = QQ[I] sage: P.<t> = PolynomialRing(K) sage: L.<u> = LaurentSeriesRing(QQ[I]) 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 + 1/1024*I*u^18 + O(u^20) :: sage: L(t*I) / L(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 + 1/1024*I*u^18 + O(u^20) TESTS: When converting from `R((z))` to `R((z))((w))`, the variable `z` is sent to `z` rather than to `w` (see :trac:`7085`):: sage: A.<z> = LaurentSeriesRing(QQ) sage: B.<w> = LaurentSeriesRing(A) sage: B(z) z sage: z/w z*w^-1 Various conversions from PARI (see also :trac:`2508`):: sage: L.<q> = LaurentSeriesRing(QQ) sage: L.set_default_prec(10) sage: L(pari('1/x')) q^-1 sage: L(pari('poltchebi(5)')) 5*q - 20*q^3 + 16*q^5 sage: L(pari('poltchebi(5) - 1/x^4')) -q^-4 + 5*q - 20*q^3 + 16*q^5 sage: L(pari('1/poltchebi(5)')) 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + O(q^9) sage: L(pari('poltchebi(5) + O(x^40)')) 5*q - 20*q^3 + 16*q^5 + O(q^40) sage: L(pari('poltchebi(5) - 1/x^4 + O(x^40)')) -q^-4 + 5*q - 20*q^3 + 16*q^5 + O(q^40) sage: L(pari('1/poltchebi(5) + O(x^10)')) 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + 8192/125*q^9 + O(q^10) sage: L(pari('1/poltchebi(5) + O(x^10)'), -10) # Multiply by q^-10 1/5*q^-11 + 4/5*q^-9 + 64/25*q^-7 + 192/25*q^-5 + 2816/125*q^-3 + 8192/125*q^-1 + O(1) sage: L(pari('O(x^-10)')) O(q^-10) """ 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 from sage.structure.element import parent P = parent(x) if isinstance(x, self.element_class) and n == 0 and P is self: return x # ok, since Laurent series are immutable (no need to make a copy) elif P is self.base_ring(): # Convert x into a power series; if P is itself a Laurent # series ring A((t)), this prevents the implementation of # LaurentSeries.__init__() from effectively applying the # ring homomorphism A((t)) -> A((t))((u)) sending t to u # instead of the one sending t to t. We cannot easily # tell LaurentSeries.__init__() to be more strict, because # A((t)) -> B((u)) is expected to send t to u if A admits # a coercion to B but A((t)) does not, and this condition # would be inefficient to check there. x = self.power_series_ring()(x) elif isinstance(x, pari_gen): t = x.type() if t == "t_RFRAC": # Rational function x = self(self.polynomial_ring()(x.numerator())) / \ self(self.polynomial_ring()(x.denominator())) return (x << n) elif t == "t_SER": # Laurent series n += x._valp() bigoh = n + x.length() x = self(self.polynomial_ring()(x.Vec())) return (x << n).add_bigoh(bigoh) else: # General case, pretend to be a polynomial return self(self.polynomial_ring()(x)) << n elif is_FractionFieldElement(x) and \ (x.base_ring() is self.base_ring() or x.base_ring() == self.base_ring()) and \ (is_Polynomial(x.numerator()) or is_MPolynomial(x.numerator())): x = self(x.numerator()) / self(x.denominator()) return (x << n) return self.element_class(self, x, n)
def __call__(self, x, n=0): r""" Coerces the element x into this Laurent series ring. INPUT: - ``x`` - the element to coerce - ``n`` - the result of the coercion will be multiplied by `t^n` (default: 0) EXAMPLES:: sage: R.<u> = LaurentSeriesRing(Qp(5, 10)) sage: S.<t> = LaurentSeriesRing(RationalField()) sage: print R(t + t^2 + O(t^3)) (1 + O(5^10))*u + (1 + O(5^10))*u^2 + O(u^3) Note that coercing an element into its own parent just produces that element again (since Laurent series are immutable):: sage: u is R(u) True Rational functions are accepted:: sage: I = sqrt(-1) sage: K.<I> = QQ[I] sage: P.<t> = PolynomialRing(K) sage: L.<u> = LaurentSeriesRing(QQ[I]) 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 + 1/1024*I*u^18 + O(u^20) :: sage: L(t*I) / L(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 + 1/1024*I*u^18 + O(u^20) Various conversions from PARI (see also #2508):: sage: L.<q> = LaurentSeriesRing(QQ) sage: L.set_default_prec(10) sage: L(pari('1/x')) q^-1 sage: L(pari('poltchebi(5)')) 5*q - 20*q^3 + 16*q^5 sage: L(pari('poltchebi(5) - 1/x^4')) -q^-4 + 5*q - 20*q^3 + 16*q^5 sage: L(pari('1/poltchebi(5)')) 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + O(q^9) sage: L(pari('poltchebi(5) + O(x^40)')) 5*q - 20*q^3 + 16*q^5 + O(q^40) sage: L(pari('poltchebi(5) - 1/x^4 + O(x^40)')) -q^-4 + 5*q - 20*q^3 + 16*q^5 + O(q^40) sage: L(pari('1/poltchebi(5) + O(x^10)')) 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + 8192/125*q^9 + O(q^10) sage: L(pari('1/poltchebi(5) + O(x^10)'), -10) # Multiply by q^-10 1/5*q^-11 + 4/5*q^-9 + 64/25*q^-7 + 192/25*q^-5 + 2816/125*q^-3 + 8192/125*q^-1 + O(1) sage: L(pari('O(x^-10)')) O(q^-10) """ 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): t = x.type() if t == "t_RFRAC": # Rational function x = self(self.polynomial_ring()(x.numerator())) / \ self(self.polynomial_ring()(x.denominator())) return (x << n) elif t == "t_SER": # Laurent series n += x._valp() bigoh = n + x.length() x = self(self.polynomial_ring()(x.Vec())) return (x << n).add_bigoh(bigoh) else: # General case, pretend to be a polynomial return self(self.polynomial_ring()(x)) << n elif is_FractionFieldElement(x) and \ (x.base_ring() is self.base_ring() or x.base_ring() == self.base_ring()) and \ (is_Polynomial(x.numerator()) or is_MPolynomial(x.numerator())): x = self(x.numerator())/self(x.denominator()) return (x << n) else: return laurent_series_ring_element.LaurentSeries(self, x, n)