Example #1
0
    def __init__(self,
                 group,
                 dchar=(1, 1),
                 dual=False,
                 is_trivial=False,
                 dimension=1,
                 **kwargs):
        r"""
        if dual is set to true we use the complex conjugate of the representation (we assume the representation is unitary)


        
        The pair dchar = (conductor,number) gives the character in conrey numbering
        If char_nr = -1  = > kronecker_character
        If char_nr = -2  = > kronecker_character_upside_down
        """
        self._group = group
        if not hasattr(self, '_weight'):
            self._weight = None
        self._dim = dimension
        self._ambient_rank = kwargs.get('ambient_rank', None)
        self._kwargs = kwargs
        self._verbose = kwargs.get("verbose", 0)
        if self._verbose > 0:
            print("Init multiplier system!")
        (conductor, char_nr) = dchar
        self._conductor = conductor
        self._char_nr = char_nr
        self._character = None
        self._level = group.generalised_level()
        if 'character' in kwargs:
            if str(type(kwargs['character'])).find('Dirichlet') >= 0:
                self._character = kwargs['character']
                self._conductor = self._character.conductor()
                try:
                    self._char_nr = self._character.number()
                except:
                    for x in DirichletGroup_conrey(self._conductor):
                        if x.sage_character() == self._character:
                            self._char_nr = x.number()
        elif group.is_congruence():
            if conductor <= 0:
                self._conductor = group.level()
                self._char_nr = 1
            if char_nr >= 0:
                self._char_nr = char_nr

            if self._char_nr == 0 or self._char_nr == 1:
                self._character = trivial_character(self._conductor)
            elif self._char_nr == -1:
                if self._conductor % 4 == 3:
                    self._character = kronecker_character(-self._conductor)
                elif self._conductor % 4 == 1:
                    self._character = kronecker_character(self._conductor)
                assert self._character.conductor() == self._conductor
            elif self._char_nr <= -2:
                self._character = kronecker_character_upside_down(
                    self._conductor)
            else:
                self._character = DirichletCharacter_conrey(
                    DirichletGroup_conrey(self._conductor),
                    self._char_nr).sage_character()
        else:
            self._conductor = 1
            self._character = trivial_character(1)
        #if not hasattr(self._character,'is_trivial'):
        #    if isinstance(self._character,(int,Integer)) and group.is_congruence():
        #        j = self._character
        #        self._character = DirichletGroup(group.level())[j]
        ## Extract the class name for the reduce algorithm
        self._class_name = str(type(self))[1:-2].split(".")[-1]
        if not isinstance(dimension, (int, Integer)):
            raise ValueError("Dimension must be integer!")
        self._is_dual = dual
        self._is_trivial = is_trivial and self._character.is_trivial()
        if is_trivial and self._character.order() <= 2:
            self._is_real = True
        else:
            self._is_real = False
        self._character_values = []  ## Store for easy access
Example #2
0
    def __init__(self,group,dchar=(1,1),dual=False,is_trivial=False,dimension=1,**kwargs):
        r"""
        if dual is set to true we use the complex conjugate of the representation (we assume the representation is unitary)


        
        The pair dchar = (conductor,number) gives the character in conrey numbering
        If char_nr = -1  = > kronecker_character
        If char_nr = -2  = > kronecker_character_upside_down
        """
        #print "kwargs0=",kwargs
        self._group = group
        self._weight = None
        self._dim = dimension
        self._ambient_rank=kwargs.get('ambient_rank',None)
        self._kwargs = kwargs
        self._verbose = kwargs.get("verbose",0)
        if self._verbose>0:
             print "Init multiplier system!"
        (conductor,char_nr)=dchar
        self._conductor=conductor
        self._char_nr=char_nr
        self._character = None
        self._level = group.generalised_level()
        if kwargs.has_key('character'):
            if str(type(kwargs['character'])).find('Dirichlet')>=0:
                self._character = kwargs['character']
                self._conductor=self._character.conductor()
                try:
                    self._char_nr=self._character.number()
                except:
                    for x in DirichletGroup_conrey(self._conductor):
                        if x.sage_character() ==  self._character:
                            self._char_nr=x.number()
        elif group.is_congruence():
            if conductor<=0:
                    self._conductor=group.level(); self._char_nr=1
            if char_nr>=0:
                self._char_nr=char_nr
            
            if self._char_nr==0 or self._char_nr==1:
                self._character = trivial_character(self._conductor)
            elif self._char_nr==-1:                
                if self._conductor % 4 == 3:
                    self._character = kronecker_character(-self._conductor)
                elif self._conductor % 4 == 1:
                    self._character = kronecker_character(self._conductor)                    
                assert self._character.conductor()==self._conductor
            elif self._char_nr<=-2:
                self._character = kronecker_character_upside_down(self._conductor)    
            else:
                self._character = DirichletCharacter_conrey(DirichletGroup_conrey(self._conductor),self._char_nr).sage_character()
        else:
            self._conductor = 1
            self._character = trivial_character(1)
        #if not hasattr(self._character,'is_trivial'):
        #    if isinstance(self._character,(int,Integer)) and group.is_congruence():
        #        j = self._character
        #        self._character = DirichletGroup(group.level())[j]
        ## Extract the class name for the reduce algorithm
        self._class_name=str(type(self))[1:-2].split(".")[-1]
        if not isinstance(dimension,(int,Integer)):
            raise ValueError,"Dimension must be integer!"
        self._is_dual = dual
        self._is_trivial=is_trivial and self._character.is_trivial()
        if is_trivial and self._character.order()<=2:
            self._is_real=True
        else:
            self._is_real=False
        self._character_values = [] ## Store for easy access
Example #3
0
class MultiplierSystem(SageObject):
    r"""
    Base class for multiplier systems.
    A multiplier system is a function:
    v : Gamma - > C^dim
    s.t. there exists a merom. function of weight k f:H->C^dim
    with f|A=v(A)f
    """
    def __init__(self,
                 group,
                 dchar=(1, 1),
                 dual=False,
                 is_trivial=False,
                 dimension=1,
                 **kwargs):
        r"""
        if dual is set to true we use the complex conjugate of the representation (we assume the representation is unitary)


        
        The pair dchar = (conductor,number) gives the character in conrey numbering
        If char_nr = -1  = > kronecker_character
        If char_nr = -2  = > kronecker_character_upside_down
        """
        self._group = group
        if not hasattr(self, '_weight'):
            self._weight = None
        self._dim = dimension
        self._ambient_rank = kwargs.get('ambient_rank', None)
        self._kwargs = kwargs
        self._verbose = kwargs.get("verbose", 0)
        if self._verbose > 0:
            print("Init multiplier system!")
        (conductor, char_nr) = dchar
        self._conductor = conductor
        self._char_nr = char_nr
        self._character = None
        self._level = group.generalised_level()
        if 'character' in kwargs:
            if str(type(kwargs['character'])).find('Dirichlet') >= 0:
                self._character = kwargs['character']
                self._conductor = self._character.conductor()
                try:
                    self._char_nr = self._character.number()
                except:
                    for x in DirichletGroup_conrey(self._conductor):
                        if x.sage_character() == self._character:
                            self._char_nr = x.number()
        elif group.is_congruence():
            if conductor <= 0:
                self._conductor = group.level()
                self._char_nr = 1
            if char_nr >= 0:
                self._char_nr = char_nr

            if self._char_nr == 0 or self._char_nr == 1:
                self._character = trivial_character(self._conductor)
            elif self._char_nr == -1:
                if self._conductor % 4 == 3:
                    self._character = kronecker_character(-self._conductor)
                elif self._conductor % 4 == 1:
                    self._character = kronecker_character(self._conductor)
                assert self._character.conductor() == self._conductor
            elif self._char_nr <= -2:
                self._character = kronecker_character_upside_down(
                    self._conductor)
            else:
                self._character = DirichletCharacter_conrey(
                    DirichletGroup_conrey(self._conductor),
                    self._char_nr).sage_character()
        else:
            self._conductor = 1
            self._character = trivial_character(1)
        #if not hasattr(self._character,'is_trivial'):
        #    if isinstance(self._character,(int,Integer)) and group.is_congruence():
        #        j = self._character
        #        self._character = DirichletGroup(group.level())[j]
        ## Extract the class name for the reduce algorithm
        self._class_name = str(type(self))[1:-2].split(".")[-1]
        if not isinstance(dimension, (int, Integer)):
            raise ValueError("Dimension must be integer!")
        self._is_dual = dual
        self._is_trivial = is_trivial and self._character.is_trivial()
        if is_trivial and self._character.order() <= 2:
            self._is_real = True
        else:
            self._is_real = False
        self._character_values = []  ## Store for easy access

    def __getinitargs__(self):
        #print "get initargs"
        return (self._group, (self._conductor, self._char_nr), self._is_dual,
                self._is_trivial, self._dim)

    def __reduce__(self):
        #print "reduce!"
        t = self.__getinitargs__()
        return self.__class__, t

    #return(TrivialMultiplier,(self._group,self._dim,(self._conductor,self._char_nr),self._is_dual,self._is_trivial))
    #    return(type(self),(self._group,self._dim,(self._conductor,self._char_nr),self._is_dual,self._is_trivial))

    def dual_multiplier(self):
        r"""
        Returns the dual multiplier of self.
        """
        m = copy(self)
        m._is_dual = int(not self._is_dual)
        o = self._character.order()
        m._character = self._character**(o - 1)
        m._weight = QQ(2) - QQ(self.weight())
        return m

    def __repr__(self):
        r"""
        Needs to be defined in subclasses.
        """
        raise NotImplementedError

    def group(self):
        return self._group

    def is_dual(self):
        return int(self._is_dual)

    def level(self):
        return self._level

    def weight(self):
        r"""
        Return (modulo 2) which weight self is a multiplier system consistent with
        """
        if self._is_trivial:
            self._weight = 0
            return self._weight
        if self._dim == 1:
            if self._weight is None:
                Z = SL2Z([-1, 0, 0, -1])
                v = self._action(Z)
                if v == 1:
                    self._weight = QQ(0)
                if v == -1:
                    self._weight = QQ(1)
                elif v == -I:
                    self._weight = QQ(1) / QQ(2)
                elif v == I:
                    self._weight = QQ(1) / QQ(2)
                else:
                    raise NotImplementedError
        return self._weight

    def __call__(self, A):
        r"""
        For eficientcy we should also allow to act on lists
        """
        if isinstance(A, (ArithmeticSubgroupElement, SL2Z_elt, list)):
            if A not in self._group:
                raise ValueError("Element {0} is not in {1}! ".format(
                    A, self._group))
            return self._action(A)
        else:
            raise NotImplementedError(
                "Do not know how the multiplier should act on {0}".format(A))

    def _action(self):
        raise NotImplementedError(" Needs to be overridden by subclasses!")

    def is_trivial(self):
        return self._is_trivial

    def is_real(self):
        return self._is_real

    def set_dual(self):
        self._is_dual = True  #not self._is_dual

    def character(self):
        return self._character

    def weil_module(self):
        if hasattr(self, "_weil_module"):
            if self._verbose > 1:
                print("self has weil_module!")
            return self._weil_module
        return None

    def rank(self):
        return self._dim

    def ambient_rank(self):
        r"""
        Return the dimension of the unsymmetrized space containing self.
        """
        if self._ambient_rank != None:
            return self._ambient_rank
        else:
            return self._dim

    def __eq__(self, other):
        r"""
        A character is determined by the group it is acting on and its type, which is given by the representation.
        """
        if str(type(other)).find('Multiplier') < 0:
            return False
        if self._group != other._group:
            return False
        if self._dim != other._dim:
            return False
        return self.__repr__() == other.__repr__()

    def __ne__(self, other):
        return not self.__eq__(other)

    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
Example #4
0
class MultiplierSystem(SageObject):
    r"""
    Base class for multiplier systems.
    A multiplier system is a function:
    v : Gamma - > C^dim
    s.t. there exists a merom. function of weight k f:H->C^dim
    with f|A=v(A)f
    """
    def __init__(self,group,dchar=(1,1),dual=False,is_trivial=False,dimension=1,**kwargs):
        r"""
        if dual is set to true we use the complex conjugate of the representation (we assume the representation is unitary)


        
        The pair dchar = (conductor,number) gives the character in conrey numbering
        If char_nr = -1  = > kronecker_character
        If char_nr = -2  = > kronecker_character_upside_down
        """
        #print "kwargs0=",kwargs
        self._group = group
        self._weight = None
        self._dim = dimension
        self._ambient_rank=kwargs.get('ambient_rank',None)
        self._kwargs = kwargs
        self._verbose = kwargs.get("verbose",0)
        if self._verbose>0:
             print "Init multiplier system!"
        (conductor,char_nr)=dchar
        self._conductor=conductor
        self._char_nr=char_nr
        self._character = None
        self._level = group.generalised_level()
        if kwargs.has_key('character'):
            if str(type(kwargs['character'])).find('Dirichlet')>=0:
                self._character = kwargs['character']
                self._conductor=self._character.conductor()
                try:
                    self._char_nr=self._character.number()
                except:
                    for x in DirichletGroup_conrey(self._conductor):
                        if x.sage_character() ==  self._character:
                            self._char_nr=x.number()
        elif group.is_congruence():
            if conductor<=0:
                    self._conductor=group.level(); self._char_nr=1
            if char_nr>=0:
                self._char_nr=char_nr
            
            if self._char_nr==0 or self._char_nr==1:
                self._character = trivial_character(self._conductor)
            elif self._char_nr==-1:                
                if self._conductor % 4 == 3:
                    self._character = kronecker_character(-self._conductor)
                elif self._conductor % 4 == 1:
                    self._character = kronecker_character(self._conductor)                    
                assert self._character.conductor()==self._conductor
            elif self._char_nr<=-2:
                self._character = kronecker_character_upside_down(self._conductor)    
            else:
                self._character = DirichletCharacter_conrey(DirichletGroup_conrey(self._conductor),self._char_nr).sage_character()
        else:
            self._conductor = 1
            self._character = trivial_character(1)
        #if not hasattr(self._character,'is_trivial'):
        #    if isinstance(self._character,(int,Integer)) and group.is_congruence():
        #        j = self._character
        #        self._character = DirichletGroup(group.level())[j]
        ## Extract the class name for the reduce algorithm
        self._class_name=str(type(self))[1:-2].split(".")[-1]
        if not isinstance(dimension,(int,Integer)):
            raise ValueError,"Dimension must be integer!"
        self._is_dual = dual
        self._is_trivial=is_trivial and self._character.is_trivial()
        if is_trivial and self._character.order()<=2:
            self._is_real=True
        else:
            self._is_real=False
        self._character_values = [] ## Store for easy access

    def __getinitargs__(self):
        #print "get initargs"
        return (self._group,(self._conductor,self._char_nr),self._is_dual,self._is_trivial,self._dim)
        
    def __reduce__(self):
        #print "reduce!"
        t = self.__getinitargs__()
        return self.__class__,t 
    #return(TrivialMultiplier,(self._group,self._dim,(self._conductor,self._char_nr),self._is_dual,self._is_trivial))
    #    return(type(self),(self._group,self._dim,(self._conductor,self._char_nr),self._is_dual,self._is_trivial))

    def dual_multiplier(self):
        r"""
        Returns the dual multiplier of self.
        """
        m = copy(self)
        m._is_dual = int(not self._is_dual)
        o = self._character.order()
        m._character = self._character**(o-1)
        m._weight = QQ(2) - QQ(self.weight())
        return m
    
    def __repr__(self):
        r"""
        Needs to be defined in subclasses.
        """
        raise NotImplementedError

    def group(self):
        return self._group

    def is_dual(self):
        return int(self._is_dual)
    def level(self):
        return self._level
    def weight(self):
        r"""
        Return (modulo 2) whish weight self is a multiplier system consistent with
        """
        if self._is_trivial:
            self._weight = 0
            return self._weight
        if self._dim == 1:
            if self._weight is None:
                Z=SL2Z([-1,0,0,-1])
                v = self._action(Z)
                if v == 1:
                    self._weight = QQ(0)
                if v == -1:
                    self._weight = QQ(1)
                elif v == -I:
                    self._weight  = QQ(1)/QQ(2)
                elif v == I:
                    self._weight = QQ(1)/QQ(2)
                else:
                    raise NotImplementedError
        return self._weight
    
    def __call__(self,A):
        r"""
        For eficientcy we should also allow to act on lists
        """
        if isinstance(A,(ArithmeticSubgroupElement,SL2Z_elt,list)):
            if A not in self._group:
                raise ValueError,"Element %s is not in %s! " %(A,self._group)
            return self._action(A)
        else:
            raise NotImplementedError,"Do not know how the multiplier should act on {0}".format(A)

        
        
    def _action(self):
        raise NotImplemented," Needs to be overridden by subclasses!"
    def is_trivial(self):
        return self._is_trivial
    def is_real(self):
        return self._is_real

    def set_dual(self):
        self._is_dual = True #not self._is_dual

    def character(self):
        return self._character

    def weil_module(self):
        if hasattr(self,"_weil_module"):
            if self._verbose>1:
                print "self has weil_module!"
            return self._weil_module
        return None
            
    
    def rank(self):
        return self._dim

    def ambient_rank(self):
        r"""
        Return the dimension of the unsymmetrized space containing self.
        """
        if self._ambient_rank<>None:
            return self._ambient_rank
        else:
            return self._dim
        
    def __eq__(self,other):
        r"""
        A character is determined by the group it is acting on and its type, which is given by the representation.
        """
        if str(type(other)).find('Multiplier')<0:
            return False
        if self._group<>other._group:
            return False
        if self._dim<>other._dim:
            return False
        return self.__repr__()==other.__repr__()

    def __ne__(self,other):
        return not self.__eq__(other)
    
    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=",k
            print "v(Z)=",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)=",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 NotImplemented,"Override this function for vector-valued multipliers!"
        return v1==v