Exemplo n.º 1
0
def genus_symbol_string_to_dict(s):
    sl = s.split('.')
    d = dict()
    for s in sl:
        L1 = s.split('^')
        if len(L1) > 2:
            raise ValueError()
        elif len(L1) == 1:
            nn = 1
        else:
            nn = L1[1]
        n = Integer(nn)
        L1 = L1[0].split("_")
        q = Integer(L1[0])
        if len(L1) > 2:  # more than one _ in item
            raise ValueError
        elif len(L1) == 2:
            if Integer(L1[1]) in range(8):
                t = Integer(L1[1])
            else:
                raise ValueError, "Type given, which ist not in 0..7: %s" % (
                    L1[1])
        else:
            t = None
        if not (n != 0 and q != 1 and q.is_prime_power() and
                (None == t or (is_even(q) and t % 2 == n % 2)) and
                (not (None == t and is_even(q)) or 0 == n % 2)):
            raise ValueError, "{0} is not a valid signature!".format(s)
        p = q.prime_factors()[0]
        r = q.factor()[0][1]
        eps = sign(n)
        n = abs(n)
        if not d.has_key(p):
            d[p] = list()
        if p == 2:
            if t == None:
                print "eps = ", eps
                if not is_even(n):
                    raise ValueError()
                d[p].append([
                    r, n, 3 * (-1)**(Integer(n - 2) / 2) % 8 if eps == -1 else
                    (-1)**(Integer(n)), t, 4 if eps == -1 else 0
                ])
                print d
            else:
                if t.kronecker(2) == eps:
                    det = t % 8
                else:
                    if eps == -1:
                        det = 3
                    else:
                        det = 1
                d[p].append([r, n, det, 1, t % 8])
        else:
            d[p].append([r, n, eps])
    return d
Exemplo n.º 2
0
def genus_symbol_string_to_dict(s):
    sl = s.split('.')
    d = dict()
    for s in sl:
        L1 = s.split('^')
        if len(L1)>2:
            raise ValueError()
        elif len(L1) == 1:
            nn = 1
        else:
            nn = L1[1]
        n = Integer(nn)
        L1= L1[0].split("_")
        q = Integer(L1[0])
        if len(L1) > 2: # more than one _ in item
            raise ValueError
        elif len(L1) == 2:
            if Integer(L1[1]) in range(8):
                t = Integer(L1[1])
            else:
                raise ValueError, "Type given, which ist not in 0..7: %s"%(L1[1])
        else:
            t = None
        if not (n != 0 and q != 1 and q.is_prime_power()
                and ( None == t or (is_even(q) and t%2 == n%2))
                and ( not (None == t and is_even(q)) or 0 == n%2)
                ):
            raise ValueError,"{0} is not a valid signature!".format(s)
        p = q.prime_factors()[0]
        r = q.factor()[0][1]
        eps = sign(n)
        n = abs(n)
        if not d.has_key(p):
            d[p]=list()
        if p==2:
            if t == None:
                print "eps = ", eps
                if not is_even(n):
                    raise ValueError()
                d[p].append([r, n, 3*(-1)**(Integer(n-2)/2) % 8 if eps == -1 else (-1)**(Integer(n)),t,4 if eps == -1 else 0])
                print d
            else:
                if t.kronecker(2) == eps:
                    det = t % 8
                else:
                    if eps == -1:
                        det = 3
                    else:
                        det = 1
                d[p].append([r,n,det,1,t % 8])
        else:
            d[p].append([r,n,eps])
    return d
Exemplo n.º 3
0
 def check_character_values(self, rec, verbose=False):
     """
     The x's listed in values and values_gens should be coprime to the modulus N in the label.
     For x's that appear in both values and values_gens, the value should be the same.
     """
     # TIME about 3000s for full table
     N = Integer(rec['modulus'])
     v2, u2 = N.val_unit(2)
     if v2 == 1:
         # Z/2 doesn't contribute generators, but 2 divides N
         adjust2 = -1
     elif v2 >= 3:
         # Z/8 and above requires two generators
         adjust2 = 1
     else:
         adjust2 = 0
     if N == 1:
         # The character stores a value in the case N=1
         ngens = 1
     else:
         ngens = len(N.factor()) + adjust2
     vals = rec['values']
     val_gens = rec['values_gens']
     val_gens_dict = dict(val_gens)
     if len(vals) != min(12, euler_phi(N)) or len(val_gens) != ngens:
         if verbose:
             print "Length failure", len(vals), euler_phi(N), len(
                 val_gens), ngens
         return False
     if N > 2 and (vals[0][0] != N - 1 or vals[1][0] != 1 or vals[1][1] != 0
                   or vals[0][1] not in [0, rec['order'] // 2]):
         if verbose:
             print "Initial value failure", N, rec['order'], vals[:2]
         return False
     if any(N.gcd(g) > 1 for g, gval in val_gens + vals):
         if verbose:
             print "gcd failure", [
                 g for g, gval in val_gens + vals if N.gcd(g) > 1
             ]
         return False
     for g, val in vals:
         if g in val_gens_dict and val != val_gens_dict[g]:
             if verbose:
                 print "Mismatch failure", g, val, val_gens_dict[g]
             return False
     return True
Exemplo n.º 4
0
 def check_character_values(self, rec, verbose=False):
     """
     The x's listed in values and values_gens should be coprime to the modulus N in the label.
     For x's that appear in both values and values_gens, the value should be the same.
     """
     # TIME about 3000s for full table
     N = Integer(rec['modulus'])
     v2, u2 = N.val_unit(2)
     if v2 == 1:
         # Z/2 doesn't contribute generators, but 2 divides N
         adjust2 = -1
     elif v2 >= 3:
         # Z/8 and above requires two generators
         adjust2 = 1
     else:
         adjust2 = 0
     if N == 1:
         # The character stores a value in the case N=1
         ngens = 1
     else:
         ngens = len(N.factor()) + adjust2
     vals = rec['values']
     val_gens = rec['values_gens']
     val_gens_dict = dict(val_gens)
     if len(vals) != min(12, euler_phi(N)) or len(val_gens) != ngens:
         if verbose:
             print "Length failure", len(vals), euler_phi(N), len(val_gens), ngens
         return False
     if N > 2 and (vals[0][0] != N-1 or vals[1][0] != 1 or vals[1][1] != 0 or vals[0][1] not in [0, rec['order']//2]):
         if verbose:
             print "Initial value failure", N, rec['order'], vals[:2]
         return False
     if any(N.gcd(g) > 1 for g, gval in val_gens+vals):
         if verbose:
             print "gcd failure", [g for g, gval in val_gens+vals if N.gcd(g) > 1]
         return False
     for g, val in vals:
         if g in val_gens_dict and val != val_gens_dict[g]:
             if verbose:
                 print "Mismatch failure", g, val, val_gens_dict[g]
             return False
     return True
Exemplo n.º 5
0
class ConreyCharacter:
    """
    tiny implementation on Conrey index only
    """
    def __init__(self, modulus, number):
        assert gcd(modulus, number) == 1
        self.modulus = Integer(modulus)
        self.number = Integer(number)

    @property
    def texname(self):
        from lmfdb.characters.web_character import WebDirichlet
        return WebDirichlet.char2tex(self.modulus, self.number)

    @cached_method
    def modfactor(self):
        return self.modulus.factor()

    @cached_method
    def conductor(self):
        cond = Integer(1)
        number = self.number
        for p, e in self.modfactor():
            mp = Mod(number, p**e)
            if mp == 1:
                continue
            if p == 2:
                cond = 4
                if number % 4 == 3:
                    mp = -mp
            else:
                cond *= p
                mp = mp**(p - 1)
            while mp != 1:
                cond *= p
                mp = mp**p
        return cond

    def is_primitive(self):
        return self.conductor() == self.modulus

    @cached_method
    def parity(self):
        number = self.number
        par = 0
        for p, e in self.modfactor():
            if p == 2:
                if number % 4 == 3:
                    par = 1 - par
            else:
                phi2 = (p - 1) / Integer(2) * p**(e - 1)
                if Mod(number, p**e)**phi2 != 1:
                    par = 1 - par
        return par

    def is_odd(self):
        return self.parity() == 1

    def is_even(self):
        return self.parity() == 0

    @cached_method
    def multiplicative_order(self):
        return Mod(self.number, self.modulus).multiplicative_order()

    @property
    def order(self):
        return self.multiplicative_order()

    @cached_method
    def kronecker_symbol(self):
        c = self.conductor()
        p = self.parity()
        return kronecker_symbol(symbol_numerator(c, p))
Exemplo n.º 6
0
class ConreyCharacter:
    """
    tiny implementation on Conrey index only
    """

    def __init__(self, modulus, number):
        assert gcd(modulus, number)==1
        self.modulus = Integer(modulus)
        self.number = Integer(number)

    @property
    def texname(self):
        return WebDirichlet.char2tex(self.modulus, self.number)

    @cached_method
    def modfactor(self):
        return self.modulus.factor()

    @cached_method
    def conductor(self):
        cond = Integer(1);
        number = self.number
        for p,e in self.modfactor():
            mp = Mod(number, p**e);
            if mp == 1:
                continue
            if p == 2:
                cond = 4
                if number % 4 == 3:
                    mp = -mp
            else:
                cond *= p
                mp = mp**(p-1)
            while mp != 1:
                cond *= p
                mp = mp**p
        return cond

    def is_primitive(self):
        return self.conductor() == self.modulus

    @cached_method
    def parity(self):
        number = self.number
        par = 0;
        for p,e in self.modfactor():
            if p == 2:
                if number % 4 == 3:
                    par = 1 - par
            else:
                phi2 = (p-1)/Integer(2) * p **(e-1)
                if Mod(number, p ** e)**phi2 != 1:
                    par = 1 - par
        return par

    def is_odd(self):
        return self.parity() == 1

    def is_even(self):
        return self.parity() == 0

    @cached_method
    def multiplicative_order(self):
        return Mod(self.number, self.modulus).multiplicative_order()

    @property
    def order(self):
        return self.multiplicative_order()

    @cached_method
    def kronecker_symbol(self):
        c = self.conductor()
        p = self.parity()
        return kronecker_symbol(symbol_numerator(c, p))
Exemplo n.º 7
0
class ConreyCharacter(object):
    """
    tiny implementation on Conrey index only
    """
    def __init__(self, modulus, number):
        assert gcd(modulus, number) == 1
        self.modulus = Integer(modulus)
        self.number = Integer(number)
        self.G = Pari("znstar({},1)".format(modulus))
        self.chi_pari = pari("znconreylog(%s,%d)" % (self.G, self.number))
        self.chi_0 = None
        self.indlabel = None

    @property
    def texname(self):
        from lmfdb.characters.web_character import WebDirichlet
        return WebDirichlet.char2tex(self.modulus, self.number)

    @cached_method
    def modfactor(self):
        return self.modulus.factor()

    @cached_method
    def conductor(self):
        B = pari("znconreyconductor(%s,%s,&chi0)" % (self.G, self.chi_pari))
        if B.type() == 't_INT':
            # means chi is primitive
            self.chi_0 = self.chi_pari
            self.indlabel = self.number
            return int(B)
        else:
            self.chi_0 = pari("chi0")
            G_0 = Pari("znstar({},1)".format(B))
            self.indlabel = int(pari("znconreyexp(%s,%s)" % (G_0, self.chi_0)))
            return int(B[0])

    def is_primitive(self):
        return self.conductor() == self.modulus

    @cached_method
    def parity(self):
        number = self.number
        par = 0
        for p, e in self.modfactor():
            if p == 2:
                if number % 4 == 3:
                    par = 1 - par
            else:
                phi2 = (p - 1) / Integer(2) * p**(e - 1)
                if Mod(number, p**e)**phi2 != 1:
                    par = 1 - par
        return par

    def is_odd(self):
        return self.parity() == 1

    def is_even(self):
        return self.parity() == 0

    @cached_method
    def multiplicative_order(self):
        return Mod(self.number, self.modulus).multiplicative_order()

    @property
    def order(self):
        return self.multiplicative_order()

    @cached_method
    def kronecker_symbol(self):
        c = self.conductor()
        p = self.parity()
        return kronecker_symbol(symbol_numerator(c, p))

    def conreyangle(self, x):
        return Rational(
            pari("chareval(%s,znconreylog(%s,%d),%d)" %
                 (self.G, self.G, self.number, x)))

    def gauss_sum_numerical(self, a):
        # There seems to be a bug in pari when a is a multiple of the modulus,
        # so we deal with that separately
        if self.modulus.divides(a):
            if self.conductor() == 1:
                return euler_phi(self.modulus)
            else:
                return Integer(0)
        else:
            return pari("znchargauss(%s,%s,a=%d)" % (self.G, self.chi_pari, a))

    def sage_zeta_order(self, order):
        return 1 if self.modulus <= 2 else lcm(2, order)

    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))