def mypushout(X, Y): if X.has_coerce_map_from(Y): return X elif Y.has_coerce_map_from(X): return Y else: Z = pushout(X, Y) assert (is_NumberField(Z) if is_NumberField(X) and is_NumberField(Y) else True) return Z
def extend_scalars(self, *pts): r""" Extend the ground field so that the new field contains pts. """ Dops = self.parent() Pols = Dops.base_ring() Scalars = Pols.base_ring() if all(Scalars.has_coerce_map_from(pt.parent()) for pt in pts): return (self, ) + pts gen = Scalars.gen() try: # Largely redundant with the other branch, but may do a better job # in some cases, e.g. pushout(QQ, QQ(α)), where as_enf_elts() would # invent new generator names. NF0 = coercion_model.common_parent(Scalars, *pts) if not is_NumberField(NF0): raise CoercionException NF, hom = utilities.good_number_field(NF0) gen1 = hom(NF0.coerce(gen)) pts1 = tuple(hom(NF0.coerce(pt)) for pt in pts) except (CoercionException, TypeError): NF, val1 = as_embedded_number_field_elements((gen, ) + pts) gen1, pts1 = val1[0], tuple(val1[1:]) hom = Scalars.hom([gen1], codomain=NF) Dops1 = OreAlgebra(Pols.change_ring(NF), (Dops.variable_name(), {}, { Pols.gen(): Pols.one() })) dop1 = Dops1([pol.map_coefficients(hom) for pol in self]) dop1 = PlainDifferentialOperator(dop1) assert dop1.base_ring().base_ring() is NF return (dop1, ) + pts1
def _normalize_number_field_data(self, R): r""" Helper method which returns the defining data of the number field ``R``. EXAMPLES:: sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone sage: R.<x> = QQ[] sage: K = R.quo(x^2 + 1) sage: pAdicValuation._normalize_number_field_data(K) (Rational Field, Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1, x^2 + 1) """ from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing from sage.rings.number_field.number_field import is_NumberField from sage.rings.fraction_field import is_FractionField if is_NumberField(R.fraction_field()): L = R.fraction_field() G = L.relative_polynomial() K = L.base_ring() elif is_PolynomialQuotientRing(R): from sage.categories.all import NumberFields if R.base_ring().fraction_field() not in NumberFields(): raise NotImplementedError("can not normalize quotients over %r"%(R.base_ring(),)) L = R.fraction_field() K = R.base_ring().fraction_field() G = R.modulus().change_ring(K) else: raise NotImplementedError("can not normalize %r"%(R,)) return K, L, G
def create_key_and_extra_args(self, R, prime=None, approximants=None): r""" Create a unique key identifying the valuation of ``R`` with respect to ``prime``. EXAMPLES:: sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone sage: pAdicValuation(QQ, 2) # indirect doctest 2-adic valuation """ from sage.rings.all import ZZ, QQ from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.number_field.number_field import is_NumberField from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if R.characteristic() != 0: # We do not support equal characteristic yet raise ValueError("R must be a ring of characteristic zero.") if R is ZZ or R is QQ: return self.create_key_for_integers(R, prime), {} elif isinstance(R, pAdicGeneric): return self.create_key_for_local_ring(R, prime), {} elif is_NumberField(R.fraction_field()) or is_PolynomialQuotientRing(R): return self.create_key_and_extra_args_for_number_field(R, prime, approximants=approximants) else: raise NotImplementedError("p-adic valuations not implemented for %r"%(R,))
def _normalize_number_field_data(self, R): r""" Helper method which returns the defining data of the number field ``R``. EXAMPLES:: sage: R.<x> = QQ[] sage: K = R.quo(x^2 + 1) sage: valuations.pAdicValuation._normalize_number_field_data(K) (Rational Field, Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1, x^2 + 1) """ from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing from sage.rings.number_field.number_field import is_NumberField from sage.rings.fraction_field import is_FractionField if is_NumberField(R.fraction_field()): L = R.fraction_field() G = L.relative_polynomial() K = L.base_ring() elif is_PolynomialQuotientRing(R): from sage.categories.all import NumberFields if R.base_ring().fraction_field() not in NumberFields(): raise NotImplementedError("can not normalize quotients over %r"%(R.base_ring(),)) L = R.fraction_field() K = R.base_ring().fraction_field() G = R.modulus().change_ring(K) else: raise NotImplementedError("can not normalize %r"%(R,)) return K, L, G
def create_key_and_extra_args(self, R, prime=None, approximants=None): r""" Create a unique key identifying the valuation of ``R`` with respect to ``prime``. EXAMPLES:: sage: QQ.valuation(2) # indirect doctest 2-adic valuation """ from sage.rings.all import ZZ, QQ from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.number_field.number_field import is_NumberField from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if R.characteristic() != 0: # We do not support equal characteristic yet raise ValueError("R must be a ring of characteristic zero.") if R is ZZ or R is QQ: return self.create_key_for_integers(R, prime), {} elif isinstance(R, pAdicGeneric): return self.create_key_for_local_ring(R, prime), {} elif is_NumberField(R.fraction_field()) or is_PolynomialQuotientRing(R): return self.create_key_and_extra_args_for_number_field(R, prime, approximants=approximants) else: raise NotImplementedError("p-adic valuations not implemented for %r"%(R,))
def extensions(self, ring): r""" Return the extensions of this valuation to ``ring``. EXAMPLES:: sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone sage: v = pAdicValuation(ZZ, 2) sage: v.extensions(GaussianIntegers()) [2-adic valuation] TESTS:: sage: R.<a> = QQ[] sage: L.<a> = QQ.extension(x^3 - 2) sage: R.<b> = L[] sage: M.<b> = L.extension(b^2 + 2*b + a) sage: pAdicValuation(M, 2) 2-adic valuation Check that we can extend to a field written as a quotient:: sage: R.<x> = QQ[] sage: K.<a> = QQ.extension(x^2 + 1) sage: R.<y> = K[] sage: L.<b> = R.quo(x^2 + a) sage: pAdicValuation(QQ, 2).extensions(L) [2-adic valuation] """ if self.domain() is ring: return [self] domain_fraction_field = _fraction_field(self.domain()) if domain_fraction_field is not self.domain(): if domain_fraction_field.is_subring(ring): return pAdicValuation(domain_fraction_field, self).extensions(ring) if self.domain().is_subring(ring): from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if is_PolynomialQuotientRing(ring): if is_PolynomialQuotientRing(self.domain()): if self.domain().modulus() == ring.modulus(): base_extensions = self._base_valuation.extensions(self._base_valuation.domain().change_ring(self._base_valuation.domain().base_ring().fraction_field())) return [pAdicValuation(ring, base._initial_approximation) for base in base_extensions] if ring.base_ring() is self.domain(): from sage.categories.all import IntegralDomains if ring in IntegralDomains(): return self._extensions_to_quotient(ring) else: return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], []) from sage.rings.number_field.number_field import is_NumberField if is_NumberField(ring.fraction_field()): if ring.base_ring().fraction_field() is self.domain().fraction_field(): from valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(ring) approximants = self.mac_lane_approximants(ring.fraction_field().relative_polynomial().change_ring(self.domain()), assume_squarefree=True) return [pAdicValuation(ring, approximant, approximants) for approximant in approximants] if ring.base_ring() is not ring and self.domain().is_subring(ring.base_ring()): return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], []) return super(pAdicValuation_base, self).extensions(ring)
def residue_field(field, uniformiser): """ Given a field, and a prime in its ring of integers, return the corresponding residue field. """ R = field.ring_of_integers() I = R.ideal(uniformiser) if not field == QQ and is_NumberField(field): return field.residue_field(uniformiser) else: return R.quotient(I)
def is_irred_rep(self, image, n, force=False): """ Returns `True` if the map generated by mapping the generators to the matrices defined in `image` is an `n`-dimensional irreducible representation of `self`, and `False` otherwise. Like above, the entries of `image` must be `n`-by-`n` matrices with entries in the algebraic closure of the base field of `self`. Its length must match the number of generators of `self.` Use `force=True` if the function does not recognize the base field as computable, but the field is computable. """ if (not force and self.base_field() not in NumberFields and self.base_field() not in FiniteFields): raise TypeError( 'Base field must be computable. If %s is computable' % self.base_field() + ' then use force=True to bypass this.') if n not in ZZ or n < 1: raise ValueError('Dimension must be a positive integer.') if not self.is_rep(image, n): return False from sage.matrix.all import Matrix from sage.rings.number_field.number_field import is_NumberField import math M = MatrixSpace(self.base_field().algebraic_closure(), n, sparse=True) image = [M(image[i]).list() for i in range(len(image))] if n <= 6 and is_NumberField(self.base_field()): p = 2 * n else: p = int( math.floor(n * math.sqrt(2 * n**2 / float(n - 1) + 1 / float(4)) + n / float(2) - 3)) prod_set = list(self._create_prod_set(image, n, p)) prod_set.append(M.one()) vector = [mat.list() for mat in prod_set] return 0 not in Matrix(vector).echelon_form().diagonal()
def create_object(self, version, key, **extra_args): r""" Create a `p`-adic valuation from ``key``. EXAMPLES:: sage: ZZ.valuation(5) # indirect doctest 5-adic valuation """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing from sage.rings.number_field.number_field import is_NumberField R = key[0] parent = DiscretePseudoValuationSpace(R) if isinstance(R, pAdicGeneric): assert (len(key) == 1) return parent.__make_element_class__(pAdicValuation_padic)(parent) elif R is ZZ or R is QQ: prime = key[1] assert (len(key) == 2) return parent.__make_element_class__(pAdicValuation_int)(parent, prime) else: v = key[1] approximants = extra_args['approximants'] parent = DiscretePseudoValuationSpace(R) K = R.fraction_field() if is_NumberField(K): G = K.relative_polynomial() elif is_PolynomialQuotientRing(R): G = R.modulus() else: raise NotImplementedError return parent.__make_element_class__(pAdicFromLimitValuation)( parent, v, G.change_ring(R.base_ring()), approximants)
def field_format(field): """Print a nice representation of the given field object. This works correctly for number fields, but for fraction fields of polynomial rings we just pretend the base field are the complex numbers (for now).""" # print("debug field = {0}".format(field)) if field == QQ: return ll("\\Q") elif is_NumberField(field): minpoly = field.defining_polynomial() g, = field.gens() # G, = minpoly.parent().gens() return (ll("K = \\Q(", g, ")") + ", where " + ll(g) + " has minimal polynomial " + ll(minpoly)) elif is_FractionField(field): ring = field.ring_of_integers() if is_PolynomialRing(ring): return ll("\\C(", ring.gens()[0], ")") else: print("debug ring = {0}".format(ring)) raise UnknownField() else: raise UnknownField()
def create_object(self, version, key, **kwds): """ Create an object from a ``UniqueFactory`` key. EXAMPLES:: sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2))) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'> .. NOTE:: Keyword arguments are currently only passed to the constructor for elliptic curves over `\\QQ`; elliptic curves over other fields do not support them. """ R, x = key if R is rings.QQ: from .ell_rational_field import EllipticCurve_rational_field return EllipticCurve_rational_field(x, **kwds) elif is_NumberField(R): from .ell_number_field import EllipticCurve_number_field return EllipticCurve_number_field(R, x) elif rings.is_pAdicField(R): from .ell_padic_field import EllipticCurve_padic_field return EllipticCurve_padic_field(R, x) elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()): from .ell_finite_field import EllipticCurve_finite_field return EllipticCurve_finite_field(R, x) elif R in _Fields: from .ell_field import EllipticCurve_field return EllipticCurve_field(R, x) from .ell_generic import EllipticCurve_generic return EllipticCurve_generic(R, x)
def create_object(self, version, key, **extra_args): r""" Create a `p`-adic valuation from ``key``. EXAMPLES:: sage: ZZ.valuation(5) # indirect doctest 5-adic valuation """ from sage.rings.all import ZZ, QQ from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing from sage.rings.number_field.number_field import is_NumberField R = key[0] parent = DiscretePseudoValuationSpace(R) if isinstance(R, pAdicGeneric): assert(len(key)==1) return parent.__make_element_class__(pAdicValuation_padic)(parent) elif R is ZZ or R is QQ: prime = key[1] assert(len(key)==2) return parent.__make_element_class__(pAdicValuation_int)(parent, prime) else: v = key[1] approximants = extra_args['approximants'] parent = DiscretePseudoValuationSpace(R) K = R.fraction_field() if is_NumberField(K): G = K.relative_polynomial() elif is_PolynomialQuotientRing(R): G = R.modulus() else: raise NotImplementedError return parent.__make_element_class__(pAdicFromLimitValuation)(parent, v, G.change_ring(R.base_ring()), approximants)
def create_object(self, version, key, **kwds): """ Create an object from a ``UniqueFactory`` key. EXAMPLES:: sage: E = EllipticCurve.create_object(0, (GF(3), (1, 2, 0, 1, 2))) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'> .. NOTE:: Keyword arguments are currently only passed to the constructor for elliptic curves over `\\QQ`; elliptic curves over other fields do not support them. """ R, x = key if R is rings.QQ: from ell_rational_field import EllipticCurve_rational_field return EllipticCurve_rational_field(x, **kwds) elif is_NumberField(R): from ell_number_field import EllipticCurve_number_field return EllipticCurve_number_field(R, x) elif rings.is_pAdicField(R): from ell_padic_field import EllipticCurve_padic_field return EllipticCurve_padic_field(R, x) elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()): from ell_finite_field import EllipticCurve_finite_field return EllipticCurve_finite_field(R, x) elif R in _Fields: from ell_field import EllipticCurve_field return EllipticCurve_field(R, x) from ell_generic import EllipticCurve_generic return EllipticCurve_generic(R, x)
def PolynomialRing(base, var): if is_NumberField(base) and base is not QQ: return polyring.PolynomialRing_field( base, var, element_class=polyelt.Polynomial_generic_dense) else: return polyringconstr.PolynomialRing(base, var)
def check_prime(K,P): r""" Function to check that `P` determines a prime of `K`, and return that ideal. INPUT: - ``K`` -- a number field (including `\QQ`). - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``. OUTPUT: - If ``K`` is `\QQ`: the prime integer equal to or which generates `P`. - If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`. .. note:: If `P` is not a prime and does not generate a prime, a TypeError is raised. EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime sage: check_prime(QQ,3) 3 sage: check_prime(QQ,ZZ.ideal(31)) 31 sage: K.<a>=NumberField(x^2-5) sage: check_prime(K,a) Fractional ideal (a) sage: check_prime(K,a+1) Fractional ideal (a + 1) sage: [check_prime(K,P) for P in K.primes_above(31)] [Fractional ideal (5/2*a + 1/2), Fractional ideal (5/2*a - 1/2)] """ if K is QQ: if isinstance(P, (int,long,Integer)): P = Integer(P) if P.is_prime(): return P else: raise TypeError("%s is not prime"%P) else: if is_Ideal(P) and P.base_ring() is ZZ and P.is_prime(): return P.gen() raise TypeError("%s is not a prime ideal of %s"%(P,ZZ)) if not is_NumberField(K): raise TypeError("%s is not a number field"%K) if is_NumberFieldFractionalIdeal(P): if P.is_prime(): return P else: raise TypeError("%s is not a prime ideal of %s"%(P,K)) if is_NumberFieldElement(P): if P in K: P = K.ideal(P) else: raise TypeError("%s is not an element of %s"%(P,K)) if P.is_prime(): return P else: raise TypeError("%s is not a prime ideal of %s"%(P,K)) raise TypeError("%s is not a valid prime of %s"%(P,K))
def Conic(base_field, F=None, names=None, unique=True): r""" Return the plane projective conic curve defined by ``F`` over ``base_field``. The input form ``Conic(F, names=None)`` is also accepted, in which case the fraction field of the base ring of ``F`` is used as base field. INPUT: - ``base_field`` -- The base field of the conic. - ``names`` -- a list, tuple, or comma separated string of three variable names specifying the names of the coordinate functions of the ambient space `\Bold{P}^3`. If not specified or read off from ``F``, then this defaults to ``'x,y,z'``. - ``F`` -- a polynomial, list, matrix, ternary quadratic form, or list or tuple of 5 points in the plane. If ``F`` is a polynomial or quadratic form, then the output is the curve in the projective plane defined by ``F = 0``. If ``F`` is a polynomial, then it must be a polynomial of degree at most 2 in 2 variables, or a homogeneous polynomial in of degree 2 in 3 variables. If ``F`` is a matrix, then the output is the zero locus of `(x,y,z) F (x,y,z)^t`. If ``F`` is a list of coefficients, then it has length 3 or 6 and gives the coefficients of the monomials `x^2, y^2, z^2` or all 6 monomials `x^2, xy, xz, y^2, yz, z^2` in lexicographic order. If ``F`` is a list of 5 points in the plane, then the output is a conic through those points. - ``unique`` -- Used only if ``F`` is a list of points in the plane. If the conic through the points is not unique, then raise ``ValueError`` if and only if ``unique`` is True OUTPUT: A plane projective conic curve defined by ``F`` over a field. EXAMPLES: Conic curves given by polynomials :: sage: X,Y,Z = QQ['X,Y,Z'].gens() sage: Conic(X^2 - X*Y + Y^2 - Z^2) Projective Conic Curve over Rational Field defined by X^2 - X*Y + Y^2 - Z^2 sage: x,y = GF(7)['x,y'].gens() sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W') Projective Conic Curve over Finite Field of size 7 defined by U^2 + 2*V^2 - U*W - 3*W^2 Conic curves given by matrices :: sage: Conic(matrix(QQ, [[1, 2, 0], [4, 0, 0], [7, 0, 9]]), 'x,y,z') Projective Conic Curve over Rational Field defined by x^2 + 6*x*y + 7*x*z + 9*z^2 sage: x,y,z = GF(11)['x,y,z'].gens() sage: C = Conic(x^2+y^2-2*z^2); C Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2 sage: Conic(C.symmetric_matrix(), 'x,y,z') Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2 Conics given by coefficients :: sage: Conic(QQ, [1,2,3]) Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + 3*z^2 sage: Conic(GF(7), [1,2,3,4,5,6], 'X') Projective Conic Curve over Finite Field of size 7 defined by X0^2 + 2*X0*X1 - 3*X1^2 + 3*X0*X2 - 2*X1*X2 - X2^2 The conic through a set of points :: sage: C = Conic(QQ, [[10,2],[3,4],[-7,6],[7,8],[9,10]]); C Projective Conic Curve over Rational Field defined by x^2 + 13/4*x*y - 17/4*y^2 - 35/2*x*z + 91/4*y*z - 37/2*z^2 sage: C.rational_point() (10 : 2 : 1) sage: C.point([3,4]) (3 : 4 : 1) sage: a=AffineSpace(GF(13),2) sage: Conic([a([x,x^2]) for x in range(5)]) Projective Conic Curve over Finite Field of size 13 defined by x^2 - y*z """ if not (is_IntegralDomain(base_field) or base_field == None): if names is None: names = F F = base_field base_field = None if isinstance(F, (list,tuple)): if len(F) == 1: return Conic(base_field, F[0], names) if names == None: names = 'x,y,z' if len(F) == 5: L=[] for f in F: if isinstance(f, SchemeMorphism_point_affine): C = Sequence(f, universe = base_field) if len(C) != 2: raise TypeError, "points in F (=%s) must be planar"%F C.append(1) elif isinstance(f, SchemeMorphism_point_projective_field): C = Sequence(f, universe = base_field) elif isinstance(f, (list, tuple)): C = Sequence(f, universe = base_field) if len(C) == 2: C.append(1) else: raise TypeError, "F (=%s) must be a sequence of planar " \ "points" % F if len(C) != 3: raise TypeError, "points in F (=%s) must be planar" % F P = C.universe() if not is_IntegralDomain(P): raise TypeError, "coordinates of points in F (=%s) must " \ "be in an integral domain" % F L.append(Sequence([C[0]**2, C[0]*C[1], C[0]*C[2], C[1]**2, C[1]*C[2], C[2]**2], P.fraction_field())) M=Matrix(L) if unique and M.rank() != 5: raise ValueError, "points in F (=%s) do not define a unique " \ "conic" % F con = Conic(base_field, Sequence(M.right_kernel().gen()), names) con.point(F[0]) return con F = Sequence(F, universe = base_field) base_field = F.universe().fraction_field() temp_ring = PolynomialRing(base_field, 3, names) (x,y,z) = temp_ring.gens() if len(F) == 3: return Conic(F[0]*x**2 + F[1]*y**2 + F[2]*z**2) if len(F) == 6: return Conic(F[0]*x**2 + F[1]*x*y + F[2]*x*z + F[3]*y**2 + \ F[4]*y*z + F[5]*z**2) raise TypeError, "F (=%s) must be a sequence of 3 or 6" \ "coefficients" % F if is_QuadraticForm(F): F = F.matrix() if is_Matrix(F) and F.is_square() and F.ncols() == 3: if names == None: names = 'x,y,z' temp_ring = PolynomialRing(F.base_ring(), 3, names) F = vector(temp_ring.gens()) * F * vector(temp_ring.gens()) if not is_MPolynomial(F): raise TypeError, "F (=%s) must be a three-variable polynomial or " \ "a sequence of points or coefficients" % F if F.total_degree() != 2: raise TypeError, "F (=%s) must have degree 2" % F if base_field == None: base_field = F.base_ring() if not is_IntegralDomain(base_field): raise ValueError, "Base field (=%s) must be a field" % base_field base_field = base_field.fraction_field() if names == None: names = F.parent().variable_names() pol_ring = PolynomialRing(base_field, 3, names) if F.parent().ngens() == 2: (x,y,z) = pol_ring.gens() F = pol_ring(F(x/z,y/z)*z**2) if F == 0: raise ValueError, "F must be nonzero over base field %s" % base_field if F.total_degree() != 2: raise TypeError, "F (=%s) must have degree 2 over base field %s" % \ (F, base_field) if F.parent().ngens() == 3: P2 = ProjectiveSpace(2, base_field, names) if is_PrimeFiniteField(base_field): return ProjectiveConic_prime_finite_field(P2, F) if is_FiniteField(base_field): return ProjectiveConic_finite_field(P2, F) if is_RationalField(base_field): return ProjectiveConic_rational_field(P2, F) if is_NumberField(base_field): return ProjectiveConic_number_field(P2, F) return ProjectiveConic_field(P2, F) raise TypeError, "Number of variables of F (=%s) must be 2 or 3" % F
def extensions(self, ring): r""" Return the extensions of this valuation to ``ring``. EXAMPLES:: sage: v = ZZ.valuation(2) sage: v.extensions(GaussianIntegers()) [2-adic valuation] TESTS:: sage: R.<a> = QQ[] sage: L.<a> = QQ.extension(x^3 - 2) sage: R.<b> = L[] sage: M.<b> = L.extension(b^2 + 2*b + a) sage: M.valuation(2) 2-adic valuation Check that we can extend to a field written as a quotient:: sage: R.<x> = QQ[] sage: K.<a> = QQ.extension(x^2 + 1) sage: R.<y> = K[] sage: L.<b> = R.quo(x^2 + a) sage: QQ.valuation(2).extensions(L) [2-adic valuation] A case where there was at some point an internal error in the approximants code:: sage: R.<x> = QQ[] sage: L.<a> = NumberField(x^4 + 2*x^3 + 2*x^2 + 8) sage: QQ.valuation(2).extensions(L) [[ 2-adic valuation, v(x + 2) = 3/2 ]-adic valuation, [ 2-adic valuation, v(x) = 1/2 ]-adic valuation] A case where the extension was incorrect at some point:: sage: v = QQ.valuation(2) sage: L.<a> = NumberField(x^2 + 2) sage: M.<b> = L.extension(x^2 + 1) sage: w = v.extension(L).extension(M) sage: w(w.uniformizer()) 1/4 A case where the extensions could not be separated at some point:: sage: v = QQ.valuation(2) sage: R.<x> = QQ[] sage: F = x^48 + 120*x^45 + 56*x^42 + 108*x^36 + 32*x^33 + 40*x^30 + 48*x^27 + 80*x^24 + 112*x^21 + 96*x^18 + 96*x^15 + 24*x^12 + 96*x^9 + 16*x^6 + 96*x^3 + 68 sage: L.<a> = QQ.extension(F) sage: v.extensions(L) [[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation, [ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation] """ if self.domain() is ring: return [self] domain_fraction_field = _fraction_field(self.domain()) if domain_fraction_field is not self.domain(): if domain_fraction_field.is_subring(ring): return pAdicValuation(domain_fraction_field, self).extensions(ring) if self.domain().is_subring(ring): from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if is_PolynomialQuotientRing(ring): if is_PolynomialQuotientRing(self.domain()): if self.domain().modulus() == ring.modulus(): base_extensions = self._base_valuation.extensions(self._base_valuation.domain().change_ring(self._base_valuation.domain().base_ring().fraction_field())) return [pAdicValuation(ring, base._initial_approximation) for base in base_extensions] if ring.base_ring() is self.domain(): from sage.categories.all import IntegralDomains if ring in IntegralDomains(): return self._extensions_to_quotient(ring) elif self.domain().is_subring(ring.base_ring()): return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], []) from sage.rings.number_field.number_field import is_NumberField if is_NumberField(ring.fraction_field()): if ring.base_ring().fraction_field() is self.domain().fraction_field(): from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(ring) approximants = self.mac_lane_approximants(ring.fraction_field().relative_polynomial().change_ring(self.domain()), assume_squarefree=True, require_incomparability=True) return [pAdicValuation(ring, approximant, approximants) for approximant in approximants] if ring.base_ring() is not ring and self.domain().is_subring(ring.base_ring()): return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], []) return super(pAdicValuation_base, self).extensions(ring)
def has_irred_rep(self, n, gen_set=None, restrict=None, force=False): """ Returns `True` if there exists an `n`-dimensional irreducible representation of `self`, and `False` otherwise. Of course, this function runs `has_rep(n, restrict)` to verify there is a representation in the first place, and returns `False` if not. The argument `restrict` may be used equivalenty to its use in `has_rep()`. The argument `gen_set` may be set to `'PBW'` or `'pbw'`, if `self` has an algebra basis similar to that of a Poincaré-Birkhoff-Witt basis. Alternatively, an explicit generating set for the algorithm implemented by this function can be given, as a tuple or array of `FreeAlgebraElements`. This is only useful if the package cannot reduce the elements of `self`, but they can be reduced in theory. Use `force=True` if the function does not recognize the base field as computable, but the field is computable. """ if (not force and self.base_field() not in NumberFields and self.base_field() not in FiniteFields): raise TypeError( 'Base field must be computable. If %s is computable' % self.base_field() + ' then use force=True to bypass this.') if n not in ZZ or n < 1: raise ValueError('Dimension must be a positive integer.') if not self.has_rep(n, restrict): return False from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.groups.all import SymmetricGroup import math B = PolynomialRing(self.base_field(), (self.ngens() * n**2 + 1), 'x', order='deglex') M = MatrixSpace(B, n, sparse=True) gen_matrix = list() if not isinstance(restrict, (tuple, list)): restrict = [None for i in range(self.ngens())] if len(restrict) != self.ngens(): raise ValueError( 'Length of restrict does not match number of generators.') for i in range(self.ngens()): ith_gen_matrix = [] for j in range(n): for k in range(n): if restrict[i] == 'upper' and j > k: ith_gen_matrix.append(B.zero()) elif restrict[i] == 'lower' and j < k: ith_gen_matrix.append(B.zero()) elif restrict[i] == 'diagonal' and j != k: ith_gen_matrix.append(B.zero()) else: ith_gen_matrix.append(B.gen(j + (j + 1) * k + i * n**2)) gen_matrix.append(M(ith_gen_matrix)) relB = list() for i in range(self.nrels()): relB += self._to_matrix(self.rel(i), M, gen_matrix).list() Z = FreeAlgebra(ZZ, 2 * n - 2, 'Y') standard_poly = Z(0) for s in SymmetricGroup(2 * n - 2).list(): standard_poly += s.sign() * reduce( lambda x, y: x * y, [Z('Y%s' % (i - 1)) for i in s.tuple()]) if n <= 6 and is_NumberField(self.base_field()): p = 2 * n else: p = int( math.floor(n * math.sqrt(2 * n**2 / float(n - 1) + 1 / float(4)) + n / float(2) - 3)) if isinstance(gen_set, (tuple, list)): try: gen_set = [ self._to_matrix(elt, M, gen_matrix) for elt in gen_set ] except (NameError, TypeError) as error: print(error) if gen_set == None: word_gen_set = list(self._create_rep_gen_set(n, p)) gen_set = [ self._to_matrix(_to_element(self, [[word, self.one()]]), M, gen_matrix) for word in word_gen_set ] elif gen_set == 'pbw' or gen_set == 'PBW': word_gen_set = list(self._create_pbw_rep_gen_set(n, p)) gen_set = [ self._to_matrix(_to_element(self, [[word, self.one()]]), M, gen_matrix) for word in word_gen_set ] else: raise TypeError('Invalid generating set.') ordering = [i for i in range(2 * n - 2)] max_ordering = [ len(gen_set) - (2 * n - 2) + i for i in range(2 * n - 2) ] ordering.insert(0, 0) max_ordering.insert(0, len(gen_set)) rep_exists = False z = B.gen(B.ngens() - 1) while ordering[0] != max_ordering[0]: y = gen_set[ordering[0]].trace_of_product( standard_poly.subs({ Z('Y%s' % (j - 1)): gen_set[ordering[j]] for j in range(1, 2 * n - 1) })) radB_test = relB + [B(1) - z * y] if B.one() not in B.ideal(radB_test): rep_exists = True break for i in range(2 * n - 2, -1, -1): if i != 0 and ordering[i] != max_ordering[i]: ordering[i] += 1 break elif i == 0: ordering[i] += 1 if ordering[i] != max_ordering[i]: for j in range(1, 2 * n - 1): ordering[j] = j - 1 return rep_exists
def check_prime(K, P): r""" Function to check that `P` determines a prime of `K`, and return that ideal. INPUT: - ``K`` -- a number field (including `\QQ`). - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``. OUTPUT: - If ``K`` is `\QQ`: the prime integer equal to or which generates `P`. - If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`. .. NOTE:: If `P` is not a prime and does not generate a prime, a ``TypeError`` is raised. EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime sage: check_prime(QQ,3) 3 sage: check_prime(QQ,QQ(3)) 3 sage: check_prime(QQ,ZZ.ideal(31)) 31 sage: K.<a> = NumberField(x^2-5) sage: check_prime(K,a) Fractional ideal (a) sage: check_prime(K,a+1) Fractional ideal (a + 1) sage: [check_prime(K,P) for P in K.primes_above(31)] [Fractional ideal (5/2*a + 1/2), Fractional ideal (5/2*a - 1/2)] sage: L.<b> = NumberField(x^2+3) sage: check_prime(K, L.ideal(5)) Traceback (most recent call last): ... TypeError: The ideal Fractional ideal (5) is not a prime ideal of Number Field in a with defining polynomial x^2 - 5 sage: check_prime(K, L.ideal(b)) Traceback (most recent call last): ... TypeError: No compatible natural embeddings found for Number Field in a with defining polynomial x^2 - 5 and Number Field in b with defining polynomial x^2 + 3 """ if K is QQ: if P in ZZ or isinstance(P, integer_types + (Integer,)): P = Integer(P) if P.is_prime(): return P else: raise TypeError("The element %s is not prime" % (P,)) elif P in QQ: raise TypeError("The element %s is not prime" % (P,)) elif is_Ideal(P) and P.base_ring() is ZZ: if P.is_prime(): return P.gen() else: raise TypeError("The ideal %s is not a prime ideal of %s" % (P, ZZ)) else: raise TypeError("%s is neither an element of QQ or an ideal of %s" % (P, ZZ)) if not is_NumberField(K): raise TypeError("%s is not a number field" % (K,)) if is_NumberFieldFractionalIdeal(P) or P in K: # if P is an ideal, making sure it is an fractional ideal of K P = K.fractional_ideal(P) if P.is_prime(): return P else: raise TypeError("The ideal %s is not a prime ideal of %s" % (P, K)) raise TypeError("%s is not a valid prime of %s" % (P, K))
def EllipticCurve(x=None, y=None, j=None, minimal_twist=True): r""" Construct an elliptic curve. In Sage, an elliptic curve is always specified by its a-invariants .. math:: y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6. INPUT: There are several ways to construct an elliptic curve: - ``EllipticCurve([a1,a2,a3,a4,a6])``: Elliptic curve with given a-invariants. The invariants are coerced into the parent of the first element. If all are integers, they are coerced into the rational numbers. - ``EllipticCurve([a4,a6])``: Same as above, but `a_1=a_2=a_3=0`. - ``EllipticCurve(label)``: Returns the elliptic curve over Q from the Cremona database with the given label. The label is a string, such as ``"11a"`` or ``"37b2"``. The letters in the label *must* be lower case (Cremona's new labeling). - ``EllipticCurve(R, [a1,a2,a3,a4,a6])``: Create the elliptic curve over ``R`` with given a-invariants. Here ``R`` can be an arbitrary ring. Note that addition need not be defined. - ``EllipticCurve(j=j0)`` or ``EllipticCurve_from_j(j0)``: Return an elliptic curve with j-invariant ``j0``. - ``EllipticCurve(polynomial)``: Read off the a-invariants from the polynomial coefficients, see :func:`EllipticCurve_from_Weierstrass_polynomial`. In each case above where the input is a list of length 2 or 5, one can instead give a 2 or 5-tuple instead. EXAMPLES: We illustrate creating elliptic curves:: sage: EllipticCurve([0,0,1,-1,0]) Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field We create a curve from a Cremona label:: sage: EllipticCurve('37b2') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field sage: EllipticCurve('5077a') Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field sage: EllipticCurve('389a') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field Old Cremona labels are allowed:: sage: EllipticCurve('2400FF') Elliptic Curve defined by y^2 = x^3 + x^2 + 2*x + 8 over Rational Field Unicode labels are allowed:: sage: EllipticCurve(u'389a') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field We create curves over a finite field as follows:: sage: EllipticCurve([GF(5)(0),0,1,-1,0]) Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5 sage: EllipticCurve(GF(5), [0, 0,1,-1,0]) Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5 Elliptic curves over `\ZZ/N\ZZ` with `N` prime are of type "elliptic curve over a finite field":: sage: F = Zmod(101) sage: EllipticCurve(F, [2, 3]) Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 101 sage: E = EllipticCurve([F(2), F(3)]) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'> sage: E.category() Category of schemes over Ring of integers modulo 101 In contrast, elliptic curves over `\ZZ/N\ZZ` with `N` composite are of type "generic elliptic curve":: sage: F = Zmod(95) sage: EllipticCurve(F, [2, 3]) Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 95 sage: E = EllipticCurve([F(2), F(3)]) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'> sage: E.category() Category of schemes over Ring of integers modulo 95 The following is a curve over the complex numbers:: sage: E = EllipticCurve(CC, [0,0,1,-1,0]) sage: E Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x over Complex Field with 53 bits of precision sage: E.j_invariant() 2988.97297297297 We can also create elliptic curves by giving the Weierstrass equation:: sage: x, y = var('x,y') sage: EllipticCurve(y^2 + y == x^3 + x - 9) Elliptic Curve defined by y^2 + y = x^3 + x - 9 over Rational Field sage: R.<x,y> = GF(5)[] sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x) Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 2 over Finite Field of size 5 We can explicitly specify the `j`-invariant:: sage: E = EllipticCurve(j=1728); E; E.j_invariant(); E.label() Elliptic Curve defined by y^2 = x^3 - x over Rational Field 1728 '32a2' sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant() Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 2 See :trac:`6657` :: sage: EllipticCurve(GF(144169),j=1728) Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169 By default, when a rational value of `j` is given, the constructed curve is a minimal twist (minimal conductor for curves with that `j`-invariant). This can be changed by setting the optional parameter ``minimal_twist``, which is True by default, to False:: sage: EllipticCurve(j=100) Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field sage: E =EllipticCurve(j=100); E Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field sage: E.conductor() 33129800 sage: E.j_invariant() 100 sage: E =EllipticCurve(j=100, minimal_twist=False); E Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field sage: E.conductor() 298168200 sage: E.j_invariant() 100 Without this option, constructing the curve could take a long time since both `j` and `j-1728` have to be factored to compute the minimal twist (see :trac:`13100`):: sage: E = EllipticCurve_from_j(2^256+1,minimal_twist=False) sage: E.j_invariant() == 2^256+1 True TESTS:: sage: R = ZZ['u', 'v'] sage: EllipticCurve(R, [1,1]) Elliptic Curve defined by y^2 = x^3 + x + 1 over Multivariate Polynomial Ring in u, v over Integer Ring We create a curve and a point over QQbar (see #6879):: sage: E = EllipticCurve(QQbar,[0,1]) sage: E(0) (0 : 1 : 0) sage: E.base_field() Algebraic Field sage: E = EllipticCurve(RR,[1,2]); E; E.base_field() Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision Real Field with 53 bits of precision sage: EllipticCurve(CC,[3,4]); E; E.base_field() Elliptic Curve defined by y^2 = x^3 + 3.00000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision Real Field with 53 bits of precision sage: E = EllipticCurve(QQbar,[5,6]); E; E.base_field() Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field Algebraic Field See :trac:`6657` :: sage: EllipticCurve(3,j=1728) Traceback (most recent call last): ... ValueError: First parameter (if present) must be a ring when j is specified sage: EllipticCurve(GF(5),j=3/5) Traceback (most recent call last): ... ValueError: First parameter must be a ring containing 3/5 If the universe of the coefficients is a general field, the object constructed has type EllipticCurve_field. Otherwise it is EllipticCurve_generic. See :trac:`9816` :: sage: E = EllipticCurve([QQbar(1),3]); E Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E = EllipticCurve([RR(1),3]); E Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 3.00000000000000 over Real Field with 53 bits of precision sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E = EllipticCurve([i,i]); E Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E.category() Category of schemes over Symbolic Ring sage: SR in Fields() True sage: F = FractionField(PolynomialRing(QQ,'t')) sage: t = F.gen() sage: E = EllipticCurve([t,0]); E Elliptic Curve defined by y^2 = x^3 + t*x over Fraction Field of Univariate Polynomial Ring in t over Rational Field sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E.category() Category of schemes over Fraction Field of Univariate Polynomial Ring in t over Rational Field See :trac:`12517`:: sage: E = EllipticCurve([1..5]) sage: EllipticCurve(E.a_invariants()) Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field See :trac:`11773`:: sage: E = EllipticCurve() Traceback (most recent call last): ... TypeError: invalid input to EllipticCurve constructor """ import ell_generic, ell_field, ell_finite_field, ell_number_field, ell_rational_field, ell_padic_field # here to avoid circular includes if j is not None: if not x is None: if is_Ring(x): try: j = x(j) except (ZeroDivisionError, ValueError, TypeError): raise ValueError, "First parameter must be a ring containing %s" % j else: raise ValueError, "First parameter (if present) must be a ring when j is specified" return EllipticCurve_from_j(j, minimal_twist) if x is None: raise TypeError, "invalid input to EllipticCurve constructor" if is_SymbolicEquation(x): x = x.lhs() - x.rhs() if parent(x) is SR: x = x._polynomial_(rings.QQ['x', 'y']) if is_MPolynomial(x): if y is None: return EllipticCurve_from_Weierstrass_polynomial(x) else: return EllipticCurve_from_cubic(x, y, morphism=False) if is_Ring(x): if is_RationalField(x): return ell_rational_field.EllipticCurve_rational_field(x, y) elif is_FiniteField(x) or (is_IntegerModRing(x) and x.characteristic().is_prime()): return ell_finite_field.EllipticCurve_finite_field(x, y) elif rings.is_pAdicField(x): return ell_padic_field.EllipticCurve_padic_field(x, y) elif is_NumberField(x): return ell_number_field.EllipticCurve_number_field(x, y) elif x in _Fields: return ell_field.EllipticCurve_field(x, y) return ell_generic.EllipticCurve_generic(x, y) if isinstance(x, unicode): x = str(x) if isinstance(x, basestring): return ell_rational_field.EllipticCurve_rational_field(x) if is_RingElement(x) and y is None: raise TypeError, "invalid input to EllipticCurve constructor" if not isinstance(x, (list, tuple)): raise TypeError, "invalid input to EllipticCurve constructor" x = Sequence(x) if not (len(x) in [2, 5]): raise ValueError, "sequence of coefficients must have length 2 or 5" R = x.universe() if isinstance(x[0], (rings.Rational, rings.Integer, int, long)): return ell_rational_field.EllipticCurve_rational_field(x, y) elif is_NumberField(R): return ell_number_field.EllipticCurve_number_field(x, y) elif rings.is_pAdicField(R): return ell_padic_field.EllipticCurve_padic_field(x, y) elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()): return ell_finite_field.EllipticCurve_finite_field(x, y) elif R in _Fields: return ell_field.EllipticCurve_field(x, y) return ell_generic.EllipticCurve_generic(x, y)
def EllipticCurve(x=None, y=None, j=None, minimal_twist=True): r""" Construct an elliptic curve. In Sage, an elliptic curve is always specified by its a-invariants .. math:: y^2 + a_1 xy + a_3 y = x^3 + a_2 x^2 + a_4 x + a_6. INPUT: There are several ways to construct an elliptic curve: - ``EllipticCurve([a1,a2,a3,a4,a6])``: Elliptic curve with given a-invariants. The invariants are coerced into the parent of the first element. If all are integers, they are coerced into the rational numbers. - ``EllipticCurve([a4,a6])``: Same as above, but `a_1=a_2=a_3=0`. - ``EllipticCurve(label)``: Returns the elliptic curve over Q from the Cremona database with the given label. The label is a string, such as ``"11a"`` or ``"37b2"``. The letters in the label *must* be lower case (Cremona's new labeling). - ``EllipticCurve(R, [a1,a2,a3,a4,a6])``: Create the elliptic curve over ``R`` with given a-invariants. Here ``R`` can be an arbitrary ring. Note that addition need not be defined. - ``EllipticCurve(j=j0)`` or ``EllipticCurve_from_j(j0)``: Return an elliptic curve with j-invariant ``j0``. - ``EllipticCurve(polynomial)``: Read off the a-invariants from the polynomial coefficients, see :func:`EllipticCurve_from_Weierstrass_polynomial`. In each case above where the input is a list of length 2 or 5, one can instead give a 2 or 5-tuple instead. EXAMPLES: We illustrate creating elliptic curves:: sage: EllipticCurve([0,0,1,-1,0]) Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field We create a curve from a Cremona label:: sage: EllipticCurve('37b2') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field sage: EllipticCurve('5077a') Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field sage: EllipticCurve('389a') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field Old Cremona labels are allowed:: sage: EllipticCurve('2400FF') Elliptic Curve defined by y^2 = x^3 + x^2 + 2*x + 8 over Rational Field Unicode labels are allowed:: sage: EllipticCurve(u'389a') Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field We create curves over a finite field as follows:: sage: EllipticCurve([GF(5)(0),0,1,-1,0]) Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5 sage: EllipticCurve(GF(5), [0, 0,1,-1,0]) Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5 Elliptic curves over `\ZZ/N\ZZ` with `N` prime are of type "elliptic curve over a finite field":: sage: F = Zmod(101) sage: EllipticCurve(F, [2, 3]) Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 101 sage: E = EllipticCurve([F(2), F(3)]) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'> sage: E.category() Category of schemes over Ring of integers modulo 101 In contrast, elliptic curves over `\ZZ/N\ZZ` with `N` composite are of type "generic elliptic curve":: sage: F = Zmod(95) sage: EllipticCurve(F, [2, 3]) Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Ring of integers modulo 95 sage: E = EllipticCurve([F(2), F(3)]) sage: type(E) <class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'> sage: E.category() Category of schemes over Ring of integers modulo 95 The following is a curve over the complex numbers:: sage: E = EllipticCurve(CC, [0,0,1,-1,0]) sage: E Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x over Complex Field with 53 bits of precision sage: E.j_invariant() 2988.97297297297 We can also create elliptic curves by giving the Weierstrass equation:: sage: x, y = var('x,y') sage: EllipticCurve(y^2 + y == x^3 + x - 9) Elliptic Curve defined by y^2 + y = x^3 + x - 9 over Rational Field sage: R.<x,y> = GF(5)[] sage: EllipticCurve(x^3 + x^2 + 2 - y^2 - y*x) Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 2 over Finite Field of size 5 We can explicitly specify the `j`-invariant:: sage: E = EllipticCurve(j=1728); E; E.j_invariant(); E.label() Elliptic Curve defined by y^2 = x^3 - x over Rational Field 1728 '32a2' sage: E = EllipticCurve(j=GF(5)(2)); E; E.j_invariant() Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5 2 See :trac:`6657` :: sage: EllipticCurve(GF(144169),j=1728) Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 144169 By default, when a rational value of `j` is given, the constructed curve is a minimal twist (minimal conductor for curves with that `j`-invariant). This can be changed by setting the optional parameter ``minimal_twist``, which is True by default, to False:: sage: EllipticCurve(j=100) Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field sage: E =EllipticCurve(j=100); E Elliptic Curve defined by y^2 = x^3 + x^2 + 3392*x + 307888 over Rational Field sage: E.conductor() 33129800 sage: E.j_invariant() 100 sage: E =EllipticCurve(j=100, minimal_twist=False); E Elliptic Curve defined by y^2 = x^3 + 488400*x - 530076800 over Rational Field sage: E.conductor() 298168200 sage: E.j_invariant() 100 Without this option, constructing the curve could take a long time since both `j` and `j-1728` have to be factored to compute the minimal twist (see :trac:`13100`):: sage: E = EllipticCurve_from_j(2^256+1,minimal_twist=False) sage: E.j_invariant() == 2^256+1 True TESTS:: sage: R = ZZ['u', 'v'] sage: EllipticCurve(R, [1,1]) Elliptic Curve defined by y^2 = x^3 + x + 1 over Multivariate Polynomial Ring in u, v over Integer Ring We create a curve and a point over QQbar (see #6879):: sage: E = EllipticCurve(QQbar,[0,1]) sage: E(0) (0 : 1 : 0) sage: E.base_field() Algebraic Field sage: E = EllipticCurve(RR,[1,2]); E; E.base_field() Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision Real Field with 53 bits of precision sage: EllipticCurve(CC,[3,4]); E; E.base_field() Elliptic Curve defined by y^2 = x^3 + 3.00000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 2.00000000000000 over Real Field with 53 bits of precision Real Field with 53 bits of precision sage: E = EllipticCurve(QQbar,[5,6]); E; E.base_field() Elliptic Curve defined by y^2 = x^3 + 5*x + 6 over Algebraic Field Algebraic Field See :trac:`6657` :: sage: EllipticCurve(3,j=1728) Traceback (most recent call last): ... ValueError: First parameter (if present) must be a ring when j is specified sage: EllipticCurve(GF(5),j=3/5) Traceback (most recent call last): ... ValueError: First parameter must be a ring containing 3/5 If the universe of the coefficients is a general field, the object constructed has type EllipticCurve_field. Otherwise it is EllipticCurve_generic. See :trac:`9816` :: sage: E = EllipticCurve([QQbar(1),3]); E Elliptic Curve defined by y^2 = x^3 + x + 3 over Algebraic Field sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E = EllipticCurve([RR(1),3]); E Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 3.00000000000000 over Real Field with 53 bits of precision sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E = EllipticCurve([i,i]); E Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E.category() Category of schemes over Symbolic Ring sage: SR in Fields() True sage: F = FractionField(PolynomialRing(QQ,'t')) sage: t = F.gen() sage: E = EllipticCurve([t,0]); E Elliptic Curve defined by y^2 = x^3 + t*x over Fraction Field of Univariate Polynomial Ring in t over Rational Field sage: type(E) <class 'sage.schemes.elliptic_curves.ell_field.EllipticCurve_field_with_category'> sage: E.category() Category of schemes over Fraction Field of Univariate Polynomial Ring in t over Rational Field See :trac:`12517`:: sage: E = EllipticCurve([1..5]) sage: EllipticCurve(E.a_invariants()) Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field See :trac:`11773`:: sage: E = EllipticCurve() Traceback (most recent call last): ... TypeError: invalid input to EllipticCurve constructor """ import ell_generic, ell_field, ell_finite_field, ell_number_field, ell_rational_field, ell_padic_field # here to avoid circular includes if j is not None: if not x is None: if is_Ring(x): try: j = x(j) except (ZeroDivisionError, ValueError, TypeError): raise ValueError, "First parameter must be a ring containing %s"%j else: raise ValueError, "First parameter (if present) must be a ring when j is specified" return EllipticCurve_from_j(j, minimal_twist) if x is None: raise TypeError, "invalid input to EllipticCurve constructor" if is_SymbolicEquation(x): x = x.lhs() - x.rhs() if parent(x) is SR: x = x._polynomial_(rings.QQ['x', 'y']) if is_MPolynomial(x): if y is None: return EllipticCurve_from_Weierstrass_polynomial(x) else: return EllipticCurve_from_cubic(x, y, morphism=False) if is_Ring(x): if is_RationalField(x): return ell_rational_field.EllipticCurve_rational_field(x, y) elif is_FiniteField(x) or (is_IntegerModRing(x) and x.characteristic().is_prime()): return ell_finite_field.EllipticCurve_finite_field(x, y) elif rings.is_pAdicField(x): return ell_padic_field.EllipticCurve_padic_field(x, y) elif is_NumberField(x): return ell_number_field.EllipticCurve_number_field(x, y) elif x in _Fields: return ell_field.EllipticCurve_field(x, y) return ell_generic.EllipticCurve_generic(x, y) if isinstance(x, unicode): x = str(x) if isinstance(x, basestring): return ell_rational_field.EllipticCurve_rational_field(x) if is_RingElement(x) and y is None: raise TypeError, "invalid input to EllipticCurve constructor" if not isinstance(x, (list, tuple)): raise TypeError, "invalid input to EllipticCurve constructor" x = Sequence(x) if not (len(x) in [2,5]): raise ValueError, "sequence of coefficients must have length 2 or 5" R = x.universe() if isinstance(x[0], (rings.Rational, rings.Integer, int, long)): return ell_rational_field.EllipticCurve_rational_field(x, y) elif is_NumberField(R): return ell_number_field.EllipticCurve_number_field(x, y) elif rings.is_pAdicField(R): return ell_padic_field.EllipticCurve_padic_field(x, y) elif is_FiniteField(R) or (is_IntegerModRing(R) and R.characteristic().is_prime()): return ell_finite_field.EllipticCurve_finite_field(x, y) elif R in _Fields: return ell_field.EllipticCurve_field(x, y) return ell_generic.EllipticCurve_generic(x, y)
def extensions(self, ring): r""" Return the extensions of this valuation to ``ring``. EXAMPLES:: sage: v = ZZ.valuation(2) sage: v.extensions(GaussianIntegers()) [2-adic valuation] TESTS:: sage: R.<a> = QQ[] sage: L.<a> = QQ.extension(x^3 - 2) sage: R.<b> = L[] sage: M.<b> = L.extension(b^2 + 2*b + a) sage: M.valuation(2) 2-adic valuation Check that we can extend to a field written as a quotient:: sage: R.<x> = QQ[] sage: K.<a> = QQ.extension(x^2 + 1) sage: R.<y> = K[] sage: L.<b> = R.quo(x^2 + a) sage: QQ.valuation(2).extensions(L) [2-adic valuation] A case where there was at some point an internal error in the approximants code:: sage: R.<x> = QQ[] sage: L.<a> = NumberField(x^4 + 2*x^3 + 2*x^2 + 8) sage: QQ.valuation(2).extensions(L) [[ 2-adic valuation, v(x + 2) = 3/2 ]-adic valuation, [ 2-adic valuation, v(x) = 1/2 ]-adic valuation] A case where the extension was incorrect at some point:: sage: v = QQ.valuation(2) sage: L.<a> = NumberField(x^2 + 2) sage: M.<b> = L.extension(x^2 + 1) sage: w = v.extension(L).extension(M) sage: w(w.uniformizer()) 1/4 A case where the extensions could not be separated at some point:: sage: v = QQ.valuation(2) sage: R.<x> = QQ[] sage: F = x^48 + 120*x^45 + 56*x^42 + 108*x^36 + 32*x^33 + 40*x^30 + 48*x^27 + 80*x^24 + 112*x^21 + 96*x^18 + 96*x^15 + 24*x^12 + 96*x^9 + 16*x^6 + 96*x^3 + 68 sage: L.<a> = QQ.extension(F) sage: v.extensions(L) [[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation, [ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation] """ if self.domain() is ring: return [self] domain_fraction_field = _fraction_field(self.domain()) if domain_fraction_field is not self.domain(): if domain_fraction_field.is_subring(ring): return pAdicValuation(domain_fraction_field, self).extensions(ring) if self.domain().is_subring(ring): from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if is_PolynomialQuotientRing(ring): if is_PolynomialQuotientRing(self.domain()): if self.domain().modulus() == ring.modulus(): base_extensions = self._base_valuation.extensions( self._base_valuation.domain().change_ring( self._base_valuation.domain().base_ring( ).fraction_field())) return [ pAdicValuation(ring, base._initial_approximation) for base in base_extensions ] if ring.base_ring() is self.domain(): from sage.categories.all import IntegralDomains if ring in IntegralDomains(): return self._extensions_to_quotient(ring) elif self.domain().is_subring(ring.base_ring()): return sum([ w.extensions(ring) for w in self.extensions(ring.base_ring()) ], []) from sage.rings.number_field.number_field import is_NumberField if is_NumberField(ring.fraction_field()): if ring.base_ring().fraction_field() is self.domain( ).fraction_field(): from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(ring) approximants = self.mac_lane_approximants( ring.fraction_field().relative_polynomial( ).change_ring(self.domain()), assume_squarefree=True, require_incomparability=True) return [ pAdicValuation(ring, approximant, approximants) for approximant in approximants ] if ring.base_ring() is not ring and self.domain().is_subring( ring.base_ring()): return sum([ w.extensions(ring) for w in self.extensions(ring.base_ring()) ], []) return super(pAdicValuation_base, self).extensions(ring)
def check_prime(K,P): r""" Function to check that `P` determines a prime of `K`, and return that ideal. INPUT: - ``K`` -- a number field (including `\QQ`). - ``P`` -- an element of ``K`` or a (fractional) ideal of ``K``. OUTPUT: - If ``K`` is `\QQ`: the prime integer equal to or which generates `P`. - If ``K`` is not `\QQ`: the prime ideal equal to or generated by `P`. .. note:: If `P` is not a prime and does not generate a prime, a TypeError is raised. EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime sage: check_prime(QQ,3) 3 sage: check_prime(QQ,QQ(3)) 3 sage: check_prime(QQ,ZZ.ideal(31)) 31 sage: K.<a>=NumberField(x^2-5) sage: check_prime(K,a) Fractional ideal (a) sage: check_prime(K,a+1) Fractional ideal (a + 1) sage: [check_prime(K,P) for P in K.primes_above(31)] [Fractional ideal (5/2*a + 1/2), Fractional ideal (5/2*a - 1/2)] sage: L.<b> = NumberField(x^2+3) sage: check_prime(K, L.ideal(5)) Traceback (most recent call last): .. TypeError: The ideal Fractional ideal (5) is not a prime ideal of Number Field in a with defining polynomial x^2 - 5 sage: check_prime(K, L.ideal(b)) Traceback (most recent call last): TypeError: No compatible natural embeddings found for Number Field in a with defining polynomial x^2 - 5 and Number Field in b with defining polynomial x^2 + 3 """ if K is QQ: if P in ZZ or isinstance(P, integer_types + (Integer,)): P = Integer(P) if P.is_prime(): return P else: raise TypeError("The element %s is not prime" % (P,) ) elif P in QQ: raise TypeError("The element %s is not prime" % (P,) ) elif is_Ideal(P) and P.base_ring() is ZZ: if P.is_prime(): return P.gen() else: raise TypeError("The ideal %s is not a prime ideal of %s" % (P, ZZ)) else: raise TypeError("%s is neither an element of QQ or an ideal of %s" % (P, ZZ)) if not is_NumberField(K): raise TypeError("%s is not a number field" % (K,) ) if is_NumberFieldFractionalIdeal(P) or P in K: # if P is an ideal, making sure it is an fractional ideal of K P = K.fractional_ideal(P) if P.is_prime(): return P else: raise TypeError("The ideal %s is not a prime ideal of %s" % (P, K)) raise TypeError("%s is not a valid prime of %s" % (P, K))
def __init__(self, diffop, dz, derivatives, nterms_est): deq_Scalars = diffop.base_ring().base_ring() E = dz.parent() if deq_Scalars.characteristic() != 0: raise ValueError("only makes sense for scalar rings of " "characteristic 0") assert deq_Scalars is dz.parent() or deq_Scalars != dz.parent() #### Recurrence operator # Reduce to the case of a number field generated by an algebraic # integer. This is mainly intended to avoid computing gcds (due to # denominators in the representation of number field elements) in the # product tree, but could also be useful to extend the field using Pari # in the future. NF_rec, AlgInts_rec = _number_field_with_integer_gen(deq_Scalars) # ore_algebra currently does not support orders as scalar rings Pols = PolynomialRing(NF_rec, 'n') Rops, Sn = ore_algebra.OreAlgebra(Pols, 'Sn').objgen() # Using the primitive part here would break the computation of # residuals! (Cf. local_solutions.) # recop = diffop.to_S(Rops).primitive_part().numerator() recop = diffop.to_S(Rops) recop = lcm([p.denominator() for p in recop.coefficients()]) * recop # Ensure that ordrec >= orddeq. When the homomorphic image of diffop in # Rops is divisible by Sn, it can happen that the recop (e.g., after # normalization to Sn-valuation 0) has order < orddeq, and our strategy # of using vectors of coefficients of the form [u(n-s'), ..., u(n+r-1)] # with s'=s-r does not work in this case. orddelta = recop.order() - diffop.order() if orddelta < 0: recop = Sn**(-orddelta) * recop #### Choose computation domains if ((isinstance(E, (RealBallField, ComplexBallField)) or E is QQ or utilities.is_QQi(E) or E is RLF or E is CLF) and (deq_Scalars is QQ or utilities.is_QQi(deq_Scalars))): # Special-case QQ and QQ[i] to use arb matrices # (overwrites AlgInts_rec) self.StepMatrix_class = StepMatrix_arb self.binsplit_threshold = 8 # Working precision. We typically want operations on exact balls to # be exact, so that overshooting shouldn't be a problem. # XXX Less clear in the case dz ∈ XBF! # XXX The rough estimate below ignores the height of rec and dz. # prec = nterms_est*(recop.degree()*nterms_est.nbits() # + recop.order().nbits() + 1) prec = 8 + nterms_est * (1 + ZZ(ZZ(recop.order()).nbits()).nbits()) if (E is QQ or isinstance(E, RealBallField)) and deq_Scalars is QQ: AlgInts_rec = AlgInts_pow = RealBallField(prec) else: AlgInts_rec = AlgInts_pow = ComplexBallField(prec) if is_NumberField(E): pow_den = AlgInts_pow(dz.denominator()) else: pow_den = AlgInts_pow.one() else: self.StepMatrix_class = StepMatrix_generic self.binsplit_threshold = 64 if is_NumberField(E): # In fact we should probably do something similar for dz in any # finite-dimensional Q-algebra. (But how?) NF_pow, AlgInts_pow = _number_field_with_integer_gen(E) pow_den = NF_pow(dz).denominator() else: # This includes the case E = ZZ, but dz could live in pretty # much any algebra over deq_Scalars (including matrices, # intervals...). Then the computation of sums_row may take time, # but we still hope to gain something on the computation of the # coefficients and/or limit interval blow-up thanks to the use # of binary splitting. AlgInts_pow = E pow_den = ZZ.one() assert pow_den.parent() is ZZ assert AlgInts_pow is AlgInts_rec or AlgInts_pow != AlgInts_rec #### Recurrence matrix self.recop = recop self.orddeq = diffop.order() self.ordrec = recop.order() self.orddelta = self.ordrec - self.orddeq Pols_rec, n = PolynomialRing(AlgInts_rec, 'n').objgen() self.rec_coeffs = [ -Pols_rec(recop[i])(n - self.orddelta) for i in xrange(self.ordrec) ] self.rec_den = Pols_rec(recop.leading_coefficient())(n - self.orddelta) # Guard against various problems related to number field embeddings and # uniqueness assert Pols_rec.base_ring() is AlgInts_rec assert self.rec_den.base_ring() is AlgInts_rec assert self.rec_den( self.rec_den.base_ring().zero()).parent() is AlgInts_rec # Also store a version of the recurrence operator of the form # b[0](n) + b[1](n) S^(-1) + ··· + b[s](n) S^(-s). # This is convenient to share code with other implementations, or at # least make the implementations easier to compare. # XXX: understand what to do about variable names! self.bwrec = [ recop[self.ordrec - k](Rops.base_ring().gen() - self.ordrec) for k in xrange(self.ordrec + 1) ] #### Power of dz. Note that this part does not depend on n. # If we extend the removal of denominators above to algebras other than # number fields, it would probably make more sense to move this into # the caller. --> support dz in non-com ring (mat)? power series work # only over com rings Series_pow = PolynomialRing(AlgInts_pow, 'delta') self.pow_num = Series_pow([pow_den * dz, pow_den]) self.pow_den = pow_den self.derivatives = derivatives #### Partial sums # We need a parent containing both the coefficients of the operator and # the evaluation point. # XXX: Is this the correct way to get one? Should we use # canonical_coercion()? Something else? # XXX: This is not powerful enough to find a number field containing # two given number fields (both given with embeddings into CC) # Work around #14982 (fixed) + weaknesses of the coercion framework for orders #Series_sums = sage.categories.pushout.pushout(AlgInts_rec, Series_pow) try: AlgInts_sums = sage.categories.pushout.pushout( AlgInts_rec, AlgInts_pow) except sage.structure.coerce_exceptions.CoercionException: AlgInts_sums = sage.categories.pushout.pushout(NF_rec, AlgInts_pow) assert AlgInts_sums is AlgInts_rec or AlgInts_sums != AlgInts_rec assert AlgInts_sums is AlgInts_pow or AlgInts_sums != AlgInts_pow Series_sums = PolynomialRing(AlgInts_sums, 'delta') assert Series_sums.base_ring() is AlgInts_sums # for speed self.Series_sums = Series_sums self.series_class_sums = type(Series_sums.gen()) self.Mat_rec = MatrixSpace(AlgInts_rec, self.ordrec, self.ordrec) self.Mat_sums_row = MatrixSpace(Series_sums, 1, self.ordrec) self.Mat_series_sums = self.Mat_rec.change_ring(Series_sums)