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

Commit

Permalink
20848: merge with ticket 20839
Browse files Browse the repository at this point in the history
  • Loading branch information
gsjorgenson committed Jun 27, 2016
2 parents df1faa6 + cae16fe commit 3427412
Show file tree
Hide file tree
Showing 4 changed files with 407 additions and 1 deletion.
52 changes: 52 additions & 0 deletions src/sage/schemes/curves/affine_curve.py
Expand Up @@ -417,6 +417,58 @@ def plot(self, *args, **kwds):
I = self.defining_ideal()
return I.plot(*args, **kwds)

def is_transverse(self, C, P):
r"""
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: A.<x,y> = AffineSpace(QQ, 2)
sage: C = Curve([x^2 + y^2 - 1], A)
sage: D = Curve([x - 1], A)
sage: Q = A([1,0])
sage: C.is_transverse(D, Q)
False
::
sage: R.<a> = QQ[]
sage: K.<b> = NumberField(a^3 + 2)
sage: A.<x,y> = AffineSpace(K, 2)
sage: C = A.curve([x*y])
sage: D = A.curve([y - b*x])
sage: Q = A([0,0])
sage: C.is_transverse(D, Q)
False
::
sage: A.<x,y> = AffineSpace(QQ, 2)
sage: C = Curve([y - x^3], A)
sage: D = Curve([y + x], A)
sage: Q = A([0,0])
sage: C.is_transverse(D, Q)
True
"""
if not self.intersects_at(C, P):
raise TypeError("(=%s) must be a point in the intersection of (=%s) and this curve"%(P,C))
if self.is_singular(P) or C.is_singular(P):
return False

# there is only one tangent at a nonsingular point of a plane curve
return not self.tangents(P)[0] == C.tangents(P)[0]

def multiplicity(self, P):
r"""
Return the multiplicity of this affine plane curve at the point ``P``.
Expand Down
114 changes: 113 additions & 1 deletion src/sage/schemes/curves/curve.py
Expand Up @@ -2,10 +2,10 @@
Generic curves.
"""

from sage.categories.finite_fields import FiniteFields
from sage.categories.fields import Fields
from sage.misc.all import latex


from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme

from sage.schemes.generic.divisor_group import DivisorGroup
Expand Down Expand Up @@ -309,3 +309,115 @@ def is_singular(self, P=None):
True
"""
return not self.is_smooth(P)

def intersects_at(self, C, P):
r"""
Return whether the point ``P`` is or is not in the intersection of this curve with the curve ``C``.
INPUT:
- ``C`` -- a curve in the same ambient space as this curve.
- ``P`` -- a point in the ambient space of this curve.
OUTPUT:
Boolean.
EXAMPLES::
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = Curve([x^2 - z^2, y^3 - w*x^2], P)
sage: D = Curve([w^2 - 2*x*y + z^2, y^2 - w^2], P)
sage: Q1 = P([1,1,-1,1])
sage: C.intersects_at(D, Q1)
True
sage: Q2 = P([0,0,1,-1])
sage: C.intersects_at(D, Q2)
False
::
sage: A.<x,y> = AffineSpace(GF(13), 2)
sage: C = Curve([y + 12*x^5 + 3*x^3 + 7], A)
sage: D = Curve([y^2 + 7*x^2 + 8], A)
sage: Q1 = A([9,6])
sage: C.intersects_at(D, Q1)
True
sage: Q2 = A([3,7])
sage: C.intersects_at(D, Q2)
False
"""
if C.ambient_space() != self.ambient_space():
raise TypeError("(=%s) must be a curve in the same ambient space as (=%s)"%(C,self))
if not isinstance(C, Curve_generic):
raise TypeError("(=%s) must be a curve"%C)
try:
P = self.ambient_space()(P)
except TypeError:
raise TypeError("(=%s) must be a point in the ambient space of this curve"%P)
try:
P = self(P)
P = C(P)
except TypeError:
return False
return True

def intersection_points(self, C, F=None):
r"""
Return the points in the intersection of this curve and the curve ``C``.
If the intersection of these two curves has dimension greater than zero, and if
the base ring of this curve is not a finite field, then an error is returned.
INPUT:
- ``C`` -- a curve in the same ambient space as this curve.
- ``F`` -- (default: None). Field over which to compute the intersection points. If not specified,
the base ring of this curve is used.
OUTPUT:
- a list of points in the ambient space of this curve.
EXAMPLES::
sage: R.<a> = QQ[]
sage: K.<b> = NumberField(a^2 + a + 1)
sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: C = Curve([y^2 - w*z, w^3 - y^3], P)
sage: D = Curve([x*y - w*z, z^3 - y^3], P)
sage: C.intersection_points(D, F=K)
[(-b - 1 : -b - 1 : b : 1), (b : b : -b - 1 : 1), (1 : 0 : 0 : 0), (1 : 1 : 1 : 1)]
::
sage: A.<x,y> = AffineSpace(GF(7), 2)
sage: C = Curve([y^3 - x^3], A)
sage: D = Curve([-x*y^3 + y^4 - 2*x^3 + 2*x^2*y], A)
sage: C.intersection_points(D)
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 3), (5, 5), (5, 6), (6, 6)]
::
sage: A.<x,y> = AffineSpace(QQ, 2)
sage: C = Curve([y^3 - x^3], A)
sage: D = Curve([-x*y^3 + y^4 - 2*x^3 + 2*x^2*y], A)
sage: C.intersection_points(D)
Traceback (most recent call last):
...
NotImplementedError: the intersection must have dimension zero or
(=Rational Field) must be a finite field
"""
if C.ambient_space() != self.ambient_space():
raise TypeError("(=%s) must be a curve in the same ambient space as (=%s)"%(C,self))
if not isinstance(C, Curve_generic):
raise TypeError("(=%s) must be a curve"%C)
X = self.intersection(C)
if F is None:
F = self.base_ring()
if X.dimension() == 0 or F in FiniteFields():
return X.rational_points(F=F)
else:
raise NotImplementedError("the intersection must have dimension zero or (=%s) must be a finite field"%F)
81 changes: 81 additions & 0 deletions src/sage/schemes/curves/projective_curve.py
Expand Up @@ -233,6 +233,36 @@ def multiplicity(self, P):
Q = [1/t*Q[j] for j in range(self.ambient_space().dimension_relative())]
return C.multiplicity(C.ambient_space()(Q))

def is_complete_intersection(self):
r"""
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
"""
singular.lib("sing.lib")
I = singular.simplify(self.defining_ideal(), 10)
L = singular.is_ci(I).sage()
return len(self.ambient_space().gens()) - len(I.sage().gens()) == L[-1]

class ProjectivePlaneCurve(ProjectiveCurve):
def __init__(self, A, f):
r"""
Expand Down Expand Up @@ -691,6 +721,57 @@ def is_ordinary_singularity(self, P):
# otherwise they are distinct
return True

def is_transverse(self, C, P):
r"""
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
"""
if not self.intersects_at(C, P):
raise TypeError("(=%s) must be a point in the intersection of (=%s) and this curve"%(P,C))
if self.is_singular(P) or C.is_singular(P):
return False

# there is only one tangent at a nonsingular point of a plane curve
return not self.tangents(P)[0] == C.tangents(P)[0]

class ProjectivePlaneCurve_finite_field(ProjectivePlaneCurve):
def rational_points_iterator(self):
r"""
Expand Down

0 comments on commit 3427412

Please sign in to comment.