Exemple #1
0
    def _I12(self, precision):
        Delta = ModularForms(1, 12).gen(0)
        assert Delta == ModularForms(1, 12).cuspidal_subspace().gen(0)

        return SiegelModularFormG2MaassLift(lambda p: Delta.qexp(p),
                                            0,
                                            precision,
                                            True,
                                            weight=12)
Exemple #2
0
def _theta_decomposition_indices(index, weight):
    r"""
    A list of possible indices of the echelon bases `M_k, S_{k+2}` etc. or `-1`
    if a component is zero." 
    """
    dims = [ ModularForms(1, weight).dimension()] + \
           [ ModularForms(1, weight + 2*i).dimension() - 1
             for i in xrange(1, index + 1) ]

    return [(i, j) for (i, d) in enumerate(dims) for j in xrange(d)]
Exemple #3
0
    def _I10(self, precision):
        # we use a standard generator, since its evaluation is much faster
        Delta = ModularForms(1, 12).gen(0)
        assert Delta == ModularForms(1, 12).cuspidal_subspace().gen(0)

        return SiegelModularFormG2MaassLift(0,
                                            lambda p: -(Delta.qexp(p)),
                                            precision,
                                            True,
                                            weight=10)
    def minimal_twist(self):
        r"""
        Return a newform (not necessarily unique) which is a twist of the
        original form `f` by a Dirichlet character of `p`-power conductor, and
        which has minimal level among such twists of `f`.

        An error will be raised if `f` is already minimal.

        EXAMPLES::

            sage: from sage.modular.local_comp.type_space import TypeSpace, example_type_space
            sage: T = example_type_space(1)
            sage: T.form().q_expansion(12)
            q - q^2 + 2*q^3 + q^4 - 2*q^6 - q^8 + q^9 + O(q^12)
            sage: g = T.minimal_twist()
            sage: g.q_expansion(12)
            q - q^2 - 2*q^3 + q^4 + 2*q^6 + q^7 - q^8 + q^9 + O(q^12)
            sage: g.level()
            14
            sage: TypeSpace(g, 7).is_minimal()
            True

        Test that :trac:`13158` is fixed::

            sage: f = Newforms(256,names='a')[0]
            sage: T = TypeSpace(f,2)
            sage: g = T.minimal_twist()
            sage: g[0:3]
            [0, 1, 0]
            sage: str(g[3]) in ('a', '-a', '-1/2*a', '1/2*a')
            True
            sage: g[4:]
            []
            sage: g.level()
            64
        """
        if self.is_minimal():
            raise ValueError("Form is already minimal")

        NN = self.form().level()
        V = self.t_space
        A = V.ambient()

        while not V.is_submodule(A.new_submodule()):
            NN = NN / self.prime()
            D1 = A.degeneracy_map(NN, 1)
            Dp = A.degeneracy_map(NN, self.prime())
            A = D1.codomain()
            vecs = [D1(v).element()
                    for v in V.basis()] + [Dp(v).element() for v in V.basis()]
            VV = A.free_module().submodule(vecs)
            V = A.submodule(VV, check=False)

        D = V.decomposition()[0]
        #if len(D.star_eigenvalues()) == 2:
        #    D = D.sign_submodule(1)
        D1 = D.modular_symbols_of_sign(1)
        M = ModularForms(D1.group(), D1.weight(), D1.base_ring())
        ff = Newform(M, D1, names='a')
        return ff
Exemple #5
0
    def maass_eisensteinseries(self, k):
        if not isinstance(k, (int, Integer)):
            raise TypeError, "k must be an integer"
        if k % 2 != 0 or k < 4:
            raise ValueError, "k must be even and greater than 4"

        return self.maass_form(
            ModularForms(1, k).eisenstein_subspace().gen(0), 0)
Exemple #6
0
    def _I6(self, precision):
        E6 = ModularForms(1, 6).gen(0)

        return SiegelModularFormG2MaassLift(lambda p: -84 * (E6.qexp(p)),
                                            0,
                                            precision,
                                            True,
                                            weight=6)
Exemple #7
0
    def _I4(self, precision):
        E4 = ModularForms(1, 4).gen(0)

        return SiegelModularFormG2MaassLift(lambda p: 60 * (E4.qexp(p)),
                                            0,
                                            precision,
                                            True,
                                            weight=4)
Exemple #8
0
    def _rank(self, K) :
        
        if K is QQ or K in NumberFields() :
            return len(_jacobi_forms_by_taylor_expansion_coords(self.__index, self.__weight, 0))

            ## This is the formula used by Poor and Yuen in Paramodular cusp forms
            if self.__weight == 2 :
                delta = len(self.__index.divisors()) // 2 - 1
            else :
                delta = 0
                
            return sum( ModularForms(1, self.__weight + 2 * j).dimension() + j**2 // (4 * self.__index)
                        for j in xrange(self.__index + 1) ) \
                   + delta
            

            ## This is the formula given by Skoruppa in 
            ## Jacobi forms of critical weight and Weil representations
            ##FIXME: There is some mistake here
            if self.__weight % 2 != 0 :
                ## Otherwise the space X(i**(n - 2 k)) is different
                ## See: Skoruppa, Jacobi forms of critical weight and Weil representations
                raise NotImplementedError
            
            m = self.__index
            K = CyclotomicField(24 * m, 'zeta')
            zeta = K.gen(0)
            
            quadform = lambda x : 6 * x**2
            bilinform = lambda x,y : quadform(x + y) - quadform(x) - quadform(y)
            
            T = diagonal_matrix([zeta**quadform(i) for i in xrange(2*m)])
            S =   sum(zeta**(-quadform(x)) for x in xrange(2 * m)) / (2 * m) \
                * matrix([[zeta**(-bilinform(j,i)) for j in xrange(2*m)] for i in xrange(2*m)])
            subspace_matrix_1 = matrix( [ [1 if j == i or j == 2*m - i else 0 for j in xrange(m + 1) ]
                                        for i in xrange(2*m)] )
            subspace_matrix_2 = zero_matrix(ZZ, m + 1, 2*m)
            subspace_matrix_2.set_block(0,0,identity_matrix(m+1))
            
            T = subspace_matrix_2 * T * subspace_matrix_1
            S = subspace_matrix_2 * S * subspace_matrix_1
            
            sqrt3 = (zeta**(4*m) - zeta**(-4*m)) * zeta**(-6*m) 
            rank =   (self.__weight - 1/2 - 1) / 2 * (m + 1) \
                   + 1/8 * (   zeta**(3*m * (2*self.__weight - 1)) * S.trace()
                             + zeta**(3*m * (1 - 2*self.__weight)) * S.trace().conjugate() ) \
                   + 2/(3*sqrt3) * (   zeta**(4 * m * self.__weight) * (S*T).trace()
                                     + zeta**(-4 * m * self.__weight) * (S*T).trace().conjugate() ) \
                   - sum((j**2 % (m+1))/(m+1) -1/2 for j in range(0,m+1))
            
            if self.__weight > 5 / 2 :
                return rank
            else :
                raise NotImplementedError
            
        raise NotImplementedError
    def __maass_lifts(self, k, precision, return_value) :
        r"""
        Return the Fourier expansion of all Maass forms of weight `k`.
        """
        result = []
        
        if k < 4 or k % 2 != 0 :
            return []
                
        mf = ModularForms(1,k).echelon_basis()
        cf = ModularForms(1,k + 2).echelon_basis()[1:]
        integrality_factor = 2*k * bernoulli(k).denominator()

        for c in [(integrality_factor * mf[0],0)] \
                     + [ (f,0) for f in mf[1:] ] + [ (0,g) for g in cf ] :
            if return_value == "lifts" :
                result.append(SiegelModularFormG2MaassLift(c[0],c[1], precision, True))
            else :
                result.append(c)
        
        return result
Exemple #10
0
def _all_weak_jacobi_forms_by_taylor_expansion(index, weight, precision):
    """
    TESTS:
    
    We compute the Fourier expansion of a Jacobi form of weight `4` and index `2`.  This
    is denoted by ``d``.  Moreover, we span the space of all Jacobi forms of weight `8` and
    index `2`.  Multiplying the weight `4` by the Eisenstein series of weight `4` must
    yield an element of the weight `8` space.  Note that the multiplication is done using
    a polynomial ring, since no native multiplication for Jacobi forms is implemented.
    
    ::
    
        sage: from psage.modform.jacobiforms.jacobiformd1nn_fourierexpansion import *
        sage: from psage.modform.jacobiforms.jacobiformd1nn_fegenerators import _all_weak_jacobi_forms_by_taylor_expansion
        sage: from psage.modform.fourier_expansion_framework import *
        sage: prec = 20
        sage: d = JacobiFormD1NNFilter(prec, 2)
        sage: f = _all_weak_jacobi_forms_by_taylor_expansion(2, 4, prec)[0]
        sage: (g1,g2) = tuple(_all_weak_jacobi_forms_by_taylor_expansion(2, 8, prec))
        sage: em = ExpansionModule([g1, g2])
        sage: P.<q, zeta> = PolynomialRing(QQ, 2)
        sage: fp = sum(f[k] * q**k[0] * zeta**k[1] for k in JacobiFormD1NNFilter(prec, 2, reduced = False))
        sage: mf4 = ModularForms(1, 4).0.qexp(prec).polynomial()
        sage: h = mf4 * fp
        sage: eh = EquivariantMonoidPowerSeries(g1.parent(), {g1.parent().characters().gen(0) : dict((k, h[k[0],k[1]]) for k in d)}, d)
        sage: em.coordinates(eh.truncate(5), in_base_ring = False)
        [7/66, 4480]
        
    According to this we express ``eh`` in terms of the basis of the weight `8` space.
    
    ::
    
        sage: neh = eh - em.0.fourier_expansion() * 7 / 66 - em.1.fourier_expansion() * 4480
        sage: neh.coefficients()
        {(18, 0): 0, (12, 1): 0, (9, 1): 0, (3, 0): 0, (11, 2): 0, (8, 0): 0, (16, 2): 0, (2, 1): 0, (15, 1): 0, (6, 2): 0, (14, 0): 0, (19, 0): 0, (5, 1): 0, (7, 2): 0, (4, 0): 0, (1, 2): 0, (12, 2): 0, (9, 0): 0, (8, 1): 0, (18, 2): 0, (15, 0): 0, (17, 2): 0, (14, 1): 0, (11, 1): 0, (18, 1): 0, (5, 0): 0, (2, 2): 0, (10, 0): 0, (4, 1): 0, (1, 1): 0, (3, 2): 0, (0, 0): 0, (13, 2): 0, (8, 2): 0, (7, 1): 0, (6, 0): 0, (17, 1): 0, (11, 0): 0, (19, 2): 0, (16, 0): 0, (10, 1): 0, (4, 2): 0, (1, 0): 0, (14, 2): 0, (0, 1): 0, (13, 1): 0, (7, 0): 0, (15, 2): 0, (12, 0): 0, (9, 2): 0, (6, 1): 0, (3, 1): 0, (16, 1): 0, (2, 0): 0, (19, 1): 0, (5, 2): 0, (17, 0): 0, (13, 0): 0, (10, 2): 0}
    """
    modular_form_bases = \
      [ ModularForms(1, weight + 2*i) \
          .echelon_basis()[(0 if i == 0 else 1):]
        for i in xrange(index + 1) ]

    factory = JacobiFormD1NNFactory(precision, index)

    return [
        weak_jacbi_form_by_taylor_expansion(
            i * [0] + [modular_form_bases[i][j]] + (index - i) * [0],
            precision,
            True,
            weight=weight,
            factory=factory)
        for (i, j) in _theta_decomposition_indices(index, weight)
    ]
Exemple #11
0
    def _test__by_taylor_expansion(q_precision, weight, jacobi_index):
        r"""
        Run tests that validate by_taylor_expansions for various indices and weights.
        
        TESTS::
            
            sage: from psage.modform.jacobiforms.jacobiformd1nn_fegenerators import *
            sage: JacobiFormD1NNFactory_class._test__by_taylor_expansion(100, 10, 2)
            sage: JacobiFormD1NNFactory_class._test__by_taylor_expansion(20, 11, 2)
            sage: JacobiFormD1NNFactory_class._test__by_taylor_expansion(50, 9, 3)      # long time 
            sage: JacobiFormD1NNFactory_class._test__by_taylor_expansion(50, 10, 10)    # long time
            sage: JacobiFormD1NNFactory_class._test__by_taylor_expansion(30, 7, 15)     # long time  
        """
        from sage.rings import big_oh

        prec = JacobiFormD1NNFilter(q_precision, jacobi_index)
        factory = JacobiFormD1NNFactory(prec)
        R = PowerSeriesRing(ZZ, 'q')
        q = R.gen(0)

        if weight % 2 == 0:
            nmb_modular_forms = jacobi_index + 1
            start_weight = weight
        else:
            nmb_modular_forms = jacobi_index - 1
            start_weight = weight + 1

        modular_forms = list()
        for (i, k) in enumerate(
                range(start_weight, start_weight + 2 * nmb_modular_forms, 2)):
            modular_forms += [[lambda p: big_oh.O(q**p)
                               for _ in range(i)] + [b.qexp] + [
                                   lambda p: big_oh.O(q**p)
                                   for _ in range(nmb_modular_forms - 1 - i)
                               ] for b in ModularForms(1, k).echelon_basis()]

        for (fs_index, fs) in enumerate(modular_forms):
            expansion = factory.by_taylor_expansion(fs, weight, True)
            taylor_coefficients = JacobiFormD1NNFactory_class._test__jacobi_taylor_coefficients(
                expansion, weight, prec)
            predicted_taylor_coefficients = JacobiFormD1NNFactory_class._test__jacobi_predicted_taylor_coefficients(
                fs, q_precision)

            for (i, (proj, f)) in enumerate(
                    zip(taylor_coefficients, predicted_taylor_coefficients)):
                if f != proj:
                    raise AssertionError(
                        "{0}-th Taylor coefficient of the {1}-th Jacobi form is not correct. Expansions are\n  {2}\nand\n {3}"
                        .format(i, fs_index, proj, f))
Exemple #12
0
def _all_weak_taylor_coefficients(weight, index):
    r"""
    A product basis of the echelon bases of 
    
    - `M_k, M_{k + 2}, ..., M_{k + 2 m}` etc. if ``weight`` is even,
    
    - `M_{k + 1}, ..., M_{k + 2 m - 3}` if ``weight`` is odd.
    
    INPUT:
    
    - ``weight`` -- An integer.
    
    - ``index`` -- A non-negative integer.
    
    TESTS::
    
        sage: from psage.modform.jacobiforms.jacobiformd1nn_fegenerators import _all_weak_taylor_coefficients
        sage: _all_weak_taylor_coefficients(12, 1)
        [[<bound method ModularFormElement.qexp of 1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + O(q^6)>, <function <lambda> at ...>], [<bound method ModularFormElement.qexp of q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)>, <function <lambda> at ...>], [<function <lambda> at ...>, <bound method ModularFormElement.qexp of 1 - 24*q - 196632*q^2 - 38263776*q^3 - 1610809368*q^4 - 29296875024*q^5 + O(q^6)>]]
    """
    R = PowerSeriesRing(ZZ, 'q')
    q = R.gen()

    if weight % 2 == 0:
        nmb_modular_forms = index + 1
        start_weight = weight
    else:
        nmb_modular_forms = index - 1
        start_weight = weight + 1

    modular_forms = list()
    for (i, k) in enumerate(
            range(start_weight, start_weight + 2 * nmb_modular_forms, 2)):
        modular_forms += [[lambda p: big_oh.O(q**p)
                           for _ in range(i)] + [b.qexp] + [
                               lambda p: big_oh.O(q**p)
                               for _ in range(nmb_modular_forms - 1 - i)
                           ] for b in ModularForms(1, k).echelon_basis()]

    return modular_forms
    def _D_3_eisensteinseries(self, i):
        """
        Here we calculate the needed vector valued Eisenstein series of weights 3
        and 5 up to precision self._qexp_precision().
        The components of these Eisensteinseries are elliptic modular forms with
        respect to `\Gamma_1(36)` and `\Gamma(6)`, respectively. More precisely
        they lie in the subspace of Eisenstein series.
        
        INPUT:
            - i -- Integer; The parameter 0 returns the weight 3 case, 1 the weight 5 case. 
        
        OUTPUT:
            - Element of self.integral_power_series_ring().
        
        NOTE:
            With the help of some calculated Fourier coefficients it is hence possible
            to represent the components as linear combinations of elliptic modular
            forms, which is faster than calculating them directly via certain other
            formulas.

        TESTS::
            sage: fac = HermitianModularFormD2Factory(2,-3)
            sage: fac._D_3_eisensteinseries(0)
            {(1, 0): 27*q^4 + 216*q^10 + 459*q^16 + O(q^19), (0, 0): 1 + 72*q^6 + 270*q^12 + 720*q^18 + O(q^24), (-1, 0): 27*q^4 + 216*q^10 + 459*q^16 + O(q^19)}
            sage: fac._D_3_eisensteinseries(1)
            {(1, 0): -45*q^4 - 1872*q^10 - 11565*q^16 + O(q^19), (0, 0): 1 - 240*q^6 - 3690*q^12 - 19680*q^18 + O(q^24), (-1, 0): -45*q^4 - 1872*q^10 - 11565*q^16 + O(q^19)}
            sage: fac._D_3_eisensteinseries(2)
            Traceback (most recent call last):
            ...
            NotImplementedError: Only weight 3 and 5 implemented. Parameter i should be 0 or 1.
        """
        R = self.integral_power_series_ring()
        q = R.gen(0)

        # weight 3 case
        if i == 0:
            # the factors for the linear combinations were calculated by comparing
            # sufficiently many Fourier coefficients
            linear_combination_factors = ((1, 72, 270, 720, 936, 2160, 2214,
                                           3600, 4590, 6552, 5184, 10800, 9360,
                                           12240, 13500, 17712, 14760, 25920,
                                           19710, 26064, 28080, 36000, 25920,
                                           47520, 37638, 43272, 45900, 59040,
                                           46800, 75600, 51840, 69264, 73710,
                                           88560, 62208, 108000, 85176, 97740,
                                           122400, 88128),
                                          (0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 216,
                                           0, 0, 0, 0, 0, 459, 0, 0, 0, 0, 0,
                                           1080, 0, 0, 0, 0, 0, 1350, 0, 0, 0,
                                           0, 0, 2592, 0, 0, 0, 0, 2808))
            echelon_basis_eisenstein_subspace_gamma_6_weight_3 = \
                          ModularForms(Gamma1(36),3).eisenstein_subspace() \
                            .q_echelon_basis(6*(self._qexp_precision() - 1) + 1)
            echelon_basis_eisenstein_subspace_gamma1_36_weight_3 = \
                          ModularForms(Gamma1(36),3).eisenstein_subspace() \
                            .q_echelon_basis(self._qexp_precision())

            e1 = R(
                sum(
                    map(operator.mul, linear_combination_factors[0],
                        echelon_basis_eisenstein_subspace_gamma1_36_weight_3)))
            e1 = e1.subs({q: q**6})
            e2 = R(
                sum(
                    map(operator.mul, linear_combination_factors[1],
                        echelon_basis_eisenstein_subspace_gamma_6_weight_3)))

            return {(0, 0): e1, (1, 0): e2, (-1, 0): e2}
        # weight 5 case
        elif i == 1:
            # the factors for the linear combinations were calculated by comparing sufficiently
            # many Fourier coefficients
            linear_combination_factors = (
                (1, -240, -3690, -19680, -57840, -153504, -295290, -576480,
                 -948330, -1594320, -2246400, -3601440, -4742880, -6854880,
                 -8863380, -12284064, -14803440, -20545920, -23914890,
                 -31277280, -36994464, -47271360, -52704000, -68840640,
                 -75889530, -93600240, -105393780, -129140160, -138931680,
                 -173990880, -184204800, -221645280, -242776170, -288203040,
                 -300672000, -368716608, -384231120, -480888180, -562100160,
                 -577324800),
                (0, 0, 0, 0, -45, 0, 0, 0, 0, 0, -1872, 0, 0, 0, 0, 0, -11565,
                 0, 0, 0, 0, 0, -43920, 0, 0, 0, 0, 0, -108090, 0, 0, 0, 0, 0,
                 -250560, 0, 0, 0, 0, -451152))
            echelon_basis_eisenstein_subspace_gamma_6_weight_5 = \
                          ModularForms(Gamma1(36),5).eisenstein_subspace() \
                            .q_echelon_basis(6*(self._qexp_precision() - 1)  + 1)
            echelon_basis_eisenstein_subspace_gamma1_36_weight_5 = \
                          ModularForms(Gamma1(36),5).eisenstein_subspace() \
                            .q_echelon_basis(self._qexp_precision())

            e1 = R(
                sum(
                    map(operator.mul, linear_combination_factors[0],
                        echelon_basis_eisenstein_subspace_gamma1_36_weight_5)))
            e1 = e1.subs({q: q**6})
            e2 = R(
                sum(
                    map(operator.mul, linear_combination_factors[1],
                        echelon_basis_eisenstein_subspace_gamma_6_weight_5)))

            return {(0, 0): e1, (1, 0): e2, (-1, 0): e2}
        else:
            raise NotImplementedError( "Only weight 3 and 5 implemented. " + \
                                       "Parameter i should be 0 or 1." )
def product_space(chi, k, weights=False, base_ring=None, verbose=False):
    r"""
    Computes all eisenstein series, and products of pairs of eisenstein series
    of lower weight, lying in the space of modular forms of weight $k$ and
    nebentypus $\chi$.
    INPUT:
     - chi - Dirichlet character, the nebentypus of the target space
     - k - an integer, the weight of the target space
    OUTPUT:
     - a matrix of coefficients of q-expansions, which are the products of
     Eisenstein series in M_k(chi).

    WARNING: It is only for principal chi that we know that the resulting
    space is the whole space of modular forms.
    """

    if weights == False:
        weights = srange(1, k / 2 + 1)
    weight_dict = {}
    weight_dict[-1] = [w for w in weights if w % 2]  # Odd weights
    weight_dict[1] = [w for w in weights if not w % 2]  # Even weights

    try:
        N = chi.modulus()
    except AttributeError:
        if chi.parent() == ZZ:
            N = chi
            chi = DirichletGroup(N)[0]

    Id = DirichletGroup(1)[0]
    if chi(-1) != (-1)**k:
        raise ValueError('chi(-1)!=(-1)^k')
    sturm = ModularForms(N, k).sturm_bound() + 1
    if N > 1:
        target_dim = dimension_modular_forms(chi, k)
    else:
        target_dim = dimension_modular_forms(1, k)
    D = DirichletGroup(N)
    # product_space should ideally be called over number fields. Over complex
    # numbers the exact linear algebra solutions might not exist.
    if base_ring == None:
        base_ring = CyclotomicField(euler_phi(N))

    Q = PowerSeriesRing(base_ring, 'q')
    q = Q.gen()

    d = len(D)
    prim_chars = [phi.primitive_character() for phi in D]
    divs = divisors(N)

    products = Matrix(base_ring, [])
    indexlist = []
    rank = 0
    if verbose:
        print(D)
        print('Sturm bound', sturm)
        #TODO: target_dim needs refinment in the case of weight 2.
        print('Target dimension', target_dim)
    for i in srange(0, d):  # First character
        phi = prim_chars[i]
        M1 = phi.conductor()
        for j in srange(0, d):  # Second character
            psi = prim_chars[j]
            M2 = psi.conductor()
            if not M1 * M2 in divs:
                continue
            parity = psi(-1) * phi(-1)
            for t1 in divs:
                if not M1 * M2 * t1 in divs:
                    continue
                #TODO: THE NEXT CONDITION NEEDS TO BE CORRECTED. THIS IS JUST A TEST
                if phi.bar() == psi and not (
                        k == 2):  #and i==0 and j==0 and t1==1):
                    E = eisenstein_series_at_inf(phi, psi, k, sturm, t1,
                                                 base_ring).padded_list()
                    try:
                        products.T.solve_right(vector(base_ring, E))
                    except ValueError:
                        products = Matrix(products.rows() + [E])
                        indexlist.append([k, i, j, t1])
                        rank += 1
                        if verbose:
                            print('Added ', [k, i, j, t1])
                            print('Rank is now', rank)
                        if rank == target_dim:
                            return products, indexlist
                for t in divs:
                    if not M1 * M2 * t1 * t in divs:
                        continue
                    for t2 in divs:
                        if not M1 * M2 * t1 * t2 * t in divs:
                            continue
                        for l in weight_dict[parity]:
                            if l == 1 and phi.is_odd():
                                continue
                            if i == 0 and j == 0 and (l == 2 or l == k - 2):
                                continue
                            #TODO: THE NEXT CONDITION NEEDS TO BE REMOVED. THIS IS JUST A TEST
                            if l == 2 or l == k - 2:
                                continue
                            E1 = eisenstein_series_at_inf(
                                phi, psi, l, sturm, t1 * t, base_ring)
                            E2 = eisenstein_series_at_inf(
                                phi**(-1), psi**(-1), k - l, sturm, t2 * t,
                                base_ring)
                            #If chi is non-principal this needs to be changed to be something like chi*phi^(-1) instead of phi^(-1)
                            E = (E1 * E2 + O(q**sturm)).padded_list()
                            try:
                                products.T.solve_right(vector(base_ring, E))
                            except ValueError:
                                products = Matrix(products.rows() + [E])
                                indexlist.append([l, k - l, i, j, t1, t2, t])
                                rank += 1
                                if verbose:
                                    print('Added ',
                                          [l, k - l, i, j, t1, t2, t])
                                    print('Rank', rank)
                                if rank == target_dim:
                                    return products, indexlist
    return products, indexlist