returns singular point of a weierstrass cubic over rationals or finite fields. Input is [a1,a2,a3,a4,a5].
output is the list of singular points, either empty or a list of one element.
{{{id=1|
def singular_point(ainvs):
x,y,z = var('x,y,z')
L = []
a1 = ainvs[0]
a2 = ainvs[1]
a3 = ainvs[2]
a4 = ainvs[3]
a6 = ainvs[4]
k =a1.base_ring()
p = k.characteristic()
Ex = a1*y*z - 3*x^2 - 2*a2*x*z - a4*z^2
Ey = 2*y*z + a1*x*z + a3*z^2
Ez = y^2 + a1*x*y + 2*a3*y*z - a2*x^2 - 2*a4*x*z - 3*a6*z^2
Eeqn = y^2*z + a1*x*y*z + a3*y*z^2 - x^3 - a2*x^2*z - a4*x*z^2 - a6*z^3
if p == 0:
P. = ProjectiveSpace(2,QQ)
S1 = solve([Ex ==0, Ey==0, Ez==0, Eeqn == 0, z-1 == 0 ],x,y,z)
S2 = solve([Ex==0, Ey==0, Ez==0, Eeqn == 0, z==0, y==1],x,y,z)
if len(S1) != 0:
x0 = S[0][0]
x1 = S[0][1]
x0 = x0.lhs() - x0.rhs()
x0 = K(x0.coefficient(0))
x1 = x1.lhs()-x1.rhs()
x1 = K(x1.coefficient(0))
pnt = P(x0,x1,1)
L=L.append(P)
if len(S2) != 0:
pnt = P(0,1,0)
L=L.append(L)
if p != 0:
P. = ProjectiveSpace(2,F)
A1=P.subscheme([a1*y*z - 3*x^2 - 2*a2*x*z - a4*z^2])
A2=P.subscheme([2*y*z + a1*x*z + a3*z^2])
A3=P.subscheme([y^2 + a1*x*y + 2*a3*y*z - a2*x^2 - 2*a4*x*z - 3*a6*z^2])
A4=P.subscheme([y^2*z + a1*x*y*z + a3*y*z^2 - x^3 - a2*x^2*z - a4*x*z^2 - a6*z^3])
A12 = A1.intersection(A2)
A123 = A12.intersection(A3)
A1234 = A123.intersection(A4)
L=A1234.rational_points()
return L
///
}}}
{{{id=38|
def is_singular_point(self):
E = self.curve()
a = self[0]
b = self[1]
c = self[2]
x,y,z = var('x,y,z')
a1 = E.a1()
a2 = E.a2()
a3 = E.a3()
a4 = E.a4()
a6 = E.a6()
Ex = a1*y*z - 3*x^2 - 2*a2*x*z - a4*z^2
Ey = 2*y*z + a1*x*z + a3*z^2
Ez = y^2 + a1*x*y + 2*a3*y*z - a2*x^2 - 2*a4*x*z - 3*a6*z^2
if E.discriminant() != 0:
return False
elif Ex(x =a,y=b,z=c) != 0 or Ey(x = a,y=b,z=c) != 0 or Ez(x = a,y=b,z=c) !=0:
return False
else:
return True
///
}}}
{{{id=35|
def is_cusp(self):
E = self.curve()
K = E.base_ring()
ch = K.characteristic()
a = self[0]
b = self[1]
c = self[2]
x,y,z = var('x,y,z')
a1 = E.a1()
a2 = E.a2()
a3 = E.a3()
a4 = E.a4()
a6 = E.a6()
Ex = a1*y*z - 3*x^2 - 2*a2*x*z - a4*z^2
Ey = 2*y*z + a1*x*z + a3*z^2
Ez = y^2 + a1*x*y + 2*a3*y*z - a2*x^2 - 2*a4*x*z - 3*a6*z^2
if E.discriminant() != 0:
return False
elif Ex(x =a,y=b,z=c) != 0 or Ey(x = a,y=b,z=c) != 0 or Ez(x = a,y=b,z=c) !=0:
return False
elif ch != 2 and ch != 3 and E.c4()==0:
return True
elif ch != 2 and ch != 3 and E.c4()!=0:
return False
else:
raise AttributeError, "The characteristic of the base field should not be 2 or 3"
///
}}}
{{{id=37|
def is_node(self):
E = self.curve()
K = E.base_ring()
ch = K.characteristic()
a = self[0]
b = self[1]
c = self[2]
x,y,z = var('x,y,z')
a1 = E.a1()
a2 = E.a2()
a3 = E.a3()
a4 = E.a4()
a6 = E.a6()
Ex = a1*y*z - 3*x^2 - 2*a2*x*z - a4*z^2
Ey = 2*y*z + a1*x*z + a3*z^2
Ez = y^2 + a1*x*y + 2*a3*y*z - a2*x^2 - 2*a4*x*z - 3*a6*z^2
if E.discriminant() != 0:
return False
elif Ex(x =a,y=b,z=c) != 0 or Ey(x = a,y=b,z=c) != 0 or Ez(x = a,y=b,z=c) !=0:
return False
elif ch != 2 and ch != 3 and E.c4()!=0:
return True
elif ch != 2 and ch != 3 and E.c4()==0:
return False
else:
raise AttributeError, "The characteristic of the base field should not be 2 or 3"
///
}}}
{{{id=21|
E = EllipticCurve([1,2,3,4,4]); E
P = E(0,1)
P.curve()
///
Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 4 over Rational Field
}}}
{{{id=22|
is_cusp(P); is_node(P); is_singular_point(P)
///
False
False
False
}}}
{{{id=23|
E = EllipticCurve([0,0,0,0,0], allow_singular = True)
///
}}}
{{{id=39|
Q = E(0,0)
///
}}}
{{{id=40|
is_cusp(Q); is_node(Q); is_singular_point(Q)
///
True
False
True
}}}
{{{id=41|
K = GF(5)
E = EllipticCurve(K,[0,1,0,0,0], allow_singular = True);E
Q = E(0,0)
///
}}}
{{{id=44|
E
///
Elliptic Curve defined by y^2 = x^3 + x^2 over Finite Field of size 5
}}}
{{{id=42|
is_cusp(Q); is_node(Q); is_singular_point(Q)
///
False
True
True
}}}
{{{id=43|
///
}}}