From 3ce05939f2f213ad13aa14a9bba760ead3b5fbe7 Mon Sep 17 00:00:00 2001 From: Matthias Zach Date: Wed, 23 Aug 2023 13:20:12 +0200 Subject: [PATCH] Add Simon's constructor for elliptic curves. --- src/EllCrv/EllCrv.jl | 32 ++++++++++++++++++++++++++++++++ test/EllCrv/EllCrv.jl | 12 ++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/EllCrv/EllCrv.jl b/src/EllCrv/EllCrv.jl index 7de387c19e..92724fa6f1 100644 --- a/src/EllCrv/EllCrv.jl +++ b/src/EllCrv/EllCrv.jl @@ -236,6 +236,38 @@ function elliptic_curve(x::Vector{Rational{T}}; check::Bool = true) where {T <: return elliptic_curve(QQFieldElem[QQ(z) for z in x], check = check) end +# A constructor to create an elliptic curve from a bivariate polynomial. +# One can specify how to interpret the polynomial via the second and the +# third argument. +function elliptic_curve(f::MPolyRingElem, x::MPolyRingElem, y::MPolyRingElem) + R = parent(f) + @assert ngens(R) == 2 "polynomial must be bivariate" + @assert x in gens(R) && y in gens(R) "second and third argument must be ring variables" + k = coefficient_ring(f) + kf = k + if !(k isa Field) + kf = fraction_field(k) + end + # coeff returns a polynomial in parent(f); we pick out the constant coefficient. + my_const = t->(iszero(t) ? zero(coefficient_ring(parent(t))) : first(coefficients(t))) + c = my_const(coeff(f, [x, y], [3, 0])::MPolyRingElem) + @assert parent(c)===k + f = inv(c)*f + @assert coeff(f, [x,y], [0,2]) == -1 "coefficient of y^2 must be -1" + a6 = coeff(f, [x,y], [0,0]) + a4 = coeff(f, [x,y], [1,0]) + a2 = coeff(f, [x,y], [2,0]) + a3 = -coeff(f, [x,y], [0,1]) + a1 = -coeff(f, [x,y], [1,1]) + @show [a1,a2,a3,a4,a6] + a_invars = [my_const(i) for i in [a1,a2,a3,a4,a6]] + (a1,a2,a3,a4,a6) = a_invars + @assert f == (-(y^2 + a1*x*y + a3*y) + (x^3 + a2*x^2 + a4*x + a6)) + E = EllipticCurve(kf, kf.([a1,a2,a3,a4,a6])) + return E +end + + @doc raw""" elliptic_curve(f::PolyElem, [h::PolyElem,] check::Bool = true) -> EllCrv diff --git a/test/EllCrv/EllCrv.jl b/test/EllCrv/EllCrv.jl index 62637645ba..fa497abc33 100644 --- a/test/EllCrv/EllCrv.jl +++ b/test/EllCrv/EllCrv.jl @@ -291,3 +291,15 @@ @test_throws ErrorException P1//5 end end + +@testset "additional constructors" begin + R, (x, y) = polynomial_ring(QQ, [:x, :y]) + f = y^2 - x^3 - 3*x^2 + 7*x - 4 + Hecke.elliptic_curve(f, x, y) + + pt, t = polynomial_ring(QQ, :t) + kt = fraction_field(pt) + R, (x, y) = polynomial_ring(kt, [:x, :y]) + f = y^2 - x^3 - 3*t*x^2 + 7*x - 4*t^2 - 3 + Hecke.elliptic_curve(f, x, y) +end