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| /// }}}