Esempio 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
Esempio 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
Esempio n. 3
0
    def _compute_simple_modules_graph_from_startpoint(self, s, p=None, cut_nonsimple_aniso=True, fast=1):
        # for forking this is necessary
        logger = get_logger(s)
        # print logger
        k = self._weight
        ###########################################################
        # Determine which primes need to be checked
        # According to the proof of Proposition XX in [BEF], we
        # only need to check primesnot dividing the 6*level(s),
        # for which prime_pol(s,p,k) <= 0.
        # For those primes, we check if there is any
        # k-simple fqm in s.C(p) and if not, we do not have to
        # consider p anymore.
        ###########################################################
        if p == None:
            p = 2
            N = Integer(6) * s.level()
            slp = N.prime_factors()
            for q in prime_range(next_prime(N) + 1):
                if not q in slp:
                    logger.info(
                        "Smallest prime not dividing 6*level({0}) = {1} is p = {2}".format(s, Integer(6) * s.level(), q))
                    p = q
                    break
            while prime_pol(s, p, k) <= 0 or p in slp:
                p = next_prime(p)
            p = uniq(prime_range(p) + slp)
        logger.info("Starting with s = {0} and primes = {1}".format(s, p))
        
        if isinstance(p, list):
            primes = p
        else:
            primes = [p]

        simple = s.is_simple(k, reduction = self._reduction, bound = self._bound)
        
        if not simple:
            logger.info("{0} is not simple.".format(s))

        # print simple
        s = FQM_vertex(s)
        # print s
        self.add_vertex(s)
        # print "added vertex ", s
        
        ############################################################
        # Starting from the list of primes we generated,
        # we now compute which primes we actually need to consider.
        # That is, the primes such that there is a fqm in s.C(p)
        # which is k-simple.
        ############################################################
        np = list()
        if cut_nonsimple_aniso and simple:
            for i in range(len(primes)):
                p = primes[i]
                fs = False
                for t in s.genus_symbol().C(p, False):
                    if t.is_simple(k, bound = self._bound):
                        fs = True
                        logger.debug("Setting fs = True")
                        break
                if fs:
                    np.append(p)
        primes = np
        # print "here", primes
        logger.info("primes for graph for {0}: {1}".format(s, primes))
        # if len(primes) == 0:
        #    return
        heights = self._heights
        h = 0
        if not heights.has_key(h):
            heights[h] = [s]
        else:
            if heights[h].count(s) == 0:
                heights[h].append(s)
        vertex_colors = self._vertex_colors
        nonsimple_color = self._nonsimple_color
        simple_color = self._simple_color
        # Bs contains the modules of the current level (= height = h)
        Bs = [s]
        # set the correct color for the vertex s
        if simple:
            if vertex_colors[simple_color].count(s) == 0:
                vertex_colors[simple_color].append(s)
        elif vertex_colors[nonsimple_color].count(s) == 0:
            vertex_colors[nonsimple_color].append(s)
        
        ###################################################
        # MAIN LOOP
        # we loop until we haven't found any simple fqm's
        ###################################################
        while simple:
            h = h + 1
            if not heights.has_key(h):
                heights[h] = list()
            # the list Bss will contain the k-simple modules of the next height level
            # recall that Bs contains the modules of the current height level
            Bss = list()
            simple = False
            # checklist = modules that we need to check for with .is_simple(k)
            # we assemble this list because afterwards
            # we check them in parallel
            checklist = []
            for s1 in Bs:
                Bs2 = list()
                for p in primes:
                    # check if we really need to check p for s1
                    # otherwise none of the fqm's in s1.C(p) are simple
                    # and we will not consider them.
                    if prime_pol(s1.genus_symbol(), p, k) <= 0:
                        Bs2 = Bs2 + s1.genus_symbol().C(p, False)
                    else:
                        logger.info(
                            "Skipping p = {0} for s1 = {1}".format(p, s1))
                        # print "Skipping p = {0} for s1 = {1}".format(p, s1)
                # print "Bs2 = ", Bs2
                # now we actually check the symbols in Bs2
                for s2 in Bs2:
                    if s2.max_rank() > self._rank_limit:
                        # we skip s2 if its minimal number of generators
                        # is > than the given rank_limit.
                        continue
                    s2 = FQM_vertex(s2)
                    skip = False
                    for v in self._heights[h]:
                        # we skip symbols that correspond to isomorphic modules
                        if v.genus_symbol().defines_isomorphic_module(s2.genus_symbol()):
                            skip = True
                            logger.debug(
                                "skipping {0} b/c isomorphic to {1}".format(s2.genus_symbol(), v.genus_symbol()))
                            s2 = v
                            break
                    if skip:
                        continue
                    if not skip:
                        self.add_vertex(s2)
                        heights[h].append(s2)
                    self.update_edges(s2, h, fast=fast)
                    # before using the actual dimension formula
                    # we check if there is already a non-k-simple neighbor
                    # (an incoming edge from a non-k-simple module)
                    # which would imply that s2 is not k-simple.
                    has_nonsimple_neighbor = False
                    for e in self.incoming_edges(s2):
                        if vertex_colors[nonsimple_color].count(e[0]) > 0:
                            has_nonsimple_neighbor = True
                            logger.debug(
                                "Has nonsimple neighbor: {0}".format(s2.genus_symbol()))
                            break
                    if has_nonsimple_neighbor:
                        #not simple
                        if not vertex_colors[nonsimple_color].count(s2) > 0:
                            vertex_colors[nonsimple_color].append(s2)
                    else:
                        checklist.append((s2, k, self._reduction, self._bound))
            logger.debug("checklist = {0}".format(checklist))
            # check the modules in checklist
            # for being k-simple
            # this is done in parallel
            # when a process returns
            # we add the vertex and give it its appropriate color
            if NCPUS1 == 1:
                checks = [([[s[0]]],check_simple(*s)) for s in checklist]
            else:
                checks = list(check_simple(checklist))
            logger.info("checks = {0}".format(checks))
            for check in checks:
                s2 = check[0][0][0]
                if check[1]:
                    simple = True
                    logger.info(
                        "Found simple module: {0}".format(s2.genus_symbol()))
                    Bss.append(s2)
                    if not vertex_colors[simple_color].count(s2) > 0:
                        vertex_colors[simple_color].append(s2)
                else:
                    if not vertex_colors[nonsimple_color].count(s2) > 0:
                        vertex_colors[nonsimple_color].append(s2)
            Bs = Bss
        simple = [v.genus_symbol() for v in vertex_colors[simple_color]]
        self._simple = uniq(simple)
Esempio n. 4
0
    def _compute_simple_modules_graph_from_startpoint(self,
                                                      s,
                                                      p=None,
                                                      cut_nonsimple_aniso=True,
                                                      fast=1):
        # for forking this is necessary
        logger = get_logger(s)
        # print logger
        k = self._weight
        ###########################################################
        # Determine which primes need to be checked
        # According to the proof of Proposition XX in [BEF], we
        # only need to check primesnot dividing the 6*level(s),
        # for which prime_pol(s,p,k) <= 0.
        # For those primes, we check if there is any
        # k-simple fqm in s.C(p) and if not, we do not have to
        # consider p anymore.
        ###########################################################
        if p == None:
            p = 2
            N = Integer(6) * s.level()
            slp = N.prime_factors()
            for q in prime_range(next_prime(N) + 1):
                if not q in slp:
                    logger.info(
                        "Smallest prime not dividing 6*level({0}) = {1} is p = {2}"
                        .format(s,
                                Integer(6) * s.level(), q))
                    p = q
                    break
            while prime_pol(s, p, k) <= 0 or p in slp:
                p = next_prime(p)
            p = uniq(prime_range(p) + slp)
        logger.info("Starting with s = {0} and primes = {1}".format(s, p))

        if isinstance(p, list):
            primes = p
        else:
            primes = [p]

        simple = s.is_simple(k, reduction=self._reduction, bound=self._bound)

        if not simple:
            logger.info("{0} is not simple.".format(s))

        # print simple
        s = FQM_vertex(s)
        # print s
        self.add_vertex(s)
        # print "added vertex ", s

        ############################################################
        # Starting from the list of primes we generated,
        # we now compute which primes we actually need to consider.
        # That is, the primes such that there is a fqm in s.C(p)
        # which is k-simple.
        ############################################################
        np = list()
        if cut_nonsimple_aniso and simple:
            for i in range(len(primes)):
                p = primes[i]
                fs = False
                for t in s.genus_symbol().C(p, False):
                    if t.is_simple(k, bound=self._bound):
                        fs = True
                        logger.debug("Setting fs = True")
                        break
                if fs:
                    np.append(p)
        primes = np
        # print "here", primes
        logger.info("primes for graph for {0}: {1}".format(s, primes))
        # if len(primes) == 0:
        #    return
        heights = self._heights
        h = 0
        if not heights.has_key(h):
            heights[h] = [s]
        else:
            if heights[h].count(s) == 0:
                heights[h].append(s)
        vertex_colors = self._vertex_colors
        nonsimple_color = self._nonsimple_color
        simple_color = self._simple_color
        # Bs contains the modules of the current level (= height = h)
        Bs = [s]
        # set the correct color for the vertex s
        if simple:
            if vertex_colors[simple_color].count(s) == 0:
                vertex_colors[simple_color].append(s)
        elif vertex_colors[nonsimple_color].count(s) == 0:
            vertex_colors[nonsimple_color].append(s)

        ###################################################
        # MAIN LOOP
        # we loop until we haven't found any simple fqm's
        ###################################################
        while simple:
            h = h + 1
            if not heights.has_key(h):
                heights[h] = list()
            # the list Bss will contain the k-simple modules of the next height level
            # recall that Bs contains the modules of the current height level
            Bss = list()
            simple = False
            # checklist = modules that we need to check for with .is_simple(k)
            # we assemble this list because afterwards
            # we check them in parallel
            checklist = []
            for s1 in Bs:
                Bs2 = list()
                for p in primes:
                    # check if we really need to check p for s1
                    # otherwise none of the fqm's in s1.C(p) are simple
                    # and we will not consider them.
                    if prime_pol(s1.genus_symbol(), p, k) <= 0:
                        Bs2 = Bs2 + s1.genus_symbol().C(p, False)
                    else:
                        logger.info("Skipping p = {0} for s1 = {1}".format(
                            p, s1))
                        # print "Skipping p = {0} for s1 = {1}".format(p, s1)
                # print "Bs2 = ", Bs2
                # now we actually check the symbols in Bs2
                for s2 in Bs2:
                    if s2.max_rank() > self._rank_limit:
                        # we skip s2 if its minimal number of generators
                        # is > than the given rank_limit.
                        continue
                    s2 = FQM_vertex(s2)
                    skip = False
                    for v in self._heights[h]:
                        # we skip symbols that correspond to isomorphic modules
                        if v.genus_symbol().defines_isomorphic_module(
                                s2.genus_symbol()):
                            skip = True
                            logger.debug(
                                "skipping {0} b/c isomorphic to {1}".format(
                                    s2.genus_symbol(), v.genus_symbol()))
                            s2 = v
                            break
                    if skip:
                        continue
                    if not skip:
                        self.add_vertex(s2)
                        heights[h].append(s2)
                    self.update_edges(s2, h, fast=fast)
                    # before using the actual dimension formula
                    # we check if there is already a non-k-simple neighbor
                    # (an incoming edge from a non-k-simple module)
                    # which would imply that s2 is not k-simple.
                    has_nonsimple_neighbor = False
                    for e in self.incoming_edges(s2):
                        if vertex_colors[nonsimple_color].count(e[0]) > 0:
                            has_nonsimple_neighbor = True
                            logger.debug("Has nonsimple neighbor: {0}".format(
                                s2.genus_symbol()))
                            break
                    if has_nonsimple_neighbor:
                        #not simple
                        if not vertex_colors[nonsimple_color].count(s2) > 0:
                            vertex_colors[nonsimple_color].append(s2)
                    else:
                        checklist.append((s2, k, self._reduction, self._bound))
            logger.debug("checklist = {0}".format(checklist))
            # check the modules in checklist
            # for being k-simple
            # this is done in parallel
            # when a process returns
            # we add the vertex and give it its appropriate color
            if NCPUS1 == 1:
                checks = [([[s[0]]], check_simple(*s)) for s in checklist]
            else:
                checks = list(check_simple(checklist))
            logger.info("checks = {0}".format(checks))
            for check in checks:
                s2 = check[0][0][0]
                if check[1]:
                    simple = True
                    logger.info("Found simple module: {0}".format(
                        s2.genus_symbol()))
                    Bss.append(s2)
                    if not vertex_colors[simple_color].count(s2) > 0:
                        vertex_colors[simple_color].append(s2)
                else:
                    if not vertex_colors[nonsimple_color].count(s2) > 0:
                        vertex_colors[nonsimple_color].append(s2)
            Bs = Bss
        simple = [v.genus_symbol() for v in vertex_colors[simple_color]]
        self._simple = uniq(simple)