Пример #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 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)
Пример #3
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
Пример #4
0
 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
Пример #5
0
    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
Пример #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
 def coefficient_at_coset(self, n):
     r"""
     Compute Fourier coefficients of f|A_n 
     """
     if hasattr(n, "matrix"):
         n = self._get_coset_n(n)
     if not self._base_coeffs:
         self.coefficients_f()
     CF = ComplexField(self._prec)
     if not self._coefficients_at_coset.has_key(n):
         M = self.truncation_M(n)
         h, w = self.get_shift_and_width_for_coset(n)
         zN = CyclotomicField(w).gens()[0]
         prec1 = self._prec + ceil(log_b(M, 2))
         RF = RealField(prec1)
         coeffs = []
         fak = RF(w)**-(RF(self._k) / RF(2))
         #print "f=",f,n
         for i in range(M):
             al = CF(self.atkin_lehner(n))
             c0 = self._base_coeffs_embedding[i]
             #if hasattr(c0,"complex_embeddings"):
             #    c0 = c0.complex_embedding(prec1)
             #else:
             #    c0 = CF(c0)
             qN = zN**((i + 1) * h)
             #print "qN=",qN,type(qN)
             an = fak * al * c0 * qN.complex_embedding(prec1)
             #an = self.atkin_lehner(n)*self._base_coeffs[i]*zN**((i+1)*h)
             #an = f*an.complex_embedding(prec1)
             coeffs.append(an)
         self._coefficients_at_coset[n] = coeffs
     return self._coefficients_at_coset[n]
Пример #8
0
 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
Пример #9
0
    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
Пример #10
0
 def character_formatted(self):
     char_vals = self.character()
     charfield = int(self.character_field())
     zet = CyclotomicField(charfield).gen()
     print char_vals
     s = [sum([y[j] * zet**j for j in range(len(y))])._latex_() for y in char_vals]
     return s
Пример #11
0
    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
 def is_consistent(self, k):
     r"""
     Checks that v(-I)=(-1)^k,
     """
     Z = SL2Z([-1, 0, 0, -1])
     zi = CyclotomicField(4).gen()
     v = self._action(Z)
     if self._verbose > 0:
         print("test consistency for k={0}".format(k))
         print("v(Z)={0}".format(v))
     if self._dim == 1:
         if isinstance(k, Integer) or k.is_integral():
             if is_even(k):
                 v1 = ZZ(1)
             else:
                 v1 = ZZ(-1)
         elif isinstance(k, Rational) and (k.denominator() == 2 or k == 0):
             v1 = zi**(-QQ(2 * k))
             if self._verbose > 0:
                 print("I**(-2k)={0}".format(v1))
         else:
             raise ValueError(
                 "Only integral and half-integral weight is currently supported! Got weight:{0} of type:{1}"
                 .format(k, type(k)))
     else:
         raise NotImplementedError(
             "Override this function for vector-valued multipliers!")
     return v1 == v
Пример #13
0
 def __init__(self,
              group,
              dchar=(0, 0),
              dual=False,
              is_trivial=False,
              dimension=1,
              **kwargs):
     if not ZZ(4).divides(group.level()):
         raise ValueError(" Need level divisible by 4. Got: {0} ".format(
             self._group.level()))
     MultiplierSystem.__init__(self,
                               group,
                               dchar=dchar,
                               dual=dual,
                               is_trivial=is_trivial,
                               dimension=dimension,
                               **kwargs)
     self._i = CyclotomicField(4).gen()
     self._one = self._i**4
     self._weight = QQ(kwargs.get("weight", QQ(1) / QQ(2)))
     ## We have to make sure that we have the correct multiplier & character
     ## for the desired weight
     if self._weight != None:
         if floor(2 * self._weight) != ceil(2 * self._weight):
             raise ValueError(
                 " Use ThetaMultiplier for half integral or integral weight only!"
             )
         t = self.is_consistent(self._weight)
         if not t:
             self.set_dual()
             t1 = self.is_consistent(self._weight)
             if not t1:
                 raise ArithmeticError(
                     "Could not find consistent theta multiplier! Try to add a character."
                 )
Пример #14
0
    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
Пример #15
0
 def sage_character(self, order, genvalues):
     H = DirichletGroup(self.modulus,
                        base_ring=CyclotomicField(
                            self.sage_zeta_order(order)))
     M = H._module
     order_corrected_genvalues = get_sage_genvalues(
         self.modulus, order, genvalues, self.sage_zeta_order(order))
     return DirichletCharacter(H, M(order_corrected_genvalues))
Пример #16
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
Пример #17
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
Пример #18
0
 def to_dirichlet_character(self, character):
     if character['order'] == 1:
         from sage.all import trivial_character
         return trivial_character(character['modulus'])
     from sage.all import DirichletGroup, CyclotomicField, QQ
     from sage.modular.dirichlet import DirichletCharacter
     zeta_order = character['zeta_order']
     R = QQ if zeta_order == 2 else CyclotomicField(zeta_order)
     G = DirichletGroup(character['modulus'], R, zeta_order=zeta_order)
     v = G.an_element().element().parent()(character['element'])
     return DirichletCharacter(G, v)
Пример #19
0
def parse_field_string(F):  # parse Q, Qsqrt2, Qsqrt-4, Qzeta5, etc
    if F == 'Q':
        return '1.1.1.1'
    if F == 'Qi':
        return '2.0.4.1'
    # Change unicode dash with minus sign
    F = F.replace(u'\u2212', '-')
    # remove non-ascii characters from F
    F = F.decode('utf8').encode('ascii', 'ignore')
    fail_string = str(
        F + ' is not a valid field label or name or polynomial, or is not ')
    if len(F) == 0:
        return "Entry for the field was left blank.  You need to enter a field label, field name, or a polynomial."
    if F[0] == 'Q':
        if F[1:5] in ['sqrt', 'root']:
            try:
                d = ZZ(str(F[5:])).squarefree_part()
            except ValueError:
                return fail_string
            if d % 4 in [2, 3]:
                D = 4 * d
            else:
                D = d
            absD = D.abs()
            s = 0 if D < 0 else 2
            return '2.%s.%s.1' % (s, str(absD))
        if F[1:5] == 'zeta':
            try:
                d = ZZ(str(F[5:]))
            except ValueError:
                return fail_string
            if d < 1:
                return fail_string
            if d % 4 == 2:
                d /= 2  # Q(zeta_6)=Q(zeta_3), etc)
            if d == 1:
                return '1.1.1.1'
            deg = euler_phi(d)
            if deg > 23:
                return '%s is not ' % F
            adisc = CyclotomicField(d).discriminant().abs()  # uses formula!
            return '%s.0.%s.1' % (deg, adisc)
        return fail_string
    # check if a polynomial was entered
    F = F.replace('X', 'x')
    if 'x' in F:
        F1 = F.replace('^', '**')
        # print F
        F1 = poly_to_field_label(F1)
        if F1:
            return F1
        return str(F + ' is not ')
    return F
Пример #20
0
 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
Пример #21
0
    def factor_perm_repn(self, nfgg=None):
        if 'artincoefs' in self._data:
            return self._data['artincoefs']
        try:
            if nfgg is not None:
                self._data["nfgg"] = nfgg
            else:
                if "nfgg" not in self._data:
                    from artin_representations.math_classes import NumberFieldGaloisGroup
                    nfgg = NumberFieldGaloisGroup(self._data['coeffs'])
                    self._data["nfgg"] = nfgg
                else:
                    nfgg = self._data["nfgg"]

            cc = nfgg.conjugacy_classes()
            # cc is list, each has methods group, size, order, representative
            ccreps = [x.representative() for x in cc]
            ccns = [int(x.size()) for x in cc]
            ccreps = [x.cycle_string() for x in ccreps]
            ccgen = '[' + ','.join(ccreps) + ']'
            ar = nfgg.artin_representations()  # list of artin reps from db
            arfull = nfgg.artin_representations_full_characters(
            )  # list of artin reps from db
            gap.set(
                'fixed',
                'function(a,b) if a*b=a then return 1; else return 0; fi; end;'
            )
            g = gap.Group(ccgen)
            h = g.Stabilizer('1')
            rc = g.RightCosets(h)
            # Permutation character for our field
            permchar = [gap.Sum(rc, 'j->fixed(j,' + x + ')') for x in ccreps]
            charcoefs = [0 for x in arfull]
            # list of lists (inner are giving char values
            ar2 = [x[0] for x in arfull]
            for j in range(len(ar)):
                fieldchar = int(arfull[j][1])
                zet = CyclotomicField(fieldchar).gen()
                ar2[j] = [psum(zet, x) for x in ar2[j]]
            for j in range(len(ar)):
                charcoefs[j] = 0
                for k in range(len(ccns)):
                    charcoefs[j] += int(permchar[k]) * ccns[k] * ar2[j][k]
            charcoefs = [x / int(g.Size()) for x in charcoefs]
            self._data['artincoefs'] = charcoefs
            return charcoefs

        except AttributeError:
            return []

        return []
Пример #22
0
    def xi(self, A):
        r""" The eight-root of unity in front of the Weil representation.

        INPUT:
        
        -''N'' -- integer
        -''A'' -- element of PSL(2,Z)

        EXAMPLES::

        
            sage: A=SL2Z([41,77,33,62])
            sage: WR.xi(A)
            -zeta8^3]
            sage: S,T=SL2Z.gens()
            sage: WR.xi(S)
            -zeta8^3
            sage: WR.xi(T)
            1
            sage: A=SL2Z([-1,1,-4,3])
            sage: WR.xi(A)
            -zeta8^2
            sage: A=SL2Z([0,1,-1,0])
            sage: WR.xi(A)
            -zeta8

        """
        a = Integer(A[0, 0])
        b = Integer(A[0, 1])
        c = Integer(A[1, 0])
        d = Integer(A[1, 1])
        if (c == 0):
            return 1
        z = CyclotomicField(8).gen()
        N = self._N
        N2 = odd_part(N)
        Neven = ZZ(2 * N).divide_knowing_divisible_by(N2)
        c2 = odd_part(c)
        Nc = gcd(Integer(2 * N), Integer(c))
        cNc = ZZ(c).divide_knowing_divisible_by(Nc)
        f1 = kronecker(-a, cNc)
        f2 = kronecker(cNc, ZZ(2 * N).divide_knowing_divisible_by(Nc))
        if (is_odd(c)):
            s = c * N2
        elif (c % Neven == 0):
            s = (c2 + 1 - N2) * (a + 1)
        else:
            s = (c2 + 1 - N2) * (a + 1) - N2 * a * c2
        r = -1 - QQ(N2) / QQ(gcd(c, N2)) + s
        xi = f1 * f2 * z**r
        return xi
Пример #23
0
def parse_field_string(F):  # parse Q, Qsqrt2, Qsqrt-4, Qzeta5, etc
    if F == 'Q':
        return '1.1.1.1'
    if F == 'Qi':
        return '2.0.4.1'
    fail_string = str(
        F + ' is not a valid field label or name or polynomial, or is not ')
    if len(F) == 0:
        return "Entry for the field was left blank.  You need to enter a field label, field name, or a polynomial."
    if F[0] == 'Q':
        if F[1:5] in ['sqrt', 'root']:
            try:
                d = ZZ(str(F[5:])).squarefree_part()
            except ValueError:
                return fail_string
            if d % 4 in [2, 3]:
                D = 4 * d
            else:
                D = d
            absD = D.abs()
            s = 0 if D < 0 else 2
            return '2.%s.%s.1' % (s, str(absD))
        if F[1:5] == 'zeta':
            try:
                d = ZZ(str(F[5:]))
            except ValueError:
                return fail_string
            if d < 1:
                return fail_string
            if d % 4 == 2:
                d /= 2  # Q(zeta_6)=Q(zeta_3), etc)
            if d == 1:
                return '1.1.1.1'
            deg = euler_phi(d)
            if deg > 20:
                return fail_string
            adisc = CyclotomicField(d).discriminant().abs()  # uses formula!
            return '%s.0.%s.1' % (deg, adisc)
        return fail_string
    # check if a polynomial was entered
    F = F.replace('X', 'x')
    if 'x' in F:
        F = F.replace('^', '**')
        # print F
        F = poly_to_field_label(F)
        if F:
            return F
        return fail_string
    return F
Пример #24
0
 def K(self, m, n, c):
     r"""
     K(m,n,c) = sum_{d (c)} e((md+n\bar{d})/c)
     """
     summa = 0
     z = CyclotomicField(c).gen()
     print("z={0}".format(z))
     for d in range(c):
         if gcd(d, c) > 1:
             continue
         try:
             dbar = inverse_mod(d, c)
         except ZeroDivisionError:
             print("c={0}".format(c))
             print("d={0}".format(d))
             raise ZeroDivisionError
         arg = m * dbar + n * d
         #print "arg=",arg
         summa = summa + z**arg
     return summa
Пример #25
0
    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
Пример #26
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
Пример #27
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
Пример #28
0
    def __init__(self, G, v=None, **kwargs):
        r"""
        G should be a subgroup of PSL(2,Z).

        EXAMPLE::

        sage: te=TestMultiplier(Gamma0(2),weight=1/2)
        sage: r=InducedRepresentation(Gamma0(2),v=te)

        """
        dim = len(list(G.coset_reps()))
        MultiplierSystem.__init__(self, Gamma0(1), dimension=dim)
        self._induced_from = G
        # setup the action on S and T (should be faster...)
        self.v = v
        if v != None:

            k = v.order()
            if k > 2:
                K = CyclotomicField(k)
            else:
                K = ZZ
            self.S = matrix(K, dim, dim)
            self.T = matrix(K, dim, dim)
        else:
            self.S = matrix(dim, dim)
            self.T = matrix(dim, dim)
        S, T = SL2Z.gens()
        if hasattr(G, "coset_reps"):
            if isinstance(G.coset_reps(), list):
                Vl = G.coset_reps()
            else:
                Vl = list(G.coset_reps())
        elif hasattr(G, "_G"):
            Vl = list(G._G.coset_reps())
        else:
            raise ValueError(
                "Could not get coset representatives from {0}!".format(G))
        self.repsT = dict()
        self.repsS = dict()
        for i in range(dim):
            Vi = Vl[i]
            for j in range(dim):
                Vj = Vl[j]
                BS = Vi * S * Vj**-1
                BT = Vi * T * Vj**-1
                #print "i,j
                #print "ViSVj^-1=",BS
                #print "ViTVj^-1=",BT
                if BS in G:
                    if v != None:
                        vS = v(BS)
                    else:
                        vS = 1
                    self.S[i, j] = vS
                    self.repsS[(i, j)] = BS
                if BT in G:
                    if v != None:
                        vT = v(BT)
                    else:
                        vT = 1
                    self.T[i, j] = vT
                    self.repsT[(i, j)] = BT
Пример #29
0
    def rho(self,M,silent=0,numeric=0,prec=-1):
        r""" The Weil representation acting on SL(2,Z).

        INPUT::

        -``M`` -- element of SL2Z
        - ''numeric'' -- set to 1 to return a Matrix_complex_dense with prec=prec instead of exact
        - ''prec'' -- precision
        EXAMPLES::
        
            sage: WR=WeilRepDiscriminantForm(1,dual=False)
            sage: S,T=SL2Z.gens()
            sage: WR.rho(S)
            [
            [-zeta8^3 -zeta8^3]
            [-zeta8^3  zeta8^3], sqrt(1/2)
            ]
            sage: WR.rho(T)
            [
            [       1        0]
            [       0 -zeta8^2], 1
            ]
            sage: A=SL2Z([-1,1,-4,3]); WR.rho(A)
            [
            [zeta8^2       0]
            [      0       1], 1
            ]
            sage: A=SL2Z([41,77,33,62]); WR.rho(A)
            [
            [-zeta8^3  zeta8^3]
            [   zeta8    zeta8], sqrt(1/2)
            ]

        """
        N=self._N; D=2*N; D2=2*D
        if numeric==0:
            K=CyclotomicField (lcm(4*self._N,8))
            z=K(CyclotomicField(4*self._N).gen())
            rho=matrix(K,D)
        else:
            CF = MPComplexField(prec)
            RF = CF.base()
            MS = MatrixSpace(CF,int(D),int(D))
            rho = Matrix_complex_dense(MS)
            #arg = RF(2)*RF.pi()/RF(4*self._N)
            z = CF(0,RF(2)*RF.pi()/RF(4*self._N)).exp()
        [a,b,c,d]=M
        fak=1; sig=1
        if c<0:
            # need to use the reflection 
            # r(-A)=r(Z)r(A)sigma(Z,A)  where sigma(Z,A)=-1 if c>0
            sig=-1
            if numeric==0:
                fz=CyclotomicField(4).gen() # = i
            else:
                fz=CF(0,1)
            # the factor is rho(Z) sigma(Z,-A)
            #if(c < 0 or (c==0 and d>0)):
            #    fak=-fz
            #else:
            #sig=1
            #fz=1
            fak=fz
            a=-a; b=-b; c=-c; d=-d;
            A=SL2Z([a,b,c,d])
            if numeric==0:
                chi=self.xi(A)            
            else:
                chi=CF(self.xi(A).complex_embedding(prec))
            if(silent>0):
                print("fz={0}".format(fz))
                print("chi={0}".format(chi))
        elif c == 0: # then we use the simple formula
            if d < 0:
                sig=-1
                if numeric == 0:
                    fz=CyclotomicField(4).gen()
                else:
                    fz=CF(0,1)
                fak=fz
                a=-a; b=-b; c=-c; d=-d;
            else:
                fak=1
            for alpha in range(D):
                arg=(b*alpha*alpha ) % D2
                if(sig==-1):
                    malpha = (D - alpha) % D
                    rho[malpha,alpha]=fak*z**arg
                else:
                    #print "D2=",D2
                    #print "b=",b
                    #print "arg=",arg
                    rho[alpha,alpha]=z**arg
            return [rho,1]
        else:
            if numeric==0:
                chi=self.xi(M)            
            else:
                chi=CF(self.xi(M).complex_embedding(prec))
        Nc=gcd(Integer(D),Integer(c))
        #chi=chi*sqrt(CF(Nc)/CF(D))
        if(valuation(Integer(c),2)==valuation(Integer(D),2)):
            xc=Integer(N)
        else:
            xc=0
        if silent>0:
            print("c={0}".format(c))
            print("xc={0}".format(xc))
            print("chi={0}".format(chi))
        for alpha in range(D):
            al=QQ(alpha)/QQ(D)
            for beta in range(D):
                be=QQ(beta)/QQ(D)
                c_div=False
                if(xc==0):
                    alpha_minus_dbeta=(alpha-d*beta) % D
                else:
                    alpha_minus_dbeta=(alpha-d*beta-xc) % D
                if silent > 0: # and alpha==7 and beta == 7):
                    print("alpha,beta={0},{1}".format(alpha,beta))
                    print("c,d={0},{1}".format(c,d))
                    print("alpha-d*beta={0}".format(alpha_minus_dbeta))
                invers=0
                for r in range(D):
                    if (r*c - alpha_minus_dbeta) % D ==0:
                        c_div=True
                        invers=r
                        break
                if c_div and silent > 0:
                    print("invers={0}".format(invers))
                    print(" inverse(alpha-d*beta) mod c={0}".format(invers))
                elif(silent>0):
                    print(" no inverse!")
                if(c_div):
                    y=invers
                    if xc==0:
                        argu=a*c*y**2+b*d*beta**2+2*b*c*y*beta
                    else:
                        argu=a*c*y**2+2*xc*(a*y+b*beta)+b*d*beta**2+2*b*c*y*beta
                    argu = argu % D2
                    tmp1=z**argu  # exp(2*pi*I*argu)
                    if silent>0:# and alpha==7 and beta==7):
                        print("a,b,c,d={0},{1},{2},{3}".format(a,b,c,d))
                        print("xc={0}".format(xc))
                        print("argu={0}".format(argu))
                        print("exp(...)={0}".format(tmp1))
                        print("chi={0}".format(chi))
                        print("sig={0}".format(sig))
                    if sig == -1:
                        minus_alpha = (D - alpha) % D
                        rho[minus_alpha,beta]=tmp1*chi
                    else:
                        rho[alpha,beta]=tmp1*chi
        #print "fak=",fak
        if numeric==0:            
            return [fak*rho,sqrt(QQ(Nc)/QQ(D))]
        else:
            return [CF(fak)*rho,RF(sqrt(QQ(Nc)/QQ(D)))]
Пример #30
0
    def __init__(self,N,k=None,dual=False,sym_type=0,verbose=0):
        r""" Creates a Weil representation (or its dual) of the discriminant form given by D=Z/2NZ.

        
        EXAMPLES::


            sage: WR=WeilRepDiscriminantForm(1,dual=True)
            sage: WR.D
            [0, 1/2]
            sage: WR.D_as_integers
            [0, 1]
            sage: WR.Qv
            [0, -1/4]
            sage: WR=WeilRepDiscriminantForm(1,dual=False)
            sage: WR.D
            [0, 1/2]
            sage: WR.D_as_integers
            [0, 1]
            sage: WR.Qv
            [0, 1/4]

            
        
        """
        ## If N<0 we use |N| and set dual rep. to true
        self._verbose = verbose
        if N<0:
            self._N=-N
            self.dual = not dual
            self._is_dual_rep= not dual # do we use dual representation or not
        else:
            self._N=N
            self._is_dual_rep=dual
        
        N2=Integer(2*self._N)
        self.group=SL2Z
        self._level=4*self._N
        self._D_as_integers=list(range(0,N2))
        self._even_submodule=[]
        self._odd_submodule=[]
        self._D=list()
        for x in range(0,N2):
            y=QQ(x)/QQ(N2)
            self._D.append(y)
        self.Qv=list()              # List of +- q(x) for x in D
        self.Qv_times_level=list()      # List of +- 4N*q(x) for x in D
        if self._is_dual_rep: # we add this already here for efficiency
            sig=-1
        else:
            sig=1
        for x in self._D:
            y=sig*self.Q(x)
            self.Qv.append(y)
            self.Qv_times_level.append(self._level*y)

        self._signature = sig
        self._sigma_invariant = CyclotomicField(8).gens()[0]**-self._signature
        self._rank = N2
        self._weight = None
        self._sym_type = sym_type
        if sym_type==0 and k != None: # Then we set it
            self._weight = QQ(k)
            if ((self._weight-QQ(1)/QQ(2)) % 2) == 0:
                sym_type = sig
            elif ((self._weight-QQ(3)/QQ(2)) % 2) == 0:
                sym_type = -sig
            else:
                raise ValueError("Got incompatible weight and signature!")
        elif sym_type != 0 and k == None:  ## Set the weight
            if sig==sym_type:
                self._weight = QQ(1)/QQ(2)
            elif sig==-sym_type:
                self._weight = QQ(3)/QQ(2)
            else:
                raise ValueError("Got incompatible symmetry type and signature!")
        elif sym_type==0 and k==None:  ## Set the weight
            ## We make a choice
            self._sym_type = sig
            self._weight = QQ(1)/QQ(2)
        else:
            ## Check consistency
            self._weight = QQ(k)
            if ((self._weight-QQ(1)/QQ(2)) % 2) == 0 and self._sym_type == sig:
                pass
            elif ((self._weight-QQ(3)/QQ(2)) % 2) == 0 and self._sym_type == -sig:
                pass

            else:
                raise ValueError("Need either sym type or weight!")
Пример #31
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
Пример #32
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
Пример #33
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
Пример #34
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
Пример #35
0
def nf_string_to_label(F):  # parse Q, Qsqrt2, Qsqrt-4, Qzeta5, etc
    if F == 'Q':
        return '1.1.1.1'
    if F == 'Qi' or F == 'Q(i)':
        return '2.0.4.1'
    # Change unicode dash with minus sign
    F = F.replace(u'\u2212', '-')
    # remove non-ascii characters from F
    F = F.decode('utf8').encode('ascii', 'ignore')
    if len(F) == 0:
        raise ValueError(
            "Entry for the field was left blank.  You need to enter a field label, field name, or a polynomial."
        )
    if F[0] == 'Q':
        if '(' in F and ')' in F:
            F = F.replace('(', '').replace(')', '')
        if F[1:5] in ['sqrt', 'root']:
            try:
                d = ZZ(str(F[5:])).squarefree_part()
            except (TypeError, ValueError):
                d = 0
            if d == 0:
                raise ValueError(
                    "After {0}, the remainder must be a nonzero integer.  Use {0}5 or {0}-11 for example."
                    .format(F[:5]))
            if d == 1:
                return '1.1.1.1'
            if d % 4 in [2, 3]:
                D = 4 * d
            else:
                D = d
            absD = D.abs()
            s = 0 if D < 0 else 2
            return '2.%s.%s.1' % (s, str(absD))
        if F[1:5] == 'zeta':
            if '_' in F:
                F = F.replace('_', '')
            try:
                d = ZZ(str(F[5:]))
            except ValueError:
                d = 0
            if d < 1:
                raise ValueError(
                    "After {0}, the remainder must be a positive integer.  Use {0}5 for example."
                    .format(F[:5]))
            if d % 4 == 2:
                d /= 2  # Q(zeta_6)=Q(zeta_3), etc)
            if d == 1:
                return '1.1.1.1'
            deg = euler_phi(d)
            if deg > 23:
                raise ValueError('%s is not in the database.' % F)
            adisc = CyclotomicField(d).discriminant().abs()  # uses formula!
            return '%s.0.%s.1' % (deg, adisc)
        raise ValueError(
            'It is not a valid field name or label, or a defining polynomial.')
    # check if a polynomial was entered
    F = F.replace('X', 'x')
    if 'x' in F:
        F1 = F.replace('^', '**')
        # print F
        from lmfdb.number_fields.number_field import poly_to_field_label
        F1 = poly_to_field_label(F1)
        if F1:
            return F1
        raise ValueError('%s does not define a number field in the database.' %
                         F)
    # Expand out factored labels, like 11.11.11e20.1
    if not re.match(r'\d+\.\d+\.[0-9e_]+\.\d+', F):
        raise ValueError("It must be of the form d.r.D.n, such as 2.2.5.1.")
    parts = F.split(".")

    def raise_power(ab):
        if ab.count("e") == 0:
            return ZZ(ab)
        elif ab.count("e") == 1:
            a, b = ab.split("e")
            return ZZ(a)**ZZ(b)
        else:
            raise ValueError(
                "Malformed absolute discriminant.  It must be a sequence of strings AeB for A and B integers, joined by _s.  For example, 2e7_3e5_11."
            )

    parts[2] = str(prod(raise_power(c) for c in parts[2].split("_")))
    return ".".join(parts)
Пример #36
0
def gauss_sum(a, p):
    K = CyclotomicField(p, names=('zeta',))
    (zeta,) = K.gens()
    return sum(legendre_symbol(n, p) * zeta**(a * n)
               for n in range(Integer(1), p))