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 points(self, B=0):
"""
Return some or all rational points of a projective scheme.
INPUT:
- `B` -- integer (optional, default=0). The bound for the
coordinates.
OUTPUT:
A list of points. Over a finite field, all points are
returned. Over an infinite field, all points satisfying the
bound are returned.
EXAMPLES::
sage: P1 = ProjectiveSpace(GF(2),1)
sage: F.<a> = GF(4,'a')
sage: P1(F).points()
[(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)]
"""
from sage.schemes.projective.projective_rational_point import enum_projective_rational_field
from sage.schemes.projective.projective_rational_point import enum_projective_finite_field
R = self.value_ring()
if is_RationalField(R):
if not B > 0:
raise TypeError("A positive bound B (= %s) must be specified."%B)
return enum_projective_rational_field(self,B)
elif is_FiniteField(R):
return enum_projective_finite_field(self.extended_codomain())
else:
raise TypeError("Unable to enumerate points over %s."%R)
def __init__(self, X, P, codomain = None, check = False):
r"""
Create the discrete probability space with probabilities on the
space X given by the dictionary P with values in the field
real_field.
EXAMPLES::
sage: S = [ i for i in range(16) ]
sage: P = {}
sage: for i in range(15): P[i] = 2^(-i-1)
sage: P[15] = 2^-16
sage: X = DiscreteProbabilitySpace(S,P)
sage: X.domain()
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
sage: X.set()
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
sage: X.entropy()
1.9997253418
A probability space can be defined on any list of elements.
EXAMPLES::
sage: AZ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
sage: S = [ AZ[i] for i in range(26) ]
sage: P = { 'A':1/2, 'B':1/4, 'C':1/4 }
sage: X = DiscreteProbabilitySpace(S,P)
sage: X
Discrete probability space defined by {'A': 1/2, 'C': 1/4, 'B': 1/4}
sage: X.entropy()
1.5
"""
if codomain is None:
codomain = RealField()
if not is_RealField(codomain) and not is_RationalField(codomain):
raise TypeError("Argument codomain (= %s) must be the reals or rationals" % codomain)
if check:
one = sum([ P[x] for x in P.keys() ])
if is_RationalField(codomain):
if not one == 1:
raise TypeError("Argument P (= %s) does not define a probability function")
else:
if not Abs(one-1) < 2^(-codomain.precision()+1):
raise TypeError("Argument P (= %s) does not define a probability function")
ProbabilitySpace_generic.__init__(self, X, codomain)
DiscreteRandomVariable.__init__(self, self, P, codomain, check)
def points(self, B=0):
r"""
Return some or all rational points of an affine scheme.
INPUT:
- ``B`` -- integer (optional, default: 0). The bound for the
height of the coordinates.
OUTPUT:
- If the base ring is a finite field: all points of the scheme,
given by coordinate tuples.
- If the base ring is `\QQ` or `\ZZ`: the subset of points whose
coordinates have height ``B`` or less.
EXAMPLES: The bug reported at #11526 is fixed::
sage: A2 = AffineSpace(ZZ,2)
sage: F = GF(3)
sage: A2(F).points()
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
sage: R = ZZ
sage: A.<x,y> = R[]
sage: I = A.ideal(x^2-y^2-1)
sage: V = AffineSpace(R,2)
sage: X = V.subscheme(I)
sage: M = X(R)
sage: M.points(1)
[(-1, 0), (1, 0)]
::
sage: u = QQ['u'].0
sage: K.<v> = NumberField(u^2 + 3)
sage: A.<x,y> = AffineSpace(K,2)
sage: len(A(K).points(9))
361
"""
R = self.value_ring()
if is_RationalField(R) or R == ZZ:
if not B > 0:
raise TypeError("A positive bound B (= %s) must be specified."%B)
from sage.schemes.affine.affine_rational_point import enum_affine_rational_field
return enum_affine_rational_field(self,B)
if R in NumberFields():
from sage.schemes.affine.affine_rational_point import enum_affine_number_field
return enum_affine_number_field(self,B)
elif is_FiniteField(R):
from sage.schemes.affine.affine_rational_point import enum_affine_finite_field
return enum_affine_finite_field(self)
else:
raise TypeError("Unable to enumerate points over %s."%R)
def relation_matrix_wtk_g0(syms, sign, field, sparse):
r"""
Compute the matrix of relations. Despite the name, this is used for all
spaces (not just for Gamma0). For a description of the algorithm, see the
docstring for ``compute_presentation``.
INPUT:
- ``syms`` -- :class:`ManinSymbolList`
- ``sign``: integer (0, 1 or -1)
- ``field``: the base field (non-field base rings not supported at present)
- ``sparse``: (True or False) whether to use sparse arithmetic.
Note that ManinSymbolList objects already have a specific weight, so there
is no need for an extra ``weight`` parameter.
OUTPUT: a pair (R, mod) where
- R is a matrix as output by ``T_relation_matrix_wtk_g0``
- mod is a set of 2-term relations as output by ``sparse_2term_quotient``
EXAMPLE::
sage: L = sage.modular.modsym.manin_symbol_list.ManinSymbolList_gamma0(8,2)
sage: A = sage.modular.modsym.relation_matrix.relation_matrix_wtk_g0(L, 0, GF(2), True); A
(
[0 0 0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 0 0 0 1 1 1 0]
[0 0 0 0 0 0 1 0 0 1 1 0]
[0 0 0 0 0 0 1 0 0 0 0 0], [(1, 1), (1, 1), (8, 1), (10, 1), (6, 1), (11, 1), (6, 1), (9, 1), (8, 1), (9, 1), (10, 1), (11, 1)]
)
sage: A[0].is_sparse()
True
"""
rels = modS_relations(syms)
if sign != 0:
# Let rels = rels union I relations.
rels.update(modI_relations(syms, sign))
if syms._apply_S_only_0pm1() and is_RationalField(field):
import relation_matrix_pyx
mod = relation_matrix_pyx.sparse_2term_quotient_only_pm1(rels, len(syms))
else:
mod = sparse_2term_quotient(rels, len(syms), field)
R = T_relation_matrix_wtk_g0(syms, mod, field, sparse)
return R, mod
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
#.........这里部分代码省略.........
if point:
return self.has_singular_point(point = True)
if obstruction:
return True, None
return True
B = self.base_ring()
if algorithm == 'default':
ret = self.has_rational_point(point=True, obstruction=False,
algorithm='rnfisnorm',
read_cache=False)
if ret[0]:
if point or obstruction:
return ret
return True
if obstruction:
ret = self.has_rational_point(point=False, obstruction=True,
algorithm='local',
read_cache=False)
if ret[0]:
raise RuntimeError("Outputs of algorithms in " \
"has_rational_point disagree " \
"for conic %s" % self)
return ret
if point:
return False, None
return False
if algorithm == 'local':
if point:
raise ValueError("Algorithm 'local' cannot be combined " \
"with point = True in has_rational_point")
obs = self.local_obstructions(infinite = True, finite = False,
read_cache = read_cache)
if obs != []:
if obstruction:
return False, obs[0]
return False
obs = self.local_obstructions(read_cache = read_cache)
if obs == []:
if obstruction:
return True, None
return True
if obstruction:
return False, obs[0]
return False
if algorithm == 'rnfisnorm':
from sage.modules.free_module_element import vector
if obstruction:
raise ValueError("Algorithm rnfisnorm cannot be combined " \
"with obstruction = True in " \
"has_rational_point")
D, T = self.diagonal_matrix()
abc = [D[0,0], D[1,1], D[2,2]]
for j in range(3):
if abc[j] == 0:
pt = self.point(T*vector({2:0,j:1}))
if point or obstruction:
return True, pt
return True
if (-abc[1]/abc[0]).is_square():
pt = self.point(T*vector([(-abc[1]/abc[0]).sqrt(), 1, 0]))
if point or obstruction:
return True, pt
return True
if (-abc[2]/abc[0]).is_square():
pt = self.point(T*vector([(-abc[2]/abc[0]).sqrt(), 0, 1]))
if point or obstruction:
return True, pt
return True
if is_RationalField(B):
K = B
[KtoB, BtoK] = [K.hom(K) for i in range(2)]
else:
K = B.absolute_field('Y')
[KtoB, BtoK] = K.structure()
X = PolynomialRing(K, 'X').gen()
d = BtoK(-abc[1]/abc[0])
den = d.denominator()
L = K.extension(X**2 - d*den**2, names='y')
isnorm = BtoK(-abc[2]/abc[0]).is_norm(L, element=True)
if isnorm[0]:
pt = self.point(T*vector([KtoB(isnorm[1][0]),
KtoB(isnorm[1][1]*den), 1]))
if point:
return True, pt
return True
if point:
return False, None
return False
if algorithm == 'qfsolve':
raise TypeError("Algorithm qfsolve in has_rational_point only " \
"for conics over QQ, not over %s" % B)
if obstruction:
raise ValueError("Invalid combination: obstruction=True and " \
"algorithm=%s" % algorithm)
return ProjectiveConic_field.has_rational_point(self, point = point,
algorithm = algorithm, read_cache = False)
#.........这里部分代码省略.........
Traceback (most recent call last):
...
SplittingFieldAbort: degree of splitting field is a multiple of 180
Use the ``degree_divisor`` attribute to recover the divisor of the
degree of the splitting field or ``degree_multiple`` to recover a
multiple::
sage: from sage.rings.number_field.splitting_field import SplittingFieldAbort
sage: try: # long time (4s on sage.math, 2014)
....: (x^8+x+1).splitting_field('b', abort_degree=60, simplify=False)
....: except SplittingFieldAbort as e:
....: print(e.degree_divisor)
....: print(e.degree_multiple)
120
1440
TESTS::
sage: from sage.rings.number_field.splitting_field import splitting_field
sage: splitting_field(polygen(QQ), name='x', map=True, simplify_all=True)
(Number Field in x with defining polynomial x, Ring morphism:
From: Rational Field
To: Number Field in x with defining polynomial x
Defn: 1 |--> 1)
"""
from sage.misc.all import verbose, cputime
degree_multiple = Integer(degree_multiple or 0)
abort_degree = Integer(abort_degree or 0)
# Kpol = PARI polynomial in y defining the extension found so far
F = poly.base_ring()
if is_RationalField(F):
Kpol = pari("'y")
else:
Kpol = F.pari_polynomial("y")
# Fgen = the generator of F as element of Q[y]/Kpol
# (only needed if map=True)
if map:
Fgen = F.gen().__pari__()
verbose("Starting field: %s"%Kpol)
# L and Lred are lists of SplittingData.
# L contains polynomials which are irreducible over K,
# Lred contains polynomials which need to be factored.
L = []
Lred = [SplittingData(poly._pari_with_name(), degree_multiple)]
# Main loop, handle polynomials one by one
while True:
# Absolute degree of current field K
absolute_degree = Integer(Kpol.poldegree())
# Compute minimum relative degree of splitting field
rel_degree_divisor = Integer(1)
for splitting in L:
rel_degree_divisor = rel_degree_divisor.lcm(splitting.poldegree())
# Check for early aborts
abort_rel_degree = abort_degree//absolute_degree
if abort_rel_degree and rel_degree_divisor > abort_rel_degree:
raise SplittingFieldAbort(absolute_degree * rel_degree_divisor, degree_multiple)
# First, factor polynomials in Lred and store the result in L
verbose("SplittingData to factor: %s"%[s._repr_tuple() for s in Lred])
#.........这里部分代码省略.........
Traceback (most recent call last):
...
ValueError: Not a hyperelliptic curve: highly singular at infinity.
sage: HyperellipticCurve(F)
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1
An example with a singularity over an inseparable extension of the
base field::
sage: F.<t> = GF(5)[]
sage: P.<x> = F[]
sage: HyperellipticCurve(x^5+t)
Traceback (most recent call last):
...
ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.
Input with integer coefficients creates objects with the integers
as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`).
In other words, it is checked that the discriminant is non-zero, but it is
not checked whether the discriminant is a unit in `\ZZ^*`.::
sage: P.<x> = ZZ[]
sage: HyperellipticCurve(3*x^7+6*x+6)
Hyperelliptic Curve over Integer Ring defined by y^2 = 3*x^7 + 6*x + 6
"""
if (not is_Polynomial(f)) or f == 0:
raise TypeError, "Arguments f (=%s) and h (= %s) must be polynomials " \
"and f must be non-zero" % (f,h)
P = f.parent()
if h is None:
h = P(0)
try:
h = P(h)
except TypeError:
raise TypeError, \
"Arguments f (=%s) and h (= %s) must be polynomials in the same ring"%(f,h)
df = f.degree()
dh_2 = 2*h.degree()
if dh_2 < df:
g = (df-1)//2
else:
g = (dh_2-1)//2
if check_squarefree:
# Assuming we are working over a field, this checks that after
# resolving the singularity at infinity, we get a smooth double cover
# of P^1.
if P(2) == 0:
# characteristic 2
if h == 0:
raise ValueError, \
"In characteristic 2, argument h (= %s) must be non-zero."%h
if h[g+1] == 0 and f[2*g+1]**2 == f[2*g+2]*h[g]**2:
raise ValueError, "Not a hyperelliptic curve: " \
"highly singular at infinity."
should_be_coprime = [h, f*h.derivative()**2+f.derivative()**2]
else:
# characteristic not 2
F = f + h**2/4
if not F.degree() in [2*g+1, 2*g+2]:
raise ValueError, "Not a hyperelliptic curve: " \
"highly singular at infinity."
should_be_coprime = [F, F.derivative()]
try:
smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree()==0
except (AttributeError, NotImplementedError, TypeError):
try:
smooth = should_be_coprime[0].resultant(should_be_coprime[1])!=0
except (AttributeError, NotImplementedError, TypeError):
raise NotImplementedError, "Cannot determine whether " \
"polynomials %s have a common root. Use " \
"check_squarefree=False to skip this check." % \
should_be_coprime
if not smooth:
raise ValueError, "Not a hyperelliptic curve: " \
"singularity in the provided affine patch."
R = P.base_ring()
PP = ProjectiveSpace(2, R)
if names is None:
names = ["x","y"]
if is_FiniteField(R):
if g == 2:
return HyperellipticCurve_g2_finite_field(PP, f, h, names=names, genus=g)
else:
return HyperellipticCurve_finite_field(PP, f, h, names=names, genus=g)
elif is_RationalField(R):
if g == 2:
return HyperellipticCurve_g2_rational_field(PP, f, h, names=names, genus=g)
else:
return HyperellipticCurve_rational_field(PP, f, h, names=names, genus=g)
elif is_pAdicField(R):
if g == 2:
return HyperellipticCurve_g2_padic_field(PP, f, h, names=names, genus=g)
else:
return HyperellipticCurve_padic_field(PP, f, h, names=names, genus=g)
else:
if g == 2:
return HyperellipticCurve_g2_generic(PP, f, h, names=names, genus=g)
else:
return HyperellipticCurve_generic(PP, f, h, names=names, genus=g)
#.........这里部分代码省略.........
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 points_of_bounded_height(self,bound, prec=53):
r"""
Returns an iterator of the points in self of absolute height of at most the given bound. Bound check
is strict for the rational field. Requires self to be projective space over a number field. Uses the
Doyle-Krumm algorithm for computing algebraic numbers up to a given height [Doyle-Krumm].
INPUT:
- ``bound`` - a real number
- ``prec`` - the precision to use to compute the elements of bounded height for number fields
OUTPUT:
- an iterator of points in self
.. WARNING::
In the current implementation, the output of the [Doyle-Krumm] algorithm
cannot be guaranteed to be correct due to the necessity of floating point
computations. In some cases, the default 53-bit precision is
considerably lower than would be required for the algorithm to
generate correct output.
EXAMPLES::
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: list(P.points_of_bounded_height(5))
[(0 : 1), (1 : 1), (-1 : 1), (1/2 : 1), (-1/2 : 1), (2 : 1), (-2 : 1), (1/3 : 1),
(-1/3 : 1), (3 : 1), (-3 : 1), (2/3 : 1), (-2/3 : 1), (3/2 : 1), (-3/2 : 1), (1/4 : 1),
(-1/4 : 1), (4 : 1), (-4 : 1), (3/4 : 1), (-3/4 : 1), (4/3 : 1), (-4/3 : 1), (1 : 0)]
::
sage: u = QQ['u'].0
sage: P.<x,y,z> = ProjectiveSpace(NumberField(u^2 - 2,'v'), 2)
sage: len(list(P.points_of_bounded_height(1.5)))
57
"""
if (is_RationalField(self.base_ring())):
ftype = False # stores whether the field is a number field or the rational field
elif (self.base_ring() in NumberFields()): # true for rational field as well, so check is_RationalField first
ftype = True
else:
raise NotImplementedError("self must be projective space over a number field.")
bound = bound**(self.base_ring().absolute_degree()) # convert to relative height
n = self.dimension_relative()
R = self.base_ring()
zero = R(0)
i = n
while not i < 0:
P = [ zero for _ in range(i) ] + [ R(1) ] + [ zero for _ in range(n-i) ]
yield self(P)
if (ftype == False): # if rational field
iters = [ R.range_by_height(bound) for _ in range(i) ]
else: # if number field
iters = [ R.elements_of_bounded_height(bound, precision=prec) for _ in range(i) ]
for x in iters: next(x) # put at zero
j = 0
while j < i:
try:
P[j] = next(iters[j])
yield self(P)
j = 0
except StopIteration:
if (ftype == False): # if rational field
iters[j] = R.range_by_height(bound) # reset
else: # if number field
iters[j] = R.elements_of_bounded_height(bound, precision=prec) # reset
next(iters[j]) # put at zero
P[j] = zero
j += 1
i -= 1
#.........这里部分代码省略.........
sage: K.<v> = NumberField(u^2 + 3)
sage: P.<x,y,z> = ProjectiveSpace(K,2)
sage: len(P(K).points(1.8))
381
::
sage: P1 = ProjectiveSpace(GF(2),1)
sage: F.<a> = GF(4,'a')
sage: P1(F).points()
[(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)]
::
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: E = P.subscheme([(y^3-y*z^2) - (x^3-x*z^2),(y^3-y*z^2) + (x^3-x*z^2)])
sage: E(P.base_ring()).points()
[(-1 : -1 : 1), (-1 : 0 : 1), (-1 : 1 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 1),
(1 : -1 : 1), (1 : 0 : 1), (1 : 1 : 1)]
"""
X = self.codomain()
from sage.schemes.projective.projective_space import is_ProjectiveSpace
if not is_ProjectiveSpace(X) and X.base_ring() in Fields():
#Then it must be a subscheme
dim_ideal = X.defining_ideal().dimension()
if dim_ideal < 1: # no points
return []
if dim_ideal == 1: # if X zero-dimensional
rat_points = set()
PS = X.ambient_space()
N = PS.dimension_relative()
BR = X.base_ring()
#need a lexicographic ordering for elimination
R = PolynomialRing(BR, N + 1, PS.gens(), order='lex')
I = R.ideal(X.defining_polynomials())
I0 = R.ideal(0)
#Determine the points through elimination
#This is much faster than using the I.variety() function on each affine chart.
for k in range(N + 1):
#create the elimination ideal for the kth affine patch
G = I.substitute({R.gen(k):1}).groebner_basis()
if G != [1]:
P = {}
#keep track that we know the kth coordinate is 1
P.update({R.gen(k):1})
points = [P]
#work backwards from solving each equation for the possible
#values of the next coordinate
for i in range(len(G) - 1, -1, -1):
new_points = []
good = 0
for P in points:
#substitute in our dictionary entry that has the values
#of coordinates known so far. This results in a single
#variable polynomial (by elimination)
L = G[i].substitute(P)
if L != 0:
L = L.factor()
#the linear factors give the possible rational values of
#this coordinate
for pol, pow in L:
if pol.degree() == 1 and len(pol.variables()) == 1:
good = 1
r = pol.variables()[0]
varindex = R.gens().index(r)
#add this coordinates information to
#each dictionary entry
P.update({R.gen(varindex):-pol.constant_coefficient() / pol.monomial_coefficient(r)})
new_points.append(copy(P))
else:
new_points.append(P)
good = 1
if good:
points = new_points
#the dictionary entries now have values for all coordinates
#they are the rational solutions to the equations
#make them into projective points
for i in range(len(points)):
if len(points[i]) == N + 1 and I.subs(points[i]) == I0:
S = X([points[i][R.gen(j)] for j in range(N + 1)])
S.normalize_coordinates()
rat_points.add(S)
rat_points = sorted(rat_points)
return rat_points
R = self.value_ring()
if is_RationalField(R):
if not B > 0:
raise TypeError("a positive bound B (= %s) must be specified"%B)
from sage.schemes.projective.projective_rational_point import enum_projective_rational_field
return enum_projective_rational_field(self,B)
elif R in NumberFields():
if not B > 0:
raise TypeError("a positive bound B (= %s) must be specified"%B)
from sage.schemes.projective.projective_rational_point import enum_projective_number_field
return enum_projective_number_field(self,B, prec=prec)
elif is_FiniteField(R):
from sage.schemes.projective.projective_rational_point import enum_projective_finite_field
return enum_projective_finite_field(self.extended_codomain())
else:
raise TypeError("unable to enumerate points over %s"%R)
def ProjectiveSpace(n, R=None, names='x'):
r"""
Return projective space of dimension `n` over the ring `R`.
EXAMPLES: The dimension and ring can be given in either order.
::
sage: ProjectiveSpace(3, QQ)
Projective Space of dimension 3 over Rational Field
sage: ProjectiveSpace(5, QQ)
Projective Space of dimension 5 over Rational Field
sage: P = ProjectiveSpace(2, QQ, names='XYZ'); P
Projective Space of dimension 2 over Rational Field
sage: P.coordinate_ring()
Multivariate Polynomial Ring in X, Y, Z over Rational Field
The divide operator does base extension.
::
sage: ProjectiveSpace(5)/GF(17)
Projective Space of dimension 5 over Finite Field of size 17
The default base ring is `\ZZ`.
::
sage: ProjectiveSpace(5)
Projective Space of dimension 5 over Integer Ring
There is also an projective space associated each polynomial ring.
::
sage: R = GF(7)['x,y,z']
sage: P = ProjectiveSpace(R); P
Projective Space of dimension 2 over Finite Field of size 7
sage: P.coordinate_ring()
Multivariate Polynomial Ring in x, y, z over Finite Field of size 7
sage: P.coordinate_ring() is R
True
::
sage: ProjectiveSpace(3, Zp(5), 'y')
Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20
::
sage: ProjectiveSpace(2,QQ,'x,y,z')
Projective Space of dimension 2 over Rational Field
::
sage: PS.<x,y>=ProjectiveSpace(1,CC)
sage: PS
Projective Space of dimension 1 over Complex Field with 53 bits of precision
Projective spaces are not cached, i.e., there can be several with
the same base ring and dimension (to facilitate gluing
constructions).
"""
if is_MPolynomialRing(n) and R is None:
A = ProjectiveSpace(n.ngens()-1, n.base_ring())
A._coordinate_ring = n
return A
if isinstance(R, (int, long, Integer)):
n, R = R, n
if R is None:
R = ZZ # default is the integers
if R in _Fields:
if is_FiniteField(R):
return ProjectiveSpace_finite_field(n, R, names)
if is_RationalField(R):
return ProjectiveSpace_rational_field(n, R, names)
else:
return ProjectiveSpace_field(n, R, names)
elif is_CommutativeRing(R):
return ProjectiveSpace_ring(n, R, names)
else:
raise TypeError("R (=%s) must be a commutative ring"%R)
def points_of_bounded_height(self,bound):
r"""
Returns an iterator of the points in self of absolute height of at most the given bound. Bound check
is strict for the rational field. Requires self to be projective space over a number field. Uses the
Doyle-Krumm algorithm for computing algebraic numbers up to a given height [Doyle-Krumm].
INPUT:
- ``bound`` - a real number
OUTPUT:
- an iterator of points in self
EXAMPLES::
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: list(P.points_of_bounded_height(5))
[(0 : 1), (1 : 1), (-1 : 1), (1/2 : 1), (-1/2 : 1), (2 : 1), (-2 : 1), (1/3 : 1),
(-1/3 : 1), (3 : 1), (-3 : 1), (2/3 : 1), (-2/3 : 1), (3/2 : 1), (-3/2 : 1), (1/4 : 1),
(-1/4 : 1), (4 : 1), (-4 : 1), (3/4 : 1), (-3/4 : 1), (4/3 : 1), (-4/3 : 1), (1 : 0)]
::
sage: u = QQ['u'].0
sage: P.<x,y,z> = ProjectiveSpace(NumberField(u^2 - 2,'v'), 2)
sage: len(list(P.points_of_bounded_height(6)))
133
"""
if (is_RationalField(self.base_ring())):
ftype = False # stores whether the field is a number field or the rational field
elif (self.base_ring() in NumberFields()): # true for rational field as well, so check is_RationalField first
ftype = True
else:
raise NotImplementedError("self must be projective space over a number field.")
bound = bound**(1/self.base_ring().absolute_degree()) # convert to relative height
n = self.dimension_relative()
R = self.base_ring()
zero = R(0)
i = n
while not i < 0:
P = [ zero for _ in range(i) ] + [ R(1) ] + [ zero for _ in range(n-i) ]
yield self(P)
if (ftype == False): # if rational field
iters = [ R.range_by_height(bound) for _ in range(i) ]
else: # if number field
iters = [ R.elements_of_bounded_height(bound) for _ in range(i) ]
for x in iters: x.next() # put at zero
j = 0
while j < i:
try:
P[j] = iters[j].next()
yield self(P)
j = 0
except StopIteration:
if (ftype == False): # if rational field
iters[j] = R.range_by_height(bound) # reset
else: # if number field
iters[j] = R.elements_of_bounded_height(bound) # reset
iters[j].next() # put at zero
P[j] = zero
j += 1
i -= 1
请发表评论