def __do_check(v):
     """
     This is used internally by the sanity check code.
     """
     for i,a in enumerate(v):
         global sanity
         sanity = a
         print i,
         sys.stdout.flush()
         if check_using_magma:
             if magma(hnf(a)[0]) != magma(a).EchelonForm():
                 print "bug computing hnf of a matrix"
                 print 'a = matrix(ZZ, %s, %s, %s)'%(a.nrows(), a.ncols(), a.list())
                 return
         else:
             if hnf(a)[0] != a.echelon_form(algorithm = 'pari'):
                 print "bug computing hnf of a matrix"
                 print 'a = matrix(ZZ, %s, %s, %s)'%(a.nrows(), a.ncols(), a.list())
                 return
     print " (done)"
 def __do_check(v):
     """
     This is used internally by the sanity check code.
     """
     for i,a in enumerate(v):
         global sanity
         sanity = a
         print i,
         sys.stdout.flush()
         if check_using_magma:
             if magma(hnf(a)[0]) != magma(a).EchelonForm():
                 print "bug computing hnf of a matrix"
                 print 'a = matrix(ZZ, %s, %s, %s)'%(a.nrows(), a.ncols(), a.list())
                 return
         else:
             if hnf(a)[0] != a.echelon_form('pari'):
                 print "bug computing hnf of a matrix"
                 print 'a = matrix(ZZ, %s, %s, %s)'%(a.nrows(), a.ncols(), a.list())
                 return
     print " (done)"
Example #3
0
 def __do_check(v):
     """
     This is used internally by the sanity check code.
     """
     for i, a in enumerate(v):
         global sanity
         sanity = a
         print(i, end=" ")
         if check_using_magma:
             if magma(hnf(a)[0]) != magma(a).EchelonForm():
                 print("bug computing hnf of a matrix")
                 print('a = matrix(ZZ, %s, %s, %s)' %
                       (a.nrows(), a.ncols(), a.list()))
                 return
         else:
             if hnf(a)[0] != a.echelon_form(algorithm='pari'):
                 print("bug computing hnf of a matrix")
                 print('a = matrix(ZZ, %s, %s, %s)' %
                       (a.nrows(), a.ncols(), a.list()))
                 return
     print(" (done)")
Example #4
0
def benchmark_magma_hnf(nrange, bits=4):
    """
    EXAMPLES:
        sage: import sage.matrix.matrix_integer_dense_hnf as hnf
        sage: hnf.benchmark_magma_hnf([50,100],32)     # optional - magma
        ('magma', 50, 32, ...),
        ('magma', 100, 32, ...),
    """
    from sage.interfaces.all import magma
    b = 2**bits
    for n in nrange:
        a = magma('MatrixAlgebra(IntegerRing(),%s)![Random(%s,%s) : i in [1..%s]]'%(n,-b,b,n**2))
        t = magma.cputime()
        h = a.EchelonForm()
        tm = magma.cputime(t)
        print '%s,'%(('magma', n, bits, tm),)
def benchmark_magma_hnf(nrange, bits=4):
    """
    EXAMPLES:
        sage: import sage.matrix.matrix_integer_dense_hnf as hnf
        sage: hnf.benchmark_magma_hnf([50,100],32)     # optional - magma
        ('magma', 50, 32, ...),
        ('magma', 100, 32, ...),
    """
    from sage.interfaces.all import magma
    b = 2**bits
    for n in nrange:
        a = magma('MatrixAlgebra(IntegerRing(),%s)![Random(%s,%s) : i in [1..%s]]'%(n,-b,b,n**2))
        t = magma.cputime()
        h = a.EchelonForm()
        tm = magma.cputime(t)
        print '%s,'%(('magma', n, bits, tm),)
Example #6
0
def matrix_multiply_QQ(n=100, bnd=2, system='sage', times=1):
    """
    Given an n x n matrix A over QQ with random entries
    whose numerators and denominators are bounded by bnd,
    compute A * (A+1).

    INPUT:

    - ``n`` - matrix dimension (default: ``300``)
    - ``bnd`` - numerator and denominator bound (default: ``bnd``)
    - ``system`` - either 'sage' or 'magma' (default: 'sage')
    - ``times`` - number of experiments (default: ``1``)

    EXAMPLES::

        sage: import sage.matrix.benchmark as b
        sage: ts = b.matrix_multiply_QQ(100)
        sage: tm = b.matrix_multiply_QQ(100, system='magma')  # optional - magma
    """
    if system == 'sage':
        A = random_matrix(QQ, n, n, num_bound=bnd, den_bound=bnd)
        B = A + 1
        t = cputime()
        for z in range(times):
            v = A * B
        return cputime(t)/times
    elif system == 'magma':
        A = magma(random_matrix(QQ, n, n, num_bound=bnd, den_bound=bnd))
        code = """
n := %s;
A := %s;
B := A + 1;
t := Cputime();
for z in [1..%s] do
    K := A * B;
end for;
s := Cputime(t);
"""%(n, A.name(), times)
        if verbose:
            print(code)
        magma.eval(code)
        return float(magma.eval('s'))/times
    else:
        raise ValueError('unknown system "%s"'%system)
Example #7
0
def matrix_multiply_QQ(n=100, bnd=2, system='sage', times=1):
    """
    Given an n x n matrix A over QQ with random entries
    whose numerators and denominators are bounded by bnd,
    compute A * (A+1).

    INPUT:

    - ``n`` - matrix dimension (default: ``300``)
    - ``bnd`` - numerator and denominator bound (default: ``bnd``)
    - ``system`` - either 'sage' or 'magma' (default: 'sage')
    - ``times`` - number of experiments (default: ``1``)

    EXAMPLES::

        sage: import sage.matrix.benchmark as b
        sage: ts = b.matrix_multiply_QQ(100)
        sage: tm = b.matrix_multiply_QQ(100, system='magma')  # optional - magma
    """
    if system == 'sage':
        A = random_matrix(QQ, n, n, num_bound=bnd, den_bound=bnd)
        B = A + 1
        t = cputime()
        for z in range(times):
            v = A * B
        return cputime(t)/times
    elif system == 'magma':
        A = magma(random_matrix(QQ, n, n, num_bound=bnd, den_bound=bnd))
        code = """
n := %s;
A := %s;
B := A + 1;
t := Cputime();
for z in [1..%s] do
    K := A * B;
end for;
s := Cputime(t);
"""%(n, A.name(), times)
        if verbose: print code
        magma.eval(code)
        return float(magma.eval('s'))/times
    else:
        raise ValueError('unknown system "%s"'%system)
Example #8
0
    def dokchitser(self,
                   prec=53,
                   max_imaginary_part=0,
                   max_asymp_coeffs=40,
                   algorithm='gp'):
        r"""
        Return interface to Tim Dokchitser's program for computing
        with the `L`-series of this elliptic curve; this provides a way
        to compute Taylor expansions and higher derivatives of
        `L`-series.

        INPUT:

        - ``prec`` -- integer (bits precision)

        - ``max_imaginary_part`` -- real number

        - ``max_asymp_coeffs`` -- integer

        - ``algorithm`` -- string: 'gp' or 'magma'

        .. note::

           If algorithm='magma', then the precision is in digits rather
           than bits and the object returned is a Magma L-series, which has
           different functionality from the Sage L-series.

        EXAMPLES::

            sage: E = EllipticCurve('37a')
            sage: L = E.lseries().dokchitser()
            sage: L(2)
            0.381575408260711
            sage: L = E.lseries().dokchitser(algorithm='magma')         # optional - magma
            sage: L.Evaluate(2)                                         # optional - magma
            0.38157540826071121129371040958008663667709753398892116

        If the curve has too large a conductor, it isn't possible to
        compute with the `L`-series using this command.  Instead a
        ``RuntimeError`` is raised::

            sage: e = EllipticCurve([1,1,0,-63900,-1964465932632])
            sage: L = e.lseries().dokchitser(15)
            Traceback (most recent call last):
            ...
            RuntimeError: Unable to create L-series, due to precision or other limits in PARI.
        """
        if algorithm == 'magma':
            from sage.interfaces.all import magma
            return magma(self.__E).LSeries(Precision=prec)

        from sage.lfunctions.all import Dokchitser
        key = (prec, max_imaginary_part, max_asymp_coeffs)
        try:
            return self.__dokchitser[key]
        except KeyError:
            pass
        except AttributeError:
            self.__dokchitser = {}
        L = Dokchitser(conductor=self.__E.conductor(),
                       gammaV=[0, 1],
                       weight=2,
                       eps=self.__E.root_number(),
                       poles=[],
                       prec=prec)
        gp = L.gp()
        s = 'e = ellinit(%s);' % list(self.__E.minimal_model().a_invariants())
        s += 'a(k) = ellak(e, k);'
        L.init_coeffs('a(k)',
                      1,
                      pari_precode=s,
                      max_imaginary_part=max_imaginary_part,
                      max_asymp_coeffs=max_asymp_coeffs)
        L.rename('Dokchitser L-function associated to %s' % self.__E)
        self.__dokchitser[key] = L
        return L
Example #9
0
    def dokchitser(self, prec=53,
                   max_imaginary_part=0,
                   max_asymp_coeffs=40,
                   algorithm='gp'):
        r"""
        Return interface to Tim Dokchitser's program for computing
        with the L-series of this elliptic curve; this provides a way
        to compute Taylor expansions and higher derivatives of
        $L$-series.

        INPUT:
            prec -- integer (bits precision)
            max_imaginary_part -- real number
            max_asymp_coeffs -- integer
            algorithm -- string: 'gp' or 'magma'

        \note{If algorithm='magma', then the precision is in digits rather
        than bits and the object returned is a Magma L-series, which has
        different functionality from the Sage L-series.}

        EXAMPLES::

            sage: E = EllipticCurve('37a')
            sage: L = E.lseries().dokchitser()
            sage: L(2)
            0.381575408260711
            sage: L = E.lseries().dokchitser(algorithm='magma')         # optional - magma
            sage: L.Evaluate(2)                                         # optional - magma
            0.38157540826071121129371040958008663667709753398892116

        If the curve has too large a conductor, it isn't possible to
        compute with the L-series using this command.  Instead a
        RuntimeError is raised::

            sage: e = EllipticCurve([1,1,0,-63900,-1964465932632])
            sage: L = e.lseries().dokchitser(15)
            Traceback (most recent call last):
            ...
            RuntimeError: Unable to create L-series, due to precision or other limits in PARI.
        """
        if algorithm == 'magma':
            from sage.interfaces.all import magma
            return magma(self.__E).LSeries(Precision = prec)

        from sage.lfunctions.all import Dokchitser
        key = (prec, max_imaginary_part, max_asymp_coeffs)
        try:
            return self.__dokchitser[key]
        except KeyError:
            pass
        except AttributeError:
            self.__dokchitser = {}
        L = Dokchitser(conductor = self.__E.conductor(),
                       gammaV = [0,1],
                       weight = 2,
                       eps = self.__E.root_number(),
                       poles = [],
                       prec = prec)
        gp = L.gp()
        s = 'e = ellinit(%s);'%list(self.__E.minimal_model().a_invariants())
        s += 'a(k) = ellak(e, k);'
        L.init_coeffs('a(k)', 1, pari_precode = s,
                      max_imaginary_part=max_imaginary_part,
                      max_asymp_coeffs=max_asymp_coeffs)
        L.rename('Dokchitser L-function associated to %s'%self.__E)
        self.__dokchitser[key] = L
        return L
Example #10
0
def HyperellipticCurve_from_invariants(i, reduced=True, precision=None,
                                       algorithm='default'):
    r"""
    Returns a hyperelliptic curve with the given Igusa-Clebsch invariants up to
    scaling.

    The output is a curve over the field in which the Igusa-Clebsch invariants
    are given. The output curve is unique up to isomorphism over the algebraic
    closure. If no such curve exists over the given field, then raise a
    ValueError.

    INPUT:

    - ``i`` - list or tuple of length 4 containing the four Igusa-Clebsch
      invariants: I2,I4,I6,I10.
    - ``reduced`` - Boolean (default = True) If True, tries to reduce the
      polynomial defining the hyperelliptic curve using the function
      :func:`reduce_polynomial` (see the :func:`reduce_polynomial`
      documentation for more details).
    - ``precision`` - integer (default = None) Which precision for real and
      complex numbers should the reduction use. This only affects the
      reduction, not the correctness. If None, the algorithm uses the default
      53 bit precision.
    - ``algorithm`` - ``'default'`` or ``'magma'``. If set to ``'magma'``, uses
      Magma to parameterize Mestre's conic (needs Magma to be installed).

    OUTPUT:

    A hyperelliptic curve object.

    EXAMPLE:

    Examples over the rationals::

        sage: HyperellipticCurve_from_invariants([3840,414720,491028480,2437709561856])
        Traceback (most recent call last):
        ...
        NotImplementedError: Reduction of hyperelliptic curves not yet implemented. See trac #14755 and #14756.
        sage: HyperellipticCurve_from_invariants([3840,414720,491028480,2437709561856],reduced = False)
        Hyperelliptic Curve over Rational Field defined by y^2 = -x^6 + 4410*x^5 - 540*x^4 + 4320*x^3 - 19440*x^2 + 46656*x - 46656
        sage: HyperellipticCurve_from_invariants([21, 225/64, 22941/512, 1])
        Traceback (most recent call last):
        ...
        NotImplementedError: Reduction of hyperelliptic curves not yet implemented. See trac #14755 and #14756.

    An example over a finite field::

        sage: HyperellipticCurve_from_invariants([GF(13)(1),3,7,5])
        Hyperelliptic Curve over Finite Field of size 13 defined by y^2 = 8*x^5 + 5*x^4 + 5*x^2 + 9*x + 3

    An example over a number field::

        sage: K = QuadraticField(353, 'a')
        sage: H = HyperellipticCurve_from_invariants([21, 225/64, 22941/512, 1], reduced = false)
        sage: f = K['x'](H.hyperelliptic_polynomials()[0])

    If the Mestre Conic defined by the Igusa-Clebsch invariants has no rational
    points, then there exists no hyperelliptic curve over the base field with
    the given invariants.::

        sage: HyperellipticCurve_from_invariants([1,2,3,4])
        Traceback (most recent call last):
        ...
        ValueError: No such curve exists over Rational Field as there are no rational points on Projective Conic Curve over Rational Field defined by -2572155000*u^2 - 317736000*u*v + 1250755459200*v^2 + 2501510918400*u*w + 39276887040*v*w + 2736219686912*w^2

    Mestre's algorithm only works for generic curves of genus two, so another
    algorithm is needed for those curves with extra automorphism. See also
    :trac:`12199`::

        sage: P.<x> = QQ[]
        sage: C = HyperellipticCurve(x^6+1)
        sage: i = C.igusa_clebsch_invariants()
        sage: HyperellipticCurve_from_invariants(i)
        Traceback (most recent call last):
        ...
        TypeError: F (=0) must have degree 2


    Igusa-Clebsch invariants also only work over fields of charateristic
    different from 2, 3, and 5, so another algorithm will be needed for fields
    of those characteristics. See also :trac:`12200`::

        sage: P.<x> = GF(3)[]
        sage: HyperellipticCurve(x^6+x+1).igusa_clebsch_invariants()
        Traceback (most recent call last):
        ...
        NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5
        sage: HyperellipticCurve_from_invariants([GF(5)(1),1,0,1])
        Traceback (most recent call last):
        ...
        ZeroDivisionError: Inverse does not exist.

    ALGORITHM:

    This is Mestre's algorithm [M1991]_. Our implementation is based on the
    formulae on page 957 of [LY2001]_, cross-referenced with [W1999]_ to
    correct typos.

    First construct Mestre's conic using the :func:`Mestre_conic` function.
    Parametrize the conic if possible.
    Let `f_1, f_2, f_3` be the three coordinates of the parametrization of the
    conic by the projective line, and change them into one variable by letting
    `F_i = f_i(t, 1)`. Note that each `F_i` has degree at most 2.

    Then construct a sextic polynomial
    `f = \sum_{0<=i,j,k<=3}{c_{ijk}*F_i*F_j*F_k}`,
    where `c_{ijk}` are defined as rational functions in the invariants
    (see the source code for detailed formulae for `c_{ijk}`).
    The output is the hyperelliptic curve `y^2 = f`.

    REFERENCES:

    .. [LY2001] K. Lauter and T. Yang, "Computing genus 2 curves from
       invariants on the Hilbert moduli space", Journal of Number Theory 131
       (2011), pages 936 - 958
    .. [M1991] J.-F. Mestre, "Construction de courbes de genre 2 a partir de
       leurs modules", in Effective methods in algebraic geometry
       (Castiglioncello, 1990), volume 94 of Progr. Math., pages 313 - 334
    .. [W1999] P. van Wamelen, Pari-GP code, section "thecubic"
       https://www.math.lsu.edu/~wamelen/Genus2/FindCurve/igusa2curve.gp
    """
    from sage.structure.sequence import Sequence
    i = Sequence(i)
    k = i.universe()
    try:
        k = k.fraction_field()
    except (TypeError, AttributeError, NotImplementedError):
        pass

    MConic, x, y, z = Mestre_conic(i, xyz=True)
    if k.is_finite():
        reduced = False

    t = k['t'].gen()

    if algorithm == 'magma':
        from sage.interfaces.all import magma
        from sage.misc.sage_eval import sage_eval
        if MConic.has_rational_point(algorithm='magma'):
            parametrization = [l.replace('$.1', 't').replace('$.2', 'u') \
               for l in str(magma(MConic).Parametrization()).splitlines()[4:7]]
            [F1, F2, F3] = [sage_eval(p, locals={'t':t,'u':1,'a':k.gen()}) \
               for p in parametrization]
        else:
            raise ValueError("No such curve exists over %s as there are no " \
                                 "rational points on %s" % (k, MConic))
    else:
        if MConic.has_rational_point():
            parametrization = MConic.parametrization(morphism=False)[0]
            [F1, F2, F3] = [p(t, 1) for p in parametrization]
        else:
            raise ValueError("No such curve exists over %s as there are no " \
                                 "rational points on %s" % (k, MConic))

    # setting the cijk from Mestre's algorithm
    c111 = 12*x*y - 2*y/3 - 4*z
    c112 = -18*x**3 - 12*x*y - 36*y**2 - 2*z
    c113 = -9*x**3 - 36*x**2*y -4*x*y - 6*x*z - 18*y**2
    c122 = c113
    c123 = -54*x**4 - 36*x**2*y - 36*x*y**2 - 6*x*z - 4*y**2 - 24*y*z
    c133 = -27*x**4/2 - 72*x**3*y - 6*x**2*y - 9*x**2*z - 39*x*y**2 - \
           36*y**3 - 2*y*z
    c222 = -27*x**4 - 18*x**2*y - 6*x*y**2 - 8*y**2/3 + 2*y*z
    c223 = 9*x**3*y - 27*x**2*z + 6*x*y**2 + 18*y**3 - 8*y*z
    c233 = -81*x**5/2 - 27*x**3*y - 9*x**2*y**2 - 4*x*y**2 + 3*x*y*z - 6*z**2
    c333 = 27*x**4*y/2 - 27*x**3*z/2 + 9*x**2*y**2 + 3*x*y**3 - 6*x*y*z + \
           4*y**3/3 - 10*y**2*z

    # writing out the hyperelliptic curve polynomial
    f = c111*F1**3 + c112*F1**2*F2 + c113*F1**2*F3 + c122*F1*F2**2 + \
        c123*F1*F2*F3 + c133*F1*F3**2 + c222*F2**3 + c223*F2**2*F3 + \
        c233*F2*F3**2 + c333*F3**3

    try:
        f = f*f.denominator()  # clear the denominator
    except (AttributeError, TypeError):
        pass

    if reduced:
        raise NotImplementedError("Reduction of hyperelliptic curves not " \
                                   "yet implemented. " \
                                   "See trac #14755 and #14756.")

    return HyperellipticCurve(f)
Example #11
0
def HyperellipticCurve_from_invariants(i,
                                       reduced=True,
                                       precision=None,
                                       algorithm='default'):
    r"""
    Returns a hyperelliptic curve with the given Igusa-Clebsch invariants up to
    scaling.

    The output is a curve over the field in which the Igusa-Clebsch invariants
    are given. The output curve is unique up to isomorphism over the algebraic
    closure. If no such curve exists over the given field, then raise a
    ValueError.

    INPUT:

    - ``i`` - list or tuple of length 4 containing the four Igusa-Clebsch
      invariants: I2,I4,I6,I10.
    - ``reduced`` - Boolean (default = True) If True, tries to reduce the
      polynomial defining the hyperelliptic curve using the function
      :func:`reduce_polynomial` (see the :func:`reduce_polynomial`
      documentation for more details).
    - ``precision`` - integer (default = None) Which precision for real and
      complex numbers should the reduction use. This only affects the
      reduction, not the correctness. If None, the algorithm uses the default
      53 bit precision.
    - ``algorithm`` - ``'default'`` or ``'magma'``. If set to ``'magma'``, uses
      Magma to parameterize Mestre's conic (needs Magma to be installed).

    OUTPUT:

    A hyperelliptic curve object.

    EXAMPLES:

    Examples over the rationals::

        sage: HyperellipticCurve_from_invariants([3840,414720,491028480,2437709561856])
        Traceback (most recent call last):
        ...
        NotImplementedError: Reduction of hyperelliptic curves not yet implemented. See trac #14755 and #14756.
        sage: HyperellipticCurve_from_invariants([3840,414720,491028480,2437709561856],reduced = False)
        Hyperelliptic Curve over Rational Field defined by y^2 = -46656*x^6 + 46656*x^5 - 19440*x^4 + 4320*x^3 - 540*x^2 + 4410*x - 1
        sage: HyperellipticCurve_from_invariants([21, 225/64, 22941/512, 1])
        Traceback (most recent call last):
        ...
        NotImplementedError: Reduction of hyperelliptic curves not yet implemented. See trac #14755 and #14756.

    An example over a finite field::

        sage: HyperellipticCurve_from_invariants([GF(13)(1),3,7,5])
        Hyperelliptic Curve over Finite Field of size 13 defined by y^2 = 8*x^5 + 5*x^4 + 5*x^2 + 9*x + 3

    An example over a number field::

        sage: K = QuadraticField(353, 'a')
        sage: H = HyperellipticCurve_from_invariants([21, 225/64, 22941/512, 1], reduced = false)
        sage: f = K['x'](H.hyperelliptic_polynomials()[0])

    If the Mestre Conic defined by the Igusa-Clebsch invariants has no rational
    points, then there exists no hyperelliptic curve over the base field with
    the given invariants.::

        sage: HyperellipticCurve_from_invariants([1,2,3,4])
        Traceback (most recent call last):
        ...
        ValueError: No such curve exists over Rational Field as there are no rational points on Projective Conic Curve over Rational Field defined by -2572155000*u^2 - 317736000*u*v + 1250755459200*v^2 + 2501510918400*u*w + 39276887040*v*w + 2736219686912*w^2

    Mestre's algorithm only works for generic curves of genus two, so another
    algorithm is needed for those curves with extra automorphism. See also
    :trac:`12199`::

        sage: P.<x> = QQ[]
        sage: C = HyperellipticCurve(x^6+1)
        sage: i = C.igusa_clebsch_invariants()
        sage: HyperellipticCurve_from_invariants(i)
        Traceback (most recent call last):
        ...
        TypeError: F (=0) must have degree 2


    Igusa-Clebsch invariants also only work over fields of characteristic
    different from 2, 3, and 5, so another algorithm will be needed for fields
    of those characteristics. See also :trac:`12200`::

        sage: P.<x> = GF(3)[]
        sage: HyperellipticCurve(x^6+x+1).igusa_clebsch_invariants()
        Traceback (most recent call last):
        ...
        NotImplementedError: Invariants of binary sextics/genus 2 hyperelliptic curves not implemented in characteristics 2, 3, and 5
        sage: HyperellipticCurve_from_invariants([GF(5)(1),1,0,1])
        Traceback (most recent call last):
        ...
        ZeroDivisionError: Inverse does not exist.

    ALGORITHM:

    This is Mestre's algorithm [M1991]_. Our implementation is based on the
    formulae on page 957 of [LY2001]_, cross-referenced with [W1999]_ to
    correct typos.

    First construct Mestre's conic using the :func:`Mestre_conic` function.
    Parametrize the conic if possible.
    Let `f_1, f_2, f_3` be the three coordinates of the parametrization of the
    conic by the projective line, and change them into one variable by letting
    `F_i = f_i(t, 1)`. Note that each `F_i` has degree at most 2.

    Then construct a sextic polynomial
    `f = \sum_{0<=i,j,k<=3}{c_{ijk}*F_i*F_j*F_k}`,
    where `c_{ijk}` are defined as rational functions in the invariants
    (see the source code for detailed formulae for `c_{ijk}`).
    The output is the hyperelliptic curve `y^2 = f`.

    REFERENCES:

    .. [LY2001] \K. Lauter and T. Yang, "Computing genus 2 curves from
       invariants on the Hilbert moduli space", Journal of Number Theory 131
       (2011), pages 936 - 958
    .. [M1991] \J.-F. Mestre, "Construction de courbes de genre 2 a partir de
       leurs modules", in Effective methods in algebraic geometry
       (Castiglioncello, 1990), volume 94 of Progr. Math., pages 313 - 334
    .. [W1999] \P. van Wamelen, Pari-GP code, section "thecubic"
       https://www.math.lsu.edu/~wamelen/Genus2/FindCurve/igusa2curve.gp
    """
    from sage.structure.sequence import Sequence
    i = Sequence(i)
    k = i.universe()
    try:
        k = k.fraction_field()
    except (TypeError, AttributeError, NotImplementedError):
        pass

    MConic, x, y, z = Mestre_conic(i, xyz=True)
    if k.is_finite():
        reduced = False

    t = k['t'].gen()

    if algorithm == 'magma':
        from sage.interfaces.all import magma
        from sage.misc.sage_eval import sage_eval
        if MConic.has_rational_point(algorithm='magma'):
            parametrization = [l.replace('$.1', 't').replace('$.2', 'u') \
               for l in str(magma(MConic).Parametrization()).splitlines()[4:7]]
            [F1, F2, F3] = [sage_eval(p, locals={'t':t,'u':1,'a':k.gen()}) \
               for p in parametrization]
        else:
            raise ValueError("No such curve exists over %s as there are no " \
                                 "rational points on %s" % (k, MConic))
    else:
        if MConic.has_rational_point():
            parametrization = MConic.parametrization(morphism=False)[0]
            [F1, F2, F3] = [p(t, 1) for p in parametrization]
        else:
            raise ValueError("No such curve exists over %s as there are no " \
                                 "rational points on %s" % (k, MConic))

    # setting the cijk from Mestre's algorithm
    c111 = 12 * x * y - 2 * y / 3 - 4 * z
    c112 = -18 * x**3 - 12 * x * y - 36 * y**2 - 2 * z
    c113 = -9 * x**3 - 36 * x**2 * y - 4 * x * y - 6 * x * z - 18 * y**2
    c122 = c113
    c123 = -54 * x**4 - 36 * x**2 * y - 36 * x * y**2 - 6 * x * z - 4 * y**2 - 24 * y * z
    c133 = -27*x**4/2 - 72*x**3*y - 6*x**2*y - 9*x**2*z - 39*x*y**2 - \
           36*y**3 - 2*y*z
    c222 = -27 * x**4 - 18 * x**2 * y - 6 * x * y**2 - 8 * y**2 / 3 + 2 * y * z
    c223 = 9 * x**3 * y - 27 * x**2 * z + 6 * x * y**2 + 18 * y**3 - 8 * y * z
    c233 = -81 * x**5 / 2 - 27 * x**3 * y - 9 * x**2 * y**2 - 4 * x * y**2 + 3 * x * y * z - 6 * z**2
    c333 = 27*x**4*y/2 - 27*x**3*z/2 + 9*x**2*y**2 + 3*x*y**3 - 6*x*y*z + \
           4*y**3/3 - 10*y**2*z

    # writing out the hyperelliptic curve polynomial
    f = c111*F1**3 + c112*F1**2*F2 + c113*F1**2*F3 + c122*F1*F2**2 + \
        c123*F1*F2*F3 + c133*F1*F3**2 + c222*F2**3 + c223*F2**2*F3 + \
        c233*F2*F3**2 + c333*F3**3

    try:
        f = f * f.denominator()  # clear the denominator
    except (AttributeError, TypeError):
        pass

    if reduced:
        raise NotImplementedError("Reduction of hyperelliptic curves not " \
                                   "yet implemented. " \
                                   "See trac #14755 and #14756.")

    return HyperellipticCurve(f)