Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
20774: Changes from first review.
Browse files Browse the repository at this point in the history
Have not yet addressed class structure to accomodate curves
defined specifically over fields, and have not
implemented corresponding singularity analysis functionality
for points on curves yet.
  • Loading branch information
gsjorgenson committed Jun 11, 2016
1 parent e1f1529 commit e6f1a93
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 57 deletions.
77 changes: 48 additions & 29 deletions src/sage/schemes/curves/affine_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,52 +149,56 @@ def multiplicity(self, P):
Return the multiplicity of this affine curve at the point ``P``.
This is computed as the multiplicity of the local ring of self corresponding to ``P``. This
curve must be defined over a field.
curve must be defined over a field. An error is raised if ``P`` is not a point on this curve.
INPUT:
- ``P`` -- a point in the ambient space of this curve.
OUTPUT:
- an integer.
An integer.
EXAMPLES::
sage: A.<x,y,z> = AffineSpace(QQ, 3)
sage: A.<x,y,z> = AffineSpace(CC, 3)
sage: C = A.curve([y - x^2, z - x^3])
sage: Q1 = A([1,1,1])
sage: C.multiplicity(Q1)
sage: Q = A([1,1,1])
sage: C.multiplicity(Q)
1
sage: Q2 = A([1,2,1])
sage: C.multiplicity(Q2)
0
::
sage: A.<x,y,z,w> = AffineSpace(QQ, 4)
sage: C = A.curve([y^9 - x^5, z^10 - w - y^4, z - y])
sage: C.multiplicity(A([0,0,0,0]))
5
::
sage: A.<x,y,z,w,v> = AffineSpace(GF(23), 5)
sage: C = A.curve([x^8 - y, y^7 - z, z^3 - 1, w^5 - v^3])
sage: Q = A([22,1,1,0,0])
sage: C.multiplicity(Q)
3
"""
if not self.base_ring() in Fields():
raise TypeError("curve must be defined over a field")

# Check whether P is in the ambient space of this curve
# Check whether P is a point on this curve
try:
P = self.ambient_space()(P)
P = self(P)
except TypeError:
raise TypeError("(=%s) must be a point on (=%s)"%(P,self))

# Apply a linear change of coordinates to self so that P is sent to the origin
# and then compute the multiplicity of the local ring of the translated curve
# corresponding to the point (0,...,0)
AA = self.ambient_space()
chng_coords = [AA.gens()[i] + P[i] for i in range(AA.dimension_relative())]
I = AA.coordinate_ring().ideal([f(chng_coords) for f in self.defining_polynomials()])

# Compute the multiplicity of the local ring of the new curve defined by I
# corresponding to the point (0,...,0)
R = AA.coordinate_ring().change_ring(order='negdegrevlex')
return singular.mult(singular.std(I.change_ring(R))).sage()
I = R.ideal([f(chng_coords) for f in self.defining_polynomials()])
return singular.mult(singular.std(I)).sage()

class AffinePlaneCurve(AffineCurve):
def __init__(self, A, f):
Expand Down Expand Up @@ -411,38 +415,45 @@ def multiplicity(self, P):
of the homogeneous components of its defining polynomial. To compute the
multiplicity of a different point, a linear change of coordinates is used.
This curve must be defined over a field.
This curve must be defined over a field. An error if raised if ``P`` is
not a point on this curve.
INPUT:
- ``P`` -- a point in the ambient space of this curve.
OUTPUT:
- an integer.
An integer.
EXAMPLES::
sage: A.<x,y> = AffineSpace(QQ, 2)
sage: C = Curve([y^2 - x^3], A)
sage: Q1 = A([1,0])
sage: Q1 = A([1,1])
sage: C.multiplicity(Q1)
0
sage: Q2 = A([1,1])
sage: C.multiplicity(Q2)
1
sage: Q3 = A([0,0])
sage: C.multiplicity(Q3)
sage: Q2 = A([0,0])
sage: C.multiplicity(Q2)
2
::
sage: A.<x,y> = AffineSpace(QQbar,2)
sage: C = Curve([-x^7 + (-7)*x^6 + y^6 + (-21)*x^5 + 12*y^5 + (-35)*x^4 + 60*y^4 +\
(-35)*x^3 + 160*y^3 + (-21)*x^2 + 240*y^2 + (-7)*x + 192*y + 63], A)
sage: Q = A([-1,-2])
sage: C.multiplicity(Q)
6
"""
if not self.base_ring() in Fields():
raise TypeError("curve must be defined over a field")

# Check whether P in in the ambient space of this curve
# Check whether P is a point on this curve
try:
P = self.ambient_space()(P)
P = self(P)
except TypeError:
raise TypeError("(=%s) must be a point in the ambient space of (=%s)"%(P,self))
raise TypeError("(=%s) must be a point on (=%s)"%(P,self))

# Apply a linear change of coordinates to self so that P becomes (0,0)
AA = self.ambient_space()
Expand All @@ -456,6 +467,8 @@ def tangents(self, P):
r"""
Return the tangents of this affine plane curve at the point ``P``.
The point ``P`` must be a point on this curve.
INPUT:
- ``P`` -- a point on this curve.
Expand All @@ -473,10 +486,16 @@ def tangents(self, P):
sage: Q = A([0,0])
sage: C.tangents(Q)
[x + (-1/3*b)*y, x + (1/3*b)*y]
::
sage: A.<x,y> = AffineSpace(QQ, 2)
sage: C = A.curve([y^2 - x^3 - x^2])
sage: Q = A([0,0])
sage: C.tangents(Q)
[x - y, x + y]
"""
r = self.multiplicity(P)
if r < 1:
raise TypeError("(=%s) must be a point on (=%s)"%(P,self))
f = self.defining_polynomials()[0]
vars = self.ambient_space().gens()
deriv = [f.derivative(vars[0],i).derivative(vars[1],r-i)(list(P)) for i in range(r+1)]
Expand All @@ -499,7 +518,7 @@ def is_ordinary_singularity(self, P):
OUTPUT:
- Boolean. True or False depending on whether ``P`` is or is not an ordinary singularity of this
curve, respectively.
curve, respectively. An error is raised if ``P`` is not a singular point of this curve.
EXAMPLES::
Expand Down
76 changes: 74 additions & 2 deletions src/sage/schemes/curves/curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,44 @@ def union(self, other):

__add__ = union

def singular_subscheme(self):
r"""
Return the subscheme of singular points of this curve.
OUTPUT:
- a subscheme in the ambient space of this curve.
EXAMPLES::
sage: A.<x,y> = AffineSpace(CC, 2)
sage: C = Curve([y^4 - 2*x^5 - x^2*y], A)
sage: C.singular_subscheme()
Closed subscheme of Affine Space of dimension 2 over Complex Field with
53 bits of precision defined by:
(-2.00000000000000)*x^5 + y^4 - x^2*y,
(-10.0000000000000)*x^4 + (-2.00000000000000)*x*y,
4.00000000000000*y^3 - x^2
::
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = Curve([y^8 - x^2*z*w^5, w^2 - 2*y^2 - x*z], P)
sage: C.singular_subscheme()
Closed subscheme of Projective Space of dimension 3 over Rational Field
defined by:
y^8 - x^2*z*w^5,
-2*y^2 - x*z + w^2,
-x^3*y*z^4 + 3*x^2*y*z^3*w^2 - 3*x*y*z^2*w^4 + 8*x*y*z*w^5 + y*z*w^6,
x^2*z*w^5,
-5*x^2*z^2*w^4 - 4*x*z*w^6,
x^4*y*z^3 - 3*x^3*y*z^2*w^2 + 3*x^2*y*z*w^4 - 4*x^2*y*w^5 - x*y*w^6,
-2*x^3*y*z^3*w + 6*x^2*y*z^2*w^3 - 20*x^2*y*z*w^4 - 6*x*y*z*w^5 +
2*y*w^7,
-5*x^3*z*w^4 - 2*x^2*w^6
"""
return self.ambient_space().subscheme(self.Jacobian())

def singular_points(self, F=None):
r"""
Return the set of singular points of this curve.
Expand Down Expand Up @@ -235,5 +273,39 @@ def singular_points(self, F=None):
raise TypeError("curve must be defined over a field")
elif not F in Fields():
raise TypeError("(=%s) must be a field"%F)
X = self.ambient_space().subscheme(self.Jacobian())
return X.rational_points(0, F)
X = self.singular_subscheme()
return X.rational_points(F=F)

def is_singular(self, P=None):
r"""
Return whether ``P`` is a singular point of this curve, or if no point is passed,
whether this curve is singular or not.
This just uses the is_smooth function for algebraic subschemes.
INPUT:
- ``P`` -- (default: None) a point on this curve.
OUTPUT:
- Boolean. If a point ``P`` is provided, and if ``P`` lies on this curve, returns True
if ``P`` is a singular point of this curve, and False otherwise. If no point is provided,
returns True or False depending on whether this curve is or is not singular, respectively.
EXAMPLES::
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = P.curve([y^2 - x^2 - z^2, z - w])
sage: C.is_singular()
False
::
sage: A.<x,y,z> = AffineSpace(GF(11), 3)
sage: C = A.curve([y^3 - z^5, x^5 - y + 1])
sage: Q = A([7,0,0])
sage: C.is_singular(Q)
True
"""
return not self.is_smooth(P)

0 comments on commit e6f1a93

Please sign in to comment.