Projective curves.

EXAMPLES:

We can construct curves in either a projective plane:

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = Curve([y*z^2 - x^3], P); C
Projective Plane Curve over Rational Field defined by -x^3 + y*z^2

or in higher dimensional projective spaces:

sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = Curve([y*w^3 - x^4, z*w^3 - x^4], P); C
Projective Curve over Rational Field defined by -x^4 + y*w^3, -x^4 + z*w^3

AUTHORS:

  • William Stein (2005-11-13)
  • David Joyner (2005-11-13)
  • David Kohel (2006-01)
  • Moritz Minzlaff (2010-11)
sage.schemes.curves.projective_curve.Hasse_bounds(q, genus=1)

Return the Hasse-Weil bounds for the cardinality of a nonsingular curve defined over \GF{q} of given genus.

INPUT:

  • q (int) – a prime power
  • genus (int, default 1) – a non-negative integer,

OUTPUT:

(tuple) The Hasse bounds (lb,ub) for the cardinality of a curve of genus genus defined over \GF{q}.

EXAMPLES:

sage: Hasse_bounds(2)
(1, 5)
sage: Hasse_bounds(next_prime(10^30))
(999999999999998000000000000058, 1000000000000002000000000000058)
class sage.schemes.curves.projective_curve.ProjectiveCurve(A, X)

Bases: sage.schemes.curves.curve.Curve_generic, sage.schemes.generic.algebraic_scheme.AlgebraicScheme_subscheme_projective

Initialization function.

EXMAPLES:

sage: P.<x,y,z,w,u> = ProjectiveSpace(GF(7), 4)
sage: C = Curve([y*u^2 - x^3, z*u^2 - x^3, w*u^2 - x^3, y^3 - x^3], P); C
Projective Curve over Finite Field of size 7 defined by -x^3 + y*u^2,
-x^3 + z*u^2, -x^3 + w*u^2, -x^3 + y^3
sage: K.<u> = CyclotomicField(11)
sage: P.<x,y,z,w> = ProjectiveSpace(K, 3)
sage: C = Curve([y*w - u*z^2 - x^2, x*w - 3*u^2*z*w], P); C
Projective Curve over Cyclotomic Field of order 11 and degree 10 defined
by -x^2 + (-u)*z^2 + y*w, x*w + (-3*u^2)*z*w
affine_patch(i, AA=None)

Return the i-th affine patch of this projective curve.

INPUT:

  • i – affine coordinate chart of the projective ambient space of this curve to compute affine patch with respect to.
  • AA – (default: None) ambient affine space, this is constructed if it is not given.

OUTPUT:

  • a curve in affine space.

EXAMPLES:

sage: P.<x,y,z,w> = ProjectiveSpace(CC, 3)
sage: C = Curve([y*z - x^2, w^2 - x*y], P)
sage: C.affine_patch(0)
Affine Curve over Complex Field with 53 bits of precision defined by
x0*x1 - 1.00000000000000, x2^2 - x0
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = Curve(x^3 - x^2*y + y^3 - x^2*z, P)
sage: C.affine_patch(1)
Affine Plane Curve over Rational Field defined by x0^3 - x0^2*x1 - x0^2 + 1
sage: A.<x,y> = AffineSpace(QQ, 2)
sage: P.<u,v,w> = ProjectiveSpace(QQ, 2)
sage: C = Curve([u^2 - v^2], P)
sage: C.affine_patch(1, A).ambient_space() == A
True
arithmetic_genus()

Return the arithmetic genus of this projective curve.

This is the arithmetic genus g_a(C) as defined in [Hartshorne]. If P is the Hilbert polynomial of the defining ideal of this curve, then the arithmetic genus of this curve is 1 - P(0). This curve must be irreducible.

OUTPUT: Integer.

EXAMPLES:

sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = P.curve([w*z - x^2, w^2 + y^2 + z^2])
sage: C.arithmetic_genus()
1
sage: P.<x,y,z,w,t> = ProjectiveSpace(GF(7), 4)
sage: C = P.curve([t^3 - x*y*w, x^3 + y^3 + z^3, z - w])
sage: C.arithmetic_genus()
10
is_complete_intersection()

Return whether this projective curve is or is not a complete intersection.

OUTPUT: Boolean.

EXAMPLES:

sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = Curve([x*y - z*w, x^2 - y*w, y^2*w - x*z*w], P)
sage: C.is_complete_intersection()
False
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = Curve([y*w - x^2, z*w^2 - x^3], P)
sage: C.is_complete_intersection()
True

sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = Curve([z^2 - y*w, y*z - x*w, y^2 - x*z], P)
sage: C.is_complete_intersection()
False
class sage.schemes.curves.projective_curve.ProjectivePlaneCurve(A, f)

Bases: sage.schemes.curves.projective_curve.ProjectiveCurve

Initialization function.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQbar, 2)
sage: C = Curve([y*z - x^2 - QQbar.gen()*z^2], P); C
Projective Plane Curve over Algebraic Field defined by
-x^2 + y*z + (-I)*z^2
sage: P.<x,y,z> = ProjectiveSpace(GF(5^2, 'v'), 2)
sage: C = Curve([y^2*z - x*z^2 - z^3], P); C
Projective Plane Curve over Finite Field in v of size 5^2 defined by y^2*z - x*z^2 - z^3
arithmetic_genus()

Return the arithmetic genus of this projective curve.

This is the arithmetic genus g_a(C) as defined in [Hartshorne]. For a projective plane curve of degree d, this is simply (d-1)(d-2)/2. It need not equal the geometric genus (the genus of the normalization of the curve). This curve must be irreducible.

OUTPUT: Integer.

EXAMPLE:

sage: x,y,z = PolynomialRing(GF(5), 3, 'xyz').gens()
sage: C = Curve(y^2*z^7 - x^9 - x*z^8); C
Projective Plane Curve over Finite Field of size 5 defined by -x^9 + y^2*z^7 - x*z^8
sage: C.arithmetic_genus()
28
sage: C.genus()
4
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = Curve([y^3*x - x^2*y*z - 7*z^4])
sage: C.arithmetic_genus()
3

REFERENCES:

[Hartshorne](1, 2) R. Hartshorne. Algebraic Geometry. Springer-Verlag, New York, 1977.
divisor_of_function(r)

Return the divisor of a function on a curve.

INPUT: r is a rational function on X

OUTPUT:

  • list - The divisor of r represented as a list of coefficients and points. (TODO: This will change to a more structural output in the future.)

EXAMPLES:

sage: FF = FiniteField(5)
sage: P2 = ProjectiveSpace(2, FF, names = ['x','y','z'])
sage: R = P2.coordinate_ring()
sage: x, y, z = R.gens()
sage: f = y^2*z^7 - x^9 - x*z^8
sage: C = Curve(f)
sage: K = FractionField(R)
sage: r = 1/x
sage: C.divisor_of_function(r)     # todo: not implemented  !!!!
[[-1, (0, 0, 1)]]
sage: r = 1/x^3
sage: C.divisor_of_function(r)     # todo: not implemented  !!!!
[[-3, (0, 0, 1)]]
is_ordinary_singularity(P)

Return whether the singular point P of this projective plane curve is an ordinary singularity.

The point P is an ordinary singularity of this curve if it is a singular point, and if the tangents of this curve at P are distinct.

INPUT:

  • P – a point on this curve.

OUTPUT:

  • Boolean. True or False depending on whether P is or is not an ordinary singularity of this curve, respectively. An error is raised if P is not a singular point of this curve.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = Curve([y^2*z^3 - x^5], P)
sage: Q = P([0,0,1])
sage: C.is_ordinary_singularity(Q)
False
sage: R.<a> = QQ[]
sage: K.<b> = NumberField(a^2 - 3)
sage: P.<x,y,z> = ProjectiveSpace(K, 2)
sage: C = P.curve([x^2*y^3*z^4 - y^6*z^3 - 4*x^2*y^4*z^3 - 4*x^4*y^2*z^3 + 3*y^7*z^2 + 10*x^2*y^5*z^2\
+ 9*x^4*y^3*z^2 + 5*x^6*y*z^2 - 3*y^8*z - 9*x^2*y^6*z - 11*x^4*y^4*z - 7*x^6*y^2*z - 2*x^8*z + y^9 +\
2*x^2*y^7 + 3*x^4*y^5 + 4*x^6*y^3 + 2*x^8*y])
sage: Q = P([0,1,1])
sage: C.is_ordinary_singularity(Q)
True
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = P.curve([z^5 - y^5 + x^5 + x*y^2*z^2])
sage: Q = P([0,1,1])
sage: C.is_ordinary_singularity(Q)
Traceback (most recent call last):
...
TypeError: (=(0 : 1 : 1)) is not a singular point of (=Projective Plane
Curve over Rational Field defined by x^5 - y^5 + x*y^2*z^2 + z^5)
is_singular(P=None)

Return whether this curve is singular or not, or if a point P is provided, whether P is a singular point of this curve.

INPUT:

  • P – (default: None) a point on this curve.

OUTPUT:

  • Boolean. If no point P is provided, returns True of False depending on whether this curve is singular or not. If a point P is provided, returns True or False depending on whether P is or is not a singular point of this curve.

EXAMPLES:

Over \QQ:

sage: F = QQ
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X^3-Y^2*Z)
sage: C.is_singular()
True

Over a finite field:

sage: F = GF(19)
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X^3+Y^3+Z^3)
sage: C.is_singular()
False
sage: D = Curve(X^4-X*Z^3)
sage: D.is_singular()
True
sage: E = Curve(X^5+19*Y^5+Z^5)
sage: E.is_singular()
True
sage: E = Curve(X^5+9*Y^5+Z^5)
sage: E.is_singular()
False

Over \CC:

sage: F = CC
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X)
sage: C.is_singular()
False
sage: D = Curve(Y^2*Z-X^3)
sage: D.is_singular()
True
sage: E = Curve(Y^2*Z-X^3+Z^3)
sage: E.is_singular()
False

Showing that ticket #12187 is fixed:

sage: F.<X,Y,Z> = GF(2)[]
sage: G = Curve(X^2+Y*Z)
sage: G.is_singular()
False
sage: P.<x,y,z> = ProjectiveSpace(CC, 2)
sage: C = Curve([y^4 - x^3*z], P)
sage: Q = P([0,0,1])
sage: C.is_singular()
True
is_transverse(C, P)

Return whether the intersection of this curve with the curve C at the point P is transverse.

The intersection at P is transverse if P is a nonsingular point of both curves, and if the tangents of the curves at P are distinct.

INPUT:

  • C – a curve in the ambient space of this curve.
  • P – a point in the intersection of both curves.

OUPUT: Boolean.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = Curve([x^2 - y^2], P)
sage: D = Curve([x - y], P)
sage: Q = P([1,1,0])
sage: C.is_transverse(D, Q)
False
sage: K = QuadraticField(-1)
sage: P.<x,y,z> = ProjectiveSpace(K, 2)
sage: C = Curve([y^2*z - K.0*x^3], P)
sage: D = Curve([z*x + y^2], P)
sage: Q = P([0,0,1])
sage: C.is_transverse(D, Q)
False
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = Curve([x^2 - 2*y^2 - 2*z^2], P)
sage: D = Curve([y - z], P)
sage: Q = P([2,1,1])
sage: C.is_transverse(D, Q)
True
local_coordinates(pt, n)

Return local coordinates to precision n at the given point.

Behaviour is flaky - some choices of n are worst that others.

INPUT:

  • pt - an F-rational point on X which is not a point of ramification for the projection (x,y) - x.
  • n - the number of terms desired

OUTPUT: x = x0 + t y = y0 + power series in t

EXAMPLES:

sage: FF = FiniteField(5)
sage: P2 = ProjectiveSpace(2, FF, names = ['x','y','z'])
sage: x, y, z = P2.coordinate_ring().gens()
sage: C = Curve(y^2*z^7-x^9-x*z^8)
sage: pt = C([2,3,1])
sage: C.local_coordinates(pt,9)     # todo: not implemented  !!!!
      [2 + t, 3 + 3*t^2 + t^3 + 3*t^4 + 3*t^6 + 3*t^7 + t^8 + 2*t^9 + 3*t^11 + 3*t^12]
plot(*args, **kwds)

Plot the real points of an affine patch of this projective plane curve.

INPUT:

  • self - an affine plane curve
  • patch - (optional) the affine patch to be plotted; if not specified, the patch corresponding to the last projective coordinate being nonzero
  • *args - optional tuples (variable, minimum, maximum) for plotting dimensions
  • **kwds - optional keyword arguments passed on to implicit_plot

EXAMPLES:

A cuspidal curve:

sage: R.<x, y, z> = QQ[]
sage: C = Curve(x^3 - y^2*z)
sage: C.plot()
Graphics object consisting of 1 graphics primitive

The other affine patches of the same curve:

sage: C.plot(patch=0)
Graphics object consisting of 1 graphics primitive
sage: C.plot(patch=1)
Graphics object consisting of 1 graphics primitive

An elliptic curve:

sage: E = EllipticCurve('101a')
sage: C = Curve(E)
sage: C.plot()
Graphics object consisting of 1 graphics primitive
sage: C.plot(patch=0)
Graphics object consisting of 1 graphics primitive
sage: C.plot(patch=1)
Graphics object consisting of 1 graphics primitive

A hyperelliptic curve:

sage: P.<x> = QQ[]
sage: f = 4*x^5 - 30*x^3 + 45*x - 22
sage: C = HyperellipticCurve(f)
sage: C.plot()
Graphics object consisting of 1 graphics primitive
sage: C.plot(patch=0)
Graphics object consisting of 1 graphics primitive
sage: C.plot(patch=1)
Graphics object consisting of 1 graphics primitive
tangents(P)

Return the tangents of this projective plane curve at the point P.

These are found by homogenizing the tangents of an affine patch of this curve containing P. The point P must be a point on this curve.

INPUT:

  • P – a point on this curve.

OUTPUT:

  • a list of polynomials in the coordinate ring of the ambient space of this curve.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: C = P.curve([x^2*y^3*z^4 - y^6*z^3 - 4*x^2*y^4*z^3 - 4*x^4*y^2*z^3 + 3*y^7*z^2 +\
10*x^2*y^5*z^2 + 9*x^4*y^3*z^2 + 5*x^6*y*z^2 - 3*y^8*z - 9*x^2*y^6*z - 11*x^4*y^4*z -\
7*x^6*y^2*z - 2*x^8*z + y^9 + 2*x^2*y^7 + 3*x^4*y^5 + 4*x^6*y^3 + 2*x^8*y])
sage: Q = P([0,1,1])
sage: C.tangents(Q)
[-y + z, -3*x^2 + y^2 - 2*y*z + z^2]
sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: C = P.curve([z^3*x + y^4 - x^2*z^2])
sage: Q = P([1,1,1])
sage: C.tangents(Q)
Traceback (most recent call last):
...
TypeError: (=(1 : 1 : 1)) is not a point on (=Projective Plane Curve
over Rational Field defined by y^4 - x^2*z^2 + x*z^3)
class sage.schemes.curves.projective_curve.ProjectivePlaneCurve_finite_field(A, f)

Bases: sage.schemes.curves.projective_curve.ProjectivePlaneCurve

Initialization function.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQbar, 2)
sage: C = Curve([y*z - x^2 - QQbar.gen()*z^2], P); C
Projective Plane Curve over Algebraic Field defined by
-x^2 + y*z + (-I)*z^2
sage: P.<x,y,z> = ProjectiveSpace(GF(5^2, 'v'), 2)
sage: C = Curve([y^2*z - x*z^2 - z^3], P); C
Projective Plane Curve over Finite Field in v of size 5^2 defined by y^2*z - x*z^2 - z^3
rational_points(algorithm='enum', sort=True)

Return the rational points on this curve computed via enumeration.

INPUT:

  • algorithm (string, default: ‘enum’) – the algorithm to use. Currently this is ignored.
  • sort (boolean, default True) – whether the output points should be sorted. If False, the order of the output is non-deterministic.

OUTPUT:

A list of all the rational points on the curve defined over its base field, possibly sorted.

Note

This is a slow Python-level implementation.

EXAMPLES:

sage: F = GF(7)
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X^3+Y^3-Z^3)
sage: C.rational_points()
[(0 : 1 : 1), (0 : 2 : 1), (0 : 4 : 1), (1 : 0 : 1), (2 : 0 : 1), (3 : 1 : 0), (4 : 0 : 1), (5 : 1 : 0), (6 : 1 : 0)]
sage: F = GF(1237)
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X^7+7*Y^6*Z+Z^4*X^2*Y*89)
sage: len(C.rational_points())
1237
sage: F = GF(2^6,'a')
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X^5+11*X*Y*Z^3 + X^2*Y^3 - 13*Y^2*Z^3)
sage: len(C.rational_points())
104
sage: R.<x,y,z> = GF(2)[]
sage: f = x^3*y + y^3*z + x*z^3
sage: C = Curve(f); pts = C.rational_points()
sage: pts
[(0 : 0 : 1), (0 : 1 : 0), (1 : 0 : 0)]
rational_points_iterator()

Return a generator object for the rational points on this curve.

INPUT:

  • self – a projective curve

OUTPUT:

A generator of all the rational points on the curve defined over its base field.

EXAMPLE:

sage: F = GF(37)
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X^7+Y*X*Z^5*55+Y^7*12)
sage: len(list(C.rational_points_iterator()))
37
sage: F = GF(2)
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X*Y*Z)
sage: a = C.rational_points_iterator()
sage: next(a)
(1 : 0 : 0)
sage: next(a)
(0 : 1 : 0)
sage: next(a)
(1 : 1 : 0)
sage: next(a)
(0 : 0 : 1)
sage: next(a)
(1 : 0 : 1)
sage: next(a)
(0 : 1 : 1)
sage: next(a)
Traceback (most recent call last):
...
StopIteration
sage: F = GF(3^2,'a')
sage: P2.<X,Y,Z> = ProjectiveSpace(F,2)
sage: C = Curve(X^3+5*Y^2*Z-33*X*Y*X)
sage: b = C.rational_points_iterator()
sage: next(b)
(0 : 1 : 0)
sage: next(b)
(0 : 0 : 1)
sage: next(b)
(2*a + 2 : a : 1)
sage: next(b)
(2 : a + 1 : 1)
sage: next(b)
(a + 1 : 2*a + 1 : 1)
sage: next(b)
(1 : 2 : 1)
sage: next(b)
(2*a + 2 : 2*a : 1)
sage: next(b)
(2 : 2*a + 2 : 1)
sage: next(b)
(a + 1 : a + 2 : 1)
sage: next(b)
(1 : 1 : 1)
sage: next(b)
Traceback (most recent call last):
...
StopIteration
class sage.schemes.curves.projective_curve.ProjectivePlaneCurve_prime_finite_field(A, f)

Bases: sage.schemes.curves.projective_curve.ProjectivePlaneCurve_finite_field

Initialization function.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQbar, 2)
sage: C = Curve([y*z - x^2 - QQbar.gen()*z^2], P); C
Projective Plane Curve over Algebraic Field defined by
-x^2 + y*z + (-I)*z^2
sage: P.<x,y,z> = ProjectiveSpace(GF(5^2, 'v'), 2)
sage: C = Curve([y^2*z - x*z^2 - z^3], P); C
Projective Plane Curve over Finite Field in v of size 5^2 defined by y^2*z - x*z^2 - z^3
rational_points(algorithm='enum', sort=True)

INPUT:

  • algorithm - string:
  • 'enum' - straightforward enumeration
  • 'bn' - via Singular’s brnoeth package.

EXAMPLE:

sage: x, y, z = PolynomialRing(GF(5), 3, 'xyz').gens()
sage: f = y^2*z^7 - x^9 - x*z^8
sage: C = Curve(f); C
Projective Plane Curve over Finite Field of size 5 defined by
-x^9 + y^2*z^7 - x*z^8
sage: C.rational_points()
[(0 : 0 : 1), (0 : 1 : 0), (2 : 2 : 1), (2 : 3 : 1),
 (3 : 1 : 1), (3 : 4 : 1)]
sage: C = Curve(x - y + z)
sage: C.rational_points()
[(0 : 1 : 1), (1 : 1 : 0), (1 : 2 : 1), (2 : 3 : 1),
 (3 : 4 : 1), (4 : 0 : 1)]
sage: C = Curve(x*z+z^2)
sage: C.rational_points('all')
[(0 : 1 : 0), (1 : 0 : 0), (1 : 1 : 0), (2 : 1 : 0),
 (3 : 1 : 0), (4 : 0 : 1), (4 : 1 : 0), (4 : 1 : 1),
 (4 : 2 : 1), (4 : 3 : 1), (4 : 4 : 1)]

Note

The Brill-Noether package does not always work (i.e., the ‘bn’ algorithm. When it fails a RuntimeError exception is raised.

riemann_roch_basis(D)

Return a basis for the Riemann-Roch space corresponding to D.

This uses Singular’s Brill-Noether implementation.

INPUT:

  • D - a divisor

OUTPUT:

A list of function field elements that form a basis of the Riemann-Roch space

EXAMPLE:

sage: R.<x,y,z> = GF(2)[]
sage: f = x^3*y + y^3*z + x*z^3
sage: C = Curve(f); pts = C.rational_points()
sage: D = C.divisor([ (4, pts[0]), (4, pts[2]) ])
sage: C.riemann_roch_basis(D)
[x/y, 1, z/y, z^2/y^2, z/x, z^2/(x*y)]
sage: R.<x,y,z> = GF(5)[]
sage: f = x^7 + y^7 + z^7
sage: C = Curve(f); pts = C.rational_points()
sage: D = C.divisor([ (3, pts[0]), (-1,pts[1]), (10, pts[5]) ])
sage: C.riemann_roch_basis(D)
[(-2*x + y)/(x + y), (-x + z)/(x + y)]

Note

Currently this only works over prime field and divisors supported on rational points.