Beispiel #1
0
    def gritsenko_lift(self, f, k, is_integral=False):
        """
        INPUT:
            - `f` -- the Fourier expansion of a Jacobi form as a dictionary
        """
        N = self.level()
        frN = 4 * N
        p1list = self.precision()._p1list()

        divisor_dict = self._divisor_dict()

        ##TODO: Precalculate disc_coeffs or at least use a recursive definition
        disc_coeffs = dict()
        coeffs = dict()
        f_index = lambda d, b: ((d + b**2) // frN, b)

        for (
            ((a, b, c), l), eps, disc
        ) in self.__precision._iter_positive_forms_with_content_and_discriminant(
        ):
            (_, bp, _) = apply_GL_to_form(p1list[l], (a, b, c))
            try:
                coeffs[((a, b, c), l)] = disc_coeffs[(disc, bp, eps)]
            except KeyError:
                disc_coeffs[(disc, bp, eps)] = \
                    sum(t**(k-1) * f[ f_index(disc//t**2, (bp // t) % (2 * N)) ]
                           for t in divisor_dict[eps])

                if disc_coeffs[(disc, bp, eps)] != 0:
                    coeffs[((a, b, c), l)] = disc_coeffs[(disc, bp, eps)]

        for ((a, b, c), l) in self.__precision.iter_indefinite_forms():
            if l == 0:
                coeffs[((a, b, c), l)] = (
                    sigma(c, k - 1) * f[(0, 0)] if c != 0 else
                    (Integer(-bernoulli(k) / Integer(2 * k) *
                             f[(0, 0)]) if is_integral else -bernoulli(k) /
                     Integer(2 * k) * f[(0, 0)]))
            else:
                coeffs[((a, b, c), l)] = (
                    sigma(c // self.level(), k - 1) * f[(0, 0)] if c != 0 else
                    (Integer(-bernoulli(k) / Integer(2 * k) *
                             f[(0, 0)]) if is_integral else -bernoulli(k) /
                     Integer(2 * k) * f[(0, 0)]))

        return coeffs
    def gritsenko_lift(self, f, k, is_integral = False) :
        """
        INPUT:
            - `f` -- the Fourier expansion of a Jacobi form as a dictionary
        """
        N = self.level()
        frN = 4 * N
        p1list = self.precision()._p1list()

        divisor_dict = self._divisor_dict()
        
        ##TODO: Precalculate disc_coeffs or at least use a recursive definition
        disc_coeffs = dict()
        coeffs = dict()
        f_index = lambda d,b : ((d + b**2)//frN, b)
        
        for (((a,b,c),l), eps, disc) in self.__precision._iter_positive_forms_with_content_and_discriminant() :
            (_,bp,_) = apply_GL_to_form(p1list[l], (a,b,c))
            try :
                coeffs[((a,b,c),l)] = disc_coeffs[(disc, bp, eps)]
            except KeyError :
                disc_coeffs[(disc, bp, eps)] = \
                    sum(   t**(k-1) * f[ f_index(disc//t**2, (bp // t) % (2 * N)) ]
                           for t in divisor_dict[eps] )
 
                if disc_coeffs[(disc, bp, eps)]  != 0 :
                    coeffs[((a,b,c),l)] = disc_coeffs[(disc, bp, eps)]

        for ((a,b,c), l) in self.__precision.iter_indefinite_forms() :
            if l == 0 :
                coeffs[((a,b,c),l)] = ( sigma(c, k-1) * f[(0,0)]
                                        if c != 0 else 
                                         ( Integer(-bernoulli(k) / Integer(2 * k) * f[(0,0)])
                                           if is_integral else
                                           -bernoulli(k) / Integer(2 * k) * f[(0,0)] ) )
            else :
                coeffs[((a,b,c),l)] = ( sigma(c//self.level(), k-1) * f[(0,0)]
                                        if c != 0 else 
                                         ( Integer(-bernoulli(k) / Integer(2 * k) * f[(0,0)])
                                           if is_integral else
                                           -bernoulli(k) / Integer(2 * k) * f[(0,0)] ) )
        
        return coeffs
Beispiel #3
0
    def _compute_hecke_matrix(self, n):
        """
        Compute the matrix of the Hecke operator T_n acting on self.

        NOTE:

        If self is a level 1 space, the much faster Victor Miller basis
        is used for this computation.

        EXAMPLES::

            sage: M = ModularForms(11, 2)
            sage: M._compute_hecke_matrix(6)
            [ 2  0]
            [ 0 12]

        Check that :trac:`22780` is fixed::

            sage: M = ModularForms(1, 12)
            sage: M._compute_hecke_matrix(2)
            [ -24    0]
            [   0 2049]
            sage: ModularForms(1, 2).hecke_matrix(2)
            []

        TESTS:

        The following Hecke matrix is 43x43 with very large integer entries.
        We test it indirectly by computing the product and the sum of its
        eigenvalues, and reducing these two integers modulo all the primes
        less than 100::

            sage: M = ModularForms(1, 512)
            sage: t = M._compute_hecke_matrix(5)     # long time (2s)
            sage: t[-1, -1] == 1 + 5^511             # long time (0s, depends on above)
            True
            sage: f = t.charpoly()                   # long time (4s)
            sage: [f[0]%p for p in prime_range(100)] # long time (0s, depends on above)
            [0, 0, 0, 0, 1, 9, 2, 7, 0, 0, 0, 0, 1, 12, 9, 16, 37, 0, 21, 11, 70, 22, 0, 58, 76]
            sage: [f[42]%p for p in prime_range(100)] # long time (0s, depends on above)
            [0, 0, 4, 0, 10, 4, 4, 8, 12, 1, 23, 13, 10, 27, 20, 13, 16, 59, 53, 41, 11, 13, 12, 6, 82]
        """
        if self.level() == 1:
            k = self.weight()
            d = self.dimension()
            if d == 0:
                return matrix(self.base_ring(), 0, 0, [])
            from sage.modular.all import victor_miller_basis, hecke_operator_on_basis
            vmb = victor_miller_basis(k, prec=d * n + 1)[1:]
            Tcusp = hecke_operator_on_basis(vmb, n, k)
            return Tcusp.block_sum(matrix(self.base_ring(), 1, 1,
                                          [sigma(n, k - 1)]))
        else:
            return space.ModularFormsSpace._compute_hecke_matrix(self, n)
Beispiel #4
0
    def _compute_hecke_matrix(self, n):
        """
        Compute the matrix of the Hecke operator T_n acting on self.

        NOTE:

        If self is a level 1 space, the much faster Victor Miller basis
        is used for this computation.

        EXAMPLES::

            sage: M = ModularForms(11, 2)
            sage: M._compute_hecke_matrix(6)
            [ 2  0]
            [ 0 12]
        
        Check that :trac:`22780` is fixed::

            sage: M = ModularForms(1, 12)
            sage: M._compute_hecke_matrix(2)
            [ -24    0]
            [   0 2049]
            sage: ModularForms(1, 2).hecke_matrix(2)
            []

        TESTS:

        The following Hecke matrix is 43x43 with very large integer entries.
        We test it indirectly by computing the product and the sum of its
        eigenvalues, and reducing these two integers modulo all the primes
        less than 100::

            sage: M = ModularForms(1, 512)
            sage: t = M._compute_hecke_matrix(5)     # long time (2s)
            sage: t[-1, -1] == 1 + 5^511             # long time (0s, depends on above)
            True
            sage: f = t.charpoly()                   # long time (4s)
            sage: [f[0]%p for p in prime_range(100)] # long time (0s, depends on above)
            [0, 0, 0, 0, 1, 9, 2, 7, 0, 0, 0, 0, 1, 12, 9, 16, 37, 0, 21, 11, 70, 22, 0, 58, 76]
            sage: [f[42]%p for p in prime_range(100)] # long time (0s, depends on above)
            [0, 0, 4, 0, 10, 4, 4, 8, 12, 1, 23, 13, 10, 27, 20, 13, 16, 59, 53, 41, 11, 13, 12, 6, 82]
        """
        if self.level() == 1:
            k = self.weight()
            d = self.dimension()
            if d == 0: return matrix(self.base_ring(), 0, 0, [])
            from sage.modular.all import victor_miller_basis, hecke_operator_on_basis
            vmb = victor_miller_basis(k, prec=d*n+1)[1:]
            Tcusp = hecke_operator_on_basis(vmb, n, k)
            return Tcusp.block_sum(matrix(self.base_ring(), 1, 1, [sigma(n, k-1)]))
        else:
            return space.ModularFormsSpace._compute_hecke_matrix(self, n)
Beispiel #5
0
        def coeff(m):
            m = ZZ(m)
            if m < 0:
                return ZZ(0)
            elif m == 0:
                return ZZ(1)

            factor = -2 * k / QQ(bernoulli(k)) / lamk
            sum1 = sigma(m, k - 1)
            if M.divides(m):
                sum2 = (lamk - 1) * sigma(ZZ(m / M), k - 1)
            else:
                sum2 = ZZ(0)
            if (M == 1):
                sum3 = ZZ(0)
            else:
                if (m == 1):
                    N = ZZ(1)
                else:
                    N = ZZ(m / M**ZZ(m.valuation(M)))
                sum3 = -sigma(ZZ(N), k - 1) * ZZ(m / N)**(k - 1) / (lamk + 1)

            return factor * (sum1 + sum2 + sum3) * dval**m
        def coeff(m):
            m = ZZ(m)
            if m < 0:
                return ZZ(0)
            elif m == 0:
                return ZZ(1)

            factor = -2*k / QQ(bernoulli(k)) / lamk
            sum1   = sigma(m, k-1)
            if M.divides(m):
                sum2 = (lamk-1) * sigma(ZZ(m/M), k-1)
            else:
                sum2 = ZZ(0)
            if (M == 1):
                sum3 = ZZ(0)
            else:
                if (m == 1):
                    N = ZZ(1)
                else:
                    N = ZZ(m / M**ZZ(m.valuation(M)))
                sum3 = -sigma(ZZ(N), k-1) * ZZ(m/N)**(k-1) / (lamk + 1)

            return factor * (sum1 + sum2 + sum3) * dval**m
Beispiel #7
0
    def maass_form(self, f, g, k=None, is_integral=False):
        r"""
        Return the Siegel modular form `I(f,g)` (Notation as in [Sko]).
    
        INPUT:
        - `f`              -- modular form of level `1`
        - `g`              -- cusp form of level `1` and weight = ``weight of f + 2``
        - ``is_integral``  -- ``True`` if the result is guaranteed to have integer
                              coefficients
        """

        ## we introduce an abbreviations
        if is_integral:
            PS = self.integral_power_series_ring()
        else:
            PS = self.power_series_ring()

        fismodular = isinstance(f, ModularFormElement)
        gismodular = isinstance(g, ModularFormElement)

        ## We only check the arguments if f and g are ModularFormElements.
        ## Otherwise we trust in the user
        if fismodular and gismodular:
            assert(f.weight() + 2 == g.weight() | (f==0) | (g==0)), \
                    "incorrect weights!"
            assert (
                g.q_expansion(1) == 0), "second argument is not a cusp form"

        qexp_prec = self._get_maass_form_qexp_prec()
        if qexp_prec is None:  # there are no forms below prec
            return dict()

        if fismodular:
            k = f.weight()
            if f == f.parent()(0):
                f = PS(0, qexp_prec)
            else:
                f = PS(f.qexp(qexp_prec), qexp_prec)
        elif f == 0:
            f = PS(0, qexp_prec)
        else:
            f = PS(f(qexp_prec), qexp_prec)

        if gismodular:
            k = g.weight() - 2
            if g == g.parent()(0):
                g = PS(0, qexp_prec)
            else:
                g = PS(g.qexp(qexp_prec), qexp_prec)
        elif g == 0:
            g = PS(0, qexp_prec)
        else:
            g = PS(g(qexp_prec), qexp_prec)

        if k is None:
            raise ValueError("if neither f nor g are not ModularFormElements " + \
                              "you must pass k")

        fderiv = f.derivative().shift(1)
        f *= Integer(k / 2)
        gfderiv = g - fderiv

        ## Form A and B - the Jacobi forms used in [Sko]'s I map.
        ## This is not necessary if we multiply Ifg0 and Ifg1 by etapow
        # (A0,A1,B0,B1) = (a0*etapow, a1*etapow, b0*etapow, b1*etapow)

        ## Calculate the image of the pair of modular forms (f,g) under
        ## [Sko]'s isomorphism I: M_{k} \oplus S_{k+2} -> J_{k,1}.

        # Multiplication of big polynomials may take > 60 GB, so wie have
        # to do it in small parts; This is only implemented for integral
        # coefficients.
        r"""
        Create the Jacobi form I(f,g) as in [Sko].
    
        It suffices to construct for all Jacobi forms phi only the part
        sum_{r=0,1;n} c_phi(r^2-4n) q^n zeta^r.
        When, in this code part, we speak of Jacobi form we only mean this part.
        
        We need to compute Ifg = \sum_{r=0,1; n} c(r^2-4n) q^n zeta^r up to
        4n-r^2 <= Dtop, i.e. n < precision
        """

        ## Create the Jacobi forms A=a*etapow and B=b*etapow in stages.
        ## Recall a = sum_{s != r mod 2} s^2*(-1)^r*q^((s^2+r^2-1)/4)*zeta^r
        ##        b = sum_{s != r mod 2}     (-1)^r*q^((s^2+r^2-1)/4)*zeta^r
        ## r, s run over ZZ but with opposite parities.
        ## For r=0, we need s odd, (s^2-1)/4 < precision, with s=2t+1 hence t^2+t < precision.
        ## For r=1, we need s even, s^2/4 < precision, with s=2t hence t^2 < precision.

        ## we use a slightly overestimated ab_prec

        ab_prec = isqrt(qexp_prec + 1)
        a1dict = dict()
        a0dict = dict()
        b1dict = dict()
        b0dict = dict()

        for t in range(1, ab_prec + 1):
            tmp = t**2
            a1dict[tmp] = -8 * tmp
            b1dict[tmp] = -2

            tmp += t
            a0dict[tmp] = 8 * tmp + 2
            b0dict[tmp] = 2
        b1dict[0] = -1
        a0dict[0] = 2
        b0dict[0] = 2

        a1 = PS(a1dict)
        b1 = PS(b1dict)
        a0 = PS(a0dict)
        b0 = PS(b0dict)

        ## Finally: I(f,g) is given by the formula below:
        ## We multiply by etapow explicitly and save two multiplications
        # Ifg0 = k/2*f*A0 - fderiv*B0 + g*B0 + O(q^precision)
        # Ifg1 = k/2*f*A1 - fderiv*B1 + g*B1 + O(q^precision)
        Ifg0 = (self._eta_power() * (f * a0 + gfderiv * b0)).list()
        Ifg1 = (self._eta_power() * (f * a1 + gfderiv * b1)).list()

        if len(Ifg0) < qexp_prec:
            Ifg0 += [0] * (qexp_prec - len(Ifg0))
        if len(Ifg1) < qexp_prec:
            Ifg1 += [0] * (qexp_prec - len(Ifg1))

        ## For applying the Maass' lifting to genus 2 modular forms.
        ## we put the coefficients of Ifg into a dictionary Chi
        ## so that we can access the coefficient corresponding to
        ## discriminant D by going Chi[D].

        Cphi = dict([(0, 0)])
        for i in range(qexp_prec):
            Cphi[-4 * i] = Ifg0[i]
            Cphi[1 - 4 * i] = Ifg1[i]

        del Ifg0[:], Ifg1[:]
        """
        Create the Maas lift F:= VI(f,g) as in [Sko].
        """

        ## The constant term is given by -Cphi[0]*B_{2k}/(4*k)
        ## (note in [Sko] this coeff has typos).
        ## For nonconstant terms,
        ## The Siegel coefficient of q^n * zeta^r * qdash^m is given
        ## by the formula  \sum_{ a | gcd(n,r,m) } Cphi[D/a^2] where
        ## D = r^2-4*n*m is the discriminant.
        ## Hence in either case the coefficient
        ## is fully determined by the pair (D,gcd(n,r,m)).
        ## Put (D,t) -> \sum_{ a | t } Cphi[D/a^2]
        ## in a dictionary (hash table) maassc.

        maass_coeffs = dict()
        divisor_dict = self._divisor_dict()

        ## First calculate maass coefficients corresponding to strictly positive definite matrices:
        for disc in self._negative_fundamental_discriminants():
            for s in range(
                    1,
                    isqrt((-self.__precision.discriminant()) // disc) + 1):
                ## add (disc*s^2,t) as a hash key, for each t that divides s
                for t in divisor_dict[s]:
                    maass_coeffs[(disc * s**2,t)] = \
                       sum(a**(k-1) * Cphi[disc * s**2 / a**2]
                            for a in divisor_dict[t])

        ## Compute the coefficients of the Siegel form $F$:
        siegel_coeffs = dict()
        for (n, r,
             m), g in self.__precision.iter_positive_forms_with_content():
            siegel_coeffs[(n, r, m)] = maass_coeffs[(r**2 - 4 * m * n, g)]

        ## Secondly, deal with the singular part.
        ## Include the coeff corresponding to (0,0,0):
        ## maass_coeffs = {(0,0): -bernoulli(k)/(2*k)*Cphi[0]}
        siegel_coeffs[(0, 0, 0)] = -bernoulli(k) / (2 * k) * Cphi[0]
        if is_integral:
            siegel_coeffs[(0, 0, 0)] = Integer(siegel_coeffs[(0, 0, 0)])

        ## Calculate the other discriminant-zero maass coefficients.
        ## Since sigma is quite cheap it is faster to estimate the bound and
        ## save the time for repeated calculation
        for i in range(1, self.__precision._indefinite_content_bound()):
            ## maass_coeffs[(0,i)] = sigma(i, k-1) * Cphi[0]
            siegel_coeffs[(0, 0, i)] = sigma(i, k - 1) * Cphi[0]

        return siegel_coeffs
    def maass_form( self, f, g, k = None, is_integral = False) :
        r"""
        Return the Siegel modular form `I(f,g)` (Notation as in [Sko]).
    
        INPUT:
        - `f`              -- modular form of level `1`
        - `g`              -- cusp form of level `1` and weight = ``weight of f + 2``
        - ``is_integral``  -- ``True`` if the result is garanteed to have integer
                              coefficients
        """
        
        ## we introduce an abbreviations
        if is_integral :
            PS = self.integral_power_series_ring()
        else :
            PS = self.power_series_ring()
        
        fismodular = isinstance(f, ModularFormElement)
        gismodular = isinstance(g, ModularFormElement)
    
        ## We only check the arguments if f and g are ModularFormElements.
        ## Otherwise we trust in the user 
        if fismodular and gismodular :
            assert( f.weight() + 2 == g.weight() | (f==0) | (g==0)), \
                    "incorrect weights!"
            assert( g.q_expansion(1) == 0), "second argument is not a cusp form"

        qexp_prec = self._get_maass_form_qexp_prec()
        if qexp_prec is None : # there are no forms below prec
            return dict()

        if fismodular :
            k = f.weight()
            if f == f.parent()(0) :
                f = PS(0, qexp_prec)
            else :
                f = PS(f.qexp(qexp_prec), qexp_prec)
        elif f == 0 :
            f = PS(0, qexp_prec)
        else :
            f = PS(f(qexp_prec), qexp_prec)
        
        if gismodular :
            k = g.weight() - 2
            if g == g.parent()(0) :
                g = PS(0, qexp_prec)
            else :
                g = PS(g.qexp(qexp_prec), qexp_prec)
        elif g == 0 :
            g = PS(0, qexp_prec)
        else :
            g = PS(g(qexp_prec), qexp_prec)
                
        if k is None :
            raise ValueError, "if neither f nor g are not ModularFormElements " + \
                              "you must pass k"
            
        fderiv = f.derivative().shift(1)
        f *= Integer(k/2)
        gfderiv = g - fderiv

        ## Form A and B - the Jacobi forms used in [Sko]'s I map.
        ## This is not necessary if we multiply Ifg0 and Ifg1 by etapow
        # (A0,A1,B0,B1) = (a0*etapow, a1*etapow, b0*etapow, b1*etapow)
    
        ## Calculate the image of the pair of modular forms (f,g) under
        ## [Sko]'s isomorphism I : M_{k} \oplus S_{k+2} -> J_{k,1}.
        
        # Multiplication of big polynomials may take > 60 GB, so wie have
        # to do it in small parts; This is only implemented for integral
        # coefficients.

        """
        Create the Jacobi form I(f,g) as in [Sko].
    
        It suffices to construct for all Jacobi forms phi only the part
        sum_{r=0,1;n} c_phi(r^2-4n) q^n zeta^r.
        When, in this code part, we speak of Jacobi form we only mean this part.
        
        We need to compute Ifg = \sum_{r=0,1; n} c(r^2-4n) q^n zeta^r up to
        4n-r^2 <= Dtop, i.e. n < precision
        """

        ## Create the Jacobi forms A=a*etapow and B=b*etapow in stages.
        ## Recall a = sum_{s != r mod 2} s^2*(-1)^r*q^((s^2+r^2-1)/4)*zeta^r
        ##        b = sum_{s != r mod 2}     (-1)^r*q^((s^2+r^2-1)/4)*zeta^r
        ## r, s run over ZZ but with opposite parities.
        ## For r=0, we need s odd, (s^2-1)/4 < precision, with s=2t+1 hence t^2+t < precision.
        ## For r=1, we need s even, s^2/4 < precision, with s=2t hence t^2 < precision.
    
        ## we use a slightly overestimated ab_prec 
        
        ab_prec = isqrt(qexp_prec + 1)
        a1dict = dict(); a0dict = dict()
        b1dict = dict(); b0dict = dict()
    
        for t in xrange(1, ab_prec + 1) :
            tmp = t**2
            a1dict[tmp] = -8*tmp
            b1dict[tmp] = -2
        
            tmp += t
            a0dict[tmp] = 8*tmp + 2
            b0dict[tmp] = 2
        b1dict[0] = -1
        a0dict[0] = 2; b0dict[0] = 2 
        
        a1 = PS(a1dict); b1 = PS(b1dict)
        a0 = PS(a0dict); b0 = PS(b0dict)

        ## Finally: I(f,g) is given by the formula below:
        ## We multiply by etapow explecitely and save two multiplications
        # Ifg0 = k/2*f*A0 - fderiv*B0 + g*B0 + O(q^precision)
        # Ifg1 = k/2*f*A1 - fderiv*B1 + g*B1 + O(q^precision)
        Ifg0 = (self._eta_power() * (f*a0 + gfderiv*b0)).list()
        Ifg1 = (self._eta_power() * (f*a1 + gfderiv*b1)).list()

        if len(Ifg0) < qexp_prec :
            Ifg0 += [0]*(qexp_prec - len(Ifg0))
        if len(Ifg1) < qexp_prec :
            Ifg1 += [0]*(qexp_prec - len(Ifg1))
        
        ## For applying the Maass' lifting to genus 2 modular forms.
        ## we put the coefficients of Ifg into a dictionary Chi
        ## so that we can access the coefficient corresponding to 
        ## discriminant D by going Chi[D].
        
        Cphi = dict([(0,0)])
        for i in xrange(qexp_prec) :
            Cphi[-4*i] = Ifg0[i]
            Cphi[1-4*i] = Ifg1[i]

        del Ifg0[:], Ifg1[:]

        """
        Create the Maas lift F := VI(f,g) as in [Sko].
        """
        
        ## The constant term is given by -Cphi[0]*B_{2k}/(4*k)
        ## (note in [Sko] this coeff has typos).
        ## For nonconstant terms,
        ## The Siegel coefficient of q^n * zeta^r * qdash^m is given 
        ## by the formula  \sum_{ a | gcd(n,r,m) } Cphi[D/a^2] where 
        ## D = r^2-4*n*m is the discriminant.  
        ## Hence in either case the coefficient 
        ## is fully deterimined by the pair (D,gcd(n,r,m)).
        ## Put (D,t) -> \sum_{ a | t } Cphi[D/a^2]
        ## in a dictionary (hash table) maassc.

        maass_coeffs = dict()
        divisor_dict = self._divisor_dict()

        ## First calculate maass coefficients corresponding to strictly positive definite matrices:        
        for disc in self._negative_fundamental_discriminants() :
            for s in xrange(1, isqrt((-self.__precision.discriminant()) // disc) + 1) :
                ## add (disc*s^2,t) as a hash key, for each t that divides s
                for t in divisor_dict[s] :
                    maass_coeffs[(disc * s**2,t)] = \
                       sum( a**(k-1) * Cphi[disc * s**2 / a**2] 
                            for a in divisor_dict[t] )

        ## Compute the coefficients of the Siegel form $F$:
        siegel_coeffs = dict()
        for (n,r,m), g in self.__precision.iter_positive_forms_with_content() :
            siegel_coeffs[(n,r,m)] = maass_coeffs[(r**2 - 4*m*n, g)]

        ## Secondly, deal with the singular part.
        ## Include the coeff corresponding to (0,0,0):
        ## maass_coeffs = {(0,0): -bernoulli(k)/(2*k)*Cphi[0]}
        siegel_coeffs[(0,0,0)] = -bernoulli(k)/(2*k)*Cphi[0]
        if is_integral :
            siegel_coeffs[(0,0,0)] = Integer(siegel_coeffs[(0,0,0)])
        
        ## Calculate the other discriminant-zero maass coefficients.
        ## Since sigma is quite cheap it is faster to estimate the bound and
        ## save the time for repeated calculation
        for i in xrange(1, self.__precision._indefinite_content_bound()) :
            ## maass_coeffs[(0,i)] = sigma(i, k-1) * Cphi[0]
            siegel_coeffs[(0,0,i)] = sigma(i, k-1) * Cphi[0]

        return siegel_coeffs