Exemple #1
0
def _multiply_theta_char(l, f):
    r"""
    Return the coefficient at ``f`` of the theta series `\prod_t \theta_t` 
    where `t` runs through the list ``l`` of theta characteristics.

    INPUT:

    - ``l`` -- a list of quadruples `t` in `{0,1}^4`
    - ``f`` -- a triple `(a,b,c)` of rational numbers such that the
      quadratic form `[a,b,c]` is semi positive definite 
      (i.e. `a,c \geq 0` and `b^2-4ac \leq 0`).

    EXAMPLES::

        sage: from sage.modular.siegel.theta_constant import _multiply_theta_char
        sage: from sage.modular.siegel.theta_constant import _compute_theta_char_poly
        sage: tc = [(1, 1, 0, 0), (0, 0, 1, 1), (1, 1, 0, 0), (0, 0, 1, 1)]
        sage: _multiply_theta_char(tc, [2, 0, 6])
        -32
        sage: _multiply_theta_char(tc, [2, 0, 10])
        32
        sage: _multiply_theta_char(tc, [0, 0, 0]) 
        0
    """
    if 0 == len(l):
        return (1 if (0, 0, 0) == f else 0)
    a, b, c = f
    m1, m2, m3, m4 = l[0]
    # if the characteristic is not even:
    if 1 == (m1 * m3 + m2 * m4) % 2:
        return 0
    coeff = 0
    from sage.misc.all import isqrt, xsrange
    for u in xsrange(m1, isqrt(a) + 1, 2):
        for v in xsrange(m2, isqrt(c) + 1, 2):
            if 0 == u and 0 == v:
                coeff += _multiply_theta_char(l[1:], (a, b, c))
                continue
            ap, bp, cp = (a - u * u, b - 2 * u * v, c - v * v)
            if bp * bp - 4 * ap * cp <= 0:
                val = (2 if 0 == (u * m3 + v * m4) % 4 else -2)
                coeff += val * _multiply_theta_char(l[1:], (ap, bp, cp))
            if u != 0 and v != 0:
                ap, bp, cp = (a - u * u, b + 2 * u * v, c - v * v)
                if bp * bp - 4 * ap * cp <= 0:
                    val = (2 if 0 == (u * m3 - v * m4) % 4 else -2)
                    coeff += val * _multiply_theta_char(l[1:], (ap, bp, cp))
    return coeff
def _multiply_theta_char(l, f):
    r"""
    Return the coefficient at ``f`` of the theta series `\prod_t \theta_t` 
    where `t` runs through the list ``l`` of theta characteristics.

    INPUT:

    - ``l`` -- a list of quadruples `t` in `{0,1}^4`
    - ``f`` -- a triple `(a,b,c)` of rational numbers such that the
      quadratic form `[a,b,c]` is semi positive definite 
      (i.e. `a,c \geq 0` and `b^2-4ac \leq 0`).

    EXAMPLES::

        sage: from sage.modular.siegel.theta_constant import _multiply_theta_char
        sage: from sage.modular.siegel.theta_constant import _compute_theta_char_poly
        sage: tc = [(1, 1, 0, 0), (0, 0, 1, 1), (1, 1, 0, 0), (0, 0, 1, 1)]
        sage: _multiply_theta_char(tc, [2, 0, 6])
        -32
        sage: _multiply_theta_char(tc, [2, 0, 10])
        32
        sage: _multiply_theta_char(tc, [0, 0, 0]) 
        0
    """
    if 0 == len(l):
        return (1 if (0, 0, 0) == f else 0)
    a, b, c = f
    m1, m2, m3, m4 = l[0]
    # if the characteristic is not even:
    if 1 == (m1*m3 + m2*m4)%2: 
        return 0
    coeff = 0
    from sage.misc.all import isqrt, xsrange
    for u in xsrange(m1, isqrt(a)+1, 2):
        for v in xsrange(m2, isqrt(c)+1, 2):
            if 0 == u and 0 == v:
                coeff += _multiply_theta_char(l[1:], (a, b, c))
                continue
            ap, bp, cp = (a-u*u, b-2*u*v, c-v*v)
            if bp*bp-4*ap*cp <= 0:
                val = (2 if  0 == (u*m3 + v*m4)%4 else -2)
                coeff += val * _multiply_theta_char(l[1:], (ap, bp, cp))
            if u != 0 and v != 0:
                ap, bp, cp = (a-u*u, b+2*u*v, c-v*v)
                if bp*bp-4*ap*cp <= 0:
                    val = (2 if  0 == (u*m3 - v*m4)%4 else -2)
                    coeff += val * _multiply_theta_char(l[1:], (ap, bp, cp))
    return coeff
Exemple #3
0
def BinaryQF_reduced_representatives(D, primitive_only=False):
    r"""
    Returns a list of inequivalent reduced representatives for the
    equivalence classes of positive definite binary forms of
    discriminant D.

    INPUT:

    - `D` -- (integer) A negative discriminant.

    - ``primitive_only`` -- (bool, default False) flag controlling whether only
      primitive forms are included.

    OUTPUT:

    (list) A lexicographically-ordered list of inequivalent reduced
    representatives for the equivalence classes of positive definite binary
    forms of discriminant `D`.  If ``primitive_only`` is ``True`` then
    imprimitive forms (which only exist when `D` is not fundamental) are
    omitted; otherwise they are included.

    EXAMPLES::

        sage: BinaryQF_reduced_representatives(-4)
        [x^2 + y^2]

        sage: BinaryQF_reduced_representatives(-163)
        [x^2 + x*y + 41*y^2]

        sage: BinaryQF_reduced_representatives(-12)
        [x^2 + 3*y^2, 2*x^2 + 2*x*y + 2*y^2]

        sage: BinaryQF_reduced_representatives(-16)
        [x^2 + 4*y^2, 2*x^2 + 2*y^2]

        sage: BinaryQF_reduced_representatives(-63)
        [x^2 + x*y + 16*y^2, 2*x^2 - x*y + 8*y^2, 2*x^2 + x*y + 8*y^2, 3*x^2 + 3*x*y + 6*y^2, 4*x^2 + x*y + 4*y^2]

    The number of inequivalent reduced binary forms with a fixed negative
    fundamental discriminant D is the class number of the quadratic field
    `Q(\sqrt{D})`::

        sage: len(BinaryQF_reduced_representatives(-13*4))
        2
        sage: QuadraticField(-13*4, 'a').class_number()
        2
        sage: p=next_prime(2^20); p
        1048583
        sage: len(BinaryQF_reduced_representatives(-p))
        689
        sage: QuadraticField(-p, 'a').class_number()
        689

        sage: BinaryQF_reduced_representatives(-23*9)
        [x^2 + x*y + 52*y^2,
        2*x^2 - x*y + 26*y^2,
        2*x^2 + x*y + 26*y^2,
        3*x^2 + 3*x*y + 18*y^2,
        4*x^2 - x*y + 13*y^2,
        4*x^2 + x*y + 13*y^2,
        6*x^2 - 3*x*y + 9*y^2,
        6*x^2 + 3*x*y + 9*y^2,
        8*x^2 + 7*x*y + 8*y^2]
        sage: BinaryQF_reduced_representatives(-23*9, primitive_only=True)
        [x^2 + x*y + 52*y^2,
        2*x^2 - x*y + 26*y^2,
        2*x^2 + x*y + 26*y^2,
        4*x^2 - x*y + 13*y^2,
        4*x^2 + x*y + 13*y^2,
        8*x^2 + 7*x*y + 8*y^2]

    TESTS::

        sage: BinaryQF_reduced_representatives(5)
        Traceback (most recent call last):
        ...
        ValueError: discriminant must be negative and congruent to 0 or 1 modulo 4
    """
    D = ZZ(D)
    if not ( D < 0 and (D % 4 in [0,1])):
        raise ValueError, "discriminant must be negative and congruent to 0 or 1 modulo 4"

    # For a fundamental discriminant all forms are primitive so we need not check:
    if primitive_only:
        primitive_only = not is_fundamental_discriminant(D)

    form_list = []

    from sage.misc.all import xsrange
    from sage.rings.arith import gcd

    # Only iterate over positive a and over b of the same
    # parity as D such that 4a^2 + D <= b^2 <= a^2
    for a in xsrange(1,1+((-D)//3).isqrt()):
        a4 = 4*a
        s = D + a*a4
        w = 1+(s-1).isqrt() if s > 0 else 0
        if w%2 != D%2: w += 1
        for b in xsrange(w,a+1,2):
            t = b*b-D
            if t % a4 == 0:
                c = t // a4
                if (not primitive_only) or gcd([a,b,c])==1:
                    if b>0 and a>b and c>a:
                        form_list.append(BinaryQF([a,-b,c]))
                    form_list.append(BinaryQF([a,b,c]))

    form_list.sort()
    return form_list
Exemple #4
0
def BinaryQF_reduced_representatives(D, primitive_only=False):
    r"""
    Returns a list of inequivalent reduced representatives for the
    equivalence classes of positive definite binary forms of
    discriminant D.

    INPUT:

    - `D` -- (integer) A negative discriminant.

    - ``primitive_only`` -- (bool, default False) flag controlling whether only
      primitive forms are included.

    OUTPUT:

    (list) A lexicographically-ordered list of inequivalent reduced
    representatives for the equivalence classes of positive definite binary
    forms of discriminant `D`.  If ``primitive_only`` is ``True`` then
    imprimitive forms (which only exist when `D` is not fundamental) are
    omitted; otherwise they are included.

    EXAMPLES::

        sage: BinaryQF_reduced_representatives(-4)
        [x^2 + y^2]

        sage: BinaryQF_reduced_representatives(-163)
        [x^2 + x*y + 41*y^2]

        sage: BinaryQF_reduced_representatives(-12)
        [x^2 + 3*y^2, 2*x^2 + 2*x*y + 2*y^2]

        sage: BinaryQF_reduced_representatives(-16)
        [x^2 + 4*y^2, 2*x^2 + 2*y^2]

        sage: BinaryQF_reduced_representatives(-63)
        [x^2 + x*y + 16*y^2, 2*x^2 - x*y + 8*y^2, 2*x^2 + x*y + 8*y^2, 3*x^2 + 3*x*y + 6*y^2, 4*x^2 + x*y + 4*y^2]

    The number of inequivalent reduced binary forms with a fixed negative
    fundamental discriminant D is the class number of the quadratic field
    `Q(\sqrt{D})`::

        sage: len(BinaryQF_reduced_representatives(-13*4))
        2
        sage: QuadraticField(-13*4, 'a').class_number()
        2
        sage: p=next_prime(2^20); p
        1048583
        sage: len(BinaryQF_reduced_representatives(-p))
        689
        sage: QuadraticField(-p, 'a').class_number()
        689

        sage: BinaryQF_reduced_representatives(-23*9)
        [x^2 + x*y + 52*y^2,
        2*x^2 - x*y + 26*y^2,
        2*x^2 + x*y + 26*y^2,
        3*x^2 + 3*x*y + 18*y^2,
        4*x^2 - x*y + 13*y^2,
        4*x^2 + x*y + 13*y^2,
        6*x^2 - 3*x*y + 9*y^2,
        6*x^2 + 3*x*y + 9*y^2,
        8*x^2 + 7*x*y + 8*y^2]
        sage: BinaryQF_reduced_representatives(-23*9, primitive_only=True)
        [x^2 + x*y + 52*y^2,
        2*x^2 - x*y + 26*y^2,
        2*x^2 + x*y + 26*y^2,
        4*x^2 - x*y + 13*y^2,
        4*x^2 + x*y + 13*y^2,
        8*x^2 + 7*x*y + 8*y^2]

    TESTS::

        sage: BinaryQF_reduced_representatives(5)
        Traceback (most recent call last):
        ...
        ValueError: discriminant must be negative and congruent to 0 or 1 modulo 4
    """
    D = ZZ(D)
    if not (D < 0 and (D % 4 in [0, 1])):
        raise ValueError, "discriminant must be negative and congruent to 0 or 1 modulo 4"

    # For a fundamental discriminant all forms are primitive so we need not check:
    if primitive_only:
        primitive_only = not is_fundamental_discriminant(D)

    form_list = []

    from sage.misc.all import xsrange
    from sage.rings.arith import gcd

    # Only iterate over positive a and over b of the same
    # parity as D such that 4a^2 + D <= b^2 <= a^2
    for a in xsrange(1, 1 + ((-D) // 3).isqrt()):
        a4 = 4 * a
        s = D + a * a4
        w = 1 + (s - 1).isqrt() if s > 0 else 0
        if w % 2 != D % 2: w += 1
        for b in xsrange(w, a + 1, 2):
            t = b * b - D
            if t % a4 == 0:
                c = t // a4
                if (not primitive_only) or gcd([a, b, c]) == 1:
                    if b > 0 and a > b and c > a:
                        form_list.append(BinaryQF([a, -b, c]))
                    form_list.append(BinaryQF([a, b, c]))

    form_list.sort()
    return form_list