示例#1
0
 def _action2(self,A):
     [a,b,c,d]=A
     fak=1
     if c<0:
         a=-a; b=-b; c=-c;  d=-d; fak=-self._fak
     if c==0:
         if a>0:
             res = self._z**b
         else:
             res = self._fak*self._z**b
     else:
         arg = dedekind_sum(-d,c)
         arg = arg+QQ(a+d)/QQ(12*c)-QQ(1)/QQ(4)
         # print "arg=",arg
         arg=arg*QQ(2)
         den = arg.denominator()*self._k_den
         num = arg.numerator()*self._k_num
         K = CyclotomicField(2*den)
         z=K.gen()
         if z.multiplicative_order()>4:
             fak=K(fak)
             # z = CyclotomicField(2*arg.denominator()).gen()
         res = z**num #rg.numerator()
         if self._character:
             ch = self._character(d)
             res=res*ch
         res = res*fak
     if self._is_dual:
         return res**-1
     return res
示例#2
0
 def _action2(self, A):
     [a, b, c, d] = A
     fak = 1
     if c < 0:
         a = -a
         b = -b
         c = -c
         d = -d
         fak = -self._fak
     if c == 0:
         if a > 0:
             res = self._z**b
         else:
             res = self._fak * self._z**b
     else:
         arg = dedekind_sum(-d, c)
         arg = arg + QQ(a + d) / QQ(12 * c) - QQ(1) / QQ(4)
         # print "arg=",arg
         arg = arg * QQ(2)
         den = arg.denominator() * self._k_den
         num = arg.numerator() * self._k_num
         K = CyclotomicField(2 * den)
         z = K.gen()
         if z.multiplicative_order() > 4:
             fak = K(fak)
             # z = CyclotomicField(2*arg.denominator()).gen()
         res = z**num  #rg.numerator()
         if self._character:
             ch = self._character(d)
             res = res * ch
         res = res * fak
     if self._is_dual:
         return res**-1
     return res
示例#3
0
def power_charpoly(f, k):
    r""""
    INPUT:

    - ``f`` -- the characteristic polynomial of a linear transformation

    OUTPUT: the characteristic polynomial of the kth power of the linear transformation

    """
    K = CyclotomicField(k)
    R = f.base_ring()
    RT = f.parent()
    f = f.change_ring(K)
    T = f.parent().gen()
    a = K.gen()
    g = 1
    for i in range(k):
        g *= f(a**i * T)
    glist = g.list()
    newf = [None] * (1 + f.degree())
    for i, ci in enumerate(glist):
        if i % k != 0:
            assert ci == 0, "i = %s, ci = %s" % (i, ci)
        else:
            newf[i / k] = R(ci)
    return RT(newf)
示例#4
0
class TestMultiplier(MultiplierSystem):
    r"""
    Test of multiplier for f(q). As in e.g. the paper of Bringmann and Ono.
    """
    def __init__(self,group,dchar=(0,0),dual=False,weight=QQ(1)/QQ(2),dimension=1,version=1,**kwargs):
        self._weight=QQ(weight)
        MultiplierSystem.__init__(self,group,dchar=dchar,dual=dual,dimension=dimension,**kwargs)
        self._k_den=self._weight.denominator()
        self._k_num=self._weight.numerator()
        self._K = CyclotomicField(12*self._k_den)
        self._z = self._K.gen()**self._k_num
        self._sqrti = CyclotomicField(8).gen()
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num
        self._fak_arg=QQ(self._weight)/QQ(2)
        self._version = version
        self.is_consistent(weight) # test consistency


    def order(self):
        return 12*self._k_den

    def z(self):
        return self._z

    def __repr__(self):
        s="Test multiplier"
        if self._character<>None and not self._character.is_trivial():
            s+="and character "+str(self._character)
        return s


        
    def _action(self,A):
        [a,b,c,d]=A
        fak=0
        if c<0:
            a=-a; b=-b; c=-c;  d=-d; fak=self._fak_arg
        if c==0:
            if a>0:
                res = self._z**-b
            else:
                res = self._fak*self._z**-b
        else:
            arg=-QQ(1)/QQ(8)+QQ(c+a*d+1)/QQ(4)-QQ(a+d)/QQ(24*c)-QQ(a)/QQ(4)+QQ(3*d*c)/QQ(8)
            # print "arg=",arg
            arg = arg-dedekind_sum(-d,c)/QQ(2)+fak #self._fak_arg
            den=arg.denominator()
            num=arg.numerator()
            # print "den=",den
            # print  "num=",num
            res = self._K(CyclotomicField(den).gen())**num
            #res = res*fak
        if self._is_dual:
            return res**-1
        return res
class TestMultiplier(MultiplierSystem):
    r"""
    Test of multiplier for f(q). As in e.g. the paper of Bringmann and Ono.
    """
    def __init__(self,group,dchar=(0,0),dual=False,weight=QQ(1)/QQ(2),dimension=1,version=1,**kwargs):
        self._weight=QQ(weight)
        MultiplierSystem.__init__(self,group,dchar=dchar,dual=dual,dimension=dimension,**kwargs)
        self._k_den=self._weight.denominator()
        self._k_num=self._weight.numerator()
        self._K = CyclotomicField(12*self._k_den)
        self._z = self._K.gen()**self._k_num
        self._sqrti = CyclotomicField(8).gen()
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num
        self._fak_arg=QQ(self._weight)/QQ(2)
        self._version = version
        self.is_consistent(weight) # test consistency


    def order(self):
        return 12*self._k_den

    def z(self):
        return self._z

    def __repr__(self):
        s="Test multiplier"
        if self._character<>None and not self._character.is_trivial():
            s+="and character "+str(self._character)
        return s


        
    def _action(self,A):
        [a,b,c,d]=A
        fak=0
        if c<0:
            a=-a; b=-b; c=-c;  d=-d; fak=self._fak_arg
        if c==0:
            if a>0:
                res = self._z**-b
            else:
                res = self._fak*self._z**-b
        else:
            arg=-QQ(1)/QQ(8)+QQ(c+a*d+1)/QQ(4)-QQ(a+d)/QQ(24*c)-QQ(a)/QQ(4)+QQ(3*d*c)/QQ(8)
            # print "arg=",arg
            arg = arg-dedekind_sum(-d,c)/QQ(2)+fak #self._fak_arg
            den=arg.denominator()
            num=arg.numerator()
            # print "den=",den
            # print  "num=",num
            res = self._K(CyclotomicField(den).gen())**num
            #res = res*fak
        if self._is_dual:
            return res**-1
        return res
示例#6
0
def induced_rep_from_twisted_cocycle(p, rho, chi, cocycle):
    """
    The main metabelian representation from Section 7 of [HKL] for the
    group of a knot complement, where p is the degree of the branched
    cover, rho is an irreducible cyclic representation acting on the
    F_q vector space V, chi is a homomorpism V -> F_q, and cocycle
    describes the semidirect product extension.

    We differ from [HKL] in that all actions are on the left, meaning
    that this representation is defined in terms of the convention for the
    semidirect product discussed in::

      MatrixRepresentation.semidirect_rep_from_twisted_cocycle

    Here is an example::

       sage: G = Manifold('K12n132').fundamental_group()
       sage: A = matrix(GF(5), [[0, 4], [1, 4]])
       sage: rho = cyclic_rep(G, A)
       sage: cocycle = (0, 0, 0, 1, 1, 2)
       sage: chi = lambda v: v[0] + 4*v[1]
       sage: rho_ind = induced_rep_from_twisted_cocycle(3, rho, chi, cocycle)
       sage: rho_ind('c').list()
       [0, 0, (-z^3 - z^2 - z - 1), z^2*t^-1, 0, 0, 0, (-z^3 - z^2 - z - 1)*t^-1, 0]
    """
    q = rho.base_ring.order()
    n = rho.dim
    K = CyclotomicField(q, 'z')
    z = K.gen()
    A = rho.A
    R = LaurentPolynomialRing(K, 't')
    t = R.gen()
    MatSp = MatrixSpace(R, p)
    gens = rho.generators
    images = dict()
    for s, g in enumerate(gens):
        v = vector(cocycle[s * n:(s + 1) * n])
        e = rho.epsilon(g)[0]
        U = MatSp(0)
        for j in range(0, p):
            k, l = (e + j).quo_rem(p)
            U[l, j] = t**k * z**chi(A**(-l) * v)
        images[g] = U

        e, v = -e, -A**(-e) * v
        V = MatSp(0)
        for j in range(0, p):
            k, l = (e + j).quo_rem(p)
            V[l, j] = t**k * z**chi(A**(-l) * v)
        images[g.swapcase()] = V

    alpha = MatrixRepresentation(gens, rho.relators, MatSp, images)
    alpha.epsilon = rho.epsilon
    return alpha
示例#7
0
class EtaQuotientMultiplier(MultiplierSystem):
    r"""
    Eta multiplier given by eta(Az)^{r}/eta(Bz)^s
    The weight should be r/2-s/2 mod 2.
    The group is Gamma0(lcm(A,B))
    """
    def __init__(self,A,B,r,s,k=None,number=0,ch=None,dual=False,version=1,**kwargs):
        r"""
        Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$.
        INPUT:

        - G -- Group
        - ch -- character
        - dual -- if we have the dual (in this case conjugate)
        - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly.
        - number -- we consider eta^power (here power should be an integer so as not to change the weight...)

        EXAMPLE:
        
                
        """
        self._level=lcm(A,B)
        G = Gamma0(self._level)
        if k==None:
            k = (QQ(r)-QQ(s))/QQ(2)
        self._weight=QQ(k)
        if floor(self._weight-QQ(1)/QQ(2))==ceil(self._weight-QQ(1)/QQ(2)):
            self._half_integral_weight=1
        else:
            self._half_integral_weight=0
        MultiplierSystem.__init__(self,G,dimension=1,character=ch,dual=dual)
        number = number % 12
        if not is_even(number):
            raise ValueError,"Need to have v_eta^(2(k+r)) with r even!"
        self._arg_num = A
        self._arg_den = B
        self._exp_num = r
        self._exp_den = s
        self._pow=QQ((self._weight+number)) ## k+r
        self._k_den=self._pow.denominator()
        self._k_num=self._pow.numerator()
        self._K = CyclotomicField(12*self._k_den)
        self._z = self._K.gen()**self._k_num
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num
        self._version = version
        self.is_consistent(k) # test consistency

    def __repr__(self):
        s="Quotient of Eta multipliers :  "
        s+="eta({0})^{1}/eta({2})^{3}".format(self._arg_num,self._exp_num,self._arg_den,self._exp_den)
        if self._character<>None and not self._character.is_trivial():
            s+=" and character "+str(self._character)
        s+=" with weight="+str(self._weight)
        return s

    def level(self):
        return self._level
        
    def order(self):
        return 12*self._k_den

    def z(self):
        return self._z

    def q_shift(self):
        r"""
        Gives the 'shift' at the cusp at infinity of the q-series.
        The 'true' q-expansion of the eta quotient is then q^shift*q_expansion
        """
        num =  self._arg_num*self._exp_num-self._arg_den*self._exp_den
        return QQ(num)/QQ(24)
    
    def q_expansion(self,n=20):
        r"""
        Give the q-expansion of the quotient.
        """
        var('q')
        et = qexp_eta(ZZ[['q']],n)
        etA= et.subs(q=q**self._arg_num).power_series(ZZ[['q']])
        etB= et.subs(q=q**self._arg_den).power_series(ZZ[['q']])
        res = etA**(self._exp_num)/etB**(self._exp_den)
        return res
    #def _action(self,A):
    #    return self._action(A)
        
    def _action(self,A):
        [a,b,c,d]=A
        if not c % self._level == 0 :
            raise ValueError,"Need A in {0}! Got: {1}".format(self.group,A)
        fak=1
        if c<0:
            a=-a; b=-b; c=-c;  d=-d; fak=-self._fak
            #fak = fak*(-1)**(self._exp_num-self._exp_den)
        arg1,v1 = eta_conjugated(a,b,c,d,self._arg_num)
        arg2,v2 = eta_conjugated(a,b,c,d,self._arg_den)
        res=self._z**(arg1*self._exp_num-arg2*self._exp_den)
        if v1<>1:
            res=res*v1**self._exp_num
        if v2<>1:
            res=res/v2**self._exp_den
        if fak<>1:
            res=res*fak**(self._exp_num-self._exp_den)
        return res
示例#8
0
class EtaMultiplier(MultiplierSystem):
    r"""
    Eta multiplier. Valid for any (real) weight.
    """
    def __init__(self,G,k=QQ(1)/QQ(2),number=0,ch=None,dual=False,version=1,dimension=1,**kwargs):
        r"""
        Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$.
        INPUT:

        - G -- Group
        - ch -- character
        - dual -- if we have the dual (in this case conjugate)
        - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly.
        - number -- we consider eta^power (here power should be an integer so as not to change the weight...)
                
        """
        self._weight=QQ(k)
        if floor(self._weight-QQ(1)/QQ(2))==ceil(self._weight-QQ(1)/QQ(2)):
            self._half_integral_weight=1
        else:
            self._half_integral_weight=0
        MultiplierSystem.__init__(self,G,character=ch,dual=dual,dimension=dimension)
        number = number % 12
        if not is_even(number):
            raise ValueError,"Need to have v_eta^(2(k+r)) with r even!"
        self._pow=QQ((self._weight+number)) ## k+r
        self._k_den=self._pow.denominator()
        self._k_num=self._pow.numerator()
        self._K = CyclotomicField(12*self._k_den)
        self._z = self._K.gen()**self._k_num
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num
        self._version = version
        
        self.is_consistent(k) # test consistency

    def __repr__(self):
        s="Eta multiplier "
        if self._pow<>1:
            s+="to power 2*"+str(self._pow)+" "
        if self._character<>None and not self._character.is_trivial():
            s+=" and character "+str(self._character)
        s+="with weight="+str(self._weight)
        return s
        
    def order(self):
        return 12*self._k_den

    def z(self):
        return self._z
    
     
    def _action(self,A):
        if self._version==1:
            return self._action1(A)
        elif self._version==2:
            return self._action2(A)
        else:
            raise ValueError

    def _action1(self,A):
        [a,b,c,d]=A
        return self._action0(a,b,c,d)
    def _action0(self,a,b,c,d):
        r"""
        Recall that the formula is valid only for c>0. Otherwise we have to use:
        v(A)=v((-I)(-A))=sigma(-I,-A)v(-I)v(-A).
        Then note that by the formula for sigma we have:
        sigma(-I,SL2Z[a, b, c, d])=-1 if (c=0 and d<0) or c>0 and other wise it is =1.
        """

        fak=1
        if c<0:
            a=-a; b=-b; c=-c;  d=-d; fak=-self._fak
        if c==0:
            if a>0:
                res = self._z**b
            else:
                res = self._fak*self._z**b
        else:
            if is_even(c):
                arg = (a+d)*c-b*d*(c*c-1)+3*d-3-3*c*d
                v=kronecker(c,d)
            else:
                arg = (a+d)*c-b*d*(c*c-1)-3*c
                v=kronecker(d,c)
            if not self._half_integral_weight:
                # recall that we can use eta for any real weight
                v=v**(2*self._weight)
            arg=arg*(self._k_num)
            res = v*fak*self._z**arg
            if self._character:
                res = res * self._character(d)
        if self._is_dual:
            res=res**-1
        return res


    def _action2(self,A):
        [a,b,c,d]=A
        fak=1
        if c<0:
            a=-a; b=-b; c=-c;  d=-d; fak=-self._fak
        if c==0:
            if a>0:
                res = self._z**b
            else:
                res = self._fak*self._z**b
        else:
            arg = dedekind_sum(-d,c)
            arg = arg+QQ(a+d)/QQ(12*c)-QQ(1)/QQ(4)
            # print "arg=",arg
            arg=arg*QQ(2)
            den = arg.denominator()*self._k_den
            num = arg.numerator()*self._k_num
            K = CyclotomicField(2*den)
            z=K.gen()
            if z.multiplicative_order()>4:
                fak=K(fak)
                # z = CyclotomicField(2*arg.denominator()).gen()
            res = z**num #rg.numerator()
            if self._character:
                ch = self._character(d)
                res=res*ch
            res = res*fak
        if self._is_dual:
            return res**-1
        return res
示例#9
0
class EtaMultiplier(MultiplierSystem):
    r"""
    Eta multiplier. Valid for any (real) weight.
    """
    def __init__(self,
                 G,
                 k=QQ(1) / QQ(2),
                 number=0,
                 ch=None,
                 dual=False,
                 version=1,
                 dimension=1,
                 **kwargs):
        r"""
        Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$.
        INPUT:

        - G -- Group
        - ch -- character
        - dual -- if we have the dual (in this case conjugate)
        - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly.
        - number -- we consider eta^power (here power should be an integer so as not to change the weight...)
                
        """
        self._weight = QQ(k)
        if floor(self._weight - QQ(1) / QQ(2)) == ceil(self._weight -
                                                       QQ(1) / QQ(2)):
            self._half_integral_weight = 1
        else:
            self._half_integral_weight = 0
        MultiplierSystem.__init__(self,
                                  G,
                                  character=ch,
                                  dual=dual,
                                  dimension=dimension)
        number = number % 12
        if not is_even(number):
            raise ValueError("Need to have v_eta^(2(k+r)) with r even!")
        self._pow = QQ((self._weight + number))  ## k+r
        self._k_den = self._pow.denominator()
        self._k_num = self._pow.numerator()
        self._K = CyclotomicField(12 * self._k_den)
        self._z = self._K.gen()**self._k_num
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2 * self._k_den).gen()**-self._k_num
        self._version = version

        self.is_consistent(k)  # test consistency

    def __repr__(self):
        s = "Eta multiplier "
        if self._pow != 1:
            s += "to power 2*" + str(self._pow) + " "
        if self._character != None and not self._character.is_trivial():
            s += " and character " + str(self._character)
        s += "with weight=" + str(self._weight)
        return s

    def order(self):
        return 12 * self._k_den

    def z(self):
        return self._z

    def _action(self, A):
        if self._version == 1:
            return self._action1(A)
        elif self._version == 2:
            return self._action2(A)
        else:
            raise ValueError

    def _action1(self, A):
        [a, b, c, d] = A
        return self._action0(a, b, c, d)

    def _action0(self, a, b, c, d):
        r"""
        Recall that the formula is valid only for c>0. Otherwise we have to use:
        v(A)=v((-I)(-A))=sigma(-I,-A)v(-I)v(-A).
        Then note that by the formula for sigma we have:
        sigma(-I,SL2Z[a, b, c, d])=-1 if (c=0 and d<0) or c>0 and other wise it is =1.
        """

        fak = 1
        if c < 0:
            a = -a
            b = -b
            c = -c
            d = -d
            fak = -self._fak
        if c == 0:
            if a > 0:
                res = self._z**b
            else:
                res = self._fak * self._z**b
        else:
            if is_even(c):
                arg = (a + d) * c - b * d * (c * c - 1) + 3 * d - 3 - 3 * c * d
                v = kronecker(c, d)
            else:
                arg = (a + d) * c - b * d * (c * c - 1) - 3 * c
                v = kronecker(d, c)
            if not self._half_integral_weight:
                # recall that we can use eta for any real weight
                v = v**(2 * self._weight)
            arg = arg * (self._k_num)
            res = v * fak * self._z**arg
            if self._character:
                res = res * self._character(d)
        if self._is_dual:
            res = res**-1
        return res

    def _action2(self, A):
        [a, b, c, d] = A
        fak = 1
        if c < 0:
            a = -a
            b = -b
            c = -c
            d = -d
            fak = -self._fak
        if c == 0:
            if a > 0:
                res = self._z**b
            else:
                res = self._fak * self._z**b
        else:
            arg = dedekind_sum(-d, c)
            arg = arg + QQ(a + d) / QQ(12 * c) - QQ(1) / QQ(4)
            # print "arg=",arg
            arg = arg * QQ(2)
            den = arg.denominator() * self._k_den
            num = arg.numerator() * self._k_num
            K = CyclotomicField(2 * den)
            z = K.gen()
            if z.multiplicative_order() > 4:
                fak = K(fak)
                # z = CyclotomicField(2*arg.denominator()).gen()
            res = z**num  #rg.numerator()
            if self._character:
                ch = self._character(d)
                res = res * ch
            res = res * fak
        if self._is_dual:
            return res**-1
        return res
示例#10
0
class EtaQuotientMultiplier_2(MultiplierSystem):
    r"""
    Eta multiplier given by eta(Az)^{r}/eta(Bz)^s
    The weight should be r/2-s/2 mod 2.
    The group is Gamma0(lcm(A,B))
    """
    def __init__(self,
                 A,
                 B,
                 r,
                 s,
                 k=None,
                 number=0,
                 ch=None,
                 dual=False,
                 version=1,
                 **kwargs):
        r"""
        Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$.
        INPUT:

        - G -- Group
        - ch -- character
        - dual -- if we have the dual (in this case conjugate)
        - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly.
        - number -- we consider eta^power (here power should be an integer so as not to change the weight...)

        EXAMPLE:
        
                
        """
        self._level = lcm(A, B)
        G = Gamma0(self._level)
        if k == None:
            k = (QQ(r) - QQ(s)) / QQ(2)
        self._weight = QQ(k)
        if floor(self._weight - QQ(1) / QQ(2)) == ceil(self._weight -
                                                       QQ(1) / QQ(2)):
            self._half_integral_weight = 1
        else:
            self._half_integral_weight = 0
        MultiplierSystem.__init__(self,
                                  G,
                                  dimension=1,
                                  character=ch,
                                  dual=dual)
        number = number % 12
        if not is_even(number):
            raise ValueError("Need to have v_eta^(2(k+r)) with r even!")
        self._arg_num = A
        self._arg_den = B
        self._exp_num = r
        self._exp_den = s
        self._pow = QQ((self._weight + number))  ## k+r
        self._k_den = self._pow.denominator()
        self._k_num = self._pow.numerator()
        self._K = CyclotomicField(12 * self._k_den)
        self._z = self._K.gen()**self._k_num
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2 * self._k_den).gen()**-self._k_num
        self._version = version
        self.is_consistent(k)  # test consistency

    def __repr__(self):
        s = "Quotient of Eta multipliers :  "
        s += "eta({0})^{1}/eta({2})^{3}".format(self._arg_num, self._exp_num,
                                                self._arg_den, self._exp_den)
        if self._character != None and not self._character.is_trivial():
            s += " and character " + str(self._character)
        s += " with weight=" + str(self._weight)
        return s

    def level(self):
        return self._level

    def order(self):
        return 12 * self._k_den

    def z(self):
        return self._z

    def q_shift(self):
        r"""
        Gives the 'shift' at the cusp at infinity of the q-series.
        The 'true' q-expansion of the eta quotient is then q^shift*q_expansion
        """
        num = self._arg_num * self._exp_num - self._arg_den * self._exp_den
        return QQ(num) / QQ(24)

    def q_expansion(self, n=20):
        r"""
        Give the q-expansion of the quotient.
        """
        q = ZZ[['q']].gen()
        et = qexp_eta(ZZ[['q']], n)
        etA = et.subs(q=q**self._arg_num).power_series(ZZ[['q']])
        etB = et.subs(q=q**self._arg_den).power_series(ZZ[['q']])
        res = etA**(self._exp_num) * etB**(-self._exp_den)
        return res

    #def _action(self,A):
    #    return self._action(A)

    def _action(self, A):
        [a, b, c, d] = A
        if not c % self._level == 0:
            raise ValueError("Need A in {0}! Got: {1}".format(self.group, A))
        fak = 1
        if c < 0:
            a = -a
            b = -b
            c = -c
            d = -d
            fak = -self._fak
            #fak = fak*(-1)**(self._exp_num-self._exp_den)
        arg1, v1 = eta_conjugated(a, b, c, d, self._arg_num)
        arg2, v2 = eta_conjugated(a, b, c, d, self._arg_den)
        res = self._z**(arg1 * self._exp_num - arg2 * self._exp_den)
        if v1 != 1:
            res = res * v1**self._exp_num
        if v2 != 1:
            res = res * v2**(-self._exp_den)
        if fak != 1:
            res = res * fak**(self._exp_num - self._exp_den)
        return res
示例#11
0
class EtaQuotientMultiplier(MultiplierSystem):
    r"""
    Eta multiplier given by eta(Az)^{r}/eta(Bz)^s
    The weight should be r/2-s/2 mod 2.
    The group is Gamma0(lcm(A,B))
    """
    def __init__(self,
                 args=[1],
                 exponents=[1],
                 ch=None,
                 dual=False,
                 version=1,
                 **kwargs):
        r"""
        Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$.
        INPUT:

        - G -- Group
        - ch -- character
        - dual -- if we have the dual (in this case conjugate)
        - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly.
        - number -- we consider eta^power (here power should be an integer so as not to change the weight...)

        EXAMPLE:
        
                
        """
        assert len(args) == len(exponents)
        self._level = lcm(args)
        G = Gamma0(self._level)
        k = sum([QQ(x) * QQ(1) / QQ(2) for x in exponents])
        self._weight = QQ(k)
        if floor(self._weight - QQ(1) / QQ(2)) == ceil(self._weight -
                                                       QQ(1) / QQ(2)):
            self._half_integral_weight = 1
        else:
            self._half_integral_weight = 0
        MultiplierSystem.__init__(self,
                                  G,
                                  dimension=1,
                                  character=ch,
                                  dual=dual)
        self._arguments = args
        self._exponents = exponents
        self._pow = QQ((self._weight))  ## k+r
        self._k_den = self._weight.denominator()
        self._k_num = self._weight.numerator()
        self._K = CyclotomicField(12 * self._k_den)
        self._z = self._K.gen()**self._k_num
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2 * self._k_den).gen()**-self._k_num
        self._version = version
        self.is_consistent(k)  # test consistency

    def __repr__(self):
        s = "Quotient of Eta multipliers :  "
        for i in range(len(self._arguments)):
            n = self._arguments[i]
            e = self._exponents[i]
            s += "eta({0}z)^{1}".format(n, e)
            if i < len(self._arguments) - 1:
                s += "*"
        if self._character != None and not self._character.is_trivial():
            s += " and character " + str(self._character)
        s += " with weight=" + str(self._weight)
        return s

    def level(self):
        return self._level

    def order(self):
        return 12 * self._k_den

    def z(self):
        return self._z

    def q_shift(self):
        r"""
        Gives the 'shift' at the cusp at infinity of the q-series.
        The 'true' q-expansion of the eta quotient is then q^shift*q_expansion
        """
        num = sum([
            self._argument[i] * self._exponent[i]
            for i in range(len(self._arguments))
        ])

        return QQ(num) / QQ(24)

    def q_expansion(self, n=20):
        r"""
        Give the q-expansion of the quotient.
        """
        eta = qexp_eta(ZZ[['q']], n)
        R = eta.parent()
        q = R.gens()[0]
        res = R(1)
        prefak = 0
        for i in range(len(self._arguments)):
            res = res * eta.subs({q: q**self._arguments[i]
                                  })**self._exponents[i]
            prefak = prefak + self._arguments[i] * self._exponents[i]
        if prefak % 24 == 0:
            return res * q**(prefak / QQ(24))
        else:
            return res, prefak / QQ(24)
        #etA= et.subs(q=q**self._arg_num).power_series(ZZ[['q']])
        #etB= et.subs(q=q**self._arg_den).power_series(ZZ[['q']])
        #res = etA**(self._exp_num)/etB**(self._exp_den)
        #return res

    #def _action(self,A):
    #    return self._action(A)

    def _action(self, A):
        [a, b, c, d] = A
        if not c % self._level == 0:
            raise ValueError("Need A in {0}! Got: {1}".format(self.group, A))
        fak = 1
        if c < 0:
            a = -a
            b = -b
            c = -c
            d = -d
            fak = -self._fak
            #fak = fak*(-1)**(self._exp_num-self._exp_den)
        res = 1
        exp = 0
        for i in range(len(self._exponents)):
            z = CyclotomicField(lcm(12,
                                    self._exponents[i].denominator())).gen()
            arg, v = eta_conjugated(a, b, c, d, self._arguments[i])
            #arg2,v2 = eta_conjugated(a,b,c,d,self._arg_den)
            #res=self._z**(arg1*self._exp_num-arg2*self._exp_den)
            #            exp += arg*self._exponents[i]
            if v != 1:
                res = res * v**self._exponents[i]
            #if v2<>1:
            #res=res/v2**self._exp_den
            res = res * z**(arg * self._exponents[i].numerator())


#        res = res*self._z**exp
        if fak != 1:
            res = res * fak**exp
        return res
示例#12
0
class EtaQuotientMultiplier(MultiplierSystem):
    r"""
    Eta multiplier given by eta(Az)^{r}/eta(Bz)^s
    The weight should be r/2-s/2 mod 2.
    The group is Gamma0(lcm(A,B))
    """
    def __init__(self,args=[1],exponents=[1],ch=None,dual=False,version=1,**kwargs):
        r"""
        Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$.
        INPUT:

        - G -- Group
        - ch -- character
        - dual -- if we have the dual (in this case conjugate)
        - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly.
        - number -- we consider eta^power (here power should be an integer so as not to change the weight...)

        EXAMPLE:
        
                
        """
        assert len(args) == len(exponents)
        self._level=lcm(args)
        G = Gamma0(self._level)
        k = sum([QQ(x)*QQ(1)/QQ(2) for x in exponents])
        self._weight=QQ(k)
        if floor(self._weight-QQ(1)/QQ(2))==ceil(self._weight-QQ(1)/QQ(2)):
            self._half_integral_weight=1
        else:
            self._half_integral_weight=0
        MultiplierSystem.__init__(self,G,dimension=1,character=ch,dual=dual)
        self._arguments = args
        self._exponents =exponents
        self._pow=QQ((self._weight)) ## k+r
        self._k_den = self._weight.denominator()
        self._k_num = self._weight.numerator()
        self._K = CyclotomicField(12*self._k_den)
        self._z = self._K.gen()**self._k_num
        self._i = CyclotomicField(4).gen()
        self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num
        self._version = version
        self.is_consistent(k) # test consistency

    def __repr__(self):
        s="Quotient of Eta multipliers :  "
        for i in range(len(self._arguments)):
            n = self._arguments[i]
            e = self._exponents[i]
            s+="eta({0}z)^{1}".format(n,e)
            if i < len(self._arguments)-1:
                s+="*"
        if self._character<>None and not self._character.is_trivial():
            s+=" and character "+str(self._character)
        s+=" with weight="+str(self._weight)
        return s

    def level(self):
        return self._level
        
    def order(self):
        return 12*self._k_den

    def z(self):
        return self._z

    def q_shift(self):
        r"""
        Gives the 'shift' at the cusp at infinity of the q-series.
        The 'true' q-expansion of the eta quotient is then q^shift*q_expansion
        """
        num =  sum([self._argument[i]*self._exponent[i] for i in range(len(self._arguments))])

        return QQ(num)/QQ(24)
    
    def q_expansion(self,n=20):
        r"""
        Give the q-expansion of the quotient.
        """
        eta = qexp_eta(ZZ[['q']],n)
        R = eta.parent()
        q = R.gens()[0]
        res = R(1)
        prefak = 0
        for i in range(len(self._arguments)):        
            res = res*eta.subs({q:q**self._arguments[i]})**self._exponents[i]
            prefak = prefak+self._arguments[i]*self._exponents[i]
        if prefak % 24 == 0:
            return res*q**(prefak/24)
        else:
            return res,prefak/24
        #etA= et.subs(q=q**self._arg_num).power_series(ZZ[['q']])
        #etB= et.subs(q=q**self._arg_den).power_series(ZZ[['q']])
        #res = etA**(self._exp_num)/etB**(self._exp_den)
        #return res
    #def _action(self,A):
    #    return self._action(A)
        
    def _action(self,A):
        [a,b,c,d]=A
        if not c % self._level == 0 :
            raise ValueError,"Need A in {0}! Got: {1}".format(self.group,A)
        fak=1
        if c<0:
            a=-a; b=-b; c=-c;  d=-d; fak=-self._fak
            #fak = fak*(-1)**(self._exp_num-self._exp_den)
        res = 1
        exp = 0
        for i in range(len(self._exponents)):
            z = CyclotomicField(lcm(12,self._exponents[i].denominator())).gen()
            arg,v = eta_conjugated(a,b,c,d,self._arguments[i])
            #arg2,v2 = eta_conjugated(a,b,c,d,self._arg_den)
            #res=self._z**(arg1*self._exp_num-arg2*self._exp_den)
#            exp += arg*self._exponents[i]
            if v<>1:
                res=res*v**self._exponents[i]
            #if v2<>1:
            #res=res/v2**self._exp_den
            res = res*z**(arg*self._exponents[i].numerator())
#        res = res*self._z**exp
        if fak<>1:
            res=res*fak**exp
        return res