def can_convert_to_singular(R): """ Returns True if this ring's base field or ring can be represented in Singular, and the polynomial ring has at least one generator. If this is True then this polynomial ring can be represented in Singular. The following base rings are supported: finite fields, rationals, number fields, and real and complex fields. EXAMPLES:: sage: from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular sage: can_convert_to_singular(PolynomialRing(QQ, names=['x'])) True sage: can_convert_to_singular(PolynomialRing(QQ, names=[])) False """ if R.ngens() == 0: return False; base_ring = R.base_ring() return ( sage.rings.finite_rings.constructor.is_FiniteField(base_ring) or is_RationalField(base_ring) or (base_ring.is_prime_field() and base_ring.characteristic() <= 2147483647) or is_RealField(base_ring) or is_ComplexField(base_ring) or is_RealDoubleField(base_ring) or is_ComplexDoubleField(base_ring) or number_field.all.is_NumberField(base_ring) or ( sage.rings.fraction_field.is_FractionField(base_ring) and ( base_ring.base_ring().is_prime_field() or base_ring.base_ring() is ZZ ) ) or base_ring is ZZ or is_IntegerModRing(base_ring) )
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 if not sparse else None) R = _get_from_cache(key) if not R is None: return R if isinstance(base_ring, ring.CommutativeRing): if is_IntegerModRing(base_ring) and not sparse: n = base_ring.order() if n.is_prime(): R = m.PolynomialRing_dense_mod_p(base_ring, name, implementation=implementation) elif n > 1: R = m.PolynomialRing_dense_mod_n(base_ring, name, implementation=implementation) else: # n == 1! R = m.PolynomialRing_integral_domain( base_ring, name) # specialized code breaks in this case. elif is_FiniteField(base_ring) and not sparse: R = m.PolynomialRing_dense_finite_field( base_ring, name, implementation=implementation) elif isinstance(base_ring, padic_base_leaves.pAdicFieldCappedRelative): R = m.PolynomialRing_dense_padic_field_capped_relative( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedRelative): R = m.PolynomialRing_dense_padic_ring_capped_relative( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedAbsolute): R = m.PolynomialRing_dense_padic_ring_capped_absolute( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingFixedMod): R = m.PolynomialRing_dense_padic_ring_fixed_mod(base_ring, name) elif base_ring.is_field(proof=False): R = m.PolynomialRing_field(base_ring, name, sparse) elif base_ring.is_integral_domain(proof=False): R = m.PolynomialRing_integral_domain(base_ring, name, sparse, implementation) else: R = m.PolynomialRing_commutative(base_ring, name, sparse) else: R = m.PolynomialRing_general(base_ring, name, sparse) if hasattr(R, '_implementation_names'): for name in R._implementation_names: real_key = key[0:3] + (name, ) _save_in_cache(real_key, R) else: _save_in_cache(key, R) return R
def can_convert_to_singular(R): """ Returns True if this ring's base field or ring can be represented in Singular, and the polynomial ring has at least one generator. If this is True then this polynomial ring can be represented in Singular. The following base rings are supported: finite fields, rationals, number fields, and real and complex fields. EXAMPLES:: sage: from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular sage: can_convert_to_singular(PolynomialRing(QQ, names=['x'])) True sage: can_convert_to_singular(PolynomialRing(QQ, names=[])) False """ if R.ngens() == 0: return False; base_ring = R.base_ring() return ( sage.rings.finite_rings.constructor.is_FiniteField(base_ring) or is_RationalField(base_ring) or (base_ring.is_prime_field() and base_ring.characteristic() <= 2147483647) or is_RealField(base_ring) or is_ComplexField(base_ring) or is_RealDoubleField(base_ring) or is_ComplexDoubleField(base_ring) or number_field.all.is_NumberField(base_ring) or ( sage.rings.fraction_field.is_FractionField(base_ring) and ( base_ring.base_ring().is_prime_field() or base_ring.base_ring() is ZZ ) ) or base_ring is ZZ or is_IntegerModRing(base_ring) )
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 if not sparse else None) R = _get_from_cache(key) if not R is None: return R if isinstance(base_ring, ring.CommutativeRing): if is_IntegerModRing(base_ring) and not sparse: n = base_ring.order() if n.is_prime(): R = m.PolynomialRing_dense_mod_p(base_ring, name, implementation=implementation) elif n > 1: R = m.PolynomialRing_dense_mod_n(base_ring, name, implementation=implementation) else: # n == 1! R = m.PolynomialRing_integral_domain(base_ring, name) # specialized code breaks in this case. elif is_FiniteField(base_ring) and not sparse: R = m.PolynomialRing_dense_finite_field(base_ring, name, implementation=implementation) elif isinstance(base_ring, padic_base_leaves.pAdicFieldCappedRelative): R = m.PolynomialRing_dense_padic_field_capped_relative(base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedRelative): R = m.PolynomialRing_dense_padic_ring_capped_relative(base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedAbsolute): R = m.PolynomialRing_dense_padic_ring_capped_absolute(base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingFixedMod): R = m.PolynomialRing_dense_padic_ring_fixed_mod(base_ring, name) elif base_ring in _CompleteDiscreteValuationRings: R = m.PolynomialRing_cdvr(base_ring, name, sparse) elif base_ring in _CompleteDiscreteValuationFields: R = m.PolynomialRing_cdvf(base_ring, name, sparse) elif base_ring.is_field(proof = False): R = m.PolynomialRing_field(base_ring, name, sparse) elif base_ring.is_integral_domain(proof = False): R = m.PolynomialRing_integral_domain(base_ring, name, sparse, implementation) else: R = m.PolynomialRing_commutative(base_ring, name, sparse) else: R = m.PolynomialRing_general(base_ring, name, sparse) if hasattr(R, '_implementation_names'): for name in R._implementation_names: real_key = key[0:3] + (name,) _save_in_cache(real_key, R) else: _save_in_cache(key, R) return R
def can_convert_to_singular(R): """ Returns True if this ring's base field or ring can be represented in Singular, and the polynomial ring has at least one generator. If this is True then this polynomial ring can be represented in Singular. The following base rings are supported: finite fields, rationals, number fields, and real and complex fields. EXAMPLES:: sage: from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular sage: can_convert_to_singular(PolynomialRing(QQ, names=['x'])) True sage: can_convert_to_singular(PolynomialRing(ZZ, names=['x'])) True sage: can_convert_to_singular(PolynomialRing(QQ, names=[])) False TESTS: Avoid non absolute number fields (see :trac:`23535`):: sage: K.<a,b> = NumberField([x^2-2,x^2-5]) sage: can_convert_to_singular(K['s,t']) False """ if R.ngens() == 0: return False base_ring = R.base_ring() if (base_ring is ZZ or sage.rings.finite_rings.finite_field_constructor.is_FiniteField( base_ring) or is_RationalField(base_ring) or is_IntegerModRing(base_ring) or is_RealField(base_ring) or is_ComplexField(base_ring) or is_RealDoubleField(base_ring) or is_ComplexDoubleField(base_ring)): return True elif base_ring.is_prime_field(): return base_ring.characteristic() <= 2147483647 elif number_field.number_field_base.is_NumberField(base_ring): return base_ring.is_absolute() elif sage.rings.fraction_field.is_FractionField(base_ring): B = base_ring.base_ring() return B.is_prime_field() or B is ZZ or is_FiniteField(B) elif is_RationalFunctionField(base_ring): return base_ring.constant_field().is_prime_field() else: return False
def can_convert_to_singular(R): """ Returns True if this ring's base field or ring can be represented in Singular, and the polynomial ring has at least one generator. If this is True then this polynomial ring can be represented in Singular. The following base rings are supported: finite fields, rationals, number fields, and real and complex fields. EXAMPLES:: sage: from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular sage: can_convert_to_singular(PolynomialRing(QQ, names=['x'])) True sage: can_convert_to_singular(PolynomialRing(QQ, names=[])) False TESTS: Avoid non absolute number fields (see :trac:`23535`):: sage: K.<a,b> = NumberField([x^2-2,x^2-5]) sage: can_convert_to_singular(K['s,t']) False """ if R.ngens() == 0: return False; base_ring = R.base_ring() if (base_ring is ZZ or sage.rings.finite_rings.finite_field_constructor.is_FiniteField(base_ring) or is_RationalField(base_ring) or is_IntegerModRing(base_ring) or is_RealField(base_ring) or is_ComplexField(base_ring) or is_RealDoubleField(base_ring) or is_ComplexDoubleField(base_ring)): return True elif base_ring.is_prime_field(): return base_ring.characteristic() <= 2147483647 elif number_field.number_field_base.is_NumberField(base_ring): return base_ring.is_absolute() elif sage.rings.fraction_field.is_FractionField(base_ring): B = base_ring.base_ring() return B.is_prime_field() or B is ZZ or is_FiniteField(B) elif is_RationalFunctionField(base_ring): return base_ring.constant_field().is_prime_field() else: return False
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, **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 _singular_init_(self, singular=singular): """ Return a newly created Singular ring matching this ring. EXAMPLES:: sage: PolynomialRing(QQ,'u_ba')._singular_init_() // characteristic : 0 // number of vars : 1 // block 1 : ordering lp // : names u_ba // block 2 : ordering C """ if not can_convert_to_singular(self): raise TypeError("no conversion of this ring to a Singular ring defined") if self.ngens()==1: _vars = '(%s)'%self.gen() if "*" in _vars: # 1.000...000*x _vars = _vars.split("*")[1] order = 'lp' else: _vars = str(self.gens()) order = self.term_order().singular_str() base_ring = self.base_ring() if is_RealField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.arith.all.integer_ceil((2*precision - 2)/7.0) self.__singular = singular.ring("(real,%d,0)"%digits, _vars, order=order, check=False) elif is_ComplexField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.arith.all.integer_ceil((2*precision - 2)/7.0) self.__singular = singular.ring("(complex,%d,0,I)"%digits, _vars, order=order, check=False) elif is_RealDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(real,15,0)", _vars, order=order, check=False) elif is_ComplexDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(complex,15,0,I)", _vars, order=order, check=False) elif base_ring.is_prime_field(): self.__singular = singular.ring(self.characteristic(), _vars, order=order, check=False) elif sage.rings.finite_rings.finite_field_constructor.is_FiniteField(base_ring): # not the prime field! gen = str(base_ring.gen()) r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False) self.__minpoly = (str(base_ring.modulus()).replace("x",gen)).replace(" ","") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s"%(self.__minpoly) ) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif number_field.number_field_base.is_NumberField(base_ring) and base_ring.is_absolute(): # not the rationals! gen = str(base_ring.gen()) poly=base_ring.polynomial() poly_gen=str(poly.parent().gen()) poly_str=str(poly).replace(poly_gen,gen) r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False) self.__minpoly = (poly_str).replace(" ","") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s"%(self.__minpoly) ) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif sage.rings.fraction_field.is_FractionField(base_ring) and (base_ring.base_ring() is ZZ or base_ring.base_ring().is_prime_field() or is_FiniteField(base_ring.base_ring())): if base_ring.ngens()==1: gens = str(base_ring.gen()) else: gens = str(base_ring.gens()) if not (not base_ring.base_ring().is_prime_field() and is_FiniteField(base_ring.base_ring())) : self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gens), _vars, order=order, check=False) else: ext_gen = str(base_ring.base_ring().gen()) _vars = '(' + ext_gen + ', ' + _vars[1:]; R = self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gens), _vars, order=order, check=False) self.base_ring().__minpoly = (str(base_ring.base_ring().modulus()).replace("x",ext_gen)).replace(" ","") singular.eval('setring '+R._name); self.__singular = singular("std(ideal(%s))"%(self.base_ring().__minpoly),type='qring') elif sage.rings.function_field.function_field.is_RationalFunctionField(base_ring) and base_ring.constant_field().is_prime_field(): gen = str(base_ring.gen()) self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gen), _vars, order=order, check=False) elif is_IntegerModRing(base_ring): ch = base_ring.characteristic() if ch.is_power_of(2): exp = ch.nbits() -1 self.__singular = singular.ring("(integer,2,%d)"%(exp,), _vars, order=order, check=False) else: self.__singular = singular.ring("(integer,%d)"%(ch,), _vars, order=order, check=False) elif base_ring is ZZ: self.__singular = singular.ring("(integer)", _vars, order=order, check=False) else: raise TypeError("no conversion to a Singular ring defined") return self.__singular
def _single_variate(base_ring, name, sparse=None, implementation=None, order=None): # The "order" argument is unused, but we allow it (and ignore it) # for consistency with the multi-variate case. sparse = bool(sparse) # "implementation" must be last key = [base_ring, name, sparse, implementation] R = _get_from_cache(key) if R is not None: return R from . import polynomial_ring # Find the right constructor and **kwds for our polynomial ring constructor = None kwds = {} if sparse: kwds["sparse"] = True # Specialized implementations specialized = None if is_IntegerModRing(base_ring): n = base_ring.order() if n.is_prime(): specialized = polynomial_ring.PolynomialRing_dense_mod_p elif n > 1: # Specialized code breaks for n == 1 specialized = polynomial_ring.PolynomialRing_dense_mod_n elif is_FiniteField(base_ring): specialized = polynomial_ring.PolynomialRing_dense_finite_field elif isinstance(base_ring, padic_base_leaves.pAdicFieldCappedRelative): specialized = polynomial_ring.PolynomialRing_dense_padic_field_capped_relative elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedRelative): specialized = polynomial_ring.PolynomialRing_dense_padic_ring_capped_relative elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedAbsolute): specialized = polynomial_ring.PolynomialRing_dense_padic_ring_capped_absolute elif isinstance(base_ring, padic_base_leaves.pAdicRingFixedMod): specialized = polynomial_ring.PolynomialRing_dense_padic_ring_fixed_mod # If the implementation is supported, then we are done if specialized is not None: implementation_names = specialized._implementation_names_impl( implementation, base_ring, sparse) if implementation_names is not NotImplemented: implementation = implementation_names[0] constructor = specialized # Generic implementations if constructor is None: if not isinstance(base_ring, ring.CommutativeRing): constructor = polynomial_ring.PolynomialRing_general elif base_ring in _CompleteDiscreteValuationRings: constructor = polynomial_ring.PolynomialRing_cdvr elif base_ring in _CompleteDiscreteValuationFields: constructor = polynomial_ring.PolynomialRing_cdvf elif base_ring.is_field(proof=False): constructor = polynomial_ring.PolynomialRing_field elif base_ring.is_integral_domain(proof=False): constructor = polynomial_ring.PolynomialRing_integral_domain else: constructor = polynomial_ring.PolynomialRing_commutative implementation_names = constructor._implementation_names( implementation, base_ring, sparse) implementation = implementation_names[0] # Only use names which are not supported by the specialized class. if specialized is not None: implementation_names = [ n for n in implementation_names if specialized._implementation_names_impl( n, base_ring, sparse) is NotImplemented ] if implementation is not None: kwds["implementation"] = implementation R = constructor(base_ring, name, **kwds) for impl in implementation_names: key[-1] = impl _save_in_cache(key, R) return R
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 _single_variate(base_ring, name, sparse=None, implementation=None, order=None): # The "order" argument is unused, but we allow it (and ignore it) # for consistency with the multi-variate case. sparse = bool(sparse) if sparse: implementation = None key = (base_ring, name, sparse, implementation) R = _get_from_cache(key) if R is not None: return R import sage.rings.polynomial.polynomial_ring as m if isinstance(base_ring, ring.CommutativeRing): if is_IntegerModRing(base_ring) and not sparse: n = base_ring.order() if n.is_prime(): R = m.PolynomialRing_dense_mod_p(base_ring, name, implementation=implementation) elif n > 1: R = m.PolynomialRing_dense_mod_n(base_ring, name, implementation=implementation) else: # n == 1! R = m.PolynomialRing_integral_domain( base_ring, name) # specialized code breaks in this case. elif is_FiniteField(base_ring) and not sparse: R = m.PolynomialRing_dense_finite_field( base_ring, name, implementation=implementation) elif isinstance(base_ring, padic_base_leaves.pAdicFieldCappedRelative): R = m.PolynomialRing_dense_padic_field_capped_relative( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedRelative): R = m.PolynomialRing_dense_padic_ring_capped_relative( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedAbsolute): R = m.PolynomialRing_dense_padic_ring_capped_absolute( base_ring, name) elif isinstance(base_ring, padic_base_leaves.pAdicRingFixedMod): R = m.PolynomialRing_dense_padic_ring_fixed_mod(base_ring, name) elif base_ring in _CompleteDiscreteValuationRings: R = m.PolynomialRing_cdvr(base_ring, name, sparse) elif base_ring in _CompleteDiscreteValuationFields: R = m.PolynomialRing_cdvf(base_ring, name, sparse) elif base_ring.is_field(proof=False): R = m.PolynomialRing_field(base_ring, name, sparse) elif base_ring.is_integral_domain(proof=False): R = m.PolynomialRing_integral_domain(base_ring, name, sparse, implementation) else: R = m.PolynomialRing_commutative(base_ring, name, sparse) else: R = m.PolynomialRing_general(base_ring, name, sparse) if hasattr(R, '_implementation_names'): for name in R._implementation_names: real_key = key[0:3] + (name, ) _save_in_cache(real_key, R) else: _save_in_cache(key, R) return R
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 _singular_init_(self, singular=singular_default): """ Return a newly created Singular ring matching this ring. EXAMPLES:: sage: PolynomialRing(QQ,'u_ba')._singular_init_() // characteristic : 0 // number of vars : 1 // block 1 : ordering lp // : names u_ba // block 2 : ordering C """ if not can_convert_to_singular(self): raise TypeError, "no conversion of this ring to a Singular ring defined" if self.ngens()==1: _vars = '(%s)'%self.gen() if "*" in _vars: # 1.000...000*x _vars = _vars.split("*")[1] order = 'lp' else: _vars = str(self.gens()) order = self.term_order().singular_str() base_ring = self.base_ring() if is_RealField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.rings.arith.integer_ceil((2*precision - 2)/7.0) self.__singular = singular.ring("(real,%d,0)"%digits, _vars, order=order, check=False) elif is_ComplexField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.rings.arith.integer_ceil((2*precision - 2)/7.0) self.__singular = singular.ring("(complex,%d,0,I)"%digits, _vars, order=order, check=False) elif is_RealDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(real,15,0)", _vars, order=order, check=False) elif is_ComplexDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(complex,15,0,I)", _vars, order=order, check=False) elif base_ring.is_prime_field(): self.__singular = singular.ring(self.characteristic(), _vars, order=order, check=False) elif sage.rings.finite_rings.constructor.is_FiniteField(base_ring): # not the prime field! gen = str(base_ring.gen()) r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False) self.__minpoly = (str(base_ring.modulus()).replace("x",gen)).replace(" ","") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s"%(self.__minpoly) ) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif number_field.all.is_NumberField(base_ring) and base_ring.is_absolute(): # not the rationals! gen = str(base_ring.gen()) poly=base_ring.polynomial() poly_gen=str(poly.parent().gen()) poly_str=str(poly).replace(poly_gen,gen) r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False) self.__minpoly = (poly_str).replace(" ","") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s"%(self.__minpoly) ) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif sage.rings.fraction_field.is_FractionField(base_ring) and (base_ring.base_ring() is ZZ or base_ring.base_ring().is_prime_field()): if base_ring.ngens()==1: gens = str(base_ring.gen()) else: gens = str(base_ring.gens()) self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gens), _vars, order=order, check=False) elif is_IntegerModRing(base_ring): ch = base_ring.characteristic() if ch.is_power_of(2): exp = ch.nbits() -1 self.__singular = singular.ring("(integer,2,%d)"%(exp,), _vars, order=order, check=False) else: self.__singular = singular.ring("(integer,%d)"%(ch,), _vars, order=order, check=False) elif base_ring is ZZ: self.__singular = singular.ring("(integer)", _vars, order=order, check=False) else: raise TypeError, "no conversion to a Singular ring defined" return self.__singular
def _singular_init_(self, singular=singular): """ Return a newly created Singular ring matching this ring. EXAMPLES:: sage: PolynomialRing(QQ,'u_ba')._singular_init_() polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names u_ba // block 2 : ordering C """ if not can_convert_to_singular(self): raise TypeError("no conversion of this ring to a Singular ring defined") if self.ngens()==1: _vars = '(%s)'%self.gen() if "*" in _vars: # 1.000...000*x _vars = _vars.split("*")[1] order = 'lp' else: _vars = str(self.gens()) order = self.term_order().singular_str() base_ring = self.base_ring() if is_RealField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.arith.all.integer_ceil((2*precision - 2)/7.0) self.__singular = singular.ring("(real,%d,0)"%digits, _vars, order=order, check=False) elif is_ComplexField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.arith.all.integer_ceil((2*precision - 2)/7.0) self.__singular = singular.ring("(complex,%d,0,I)"%digits, _vars, order=order, check=False) elif is_RealDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(real,15,0)", _vars, order=order, check=False) elif is_ComplexDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(complex,15,0,I)", _vars, order=order, check=False) elif base_ring.is_prime_field(): self.__singular = singular.ring(self.characteristic(), _vars, order=order, check=False) elif sage.rings.finite_rings.finite_field_constructor.is_FiniteField(base_ring): # not the prime field! gen = str(base_ring.gen()) r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False) self.__minpoly = (str(base_ring.modulus()).replace("x",gen)).replace(" ","") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s"%(self.__minpoly) ) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif number_field.number_field_base.is_NumberField(base_ring) and base_ring.is_absolute(): # not the rationals! gen = str(base_ring.gen()) poly=base_ring.polynomial() poly_gen=str(poly.parent().gen()) poly_str=str(poly).replace(poly_gen,gen) r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False) self.__minpoly = (poly_str).replace(" ","") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s"%(self.__minpoly) ) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif sage.rings.fraction_field.is_FractionField(base_ring) and (base_ring.base_ring() is ZZ or base_ring.base_ring().is_prime_field() or is_FiniteField(base_ring.base_ring())): if base_ring.ngens()==1: gens = str(base_ring.gen()) else: gens = str(base_ring.gens()) if not (not base_ring.base_ring().is_prime_field() and is_FiniteField(base_ring.base_ring())) : self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gens), _vars, order=order, check=False) else: ext_gen = str(base_ring.base_ring().gen()) _vars = '(' + ext_gen + ', ' + _vars[1:]; R = self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gens), _vars, order=order, check=False) self.base_ring().__minpoly = (str(base_ring.base_ring().modulus()).replace("x",ext_gen)).replace(" ","") singular.eval('setring '+R._name); from sage.misc.stopgap import stopgap stopgap("Denominators of fraction field elements are sometimes dropped without warning.", 17696) self.__singular = singular("std(ideal(%s))"%(self.base_ring().__minpoly),type='qring') elif sage.rings.function_field.function_field.is_RationalFunctionField(base_ring) and base_ring.constant_field().is_prime_field(): gen = str(base_ring.gen()) self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gen), _vars, order=order, check=False) elif is_IntegerModRing(base_ring): ch = base_ring.characteristic() if ch.is_power_of(2): exp = ch.nbits() -1 self.__singular = singular.ring("(integer,2,%d)"%(exp,), _vars, order=order, check=False) else: self.__singular = singular.ring("(integer,%d)"%(ch,), _vars, order=order, check=False) elif base_ring is ZZ: self.__singular = singular.ring("(integer)", _vars, order=order, check=False) else: raise TypeError("no conversion to a Singular ring defined") return self.__singular