# Ticket #9944: trac9944_faster_and_cleaner_coercion.2.patch

File trac9944_faster_and_cleaner_coercion.2.patch, 120.5 KB (added by mraum, 12 years ago)

Rebase to 4.7.1.alpha0

• ## sage/categories/category.py

# HG changeset patch
# User Simon King <simon.king@uni-jena.de>
# Date 1305801904 -7200
# Node ID d39a4e5e0267dc00fa94b2df86be784b40e1904e
#9944: Clean up coercion of polynomial rings (dense versus sparse etc).
Improve performance of _new_constant_poly by using specialised implementations.

diff -r 216c066ba752 sage/categories/category.py
 a Category of hom sets in Category of sets """ if hasattr(self, "HomCategory"): try: #if hasattr(self, "HomCategory"): return self.HomCategory(self) else: except AttributeError: return Category.join((category.hom_category() for category in self.super_categories())) def abstract_category(self):
• ## sage/categories/pushout.py

diff -r 216c066ba752 sage/categories/pushout.py
 a """ Construction functor for univariate polynomial rings. EXAMPLE: EXAMPLE:: sage: P = ZZ['t'].construction()[0] sage: P(GF(3)) sage: P(f)((x+y)*P(R).0) (-x + y)*t By trac ticket #9944, the construction functor distinguishes sparse and dense polynomial rings. Before, the following example failed:: sage: R. = PolynomialRing(GF(5), sparse=True) sage: F,B = R.construction() sage: F(B) is R True sage: S. = PolynomialRing(ZZ) sage: R.has_coerce_map_from(S) False sage: S.has_coerce_map_from(R) False sage: S.0 + R.0 2*x sage: (S.0 + R.0).parent() Univariate Polynomial Ring in x over Finite Field of size 5 sage: (S.0 + R.0).parent().is_sparse() False """ rank = 9 def __init__(self, var, multi_variate=False): def __init__(self, var, multi_variate=False, sparse=False): """ TESTS:: Functor.__init__(self, Rings(), Rings()) self.var = var self.multi_variate = multi_variate self.sparse = sparse def _apply_functor(self, R): """ """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing return PolynomialRing(R, self.var) return PolynomialRing(R, self.var, sparse=self.sparse) def __cmp__(self, other): """ if isinstance(other, MultiPolynomialFunctor): return other.merge(self) elif self == other: return self # i.e., they only differ in sparsity if not self.sparse: return self return other else: return None Q = R.quo(I,names=self.names) except IndexError: # That may happen! raise CoercionException, "Can not apply this quotient functor to %s"%R if self.as_field and hasattr(Q, 'field'): Q = Q.field() if self.as_field:# and hasattr(Q, 'field'): try: Q = Q.field() except AttributeError: pass return Q def __cmp__(self, other): sage: F(QQ)       # indirect doctest Algebraic Field """ if hasattr(R,'construction'): try: c = R.construction() if c is not None and c[0]==self: return R except AttributeError: pass return R.algebraic_closure() def merge(self, other):
• ## sage/modular/cusps.py

diff -r 216c066ba752 sage/modular/cusps.py
 a from sage.structure.element import Element, is_InfinityElement from sage.modular.modsym.p1list import lift_to_sl2z_llong from sage.matrix.all import is_Matrix from sage.misc.cachefunc import cached_method class Cusps_class(ParentWithBase): """ else: return self._coerce_try(x, QQ) @cached_method def zero_element(self): """ Return the zero cusp. NOTE: The existence of this method is assumed by some parts of Sage's coercion model. EXAMPLE:: sage: Cusps.zero_element() 0 """ return Cusp(0, parent=self) Cusps = Cusps_class()
• ## sage/modular/cusps_nf.py

diff -r 216c066ba752 sage/modular/cusps_nf.py
 a from sage.rings.integer_ring import IntegerRing from sage.structure.parent_base import ParentWithBase from sage.structure.element import Element, is_InfinityElement from sage.misc.cachefunc import cached_method _nfcusps_cache = {} def __call__(self, x): """ Coerce x into the set of cusps of a number field. Convert x into the set of cusps of a number field. EXAMPLES:: """ return NFCusp(self.number_field(), x, parent=self) @cached_method def zero_element(self): """ Return the zero cusp. NOTE: This method just exists to make some general algorithms work. It is not intended that the returned cusp is an additive neutral element. EXAMPLE:: sage: k. = NumberField(x^2 + 5) sage: kCusps = NFCusps(k) sage: kCusps.zero_element() Cusp [0: 1] of Number Field in a with defining polynomial x^2 + 5 """ return self(0) def number_field(self): """ Return the number field that this set of cusps is attached to.
• ## sage/modular/overconvergent/genus0.py

diff -r 216c066ba752 sage/modular/overconvergent/genus0.py
 a from sage.matrix.all        import matrix, MatrixSpace, diagonal_matrix from sage.misc.misc         import verbose from sage.misc.cachefunc    import cached_method from sage.modular.all       import (DirichletGroup, trivial_character, EtaProduct, j_invariant_qexp, hecke_operator_on_qexp) from sage.modular.arithgroup.all import (Gamma1, is_Gamma0, is_Gamma1) ##################################### # Element construction and coercion # #   (unfortunately not using        # #    the new coercion model)        # ##################################### def __call__(self, input): else: raise TypeError, "Don't know how to create an overconvergent modular form from %s" % input @cached_method def zero_element(self): """ Return the zero of this space. EXAMPLE:: sage: K. = Qp(13).extension(x^2-13); M = OverconvergentModularForms(13, 20, radius=1/2, base_ring=K) sage: K.zero_element() 0 """ return self(0) def _coerce_from_ocmf(self, f): r""" Try to convert the overconvergent modular form f into an element of self. An error will be raised if this is
• ## sage/modular/overconvergent/weightspace.py

diff -r 216c066ba752 sage/modular/overconvergent/weightspace.py
 a from sage.misc.misc import sxrange from sage.rings.padics.padic_generic_element import pAdicGenericElement from sage.misc.misc import verbose from sage.misc.cachefunc import cached_method import weakref _wscache = {} else: return ArbitraryWeight(self, arg1, arg2) @cached_method def zero_element(self): """ Return the zero of this weight space. EXAMPLES:: sage: W = pAdicWeightSpace(17) sage: W.zero_element() 0 """ return self(0) def prime(self): r""" Return the prime p such that this is a p-adic weight space.
• ## sage/modules/free_module_homspace.py

diff -r 216c066ba752 sage/modules/free_module_homspace.py
 a import sage.modules.free_module_morphism import sage.matrix.all as matrix import free_module_morphism from inspect import isfunction from matrix_morphism import MatrixMorphism def __call__(self, A, check=True): """ INPUT: A -- either a matrix or a list/tuple of images of generators check -- bool (default: True) - A -- either a matrix or a list/tuple of images of generators, or a function returning elements of the codomain for elements of the domain. - check -- bool (default: True) If A is a matrix, then it is the matrix of this linear transformation, with respect to the basis for the domain and identity morphism. EXAMPLES:: sage: V = (QQ^3).span_of_basis([[1,1,0],[1,0,2]]) sage: H = V.Hom(V); H Set of Morphisms from ... True sage: phi(V.0) == V.1 True The following tests against a bug that was fixed in trac ticket #9944. The method zero() calls this hom space with a function, not with a matrix, and that case had previously not been taken care of:: sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ) sage: V.Hom(V).zero()   # indirect doctest Free module morphism defined by the matrix [0 0 0] [0 0 0] [0 0 0] Domain: Free module of degree 3 and rank 3 over Integer Ring Echelon ... Codomain: Free module of degree 3 and rank 3 over Integer Ring Echelon ... """ if not matrix.is_Matrix(A): # Compute the matrix of the morphism that sends the # generators of the domain to the elements of A. C = self.codomain() try: v = [C(a) for a in A] A = matrix.matrix([C.coordinates(a) for a in v]) except TypeError: pass if isfunction(A): try: v = [C(A(g)) for g in self.domain().gens()] A = matrix.matrix([C.coordinates(a) for a in v]) except TypeError, msg: # Let us hope that FreeModuleMorphism knows to handle that case pass else: try: v = [C(a) for a in A] A = matrix.matrix([C.coordinates(a) for a in v]) except TypeError, msg: # Let us hope that FreeModuleMorphism knows to handle that case pass return free_module_morphism.FreeModuleMorphism(self, A) def _matrix_space(self): the homomorphisms in this free module homspace. OUTPUT: - matrix space - matrix space EXAMPLES:: Return a basis for this space of free module homomorphisms. OUTPUT: - tuple - tuple EXAMPLES::
• ## sage/rings/finite_rings/element_givaro.pyx

diff -r 216c066ba752 sage/rings/finite_rings/element_givaro.pyx
 a Sage includes the Givaro finite field library, for highly optimized arithmetic in finite fields. NOTES: The arithmetic is performed by the Givaro C++ library which uses Zech logs internally to represent finite field elements. This NOTES: The arithmetic is performed by the Givaro C++ library which uses Zech logs internally to represent finite field elements. This implementation is the default finite extension field implementation in Sage for the cardinality $< 2^{16}$, as it is vastly faster than the PARI implementation which uses polynomials to represent finite field elements. Some functionality in this class however is implemented using the PARI implementation. EXAMPLES: EXAMPLES:: sage: k = GF(5); type(k) sage: k = GF(5^2,'c'); type(k) AUTHORS: -- Martin Albrecht (2006-06-05) -- William Stein (2006-12-07): editing, lots of docs, etc. -- Robert Bradshaw (2007-05-23): is_square/sqrt, pow. - Martin Albrecht (2006-06-05) - William Stein (2006-12-07): editing, lots of docs, etc. - Robert Bradshaw (2007-05-23): is_square/sqrt, pow. """ e = e % self.characteristic() res = self.objectptr.initi(res,int(e)) elif e is None: e_int = 0 res = self.objectptr.initi(res,e_int) elif PY_TYPE_CHECK(e, float): res = self.objectptr.initd(res,e)
• ## sage/rings/finite_rings/finite_field_givaro.py

diff -r 216c066ba752 sage/rings/finite_rings/finite_field_givaro.py
 a Coerces several data types to self. INPUT: e -- data to coerce e -- data to coerce EXAMPLES: FiniteField_givaroElement are accepted where the parent is either self, equals self or is the prime subfield FiniteField_givaroElement are accepted where the parent is either self, equals self or is the prime subfield:: sage: k = GF(2**8, 'a') sage: k.gen() == k(k.gen()) True Floats, ints, longs, Integer are interpreted modulo characteristic Floats, ints, longs, Integer are interpreted modulo characteristic:: sage: k(2) 0 sage: k(float(2.0)) 0 Rational are interpreted as self(numerator)/self(denominator). Both may not be >= self.characteristic(). Rational are interpreted as self(numerator)/self(denominator). Both may not be >= self.characteristic(). :: sage: k = GF(3**8, 'a') sage: k(1/2) == k(1)/k(2) True Free module elements over self.prime_subfield() are interpreted 'little endian' Free module elements over self.prime_subfield() are interpreted 'little endian':: sage: k = GF(2**8, 'a') sage: e = k.vector_space().gen(1); e sage: k(e) a Strings are evaluated as polynomial representation of elements in self 'None' yields zero:: sage: k(None) 0 Strings are evaluated as polynomial representation of elements in self:: sage: k('a^2+1') a^2 + 1 Univariate polynomials coerce into finite fields by evaluating the polynomial at the field's generator: the polynomial at the field's generator:: sage: from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro sage: R. = QQ[] sage: k, a = FiniteField_givaro(5^2, 'a').objgen() q^2 + 2*q + 4 Multivariate polynomials only coerce if constant: Multivariate polynomials only coerce if constant:: sage: R = k['x,y,z']; R Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 5^2 sage: k(R(2)) ZeroDivisionError: division by zero in finite field. PARI elements are interpreted as finite field elements; this PARI flexibility is (absurdly!) liberal: PARI elements are interpreted as finite field elements; this PARI flexibility is (absurdly!) liberal:: sage: k = GF(2**8, 'a') sage: k(pari('Mod(1,2)')) sage: k(pari('Mod(1,3)*a^20')) a^7 + a^5 + a^4 + a^2 GAP elements need to be finite field elements: GAP elements need to be finite field elements:: sage: from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro sage: x = gap('Z(13)')
• ## sage/rings/polynomial/infinite_polynomial_element.py

diff -r 216c066ba752 sage/rings/polynomial/infinite_polynomial_element.py
 a Infinite polynomial ring in x over Rational Field """ if x._p not in self.base_ring(): #        if x._p not in self.base_ring(): try: p = self.base_ring()(x._p) except TypeError: raise NotImplementedError, "Fraction Fields of Infinite Polynomial Rings are not implemented" divisor = self.base_ring().one_element()/x._p # use induction... divisor = self.base_ring().one_element()/p # use induction... OUTP = self.parent().tensor_with_ring(divisor.base_ring()) return OUTP(self)*OUTP(divisor)
• ## sage/rings/polynomial/laurent_polynomial_ring.py

diff -r 216c066ba752 sage/rings/polynomial/laurent_polynomial_ring.py
 a # LaurentPolynomialRing(base_ring, names (list or tuple), order='degrevlex'): names = arg1 n = len(names) R = _multi_variate(base_ring, names, n, sparse, order) R = _multi_variate(base_ring, names, n, sparse, order) if arg1 is None and arg2 is None: raise TypeError, "you *must* specify the indeterminates (as not None)." prepend_string += 'k' else: break R = _multi_variate_poly(base_ring, names, 1, sparse, 'degrevlex') R = _multi_variate_poly(base_ring, names, 1, sparse, 'degrevlex', None) P = LaurentPolynomialRing_mpair(R, prepend_string, names) _save_in_cache(key, P) return P break else: break R = _multi_variate_poly(base_ring, names, n, sparse, order) R = _multi_variate_poly(base_ring, names, n, sparse, order, None) P = LaurentPolynomialRing_mpair(R, prepend_string, names) _save_in_cache(key, P) return P Composite map: From: Rational Field To:   Multivariate Laurent Polynomial Ring in x, y over Rational Field Defn:   Call morphism: Defn:   Polynomial base injection morphism: From: Rational Field To:   Multivariate Polynomial Ring in x, y over Rational Field then
• ## sage/rings/polynomial/multi_polynomial_element.py

diff -r 216c066ba752 sage/rings/polynomial/multi_polynomial_element.py
 a x = polydict.PolyDict(x, parent.base_ring()(0), remove_zero=True) MPolynomial_element.__init__(self, parent, x) def _new_constant_poly(self, x, P): """ Quickly create a new constant polynomial with value x in parent P. ASSUMPTION: x must be an element of the base ring of P. That assumption is not verified. EXAMPLE:: sage: R. = QQ['t'][] sage: x._new_constant_poly(R.base_ring()(2),R) 2 """ return MPolynomial_polydict(P, {P._zero_tuple:x}) def __neg__(self): """ EXAMPLES::
• ## sage/rings/polynomial/multi_polynomial_libsingular.pxd

diff -r 216c066ba752 sage/rings/polynomial/multi_polynomial_libsingular.pxd
 a from sage.rings.polynomial.multi_polynomial_ring_generic cimport MPolynomialRing_generic from sage.structure.parent cimport Parent cdef class MPolynomialRing_libsingular cdef class MPolynomial_libsingular(MPolynomial): cdef poly *_poly cpdef _repr_short_(self) cpdef is_constant(self) cpdef _homogenize(self, int var) cpdef MPolynomial_libsingular _new_constant_poly(self, x, MPolynomialRing_libsingular P) cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): cdef object __singular cdef object __macaulay2 cdef object __m2_set_ring_cache cdef object __minpoly cdef poly *_one_element_poly cdef ring *_ring cdef int _cmp_c_impl(left, Parent right) except -2
• ## sage/rings/polynomial/multi_polynomial_libsingular.pyx

diff -r 216c066ba752 sage/rings/polynomial/multi_polynomial_libsingular.pyx
 a TEST: Make sure that a faster conversion map from the base ring is used; Make sure that a faster coercion map from the base ring is used; see trac ticket #9944:: sage: R. = PolynomialRing(ZZ) sage: R.convert_map_from(R.base_ring()) sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: From: Integer Ring To:   Multivariate Polynomial Ring in x, y over Integer Ring self.__ngens = n self._ring = singular_ring_new(base_ring, n, self._names, order) self._one_element = new_MP(self,p_ISet(1, self._ring)) self._one_element_poly = (self._one_element)._poly self._zero_element = new_MP(self,NULL) # This polynomial ring should belong to Algebras(base_ring). # Algebras(...).parent_class, which was called from MPolynomialRing_generic.__init__, # wipe the memory and construct the conversion from scratch. from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection base_inject = PolynomialBaseringInjection(base_ring, self) self.register_conversion(base_inject) self.register_coercion(base_inject) def __dealloc__(self): r""" return new_MP(self, _p) if hasattr(element,'_polynomial_'): try: #if hasattr(element,'_polynomial_'): # SymbolicVariable return element._polynomial_(self) except AttributeError: pass if is_Macaulay2Element(element): return self(element.external_string()) if self._parent is not None and (self._parent)._ring != NULL and self._poly != NULL: p_Delete(&self._poly, (self._parent)._ring) cpdef MPolynomial_libsingular _new_constant_poly(self, x, MPolynomialRing_libsingular P): r""" Quickly create a new constant polynomial with value x in the parent P. ASSUMPTION: The value x must be an element of the base ring. That assumption is not verified. EXAMPLE:: sage: R. = QQ[] sage: x._new_constant_poly(2/1,R) 2 """ if not x: return new_MP(P, NULL) cdef ring *_ring = P._ring cdef poly *_p singular_polynomial_rmul(&_p, P._one_element_poly, x, _ring) return new_MP(P,_p) def __call__(self, *x, **kwds): """ Evaluate this multi-variate polynomial at x, where x
• ## sage/rings/polynomial/multi_polynomial_ring.py

diff -r 216c066ba752 sage/rings/polynomial/multi_polynomial_ring.py
 a if n: from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection base_inject = PolynomialBaseringInjection(base_ring, self) self.register_conversion(base_inject) self.register_coercion(base_inject) def _monomial_order_function(self): return self.__monomial_order_function

diff -r 216c066ba752 sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py
 a (1 + O(13^7))*t + (2 + O(13^7)) """ Polynomial.__init__(self, parent, is_gen=is_gen) parentbr = parent.base_ring() from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing if construct: (self._poly, self._valbase, self._relprecs, self._normalized, self._valaddeds, self._list) = x #the last two of these may be None self._poly = PolynomialRing(ZZ, parent.variable_name()).gen() self._valbase = 0 self._valaddeds = [infinity, 0] self._relprecs = [infinity, parent.base_ring().precision_cap()] self._relprecs = [infinity, parentbr.precision_cap()] self._normalized = True self._list = None return elif x.base_ring() is ZZ: self._poly = x self._valbase = Integer(0) p = parent.base_ring().prime() self._relprecs = [c.valuation(p) + parent.base_ring().precision_cap() for c in x.list()] p = parentbr.prime() self._relprecs = [c.valuation(p) + parentbr.precision_cap() for c in x.list()] self._comp_valaddeds() self._normalized = len(self._valaddeds) == 0 or (min(self._valaddeds) == 0) self._list = None self._adjust_prec_info(absprec, relprec) return else: x = [parent.base_ring()(a) for a in x.list()] x = [parentbr(a) for a in x.list()] check = False elif isinstance(x, dict): zero = parent.base_ring()(0) zero = parentbr.zero_element() n = max(x.keys()) v = [zero for _ in xrange(n + 1)] for i, z in x.iteritems(): v[i] = z x = v elif isinstance(x, pari_gen): x = [parent.base_ring()(w) for w in x.Vecrev()] x = [parentbr(w) for w in x.Vecrev()] check = False #The default behavior if we haven't already figured out what the type is is to assume it coerces into the base_ring as a constant polynomial elif not isinstance(x, list): x = [x] # constant polynomial # In contrast to other polynomials, the zero element is not distinguished # by having its list empty. Instead, it has list [0] if not x: x = [parentbr.zero_element()] if check: x = [parent.base_ring()(z) for z in x] x = [parentbr(z) for z in x] # Remove this -- for p-adics this is terrible, since it kills any non exact zero. #if len(x) == 1 and not x[0]: if not absprec is infinity or not relprec is infinity: self._adjust_prec_info(absprec, relprec) def _new_constant_poly(self, a, P): """ Create a new constant polynomial in parent P with value a. ASSUMPTION: The value a must be an element of the base ring of P. That assumption is not verified. EXAMPLE:: sage: R. = Zp(5)[] sage: t._new_constant_poly(O(5),R) (O(5)) """ return self.__class__(P,[a], check=False) def _normalize(self): # Currently slow: need to optimize if not self._normalized:
• ## sage/rings/polynomial/polynomial_compiled.pyx

diff -r 216c066ba752 sage/rings/polynomial/polynomial_compiled.pyx
 a def __repr__(self): return "CompiledPolynomialFunction(%s)"%(self._dag) def __call__(self, x): return self.eval(x) cdef object eval(CompiledPolynomialFunction self, object x): cdef object temp try:
• ## sage/rings/polynomial/polynomial_element.pxd

diff -r 216c066ba752 sage/rings/polynomial/polynomial_element.pxd
 a from sage.structure.element import Element, CommutativeAlgebraElement from sage.structure.element cimport Element, CommutativeAlgebraElement, ModuleElement from sage.structure.parent cimport Parent from polynomial_compiled import CompiledPolynomialFunction from polynomial_compiled cimport CompiledPolynomialFunction cpdef Polynomial truncate(self, long n) cdef long _hash_c(self) cpdef constant_coefficient(self) cpdef Polynomial _new_constant_poly(self, a) cpdef Polynomial _new_constant_poly(self, a, Parent P) # UNSAFE, only call from an inplace operator # may return a new element if not possible to modify inplace cdef _inplace_truncate(self, long n) cdef class Polynomial_generic_dense(Polynomial): cdef Polynomial_generic_dense _new_c(self, list coeffs) cdef Polynomial_generic_dense _new_c(self, list coeffs, Parent P) cdef list __coeffs cdef void __normalize(self) #    cdef _dict_to_list(self, x, zero) cpdef Polynomial_generic_dense _new_constant_dense_poly(list coeffs, Parent P, sample) #cdef class Polynomial_generic_sparse(Polynomial): #    cdef object __coeffs # a python dict (for now)
• ## sage/rings/polynomial/polynomial_element.pyx

diff -r 216c066ba752 sage/rings/polynomial/polynomial_element.pyx
 a from sage.rings.integer cimport Integer from sage.rings.ideal import is_Ideal from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.categories.map cimport Map from sage.categories.morphism cimport Morphism import sage.rings.complex_interval_field is_ComplexIntervalField = sage.rings.complex_interval_field.is_ComplexIntervalField cdef class Polynomial(CommutativeAlgebraElement): """ A polynomial. #         that could be in derived class. #         Note that we are guaranteed that right is in the base ring, so this could be fast. if left == 0: return self.parent()(0) return self.parent().zero_element() return self.parent()(left) * self cpdef ModuleElement _rmul_(self, RingElement right): #         that could be in derived class. #         Note that we are guaranteed that right is in the base ring, so this could be fast. if right == 0: return self.parent()(0) return self.parent().zero_element() return self * self.parent()(right) def subs(self, *x, **kwds): """ cdef long i, d = self.degree() if len(kwds) >= 1: if kwds: P = self.parent() name = P.variable_name() if kwds.has_key(name): result = self[d] if len(x) > 1: other_args = x[1:] if hasattr(result, '__call__'): try: #if hasattr(result, '__call__'): result = result(other_args) else: except TypeError: #else: raise TypeError, "Wrong number of arguments" if d == -1: try: return a.parent().zero_element() except AttributeError: pass try: # for things like the interface to the PARI C library return a.parent()(0) except AttributeError: return result if d == 0: try: return a.parent().one_element() * result except AttributeError: pass try: # for things like the interface to the PARI C library return a.parent()(1) * result except AttributeError: return result sage: ~f 1/(x - 90283) """ return self.parent()(1)/self return self.parent().one_element()/self def inverse_of_unit(self): """ for i in range(n+1): for j in range(n-1): M[i+j, j+n] = m[i] v = vector(R, [R(1)] + [R(0)]*(2*n-2)) # the constant polynomial 1 v = vector(R, [R.one_element()] + [R.zero_element()]*(2*n-2)) # the constant polynomial 1 if M.is_invertible(): x = M.solve_right(v) # there has to be a better way to solve return a.parent()(list(x)[0:n]) (t^4 + O(t^5))*s^4 + (2*t^3 + O(t^4))*s^3 + (3*t^2 + O(t^3))*s^2 + (2*t + O(t^2))*s + 1 """ if right == 0 or self == 0: return self._parent(0) return self._parent.zero_element() if self._parent.is_exact(): return self._mul_karatsuba(right) P = self.parent() R = P.base_ring() if P.is_sparse(): v = {right:R(1)} v = {right:R.one_element()} else: v = [R(0)]*right + [R(1)] v = [R.zero_element()]*right + [R.one_element()] r = self.parent()(v, check=False) else: r = generic_power(self, right) x = self.list() cdef Py_ssize_t i, j cdef Py_ssize_t d = len(x)-1 zero = self._parent.base_ring()(0) zero = self._parent.base_ring().zero_element() two = self._parent.base_ring()(2) coeffs = [zero] * (2 * d + 1) for i from 0 <= i <= d: return self cdef Py_ssize_t n, degree = self.degree() if degree == 0: return self.parent()(0) return self.parent().zero_element() coeffs = self.list() return self._parent([n*coeffs[n] for n from 1 <= n <= degree]) """ cdef Py_ssize_t n, degree = self.degree() if degree < 0: return self.parent()(0) return self.parent().zero_element() coeffs = self.list() v = [0, coeffs[0]] + [coeffs[n]/(n+1) for n from 1 <= n <= degree] else: # Otherwise we have to adjust for # the content ignored by PARI. content_fix = R.base_ring()(1) content_fix = R.base_ring().one_element() for f, e in F: if not f.is_monic(): content_fix *= f.leading_coefficient()**e unit //= content_fix if not unit.is_unit(): F.append((R(unit), ZZ(1))) unit = R.base_ring()(1) unit = R.base_ring().one_element() if not n is None: pari.set_real_precision(n)  # restore precision """ return self[0] cpdef Polynomial _new_constant_poly(self, a): """ Create a new constant polynomial from a, which MUST be an element of the base ring. """ return self._parent._element_constructor(a) cpdef Polynomial _new_constant_poly(self, a, Parent P): """ Create a new constant polynomial from a in P, which MUST be an element of the base ring of P (this is not checked). EXAMPLE:: sage: R. = PolynomialRing(GF(9,'a'), sparse=True) sage: a = w._new_constant_poly(0, R); a 0 sage: a.coeffs() [] """ if a: return self.__class__(P,[a], check=False) #P._element_constructor(a, check=False) return self.__class__(P,[], check=False) def is_monic(self): """ if n < 0: raise ValueError, "n must be at least 0" if len(v) < n: z = self._parent.base_ring()(0) z = self._parent.base_ring().zero_element() return v + [z]*(n - len(v)) else: return v[:int(n)] """ if other.is_zero(): R = self.parent() return self, R(1), R(0) return self, R.one_element(), R.zero_element() # Algorithm 3.2.2 of Cohen, GTM 138 R = self.parent() A = self B = other U = R(1) U = R.one_element() G = A V1 = R(0) V1 = R.zero_element() V3 = B while not V3.is_zero(): Q, R = G.quo_rem(V3) if n == 0 or self.degree() < 0: return self   # safe because immutable. if n > 0: output = [self.base_ring()(0)] * n output = [self.base_ring().zero_element()] * n output.extend(self.coeffs()) return self._parent(output, check=False) if n < 0: EXAMPLES:: sage: R. = ZZ[]; S. = R[] sage: R. = ZZ[]; S. = PolynomialRing(R, sparse=True) sage: f = y^3 + x*y -3*x; f y^3 + x*y - 3*x sage: f.truncate(2) sage: f.truncate(0) 0 """ return self._parent(self[:n], check=False) # We must not have check=False, since 0 must not have __coeffs = [0]. return self._parent(self[:n])#, check=False) cdef _inplace_truncate(self, long prec): return self.truncate(prec) t0 = bd return _karatsuba_sum(t0,_karatsuba_sum(t1,t2)) cpdef Polynomial_generic_dense _new_constant_dense_poly(list coeffs, Parent P, sample): cdef Polynomial_generic_dense f = PY_NEW_SAME_TYPE(sample) f._parent = P f.__coeffs = coeffs return f cdef class Polynomial_generic_dense(Polynomial): """ A generic dense polynomial. """ def __init__(self, parent, x=None, int check=1, is_gen=False, int construct=0, **kwds): Polynomial.__init__(self, parent, is_gen=is_gen) if x is None: self.__coeffs = [] return R = parent.base_ring() if PY_TYPE_CHECK(x, list): if check: self.__coeffs = [R(t) for t in x] self.__normalize() else: self.__coeffs = x return if sage.rings.fraction_field_element.is_FractionFieldElement(x): if x.denominator() != 1: raise TypeError, "denominator must be 1" if PY_TYPE_CHECK(x, Polynomial): if (x)._parent is self._parent: x = list(x.list()) elif (x)._parent is R or (x)._parent == R: elif R.has_coerce_map_from((x)._parent):# is R or (x)._parent == R: try: if x.is_zero(): self.__coeffs = [] return except (AttributeError, TypeError): pass x = [x] else: x = [R(a, **kwds) for a in x.list()] check = 0 elif PY_TYPE_CHECK(x, list): pass self.__coeffs = [R(a, **kwds) for a in x.list()] if check: self.__normalize() return elif PY_TYPE_CHECK(x, int) and x == 0: self.__coeffs = [] return elif isinstance(x, dict): x = self._dict_to_list(x, R(0)) x = self._dict_to_list(x, R.zero_element()) elif isinstance(x, pari_gen): x = [R(w, **kwds) for w in x.Vecrev()] check = 1 check = 0 elif not isinstance(x, list): # We trust that the element constructors do not send x=0 #            if x: x = [x]   # constant polynomials #            else: #                x = []    # zero polynomial if check: self.__coeffs = [R(z, **kwds) for z in x] self.__normalize() else: self.__coeffs = x if check: self.__normalize() cdef Polynomial_generic_dense _new_c(self, list coeffs): cdef Polynomial_generic_dense _new_c(self, list coeffs, Parent P): cdef Polynomial_generic_dense f = PY_NEW_SAME_TYPE(self) f._parent = self._parent f._parent = P f.__coeffs = coeffs return f cpdef Polynomial _new_constant_poly(self, a): """ Create a new constant polynomial from a, which MUST be an element of the base ring. EXAMPLES: cpdef Polynomial _new_constant_poly(self, a, Parent P): """ Create a new constant polynomial in P with value a. ASSUMPTION: The given value **must** be an element of the base ring. That assumption is not verified. EXAMPLES:: sage: S. = QQ[] sage: R. = S[] sage: x._new_constant_poly(y+1) sage: x._new_constant_poly(y+1, R) y + 1 sage: parent(x._new_constant_poly(y+1)) sage: parent(x._new_constant_poly(y+1, R)) Univariate Polynomial Ring in x over Univariate Polynomial Ring in y over Rational Field """ if a: return self._new_c([a]) return self._new_c([a],P) else: return self._new_c([]) return self._new_c([],P) def __reduce__(self): """ 0 """ if n < 0 or n >= len(self.__coeffs): return self.base_ring()(0) return self.base_ring().zero_element() return self.__coeffs[n] def __getslice__(self, Py_ssize_t i, j): i = 0 zeros = [] elif i > 0: zeros = [self._parent.base_ring()(0)] * i zeros = [self._parent.base_ring().zero_element()] * i return self._parent(zeros + self.__coeffs[i:j]) def _unsafe_mutate(self, n, value): elif n < 0: raise IndexError, "polynomial coefficient index must be nonnegative" elif value != 0: zero = self.base_ring()(0) zero = self.base_ring().zero_element() for _ in xrange(len(self.__coeffs), n): self.__coeffs.append(zero) self.__coeffs.append(value) sage: f.quo_rem(1+2*x) (4*x^2 + 4*x + 5/2, -3/2) """ if right.parent() == self.parent(): P = (self)._parent if right.parent() == P: return Polynomial.__floordiv__(self, right) d = self.parent().base_ring()(right) cdef Polynomial_generic_dense res = self._new_c([c // d for c in self.__coeffs]) d = P.base_ring()(right) cdef Polynomial_generic_dense res = self._new_c([c // d for c in self.__coeffs], P) res.__normalize() return res min = len(x) cdef list low = [x[i] + y[i] for i from 0 <= i < min] if len(x) == len(y): res = self._new_c(low) res = self._new_c(low, self._parent) res.__normalize() return res else: return self._new_c(low + high) return self._new_c(low + high, self._parent) cpdef ModuleElement _iadd_(self, ModuleElement right): cdef Py_ssize_t check=0, i, min min = len(x) low = [x[i] - y[i] for i from 0 <= i < min] if len(x) == len(y): res = self._new_c(low) res = self._new_c(low, self._parent) res.__normalize() return res else: return self._new_c(low + high) return self._new_c(low + high, self._parent) cpdef ModuleElement _isub_(self, ModuleElement right): cdef Py_ssize_t check=0, i, min if c._parent is not (self.__coeffs[0])._parent: c = (self.__coeffs[0])._parent._coerce_c(c) v = [c * a for a in self.__coeffs] cdef Polynomial_generic_dense res = self._new_c(v) if not v[len(v)-1]: res.__normalize() cdef Polynomial_generic_dense res = self._new_c(v, self._parent) #if not v[len(v)-1]: # "normalize" checks this anyway... res.__normalize() return res cpdef ModuleElement _lmul_(self, RingElement c): if c._parent is not (self.__coeffs[0])._parent: c = (self.__coeffs[0])._parent._coerce_c(c) v = [a * c for a in self.__coeffs] cdef Polynomial_generic_dense res = self._new_c(v) if not v[len(v)-1]: res.__normalize() cdef Polynomial_generic_dense res = self._new_c(v, self._parent) #if not v[len(v)-1]: # "normalize" checks this anyway... res.__normalize() return res cpdef ModuleElement _ilmul_(self, RingElement c): t """ if len(self.__coeffs) == 0: return self.base_ring()(0) return self.base_ring().zero_element() else: return self.__coeffs[0] if n == 0 or self.degree() < 0: return self if n > 0: output = [self.base_ring()(0)] * n output = [self.base_ring().zero_element()] * n output.extend(self.__coeffs) return self._new_c(output) return self._new_c(output, self._parent) if n < 0: if n > len(self.__coeffs) - 1: return self._parent([]) else: return self._new_c(self.__coeffs[-int(n):]) return self._new_c(self.__coeffs[-int(n):], self._parent) cpdef Polynomial truncate(self, long n): r""" sage: type(f) """ if n < len(self.__coeffs): while n > 0 and not self.__coeffs[n-1]: n -= 1 return self._new_c(self.__coeffs[:n]) l = len(self.__coeffs) if n > l: n = l while n > 0 and not self.__coeffs[n-1]: n -= 1 return self._new_c(self.__coeffs[:n], self._parent) cdef _inplace_truncate(self, long n): if n < len(self.__coeffs): """ This class is used for conversion from a polynomial ring to its base ring. It calls the constant_coefficient method, which can be optimized for a particular polynomial type. Since trac ticket #9944, it calls the constant_coefficient method, which can be optimized for a particular polynomial type. EXAMPLES:: sage: P0. = GF(3)[] sage: P1. = GF(3)[] sage: P0(-y_1)    # indirect doctest 2*y_1 sage: phi = GF(3).convert_map_from(P0); phi Generic map: From: Univariate Polynomial Ring in y_1 over Finite Field of size 3 To:   Finite Field of size 3 sage: type(phi) sage: phi(P0.one_element()) 1 sage: phi(y_1) Traceback (most recent call last): ... TypeError: not a constant polynomial """ cpdef Element _call_(self, x): """ TypeError: not a constant polynomial """ if x.degree() <= 0: return ((x).constant_coefficient()) try: return (x.constant_coefficient()) except AttributeError: return ((x).constant_coefficient()) else: raise TypeError, "not a constant polynomial" This class is used for conversion from a ring to a polynomial over that ring. If the polynomial ring has a One and if the elements provide an _rmul_ method, and _rmul_ does *not* return None (which is the case for p-adics) then conversion is obtained by multiplying the base ring element with the One by means of _rmul_. Otherwise It calls the _new_constant_poly method on the generator, which should be optimized for a particular polynomial type, but often isn't. It calls the _new_constant_poly method on the generator, which should be optimized for a particular polynomial type. Technically, it should be a method of the polynomial ring, but few polynomial rings are cython classes. NOTE: We use _rmul_ and not _lmul_ since for many polynomial rings _lmul_ simply calls _rmul_. few polynomial rings are cython classes, and so, as a method of a cython polynomial class, it is faster. EXAMPLES: We demonstrate that different polynomial ring classes use polynomial base injection maps:: We demonstrate that most polynomial ring classes use polynomial base injection maps for coercion. They are supposed to be the fastest maps for that purpose. See trac ticket #9944:: sage: R. = Qp(3)[] sage: R.convert_map_from(R.base_ring()) sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: From: 3-adic Field with capped relative precision 20 To:   Univariate Polynomial Ring in x over 3-adic Field with capped relative precision 20 sage: R. = Qp(3)[] sage: R.convert_map_from(R.base_ring()) sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: From: 3-adic Field with capped relative precision 20 To:   Multivariate Polynomial Ring in x, y over 3-adic Field with capped relative precision 20 sage: R. = QQ[] sage: R.convert_map_from(R.base_ring()) sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: From: Rational Field To:   Multivariate Polynomial Ring in x, y over Rational Field sage: R. = QQ[] sage: R.convert_map_from(R.base_ring()) sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: From: Rational Field To:   Univariate Polynomial Ring in x over Rational Field By trac ticket #9944, there are now only very few exceptions:: sage: PolynomialRing(QQ,names=[]).convert_map_from(QQ) sage: PolynomialRing(QQ,names=[]).coerce_map_from(QQ) Call morphism: From: Rational Field To:   Multivariate Polynomial Ring in no variables over Rational Field """ cdef RingElement _an_element cdef object _one_rmul_ cdef object _new_constant_poly_ def __init__(self, domain, codomain): """ (1 + 2 + O(2^20))*t """ assert domain is codomain.base_ring(), "domain must be basering" assert codomain.base_ring() is domain, "domain must be basering" Morphism.__init__(self, domain, codomain) self._an_element = codomain.gen() self._repr_type_str = "Polynomial base injection" if domain is codomain: # some rings are base rings of themselves! return try: one = codomain._element_constructor_(domain.one_element()) except (AttributeError, NotImplementedError, TypeError): # perhaps it uses the old model? try: one = codomain._coerce_c(domain.one_element()) except (AttributeError, NotImplementedError, TypeError): return try: one_rmul_ = one._rmul_ except AttributeError: return # For the p-adic fields, _lmul_ and _rmul_ return None!!! # To work around, we need to test its sanity before we try # to use it. try: if one_rmul_(domain.one_element()) is None: return self._one_rmul_ = one_rmul_ except TypeError: pass self._new_constant_poly_ = self._an_element._new_constant_poly cpdef Element _call_(self, x): """ TESTS: sage: parent(m(2)) Univariate Polynomial Ring in x over Integer Ring """ if self._one_rmul_ is not None: return self._one_rmul_(x) return self._an_element._new_constant_poly(x) return self._new_constant_poly_(x, self._codomain) cpdef Element _call_with_args(self, x, args=(), kwds={}): """ sage: m(1 + O(5^11), absprec = 5)   # indirect doctest (1 + O(5^11)) """ return self._codomain._element_constructor(x, *args, **kwds) try: return self._codomain._element_constructor_(x, *args, **kwds) except AttributeError: # if there is no element constructor, # there is a custom call method. return self._codomain(x, *args, **kwds) def section(self): """
• ## sage/rings/polynomial/polynomial_element_generic.py

diff -r 216c066ba752 sage/rings/polynomial/polynomial_element_generic.py
 a w = {} for n, c in x.dict().iteritems(): w[n] = R(c) #raise TypeError, "Cannot coerce %s into %s."%(x, parent) # The following line has been added in trac ticket #9944. # Apparently, the "else" case has never occured before. x = w elif isinstance(x, list): y = {} for i in xrange(len(x)): x^100000 + 4*x^75000 + 3*x AUTHOR: - David Harvey (2006-08-05) """ output = dict(self.__coeffs)
• ## sage/rings/polynomial/polynomial_integer_dense_flint.pxd

diff -r 216c066ba752 sage/rings/polynomial/polynomial_integer_dense_flint.pxd
 a from sage.rings.polynomial.polynomial_element cimport Polynomial from sage.rings.integer cimport Integer from sage.structure.parent cimport Parent cdef class Polynomial_integer_dense_flint(Polynomial): cdef fmpz_poly_t __poly
• ## sage/rings/polynomial/polynomial_integer_dense_flint.pyx

diff -r 216c066ba752 sage/rings/polynomial/polynomial_integer_dense_flint.pyx
 a x._is_gen = 0 return x cpdef Polynomial _new_constant_poly(self, a, Parent P): r""" Quickly creates a new constant polynomial with value a in parent P ASSUMPTION: The given value has to be in the base ring of P. This assumption is not verified. EXAMPLE:: sage: R. = ZZ[] sage: x._new_constant_poly(2,R) 2 """ cdef Polynomial_integer_dense_flint x = PY_NEW(Polynomial_integer_dense_flint) x._parent = P x._is_gen = 0 if not PY_TYPE_CHECK(a, Integer): a = ZZ(a) fmpz_poly_set_coeff_mpz(x.__poly, 0, (a).value) return x def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
• ## sage/rings/polynomial/polynomial_rational_flint.pxd

diff -r 216c066ba752 sage/rings/polynomial/polynomial_rational_flint.pxd
 a include "../../libs/flint/fmpq_poly.pxd" from sage.rings.polynomial.polynomial_element cimport Polynomial from sage.structure.parent cimport Parent cdef class Polynomial_rational_flint(Polynomial): cdef fmpq_poly_t __poly
• ## sage/rings/polynomial/polynomial_rational_flint.pyx

diff -r 216c066ba752 sage/rings/polynomial/polynomial_rational_flint.pyx
 a res._is_gen = 0 return res cpdef Polynomial _new_constant_poly(self, x, Parent P): r""" Quickly creates a new constant polynomial with value x in parent P ASSUMPTION: x must be a rational or convertible to an int. EXAMPLE:: sage: R. = QQ[] sage: x._new_constant_poly(2/1,R) 2 sage: x._new_constant_poly(2,R) 2 sage: x._new_constant_poly("2",R) 2 sage: x._new_constant_poly("2.1",R) Traceback (most recent call last): ... ValueError: invalid literal for int() with base 10: '2.1' """ cdef Polynomial_rational_flint res = PY_NEW(Polynomial_rational_flint) res._parent = P res._is_gen = 0 if PY_TYPE_CHECK(x, int): fmpq_poly_set_si(res.__poly, x) elif PY_TYPE_CHECK(x, Integer): fmpq_poly_set_mpz(res.__poly, ( x).value) elif PY_TYPE_CHECK(x, Rational): fmpq_poly_set_mpq(res.__poly, ( x).value) else: fmpq_poly_set_si(res.__poly, int(x)) return res def __cinit__(self): """ Initialises the underlying data structure.
• ## sage/rings/polynomial/polynomial_real_mpfr_dense.pyx

diff -r 216c066ba752 sage/rings/polynomial/polynomial_real_mpfr_dense.pyx
 a sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: PolynomialRealDense(RR['x'], [1, int(2), RR(3), 4/1, pi]) 3.14159265358979*x^4 + 4.00000000000000*x^3 + 3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000 sage: PolynomialRealDense(RR['x'], None) 0 """ Polynomial.__init__(self, parent, is_gen=is_gen) self._base_ring = parent._base cdef Py_ssize_t i, degree cdef int prec = self._base_ring.__prec cdef mp_rnd_t rnd = self._base_ring.rnd if x is None: self._coeffs = sage_malloc(sizeof(mpfr_t)) # degree zero mpfr_init2(self._coeffs[0], prec) mpfr_set_si(self._coeffs[0], PyInt_AS_LONG(int(0)), rnd) self._normalize() return if is_gen: x = [0, 1] elif isinstance(x, (int, float, Integer, Rational, RealNumber)):
• ## sage/rings/polynomial/polynomial_ring.py

diff -r 216c066ba752 sage/rings/polynomial/polynomial_ring.py
 a - Martin Albrecht (2006-08-25): removed it again as it isn't needed anymore - Simon King (2011-05): Dense and sparse polynomial rings must not be equal. EXAMPLES: Creating a polynomial ring injects the variable into the interpreter namespace:: sage: z = QQ['z'].0 sage: k = PolynomialRing(ZZ,'y', sparse=True); loads(dumps(k)) Sparse Univariate Polynomial Ring in y over Integer Ring The rings of sparse and dense polynomials in the same variable are canonically isomorphic:: sage: PolynomialRing(ZZ,'y', sparse=True) == PolynomialRing(ZZ,'y') True Rings with different variable names are not equal:: sage: QQ['y'] < QQ['x'] False sage: g * f w^2 + (i + j)*w - k Trac ticket #9944 introduced some changes related with coercion. Previously, a dense and a sparse polynomial ring with the same variable name over the same base ring evaluated equal, but of course they were not identical.Coercion maps are cached - but if a coercion to a dense ring is requested and a coercion to a sparse ring is returned instead (since the cache keys are equal!), all hell breaks loose. Therefore, the coercion between rings of sparse and dense polynomials works as follows:: sage: R. = PolynomialRing(QQ, sparse=True) sage: S. = QQ[] sage: S == R False sage: S.has_coerce_map_from(R) True sage: R.has_coerce_map_from(S) False sage: (R.0+S.0).parent() Univariate Polynomial Ring in x over Rational Field sage: (S.0+R.0).parent() Univariate Polynomial Ring in x over Rational Field It may be that one has rings of dense or sparse polynomials over different base rings. In that situation, coercion works by means of the :func:~sage.categories.pushout.pushout formalism:: sage: R. = PolynomialRing(GF(5), sparse=True) sage: S. = PolynomialRing(ZZ) sage: R.has_coerce_map_from(S) False sage: S.has_coerce_map_from(R) False sage: S.0 + R.0 2*x sage: (S.0 + R.0).parent() Univariate Polynomial Ring in x over Finite Field of size 5 sage: (S.0 + R.0).parent().is_sparse() False Similarly, there is a coercion from the (non-default) NTL implementation for univariate polynomials over the integers to the default FLINT implementation, but not vice versa:: sage: R. = PolynomialRing(ZZ, implementation = 'NTL') sage: S. = PolynomialRing(ZZ, implementation = 'FLINT') sage: (S.0+R.0).parent() is S True sage: (R.0+S.0).parent() is S True TESTS:: sage: K.=FractionField(QQ['x']) from sage.rings.integer_ring import is_IntegerRing, IntegerRing from sage.rings.integer import Integer from sage.libs.pari.all import pari_gen import sage.misc.defaults import sage.misc.latex as latex from sage.misc.prandom import randint from sage.misc.cachefunc import cached_method from sage.rings.real_mpfr import is_RealField from polynomial_real_mpfr_dense import PolynomialRealDense from sage.rings.polynomial.polynomial_singular_interface import PolynomialRing_singular_repr def _element_constructor_(self, x=None, check=True, is_gen = False, construct=False, **kwds): r""" Coerce x into this univariate polynomial ring, Convert x into this univariate polynomial ring, possibly non-canonically. Stacked polynomial rings coerce into constants if possible. First, -y TESTS: This shows that the issue at trac #4106 is fixed:: sage: x = var('x') x """ C = self._polynomial_class if isinstance(x, list): return C(self, x, check=check, is_gen=False,construct=construct) if isinstance(x, Element): P = x.parent() if P is self: return x elif P is self.base_ring(): # It *is* the base ring, hence, we should not need to check. # Moreover, if x is equal to zero then we usually need to # provide [] to the polynomial class, not [x], if we don't want # to check (normally, polynomials like to strip trailing zeroes). # However, in the padic case, we WANT that trailing # zeroes are not stripped, because O(5)==0, but still it must # not be forgotten. It should be the job of the __init__ method # to decide whether to strip or not to strip. return C(self, [x], check=False, is_gen=False, construct=construct) elif P == self.base_ring(): return C(self, [x], check=True, is_gen=False, construct=construct) construct=construct) elif self.base_ring().has_coerce_map_from(P): return C(self, [x], check=True, is_gen=False, construct=construct) if hasattr(x, '_polynomial_'): return x._polynomial_(self) try: #if hasattr(x, '_polynomial_'): return x._polynomial_(self) except AttributeError: pass if isinstance(x, SingularElement) and self._has_singular: self._singular_().set_ring() try: raise TypeError, "denominator must be a unit" if x.type() != 't_POL': x = x.Polrev() return C(self, x, check, is_gen, construct=construct, **kwds) def is_integral_domain(self, proof = True): def construction(self): from sage.categories.pushout import PolynomialFunctor return PolynomialFunctor(self.variable_name()), self.base_ring() return PolynomialFunctor(self.variable_name(), sparse=self.__is_sparse), self.base_ring() def completion(self, p, prec=20, extras=None): """ - any ring that canonically coerces to the base ring of this ring. - polynomial rings in the same variable over any base ring that canonically coerces to the base ring of this ring canonically coerces to the base ring of this ring. Caveat: There is no coercion from a dense into a sparse polynomial ring. So, when adding a dense and a sparse polynomial, the result will be dense. See trac ticket #9944. EXAMPLES:: Polynomial base injection morphism: From: Rational Field To:   Univariate Polynomial Ring in x over Rational Field Here we test against the change in the coercions introduced in trac ticket #9944:: sage: R. = PolynomialRing(QQ, sparse=True) sage: S. = QQ[] sage: (R.0+S.0).parent() Univariate Polynomial Ring in x over Rational Field sage: (S.0+R.0).parent() Univariate Polynomial Ring in x over Rational Field """ # handle constants that canonically coerce into self.base_ring() # first, if possible # coerces into self.base_ring() try: if is_PolynomialRing(P): if self.__is_sparse and not P.is_sparse(): return False if P.variable_name() == self.variable_name(): if P.base_ring() is self.base_ring() and \ self.base_ring() is ZZ_sage: # of the polynomial ring canonically coerce into codomain. # Since poly rings are free, any image of the gen # determines a homomorphism codomain.coerce(self.base_ring()(1)) codomain.coerce(self.base_ring().one_element()) except TypeError: return False return True def __cmp__(left, right): c = cmp(type(left),type(right)) if c: return c return cmp((left.base_ring(), left.variable_name()), (right.base_ring(), right.variable_name())) #    Polynomial rings should be unique parents. Hence, #    no need for __cmp__. Or actually, having a __cmp__ #    method that identifies a dense with a sparse ring #    is a bad bad idea! #    def __cmp__(left, right): #        c = cmp(type(left),type(right)) #        if c: return c #        return cmp((left.base_ring(), left.variable_name()), (right.base_ring(), right.variable_name())) def __hash__(self): # should be faster than just relying on the string representation try: return self._cached_hash except AttributeError: pass h = self._cached_hash = hash((self.base_ring(),self.variable_name())) return h def _repr_(self): try: return self._cached_repr except AttributeError: pass s = "Univariate Polynomial Ring in %s over %s"%( self.variable_name(), self.base_ring()) if self.is_sparse(): s = "Sparse " + s self._cached_repr = s return s def _latex_(self): Refer to monics() for full documentation. """ base = self.base_ring() for coeffs in sage.misc.mrange.xmrange_iter([[base(1)]]+[base]*of_degree): for coeffs in sage.misc.mrange.xmrange_iter([[base.one_element()]]+[base]*of_degree): # Each iteration returns a *new* list! # safe to mutate the return coeffs.reverse() Refer to polynomials() for full documentation. """ base = self.base_ring() base0 = base.zero_element() for leading_coeff in base: if leading_coeff != base(0): if leading_coeff != base0: for lt1 in sage.misc.mrange.xmrange_iter([base]*(of_degree)): # Each iteration returns a *new* list! # safe to mutate the return element_class = Polynomial_integer_dense_flint self._implementation_names = (None, 'FLINT') else: raise ValueError, "Unknown implementation %s for ZZ[x]" raise ValueError, "Unknown implementation %s for ZZ[x]"%implementation PolynomialRing_commutative.__init__(self, base_ring, name=name, sparse=sparse, element_class=element_class)
• ## sage/rings/polynomial/polynomial_ring_constructor.py

diff -r 216c066ba752 sage/rings/polynomial/polynomial_ring_constructor.py
 a This module provides the function :func:PolynomialRing, which constructs rings of univariate and multivariate polynomials, and implements caching to prevent the same ring being created in memory multiple times (which is wasteful). wasteful and breaks the general assumption in Sage that parents are unique). There is also a function :func:BooleanPolynomialRing_constructor, used for constructing Boolean polynomial rings, which are not technically polynomial - implementation -- string or None; selects an implementation in cases where Sage includes multiple choices (currently \ZZ[x] can be implemented with 'NTL' or 'FLINT'; default is 'FLINT') NOTE: The following rules were introduced in trac ticket #9944, in order to preserve the "unique parent assumption" in Sage (i.e., if two parents evaluate equal then they should actually be identical). - In the multivariate case, a dense representation is not supported. Hence, the argument sparse=False is silently ignored in that case. - If the given implementation does not exist for rings with the given number of generators and the given sparsity, then an error results. OUTPUT: You can't just globally change the names of those variables. This is because objects all over Sage could have pointers to that polynomial ring. :: that polynomial ring. :: sage: R._assign_names(['z','w']) Traceback (most recent call last): ... z^2 - 2*w^2 After the with block the names revert to what they were before. :: After the with block the names revert to what they were before. :: sage: print f x^2 - 2*y^2 integers, one based on NTL and one based on FLINT.  The default is FLINT. Note that FLINT uses a "more dense" representation for its polynomials than NTL, so in particular, creating a polynomial like 2^1000000 * x^1000000 in FLINT may be unwise. :: like 2^1000000 * x^1000000 in FLINT may be unwise. :: sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL Univariate Polynomial Ring in x over Integer Ring (using NTL) sage: xFLINT.parent() Univariate Polynomial Ring in x over Integer Ring There is a coercion between the two rings, so the values can be mixed in a single expression. :: There is a coercion from the non-default to the default implementation, so the values can be mixed in a single expression:: sage: (xNTL + xFLINT^2) x^2 + x Unfortunately, it is unpredictable whether the result of such an expression will use the NTL or FLINT implementation. :: The result of such an expression will use the default, i.e., the FLINT implementation:: sage: (xNTL + xFLINT^2).parent()        # random output sage: (xNTL + xFLINT^2).parent() Univariate Polynomial Ring in x over Integer Ring 2. PolynomialRing(base_ring, names,   order='degrevlex') Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 sage: (x2 + x41 + x71)^2 x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2 TESTS: We test here some changes introduced in #9944. If there is no dense implementation for the given number of variables, then requesting a dense ring results yields the corresponding sparse ring:: sage: R. = QQ[] sage: S. = PolynomialRing(QQ, sparse=False) sage: R is S True If the requested implementation is not known or not supported for the given number of variables and the given sparsity, then an error results:: sage: R. = PolynomialRing(ZZ, implementation='Foo') Traceback (most recent call last): ... ValueError: Unknown implementation Foo for ZZ[x] sage: R. = PolynomialRing(ZZ, implementation='FLINT') Traceback (most recent call last): ... ValueError: The FLINT implementation is not known for multivariate polynomial rings The following corner case used to result in a warning message from libSingular, and the generators of the resulting polynomial ring were not zero:: sage: R = Integers(1)['x','y'] sage: R.0 == 0 True """ import sage.rings.polynomial.polynomial_ring as m raise TypeError, "You *must* specify the names of the variables." n = int(arg2) names = arg1 R = _multi_variate(base_ring, names, n, sparse, order) R = _multi_variate(base_ring, names, n, sparse, order, implementation) elif isinstance(arg1, str) or (isinstance(arg1, (list,tuple)) and len(arg1) == 1): if not ',' in arg1: raise TypeError, "invalid input to PolynomialRing function; please see the docstring for that function" names = arg1.split(',') n = len(names) R = _multi_variate(base_ring, names, n, sparse, order) R = _multi_variate(base_ring, names, n, sparse, order, implementation) elif isinstance(arg1, (list, tuple)): # PolynomialRing(base_ring, names (list or tuple), order='degrevlex'): names = arg1 n = len(names) R = _multi_variate(base_ring, names, n, sparse, order) R = _multi_variate(base_ring, names, n, sparse, order, implementation) if arg1 is None and arg2 is None: raise TypeError, "you *must* specify the indeterminates (as not None)." def _get_from_cache(key): try: if _cache.has_key(key): return _cache[key] #() return _cache[key] #() except TypeError, msg: raise TypeError, 'key = %s\n%s'%(key,msg) return None raise TypeError, 'key = %s\n%s'%(key,msg) except KeyError: return None def _save_in_cache(key, R): try: def _single_variate(base_ring, name, sparse, implementation): import sage.rings.polynomial.polynomial_ring as m name = normalize_names(1, name) key = (base_ring, name, sparse, implementation) key = (base_ring, name, sparse, implementation if not sparse else None) R = _get_from_cache(key) if not R is None: return R _save_in_cache(key, R) return R def _multi_variate(base_ring, names, n, sparse, order): def _multi_variate(base_ring, names, n, sparse, order, implementation): #    if not sparse: #        raise ValueError, "A dense representation of multivariate polynomials is not supported" sparse = False # "True" would be correct, since there is no dense implementation of # multivariate polynomials. However, traditionally, "False" is used in the key, # even though it is meaningless. if implementation is not None: raise ValueError, "The %s implementation is not known for multivariate polynomial rings"%implementation names = normalize_names(n, names) import sage.rings.polynomial.multi_polynomial_ring as m except ( TypeError, NotImplementedError ): R = m.MPolynomialRing_polydict_domain(base_ring, n, names, order) else: try: R = MPolynomialRing_libsingular(base_ring, n, names, order) except ( TypeError, NotImplementedError ): if not base_ring.is_zero(): try: R = MPolynomialRing_libsingular(base_ring, n, names, order) except ( TypeError, NotImplementedError ): R = m.MPolynomialRing_polydict(base_ring, n, names, order) else: R = m.MPolynomialRing_polydict(base_ring, n, names, order) _save_in_cache(key, R) return R
• ## sage/rings/polynomial/polynomial_template.pxi

diff -r 216c066ba752 sage/rings/polynomial/polynomial_template.pxi
 a _parent = get_cparent(parent) celement_construct(&self.x, get_cparent(parent)) gen = celement_new(_parent) monomial = celement_new(_parent) for deg, coef in x.iteritems(): celement_pow(monomial, gen, deg, NULL, _parent) celement_mul(monomial, &(parent(coef)).x, monomial, _parent) celement_mul(monomial, &(self.__class__(parent, coef)).x, monomial, _parent) celement_add(&self.x, &self.x, monomial, _parent) celement_delete(gen, _parent)
• ## sage/rings/polynomial/polynomial_zmod_flint.pxd

diff -r 216c066ba752 sage/rings/polynomial/polynomial_zmod_flint.pxd
 a pass from sage.libs.flint.zmod_poly cimport zmod_poly_t, zmod_poly_struct from sage.structure.parent cimport Parent ctypedef zmod_poly_struct celement
• ## sage/rings/polynomial/polynomial_zmod_flint.pyx

diff -r 216c066ba752 sage/rings/polynomial/polynomial_zmod_flint.pyx
 a e._parent = self._parent return e cpdef Polynomial _new_constant_poly(self, x, Parent P): r""" Quickly creates a new constant polynomial with value x in parent P. ASSUMPTION: x must convertible to an int. The modulus of P must coincide with the modulus of this element. That assumption is not verified! EXAMPLE:: sage: R. = GF(3)[] sage: x._new_constant_poly(4,R) 1 sage: x._new_constant_poly('4',R) 1 sage: x._new_constant_poly('4.1',R) Traceback (most recent call last): ... ValueError: invalid literal for int() with base 10: '4.1' """ cdef Polynomial_template r = PY_NEW(self.__class__) r._parent = P zmod_poly_init(&r.x, zmod_poly_modulus(&self.x)) celement_set_si(&r.x, int(x), get_cparent(P)) return r cdef _set_list(self, x): """
• ## sage/rings/polynomial/polynomial_zz_pex.pyx

diff -r 216c066ba752 sage/rings/polynomial/polynomial_zz_pex.pyx
 a sage: R. = PolynomialRing(K,implementation='NTL') sage: x^2+a x^2 + a TEST: The following tests against a bug that was fixed in trac ticket #9944. With the ring definition above, we now have:: sage: R([3,'1234']) 1234*x + 3 sage: R([3,'12e34']) Traceback (most recent call last): ... TypeError: unable to convert '12e34' into the base ring sage: R([3,x]) Traceback (most recent call last): ... TypeError: unable to convert x into the base ring """ cdef cparent _parent cdef ntl_ZZ_pE d celement_construct(&self.x, _parent) K = parent.base_ring() for i,e in enumerate(x): if not hasattr(e,'polynomial'): try: e_polynomial = e.polynomial() except (AttributeError, TypeError): # A type error may occur, since sometimes # e.polynomial expects an additional argument try: e = K.coerce(e) except: TypeError("unable to coerce this value to the base ring") d = parent._modulus.ZZ_pE(list(e.polynomial())) # self(x) is supposed to be a conversion, # not necessarily a coercion. So, we must # not do K.coerce(e) but K(e). e = K(e) # K.coerce(e) e_polynomial = e.polynomial() except TypeError: raise TypeError, "unable to convert %s into the base ring"%repr(e) d = parent._modulus.ZZ_pE(list(e_polynomial)) ZZ_pEX_SetCoeff(self.x, i, d.x) return
• ## sage/rings/power_series_poly.pyx

diff -r 216c066ba752 sage/rings/power_series_poly.pyx
 a prec = (f)._prec f = R((f).__f) else: if f: f = R(f, check=check) else: f = R(None) else: if f: f = R(f, check=check) else: f = R(f, check=check) else: # None is supposed to yield zero f = R(None) self.__f = f if check and not (prec is infinity): sage: A. = RR[[]] sage: f = z - z^3 + O(z^10) sage: f == loads(dumps(f)) # uses __reduce__ sage: f == loads(dumps(f)) # indirect doctest True """ # do *not* delete old versions.
• ## sage/rings/power_series_ring_element.pyx

diff -r 216c066ba752 sage/rings/power_series_ring_element.pyx
 a g = _solve_linear_de(R, N, L2, a, b, f0) term1 = R(g, check=False) term2 = R(a[:L], check=False) term1 = R(g)  # we must not have check=False, since otherwise [..., 0, 0] is not stripped term2 = R(a[:L]) #, check=False) product = (term1 * term2).list() # todo: perhaps next loop could be made more efficient
• ## sage/rings/qqbar.py

diff -r 216c066ba752 sage/rings/qqbar.py
 a R. = QQbar[] v1 = AA(2) v2 = QQbar(sqrt(v1)) v3 = sqrt(QQbar(3)) v4 = v2*v3 v5 = (1 - v2)*(1 - v3) - 1 - v4 v6 = QQbar(sqrt(v1)) si1 = v6*v3 cp = AA.common_polynomial(x^2 + ((1 - v6)*(1 + v3) - 1 + si1)*x - si1) v7 = QQbar.polynomial_root(cp, RIF(-RR(1.7320508075688774), -RR(1.7320508075688772))) v8 = 1 - v7 v9 = v5 + (v8 - 1) v10 = -1 - v3 - QQbar.polynomial_root(cp, RIF(-RR(1.7320508075688774), -RR(1.7320508075688772))) v11 = 1 + v10 v12 = v8*(v5 + v4) - (v5 - v4*v7) si2 = v4*v7 AA.polynomial_root(AA.common_polynomial(x^4 + (v9 + (v11 - 1))*x^3 + (v12 + (v11*v9 - v9))*x^2 + (v11*(v12 - si2) - (v12 - si2*v10))*x - si2*v10), RIF(RR(0.99999999999999989), RR(1.0000000000000002))) v3 = QQbar(3) v4 = sqrt(v3) v5 = v2*v4 v6 = (1 - v2)*(1 - v4) - 1 - v5 v7 = QQbar(sqrt(v1)) v8 = sqrt(v3) si1 = v7*v8 cp = AA.common_polynomial(x^2 + ((1 - v7)*(1 + v8) - 1 + si1)*x - si1) v9 = QQbar.polynomial_root(cp, RIF(-RR(1.7320508075688774), -RR(1.7320508075688772))) v10 = 1 - v9 v11 = v6 + (v10 - 1) v12 = -1 - v4 - QQbar.polynomial_root(cp, RIF(-RR(1.7320508075688774), -RR(1.7320508075688772))) v13 = 1 + v12 v14 = v10*(v6 + v5) - (v6 - v5*v9) si2 = v5*v9 AA.polynomial_root(AA.common_polynomial(x^4 + (v11 + (v13 - 1))*x^3 + (v14 + (v13*v11 - v11))*x^2 + (v13*(v14 - si2) - (v14 - si2*v12))*x - si2*v12), RIF(RR(0.99999999999999989), RR(1.0000000000000002))) sage: one 1
• ## sage/rings/ring.pyx

diff -r 216c066ba752 sage/rings/ring.pyx
 a break if len(gens) == 0: gens = [self(0)] gens = [self.zero_element()] if coerce: #print [type(g) for g in gens] True """ if self._zero_ideal is None: I = Ring.ideal(self, [self(0)], coerce=False) I = Ring.ideal(self, [self.zero_element()], coerce=False) self._zero_ideal = I return I return self._zero_ideal
• ## sage/schemes/elliptic_curves/monsky_washnitzer.py

diff -r 216c066ba752 sage/schemes/elliptic_curves/monsky_washnitzer.py
 a answer mod p^{\mathrm{prec}} at the end. OUTPUT: 2x2 matrix of frobenius on Monsky-Washnitzer cohomology, OUTPUT: 2x2 matrix of frobenius on Monsky-Washnitzer cohomology, with entries in the coefficient ring of Q. EXAMPLES: A simple example:: EXAMPLES: A simple example:: sage: p = 5 sage: prec = 3

diff -r 216c066ba752 sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py
 a INPUT: - P and Q points on self in the same residue disc - P and Q points on self in the same residue disc OUTPUT: Returns a point $X(t) = ( x(t) : y(t) : z(t) )$ such that Returns a point $X(t) = ( x(t) : y(t) : z(t) )$ such that (1) $X(0) = P$ and $X(1) = Q$ if $P, Q$ are not in the infinite disc (2) $X(P[0]^g}/P[1]) = P$ and $X(Q[0]^g/Q[1]) = Q$ if $P, Q$ are in the infinite disc EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) sage: HK = H.change_ring(K) A non-Weierstrass disc: A non-Weierstrass disc:: sage: P = HK(0,3) sage: Q = HK(5, 3 + 3*5^2 + 2*5^3 + 3*5^4 + 2*5^5 + 2*5^6 + 3*5^7 + O(5^8)) sage: x,y,z, = HK.local_analytic_interpolation(P,Q) sage: x(0) == P[0], x(1) == Q[0], y(0) == P[1], y(1) == Q[1] (True, True, True, True) A finite Weierstrass disc A finite Weierstrass disc:: sage: P = HK.lift_x(1 + 2*5^2) sage: Q = HK.lift_x(1 + 3*5^2) sage: x,y,z = HK.local_analytic_interpolation(P,Q) sage: x(0) == P[0], x(1) == Q[0], y(0) == P[1], y(1) == Q[1] (True, True, True, True) The infinite disc The infinite disc:: sage: P = HK.lift_x(5^-2) sage: Q = HK.lift_x(4*5^-2) sage: x,y,z = HK.local_analytic_interpolation(P,Q) sage: y(Q[0]/Q[1]) == Q[1] True An error if points are not in the same disc: An error if points are not in the same disc:: sage: x,y,z = HK.local_analytic_interpolation(P,HK(1,0)) Traceback (most recent call last): ... ValueError: (5^-2 + O(5^6) : 5^-3 + 4*5^2 + 5^3 + 3*5^4 + O(5^5) : 1 + O(5^8)) and (1 + O(5^8) : 0 : 1 + O(5^8)) are not in the same residue disc AUTHORS: - Robert Bradshaw (2007-03) - Jennifer Balakrishnan (2010-02) - Robert Bradshaw (2007-03) - Jennifer Balakrishnan (2010-02) """ prec = self.base_ring().precision_cap() if self.is_same_disc(P,Q) == False: that is, the point at infinity and those points in the suport of the divisor of $y$ EXAMPLES: EXAMPLES:: sage: K = pAdicField(11, 5) sage: x = polygen(K) sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) """ Checks if $P$ is in a Weierstrass disc EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) True AUTHOR: - Jennifer Balakrishnan (2010-02) - Jennifer Balakrishnan (2010-02) """ if (P[1].valuation() == 0 and P != self(0,1,0)): return False """ Checks if $P$ is a Weierstrass point (i.e., fixed by the hyperelliptic involution) EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) False AUTHOR: - Jennifer Balakrishnan (2010-02) - Jennifer Balakrishnan (2010-02) """ if (P[1] == 0 or P[2] ==0): Given $Q$ a point on self in a Weierstrass disc, finds the center of the Weierstrass disc (if defined over self.base_ring()) EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) (0 : 1 + O(5^8) : 0) AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ if self.is_in_weierstrass_disc(Q) == False: raise ValueError, "%s is not in a Weierstrass disc"%Q """ Gives the residue disc of $P$ EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) (0 : 1 : 0) AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ xPv = P[0].valuation() yPv = P[1].valuation() """ Checks if $P,Q$ are in same residue disc EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) return False def tiny_integrals(self, F, P, Q): """ r""" Evaluate the integrals of $f_i dx/2y$ from $P$ to $Q$ for each $f_i$ in $F$ by formally integrating a power series in a local parameter $t$ $P$ and $Q$ MUST be in the same residue disk for this result to make sense. INPUT: - F a list of functions $f_i$ - P a point on self - Q a point on self (in the same residue disc as P) - F a list of functions $f_i$ - P a point on self - Q a point on self (in the same residue disc as P) OUTPUT: The integrals $\int_P^Q f_i dx/2y$ EXAMPLES: The integrals $\int_P^Q f_i dx/2y$ EXAMPLES:: sage: K = pAdicField(17, 5) sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a sage: P = E(K(14/3), K(11/2)) sage: E.tiny_integrals([1,x],P, TP) == E.tiny_integrals_on_basis(P,TP) True :: sage: K = pAdicField(11, 5) sage: x = polygen(K) sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) sage: C.tiny_integrals([1],P,Q) (3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8)) Note that this fails if the points are not in the same residue disc: Note that this fails if the points are not in the same residue disc:: sage: S = C(0,1/4) sage: C.tiny_integrals([1,x,x^2,x^3],P,S) Traceback (most recent call last): return vector(integrals) def tiny_integrals_on_basis(self, P, Q): """ r""" Evaluate the integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ by formally integrating a power series in a local parameter $t$. $P$ and $Q$ MUST be in the same residue disc for this result to make sense. INPUT: - P a point on self - Q a point on self (in the same residue disc as P) - P a point on self - Q a point on self (in the same residue disc as P) OUTPUT: The integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ EXAMPLES: The integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ EXAMPLES:: sage: K = pAdicField(17, 5) sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a sage: P = E(K(14/3), K(11/2)) sage: TP = E.teichmuller(P); sage: E.tiny_integrals_on_basis(P, TP) (17 + 14*17^2 + 17^3 + 8*17^4 + O(17^5), 16*17 + 5*17^2 + 8*17^3 + 14*17^4 + O(17^5)) :: sage: K = pAdicField(11, 5) sage: x = polygen(K) (3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8), 3*11 + 10*11^2 + 8*11^3 + 9*11^4 + 7*11^5 + O(11^6), 4*11^-1 + 2 + 6*11 + 6*11^2 + 7*11^3 + O(11^4), 11^-3 + 6*11^-2 + 2*11^-1 + 2 + O(11^2)) Note that this fails if the points are not in the same residue disc: Note that this fails if the points are not in the same residue disc:: sage: S = C(0,1/4) sage: C.tiny_integrals_on_basis(P,S) Traceback (most recent call last): def teichmuller(self, P): """ r""" Find a Teichm\:uller point in the same residue class of $P$. Because this lift of frobenius acts as $x \mapsto x^p$, take the Teichmuller lift of $x$ and then find a matching $y$ from that. EXAMPLES: EXAMPLES:: sage: K = pAdicField(7, 5) sage: E = EllipticCurve(K, [-31/3, -2501/108]) # 11a sage: P = E(K(14/3), K(11/2)) def coleman_integrals_on_basis(self, P, Q, algorithm=None): """ r""" Computes the Coleman integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ INPUT: - P point on self - Q point on self - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) - P point on self - Q point on self - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) OUTPUT: the Coleman integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ the Coleman integrals $\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}$ EXAMPLES: EXAMPLES:: sage: K = pAdicField(11, 5) sage: x = polygen(K) sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) sage: C.coleman_integrals_on_basis(P, Q, algorithm='teichmuller') (10*11 + 6*11^3 + 2*11^4 + O(11^5), 11 + 9*11^2 + 7*11^3 + 9*11^4 + O(11^5), 3 + 10*11 + 5*11^2 + 9*11^3 + 4*11^4 + O(11^5), 3 + 11 + 5*11^2 + 4*11^4 + O(11^5)) :: sage: K = pAdicField(11,5) sage: x = polygen(K) sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) sage: Q = C.lift_x(3*11^(-2)) sage: C.coleman_integrals_on_basis(P, Q) (3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8), 3*11 + 10*11^2 + 8*11^3 + 9*11^4 + 7*11^5 + O(11^6), 4*11^-1 + 2 + 6*11 + 6*11^2 + 7*11^3 + O(11^4), 11^-3 + 6*11^-2 + 2*11^-1 + 2 + O(11^2)) :: sage: R = C(0,1/4) sage: a = C.coleman_integrals_on_basis(P,R)  # long time (7s on sage.math, 2011) sage: b = C.coleman_integrals_on_basis(R,Q)  # long time (9s on sage.math, 2011) sage: a+b == c  # long time True :: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) (0, 0) AUTHORS: - Robert Bradshaw (2007-03): non-Weierstrass points - Jennifer Balakrishnan and Robert Bradshaw (2010-02): Weierstrass points - Robert Bradshaw (2007-03): non-Weierstrass points - Jennifer Balakrishnan and Robert Bradshaw (2010-02): Weierstrass points """ import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer from sage.misc.profiler import Profiler """ Returns the invariant differential $dx/2y$ on self EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3+1) sage: K = Qp(5,8) sage: w = HK.invariant_differential(); w (((1+O(5^8)))*1) dx/2y :: sage: K = pAdicField(11, 6) sage: x = polygen(K) sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) return MW.invariant_differential() def coleman_integral(self, w, P, Q, algorithm = 'None'): """ r""" Returns the Coleman integral $\int_P^Q w$ INPUT: - w differential (if one of P,Q is Weierstrass, w must be odd) - P point on self - Q point on self - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) - w differential (if one of P,Q is Weierstrass, w must be odd) - P point on self - Q point on self - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) OUTPUT: the Coleman integral $\int_P^Q w$ the Coleman integral $\int_P^Q w$ EXAMPLES: Example of Leprevost from Kiran Kedlaya The first two should be zero as $(P-Q) = 30(P-Q)$ in the Jacobian and $dx/2y$ and $x dx/2y$ are holomorphic. and $dx/2y$ and $x dx/2y$ are holomorphic. :: sage: K = pAdicField(11, 6) sage: x = polygen(K) O(11^6) sage: C.coleman_integral(x^2*w, P, Q) 7*11 + 6*11^2 + 3*11^3 + 11^4 + 5*11^5 + O(11^6) :: sage: p = 71; m = 4 sage: K = pAdicField(p, m) sage: x = polygen(K) 21*71 + 67*71^2 + 27*71^3 + O(71^4) sage: w.integrate(P, R) + w.integrate(P1, R1) O(71^4) A simple example, integrating dx: A simple example, integrating dx:: sage: R. = QQ['x'] sage: E= HyperellipticCurve(x^3-4*x+4) sage: K = Qp(5,10) 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10) sage: Q[0] - P[0] 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10) Yet another example: Yet another example:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x*(x-1)*(x+9)) sage: HK.coleman_integral(b,P,Q) 7 + 7^2 + 4*7^3 + 5*7^4 + 3*7^5 + 7^6 + 5*7^7 + 3*7^8 + 4*7^9 + 4*7^10 + O(7^11) :: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3+1) sage: K = Qp(5,8) 3*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9) sage: HK.coleman_integral(w,P,Q) 3*5 + 2*5^2 + 2*5^3 + 5^4 + 4*5^6 + 5^7 + O(5^9) Integrals involving Weierstrass points: Integrals involving Weierstrass points:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) 5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 3*5^6 + 2*5^7 + 4*5^8 + O(5^9) AUTHORS: - Robert Bradshaw (2007-03) - Kiran Kedlaya (2008-05) - Jennifer Balakrishnan (2010-02) - Robert Bradshaw (2007-03) - Kiran Kedlaya (2008-05) - Jennifer Balakrishnan (2010-02) """ # TODO: implement Jacobians and show the relationship directly """ Returns the $p$-th power lift of Frobenius of $P$ EXAMPLES: EXAMPLES:: sage: K = Qp(11, 5) sage: R. = K[] sage: E = HyperellipticCurve(x^5 - 21*x - 20) sage: P = E.lift_x(2) sage: E.frobenius(P) (2 + 10*11 + 5*11^2 + 11^3 + O(11^5) : 5 + 9*11 + 2*11^2 + 2*11^3 + O(11^5) : 1 + O(11^5)) sage: Q = E.teichmuller(P); Q (2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 5 + 9*11 + 6*11^2 + 11^3 + 6*11^4 + O(11^5) : 1 + O(11^5)) sage: E.frobenius(Q) (2 + 10*11 + 4*11^2 + 9*11^3 + 11^4 + O(11^5) : 5 + 9*11 + 6*11^2 + 11^3 + 6*11^4 + O(11^5) : 1 + O(11^5)) :: sage: R. = QQ[] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: Q = H(0,0) 1 + O(a^100)) AUTHORS: - Robert Bradshaw and Jennifer Balakrishnan (2010-02) - Robert Bradshaw and Jennifer Balakrishnan (2010-02) """ try: _frob = self._frob return _frob(P) def newton_sqrt(self,f,x0, prec): """ NOTE: this function should eventually be moved to $p$-adic power series ring r""" Takes the square root of the power series $f$ by Newton's method NOTE: this function should eventually be moved to $p$-adic power series ring takes the square root of the power series $f$ by Newton's method INPUT: - f power series wtih coefficients in $\Q_p$ or an extension - x0 seeds the Newton iteration - prec precision - f power series wtih coefficients in $\Q_p$ or an extension - x0 seeds the Newton iteration - prec precision OUTPUT: the square root of $f$ EXAMPLES: the square root of $f$ EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: Q = H(0,0) O(a^122) AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ z = x0 return z def curve_over_ram_extn(self,deg): """ r""" Returns self over $\Q_p(p^(1/deg))$ INPUT: - deg: the degree of the ramified extension - deg: the degree of the ramified extension OUTPUT: self over $\Q_p(p^(1/deg))$ EXAMPLES: self over $\Q_p(p^(1/deg))$ EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: K = Qp(11,5) Hyperelliptic Curve over Eisenstein Extension of 11-adic Field with capped relative precision 5 in a defined by (1 + O(11^5))*x^2 + (O(11^6))*x + (10*11 + 10*11^2 + 10*11^3 + 10*11^4 + 10*11^5 + O(11^6)) defined by (1 + O(a^10))*y^2 = (1 + O(a^10))*x^5 + (10 + 8*a^2 + 10*a^4 + 10*a^6 + 10*a^8 + O(a^10))*x^3 + (7 + a^2 + O(a^10))*x^2 + (7 + 3*a^2 + O(a^10))*x AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve Given self over an extension field, find a point in the disc of $P$ near the boundary INPUT: - curve_over_extn: self over a totally ramified extension - P: Weierstrass point - curve_over_extn: self over a totally ramified extension - P: Weierstrass point OUTPUT: a point in the disc of $P$ near the boundary a point in the disc of $P$ near the boundary EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(3,6) (1 + 2*a^2 + 2*a^6 + 2*a^18 + a^32 + a^34 + a^36 + 2*a^38 + 2*a^40 + a^42 + 2*a^44 + a^48 + 2*a^50 + 2*a^52 + a^54 + a^56 + 2*a^60 + 2*a^62 + a^70 + 2*a^72 + a^76 + 2*a^78 + a^82 + a^88 + a^96 + 2*a^98 + 2*a^102 + a^104 + 2*a^106 + a^108 + 2*a^110 + a^112 + 2*a^116 + a^126 + 2*a^130 + 2*a^132 + a^144 + 2*a^148 + 2*a^150 + a^152 + 2*a^154 + a^162 + a^164 + a^166 + a^168 + a^170 + a^176 + a^178 + O(a^180) : a + O(a^181) : 1 + O(a^180)) AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ J = curve_over_extn.base_ring() return curve_over_extn(x(a),y(a)) def P_to_S(self, P, S): """ r""" Given a finite Weierstrass point $P$ and a point $S$ in the same disc, computes the Coleman integrals $\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}$ INPUT: - P: finite Weierstrass point - S: point in disc of P - P: finite Weierstrass point - S: point in disc of P OUTPUT: Coleman integrals $\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}$ Coleman integrals $\{\int_P^S x^i dx/2y \}_{i=0}^{2g-1}$ EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,4) (2*a + 4*a^3 + 2*a^11 + 4*a^13 + 2*a^17 + 2*a^19 + a^21 + 4*a^23 + a^25 + 2*a^27 + 2*a^29 + 3*a^31 + 4*a^33 + O(a^35), a^-5 + 2*a + 2*a^3 + a^7 + 3*a^11 + a^13 + 3*a^15 + 3*a^17 + 2*a^19 + 4*a^21 + 4*a^23 + 4*a^25 + 2*a^27 + a^29 + a^31 + 3*a^33 + O(a^35)) AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ prec = self.base_ring().precision_cap() return vector(val) def coleman_integral_P_to_S(self,w,P,S): """ r""" Given a finite Weierstrass point $P$ and a point $S$ in the same disc, computes the Coleman integral $\int_P^S w$ INPUT: - w: differential - P: Weierstrass point - S: point in the same disc of P (S is defined over an extension of $\Q_p$; coordinates of S are given in terms of uniformizer $a$) - w: differential - P: Weierstrass point - S: point in the same disc of P (S is defined over an extension of $\Q_p$; coordinates of S are given in terms of uniformizer $a$) OUTPUT: Coleman integral $\int_P^S w$ in terms of $a$ Coleman integral $\int_P^S w$ in terms of $a$ EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,4) True AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ prec = self.base_ring().precision_cap() return int_sing_a def S_to_Q(self,S,Q): """ r""" Given $S$ a point on self over an extension field, computes the Coleman integrals $\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}$ **one should be able to feed $S,Q$ into coleman_integral, but currently that segfaults but currently that segfaults** INPUT: - S: a point with coordinates in an extension of $\Q_p$ (with unif. a) - Q: a non-Weierstrass point defined over $\Q_p$ - S: a point with coordinates in an extension of $\Q_p$ (with unif. a) - Q: a non-Weierstrass point defined over $\Q_p$ OUTPUT: the Coleman integrals $\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}$ in terms of $a$ the Coleman integrals $\{\int_S^Q x^i dx/2y \}_{i=0}^{2g-1}$ in terms of $a$ EXAMPLES: EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,6) (2*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 5^6 + O(5^7)) AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ FS = self.frobenius(S) return B*(b-S_to_FS-FQ_to_Q) def coleman_integral_S_to_Q(self,w,S,Q): """ r""" Computes the Coleman integral $\int_S^Q w$ **one should be able to feed $S,Q$ into coleman_integral, but currently that segfaults but currently that segfaults** INPUT: - w: a differential - S: a point with coordinates in an extension of \Q_p - Q: a non-Weierstrass point defined over \Q_p - w: a differential - S: a point with coordinates in an extension of $\Q_p$ - Q: a non-Weierstrass point defined over $\Q_p$ OUTPUT: the Coleman integral $\int_S^Q w$ EXAMPLES: the Coleman integral $\int_S^Q w$ EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,6) 3 + O(5^6) AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer return const + dot def coleman_integral_from_weierstrass_via_boundary(self, w, P, Q, d): """ r""" Computes the Coleman integral $\int_P^Q w$ via a boundary point in the disc of $P$, defined over a degree $d$ extension INPUT: - w: a differential - P: a Weierstrass point - Q: a non-Weierstrass point - d: degree of extension where coordinates of boundary point lie - w: a differential - P: a Weierstrass point - Q: a non-Weierstrass point - d: degree of extension where coordinates of boundary point lie OUTPUT: the Coleman integral $\int_P^Q w$, written in terms of the uniformizer $a$ of the degree $d$ extension EXAMPLES: the Coleman integral $\int_P^Q w$, written in terms of the uniformizer $a$ of the degree $d$ extension EXAMPLES:: sage: R. = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,6) 2*5^2 + 5^4 + 5^5 + 3*5^6 + O(5^7) AUTHOR: - Jennifer Balakrishnan - Jennifer Balakrishnan """ HJ = self.curve_over_ram_extn(d)
• ## sage/structure/coerce.pyx

diff -r 216c066ba752 sage/structure/coerce.pyx
 a (Call morphism: From: Multivariate Polynomial Ring in x, y over Integer Ring To:   Multivariate Polynomial Ring in x, y over Real Double Field, Call morphism: Polynomial base injection morphism: From: Real Double Field To:   Multivariate Polynomial Ring in x, y over Real Double Field)
• ## sage/structure/coerce_actions.pyx

diff -r 216c066ba752 sage/structure/coerce_actions.pyx
 a Left scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring sage: LeftModuleAction(QQ, ZZ['x']['y']) Left scalar multiplication by Rational Field on Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Integer Ring The following tests against a problem that was relevant during work on trac ticket #9944:: sage: R. = PolynomialRing(ZZ) sage: S. = PolynomialRing(ZZ, sparse=True) sage: 1/R.0 1/x sage: 1/S.0 1/x """ Action.__init__(self, G, S, not PY_TYPE_CHECK(self, RightModuleAction), operator.mul) if not isinstance(G, Parent): # At this point, we can assert it is safe to call _Xmul_c the_ring = G if self.connecting is None else self.connecting.codomain() the_set = S if self.extended_base is None else self.extended_base assert the_ring is the_set.base(), "BUG in coercion model" assert the_ring is the_set.base(), "BUG in coercion model\n    Apparently there are two versions of\n        %s\n    in the cache."%the_ring g = G.an_element() a = S.an_element()
• ## sage/structure/element.pyx

diff -r 216c066ba752 sage/structure/element.pyx
 a sage: (v+w).__nonzero__() False """ return self != self._parent(0) return self != self._parent.zero_element() def is_zero(self): """ cdef class RingElement(ModuleElement): ################################################## def is_one(self): return self == self._parent(1) return self == self._parent.one_element() ################################## # Fast long add/sub path.
• ## sage/structure/parent_old.pyx

diff -r 216c066ba752 sage/structure/parent_old.pyx
 a TESTS: This came up in some subtle bug once. :: sage: gp(2) + gap(3) 5 """ To:   Multivariate Polynomial Ring in q, t over Rational Field Defn:   Native morphism: From: Set of Python objects of type 'int' To:   Integer Ring To:   Rational Field then Call morphism: From: Integer Ring Polynomial base injection morphism: From: Rational Field To:   Multivariate Polynomial Ring in q, t over Rational Field """ check_old_coerce(self)