Example #1
0
    def __init__(self, G_0):
        a, ai, b, bi, c, ci, d, di = G_0.gens

        # 5,5 coxeter subgroup
        G_1 = Group.generate([a, b, c])
        assert G_0.is_subgroup(G_1)

        # orientation subgroup
        L_0 = Group.generate([a * b, a * d])
        assert G_0.is_subgroup(L_0)
        orients = G_0.left_cosets(L_0)
        assert len(orients) == 2

        H_1 = Group.generate([a, b])
        self.faces = G_1.left_cosets(H_1)
        self.act_faces = G_1.action_subgroup(H_1)

        print("faces:", len(self.faces))

        return

        K_1 = Group.generate([b, c])
        vertices = G_1.left_cosets(K_1)

        J_1 = Group.generate([a, c])
        edges = G_1.left_cosets(J_1)

        print("faces: %d, edges: %d, vertices: %d" %
              (len(faces), len(edges), len(vertices)))

        self.faces = faces
        self.edges = edges
        self.vertices = vertices
        self.act_faces = act_faces
Example #2
0
def get_perms(items, parts):
    perms = []
    for part in parts:
        for i in range(len(part) - 1):
            perm = dict((item, item) for item in items)
            perm[part[i]] = part[i + 1]
            perm[part[i + 1]] = part[i]
            perm = Perm(perm, items)
            perms.append(perm)
    if not perms:
        # identity
        perms = [Perm(dict((item, item) for item in items), items)]
    G = Group.generate(perms)
    return G
Example #3
0
def petersen_graph(R=2.0, r=1.0):
    nodes = range(10)
    layout = {}
    w = 2 * pi / 6
    for i in range(6):
        layout[i] = R * cos(w * i), R * sin(w * i)
    w = 2 * pi / 3
    for i in range(6, 9):
        layout[i] = r * sin(w * i), -r * cos(w * i)
    layout[9] = (0., 0.)
    edges = [(i, (i + 1) % 6) for i in range(6)]
    for i in range(3):
        edges.append((6 + i, 9))
        edges.append((6 + i, 2 * i))
        edges.append((6 + i, (2 * i + 3) % 6))

    if 0:
        # TODO: should be able to construct G from all graph
        # automorphisms. Choose the ones that preserve the distance between nodes.

        perm = {}
        for i in range(6):
            perm[i] = (i + 2) % 6
        for i in range(3):
            perm[i + 6] = (i + 1) % 3 + 6
        perm[9] = 9
        g = Perm(perm, nodes)

        perm = {0: 3, 1: 2, 2: 1, 3: 0, 4: 5, 5: 4, 6: 6, 7: 8, 8: 7, 9: 9}
        h = Perm(perm, nodes)

        G = Group.generate([g, h])
        assert len(G) == 6

    yield Graph(nodes, edges, layout)

    # ------------

    edges = [(i, (i + 1) % 5) for i in range(5)]
    for i in range(5):
        edges.append((i, i + 5))
        edges.append((i + 5, (i + 2) % 5 + 5))

    w = 2 * pi / 5
    layout = {}
    for i in range(5):
        layout[i] = R * sin(w * i), R * cos(w * i)
        layout[i + 5] = r * sin(w * i), r * cos(w * i)

    yield Graph(nodes, edges, layout)
Example #4
0
def main():

    if argv.A_3:
        W = Weyl.build_A(3)
    elif argv.A_4:
        W = Weyl.build_A(4)
    elif argv.B_2:
        W = Weyl.build_B(2)
    elif argv.B_3:
        W = Weyl.build_B(3)
    elif argv.D_4:
        W = Weyl.build_D(4)
    else:
        return

    G = Group.generate(W.gen)
#    for g in W.gen:
#        print(g)
#
#    for root in W.roots:
#        print(root, end=" ")
#        if root in W.simple:
#            print("*")
#        else:
#            print("")

    groups = []
    for subset in all_subsets(len(W.simple)):
        #print("subset:", subset)
        simple = tuple(W.simple[i] for i in subset)
        H = parabolic(W.roots, simple)
        #print("H:", len(H))
        assert G.is_subgroup(H)
        groups.append(H)

    assert len(groups)==2**(len(W.simple))
    print("parabolic subgroups:", len(groups))
    print("orders:", [len(H) for H in groups])

    Hs = conjugacy_subgroups(G, groups)
    print("conjugacy_subgroups:", len(Hs))

    burnside(G, Hs)
Example #5
0
def parabolic(roots, simple):
    "use _generators from reflections of simple roots"
    for root in simple:
        assert root in roots
    n = len(roots[0])
    idxs = range(n)
    lookup = dict((root, i) for (i, root) in enumerate(roots))
    gen = [] 
    for alpha in simple:
        #print "alpha:", alpha
        r0 = sum(alpha[i]*alpha[i] for i in idxs)
        perm = [] 
        for root in roots:
            #print "    root:", root
            r = sum(alpha[i]*root[i] for i in idxs)
            _root = tuple(root[i] - 2*Fraction(r, r0)*alpha[i] for i in idxs)
            #print "    _root:", _root
            perm.append(lookup[_root])
        perm = Perm(perm, roots)
        gen.append(perm)
    return Group.generate(gen, items=roots)
Example #6
0
def cayley(gen):

    G = Group.generate(gen)
    lookup = dict((g, i) for (i, g) in enumerate(G))
    graph = nx.Graph()  # undirected graph, must have gen closed under inverse
    for i, g in enumerate(G):
        graph.add_node(i)

    #for g in gen:
    #    assert (g*g).is_identity()
    for g in gen:
        assert g.inverse() in gen  # undirected graph!

    edges = set()
    for g in G:
        for h in gen:
            hg = h * g
            if (hg, g) in edges:
                continue
            edges.add((g, hg))
    for g, h in edges:
        graph.add_edge(lookup[g], lookup[h])

    return graph
Example #7
0
def test_galois():
    p = argv.get("p", 2)
    r = argv.get("r", 2)

    print("q =", p**r)
    F = GF(p**r)
    print("GF(%d) = GF(%d)[x]/(%s)" % (p**r, p, F.mod))
    print("omega =", F.omega)
    omega = F.omega
    #assert omega**2 == omega + 1

    els = F.elements
    assert len(els) == len(set(els)) == p**r

    for a in els:
        for b in els:
            if b != 0:
                c = a / b  # XXX fails for p=3, r=4
                assert c * b == a

    def orbit(a):
        items = set([a])
        while 1:
            a = F.frobenius(a)
            if a in items:
                break
            items.add(a)
        return items

    lookup = {e: i for (i, e) in enumerate(els)}
    for i, e in enumerate(els):
        print("%s: %s" % (i, e))
    g = {lookup[e]: lookup[F.frobenius(e)] for e in els}
    #print(["%s:%s"%(k,v) for (k,v) in g.items()])
    values = set(g.values())
    assert len(values) == len(g)
    items = list(range(len(els)))
    g = Perm(g, items)
    I = Perm.identity(items)
    G = [I]
    h = g
    print(g)
    while h != I:
        G.append(h)
        h = g * h
        #print(len(G))
        assert len(G) <= p**r
    print("|G| =", len(G))
    G = Group.generate([g])
    print("|G| =", len(G))

    for i in els:
        n = len(orbit(i))
        if n == 1:
            print("*", end="")
        print(n, end=" ")
    print()

    def inner(u, v):
        r = u * F.frobenius(v) - F.frobenius(u) * v
        return r

    print("els:", end=" ")
    for u in els:
        print(u, end=" ")
    print()
    print("inner(u,u):", end=" ")
    for u in els:
        print(inner(u, u), end=" ")
    print()
    print("inner(u,v):")
    for u in els:
        for v in els:
            print(inner(u, v), end=" ")
        print()

    print()
    for u in els:
        #print([int(inner(u,v)==0) for v in els])
        for v in els:
            i = int(inner(u, v) == 0)
            print(i or '.', end=" ")
        print()

    print("test_galois: OK")
Example #8
0
 def get_group(self):
     gens = self.get_gens()
     G = Group.generate(gens)
     return G
Example #9
0
def make_bring():

    # ------------------------------------------------

    # Bring's curve rotation group
    ngens = 2
    a, ai, b, bi = range(2 * ngens)
    rels = [(ai, a), (bi, b), (a, ) * 5, (b, ) * 2]
    rels += [(a, a, a, b) * 3]
    graph = Schreier(2 * ngens, rels)
    #graph.DEBUG = True
    graph.build()
    assert len(graph) == 60  # == 12 * 5

    # --------------- Group ------------------
    G = graph.get_group()
    #burnside(G)
    assert len(G.gens) == 4
    ai, a, bi, b = G.gens
    assert a == ~ai
    assert b == ~bi

    assert a.order() == 5
    assert b.order() == 2
    H = Group.generate([a])

    faces = G.left_cosets(H)
    assert len(faces) == 12
    #hom = G.left_action(faces)

    ab = a * b
    K = Group.generate([ab])
    vertices = G.left_cosets(K)
    assert len(vertices) == 12

    J = Group.generate([b])
    edges = G.left_cosets(J)
    assert len(edges) == 30

    from bruhat.solve import shortstr, zeros2, dot2
    from numpy import alltrue, zeros, dot

    def get_adj(left, right):
        A = zeros2((len(left), len(right)))
        for i, l in enumerate(left):
            for j, r in enumerate(right):
                lr = l.intersect(r)
                A[i, j] = len(lr)
        return A

    Hz = get_adj(faces, edges)
    Hxt = get_adj(edges, vertices)
    #print(shortstr(Hz))
    #print()
    #print(shortstr(Hxt))
    #print()

    assert alltrue(dot2(Hz, Hxt) == 0)

    # ------------ _oriented version ---------------

    # Bring's curve reflection group
    ngens = 3
    a, ai, b, bi, c, ci = range(2 * ngens)
    rels = [
        (ai, a),
        (bi, b),
        (ci, c),
        (a, ) * 2,
        (b, ) * 2,
        (c, ) * 2,
        (a, b) * 5,
        (b, c) * 5,
        (a, c) * 2,
    ]
    a1 = (b, a)
    b1 = (a, c)
    rels += [(3 * a1 + b1) * 3]
    graph = Schreier(2 * ngens, rels)
    graph.build()
    assert len(graph) == 120  # == 12 * 10

    # --------------- Group ------------------
    G = graph.get_group()
    assert len(G) == 120

    a, ai, b, bi, c, ci = G.gens
    a1 = b * a
    b1 = a * c

    assert a1.order() == 5
    assert b1.order() == 2

    bc = b * c
    ba = b * a
    assert bc.order() == 5
    assert ba.order() == 5
    L = Group.generate([a1, b1])
    assert len(L) == 60, len(L)
    orients = G.left_cosets(L)
    assert len(orients) == 2
    #L, gL = orients
    orients = list(orients)

    H = Group.generate([a, b])
    assert len([g for g in H if g in L]) == 5
    faces = G.left_cosets(H)
    assert len(faces) == 12  # unoriented faces
    #hom = G.left_action(faces)
    o_faces = [face.intersect(orients[0]) for face in faces]  # oriented faces
    r_faces = [face.intersect(orients[1])
               for face in faces]  # reverse oriented faces

    K = Group.generate([b, c])
    vertices = G.left_cosets(K)
    assert len(vertices) == 12  # unoriented vertices
    o_vertices = [vertex.intersect(orients[0])
                  for vertex in vertices]  # oriented vertices

    J = Group.generate([a, c])
    u_edges = G.left_cosets(J)
    assert len(u_edges) == 30  # unoriented edges

    J = Group.generate([c])
    edges = G.left_cosets(J)
    assert len(edges) == 60, len(edges)  # oriented edges ?

    # Here we choose an orientation on each edge:
    pairs = {}
    for e in u_edges:
        pairs[e] = []
        for e1 in edges:
            if e.intersect(e1):
                pairs[e].append(e1)
        assert len(pairs[e]) == 2

    def shortstr(A):
        s = str(A)
        s = s.replace("0", '.')
        return s

    Hz = zeros((len(o_faces), len(u_edges)), dtype=int)
    for i, l in enumerate(o_faces):
        for j, e in enumerate(u_edges):
            le = l.intersect(e)
            if not le:
                continue
            e1, e2 = pairs[e]
            if e1.intersect(le):
                Hz[i, j] = 1
            elif e2.intersect(le):
                Hz[i, j] = -1
            else:
                assert 0

    Hxt = zeros((len(u_edges), len(o_vertices)), dtype=int)
    for i, e in enumerate(u_edges):
        for j, v in enumerate(o_vertices):
            ev = e.intersect(v)
            if not ev:
                continue
            e1, e2 = pairs[e]
            if e1.intersect(ev):
                Hxt[i, j] = 1
            elif e2.intersect(ev):
                Hxt[i, j] = -1
            else:
                assert 0

    #print(shortstr(Hz))
    #print()
    #print(shortstr(Hxt))
    #print()

    assert alltrue(dot(Hz, Hxt) == 0)
Example #10
0
def make_surface_54_oriented(G0):
    " find integer chain complex "
    from bruhat.solve import shortstr, zeros2, dot2
    from numpy import alltrue, zeros, dot

    print()
    print("|G0| =", len(G0))

    a, ai, b, bi, c, ci, d, di = G0.gens

    # 5,5 coxeter subgroup
    G_55 = Group.generate([a, b, c])
    assert G0.is_subgroup(G_55)

    # orientation subgroup
    L = Group.generate([a * b, a * d])
    #assert len(L) == 60, len(L)
    print("L:", len(L))
    orients = G0.left_cosets(L)
    assert len(orients) == 2
    orients = list(orients)

    H = Group.generate([a, b])
    faces = G_55.left_cosets(H)
    fold_faces = G0.left_cosets(H)
    print("faces:", len(faces))
    print("fold_faces:", len(fold_faces))
    #hom = G.left_action(faces)
    o_faces = [face.intersect(orients[0]) for face in faces]  # oriented faces
    r_faces = [face.intersect(orients[1])
               for face in faces]  # reverse oriented faces

    K = Group.generate([b, c])
    vertices = G_55.left_cosets(K)
    #assert len(vertices) == 12 # unoriented vertices
    o_vertices = [vertex.intersect(orients[0])
                  for vertex in vertices]  # oriented vertices
    print("o_vertices:", len(o_vertices))

    J0 = Group.generate([a, d])
    assert len(J0) == 8

    assert G0.is_subgroup(J0)
    act_edges = G0.action_subgroup(J0)
    act_fold_faces = G0.action_subgroup(H)
    #print("stab:", len(act_edges.get_stabilizer()))
    print("|G0| =", len(G0))
    print("edges:", len(G0) // len(J0))
    edges = G0.left_cosets(J0)
    #for e in edges:
    #    k = choice(e.perms)
    #    e1 = e.left_mul(~k)
    #    assert set(e1.perms) == set(J0.perms)
    fold_perms = []
    for i, g in enumerate(G0):
        assert g in G0
        #h_edge = act_edges.tgt[act_edges.send_perms[i]]
        #h_fold_faces = act_fold_faces.tgt[act_fold_faces.send_perms[i]]
        h_edge = act_edges[g]
        h_fold_faces = act_fold_faces[g]
        n_edge = len(h_edge.fixed())
        n_fold_faces = len(h_fold_faces.fixed())
        count = 0
        #perms = [] # extract action on the fixed edges
        #for e0 in edges:
        #    #e1 = e0.left_mul(g)
        #    e1 = g*e0
        #    if e0 != e1:
        #        continue
        #    perm = e0.left_mul_perm(g)
        #    #print(perm, end=" ")
        #    perms.append(perm)
        #    count += 1
        #assert count == n_edge
        if g.order() == 2 and g not in G_55 and g not in L:
            fold_perms.append(g)
        else:
            continue
        #print([p.order() for p in perms] or '', end="")
        print(
            "[|g|=%s,%s.%s.%s.%s]" % (
                g.order(),
                n_edge or ' ',  # num fixed edges
                n_fold_faces or ' ',  # num fixed faces+vertexes
                ["    ", "pres"
                 ][int(g in G_55)],  # preserves face/vertex distinction
                ["refl", "rot "][int(g in L)],  # oriented or un-oriented
            ),
            end=" ",
            flush=True)
        print()
    print()

    J = Group.generate([a, c])
    u_edges = G_55.left_cosets(J)
    print("u_edges:", len(u_edges))

    J = Group.generate([c])
    edges = G_55.left_cosets(J)
    print("edges:", len(edges))

    # Here we choose an orientation on each edge:
    pairs = {}
    for e in u_edges:
        pairs[e] = []
        for e1 in edges:
            if e.intersect(e1):
                pairs[e].append(e1)
        assert len(pairs[e]) == 2, len(pairs[e])

    def shortstr(A):
        s = str(A)
        s = s.replace("0", '.')
        return s

    Hz = zeros((len(o_faces), len(u_edges)), dtype=int)
    for i, l in enumerate(o_faces):
        for j, e in enumerate(u_edges):
            le = l.intersect(e)
            if not le:
                continue
            e1, e2 = pairs[e]
            if e1.intersect(le):
                Hz[i, j] = 1
            elif e2.intersect(le):
                Hz[i, j] = -1
            else:
                assert 0

    Hxt = zeros((len(u_edges), len(o_vertices)), dtype=int)
    for i, e in enumerate(u_edges):
        for j, v in enumerate(o_vertices):
            ev = e.intersect(v)
            if not ev:
                continue
            e1, e2 = pairs[e]
            if e1.intersect(ev):
                Hxt[i, j] = 1
            elif e2.intersect(ev):
                Hxt[i, j] = -1
            else:
                assert 0

    #print(shortstr(Hz))
    #print()
    #print(shortstr(Hxt))
    #print()

    assert alltrue(dot(Hz, Hxt) == 0)

    for perm in fold_perms:
        pass

    import qupy.ldpc.solve
    import bruhat.solve
    qupy.ldpc.solve.int_scalar = bruhat.solve.int_scalar
    from qupy.ldpc.css import CSSCode
    Hz = Hz % 2
    Hx = Hxt.transpose() % 2
    code = CSSCode(Hz=Hz, Hx=Hx)
    print(code)
Example #11
0
def make_surface_54(G_0):
    "find Z/2 chain complex"

    from bruhat.solve import shortstr, zeros2, dot2
    from numpy import alltrue, zeros, dot

    print("|G_0| =", len(G_0))

    a, ai, b, bi, c, ci, d, di = G_0.gens

    # 5,5 coxeter subgroup
    G_1 = Group.generate([a, b, c])
    assert G_0.is_subgroup(G_1)

    # orientation subgroup
    L_0 = Group.generate([a * b, a * d])
    assert G_0.is_subgroup(L_0)
    orients = G_0.left_cosets(L_0)
    assert len(orients) == 2

    H_1 = Group.generate([a, b])
    faces = G_1.left_cosets(H_1)
    #face_vertices = G_0.left_cosets(H_1) # G_0 swaps faces & vertices

    K_1 = Group.generate([b, c])
    vertices = G_1.left_cosets(K_1)

    J_1 = Group.generate([a, c])
    edges_1 = G_1.left_cosets(J_1)

    print("faces: %d, edges: %d, vertices: %d" %
          (len(faces), len(edges_1), len(vertices)))

    J_0 = Group.generate([a, d])
    assert len(J_0) == 8

    edges_0 = G_0.left_cosets(J_0)
    print("edges_0:", len(edges_0))

    assert G_0.is_subgroup(J_0)
    act_edges_0 = G_0.action_subgroup(J_0)
    #print("here")
    #while 1:
    #    sleep(1)

    from bruhat.solve import shortstr, zeros2, dot2, array2, solve
    from numpy import alltrue, zeros, dot

    def get_adj(left, right):
        A = zeros2((len(left), len(right)))
        for i, l in enumerate(left):
            for j, r in enumerate(right):
                lr = l.intersect(r)
                A[i, j] = len(lr) > 0
        return A

    Hz = get_adj(faces, edges_0)
    Hxt = get_adj(edges_0, vertices)
    Hx = Hxt.transpose()

    #print(shortstr(Hz))
    #print()
    #print(shortstr(Hxt))
    #print()

    assert alltrue(dot2(Hz, Hxt) == 0)

    #    act_fold_faces = G_0.action_subgroup(H_1)

    dualities = []
    idx = 0
    for i, g in enumerate(G_0):
        assert g in G_0
        h_edge_0 = act_edges_0[g]
        n_edge = len(h_edge_0.fixed())

        #        h_fold_faces = act_fold_faces[g]
        #        n_fold_faces = len(h_fold_faces.fixed())
        count = 0
        #perms = [] # extract action on the fixed edges
        for e0 in edges_0:
            e1 = g * e0
            if e0 != e1:
                continue
            count += 1
        #    perm = e0.left_mul_perm(g)
        #    #print(perm, end=" ")
        #    perms.append(perm)
        assert count == n_edge

        if g in G_1:
            continue
        elif g.order() != 2:
            continue
        #elif g in L_0:
        #    continue
        #elif g.order() == 2 and g not in G_1 and g not in L_0:

        perm = h_edge_0.get_idxs()
        dualities.append(perm)
        #if g not in L_0:
        #    check_432(Hz, Hx, perm)
        #    return
        result = is_422_cat_selfdual(Hz, Hx, perm)

        print(
            "%d: [|g|=%s,%s.%s.%s.%s]" % (
                len(dualities),
                g.order(),
                n_edge or ' ',  # num fixed edges
                #            n_fold_faces or ' ',  # num fixed faces+vertexes
                ["    ", "pres"
                 ][int(g in G_1)],  # preserves face/vertex distinction
                ["refl", "rot "][int(g in L_0)],  # oriented or un-oriented
                ["        ", "selfdual"][result],
            ),
            end=" ",
            flush=True)
        print()

    print()
Example #12
0
def main():

    p = argv.get("p", 3)
    deg = argv.get("deg", 1)

    field = FiniteField(p)

    if deg == 1:
        G = GL2(field)
        return

    base, field = field, field.extend(deg)

    assert len(field.elements) == p**deg
    print("GF(%d)"%len(field.elements))

    print(field.mod)
    print()

    items = [a for a in field.elements if a!=0]
    perm = Perm(dict((a, a**p) for a in items), items)
    G = Group.generate([perm])
    print("|G| =", len(G))

    orbits = G.orbits()
    print("orbits:", len(orbits), end=", ")
    fixed = 0
    for orbit in orbits:
        if len(orbit)==1:
            fixed += 1
        print(len(orbit), end=" ")
    print()
    print("fixed points:", fixed)

    if 0:
        # find other solutions to the extension polynomial
        ring = PolynomialRing(field)
        poly = ring.evaluate(field.mod)
        assert str(poly) == str(field.mod)
        assert poly(field.x) == 0
        subs = []
        for a in field.elements:
            if poly(a) == field.zero:
                subs.append(a)
                print(a)
    
    return

    lin = Linear(deg, base)

    zero = field.zero
    one = field.one
    x = field.x
    a = one
    basis = []
    for i in range(deg):
        basis.append(a)
        a = x*a

    for a in field.elements:
        if a == zero:
            continue
        op = [[0 for j in range(deg)] for i in range(deg)]
        for j, b in enumerate(basis):
            c = a*b
            poly = c.value # unwrap
            for i in range(deg):
                op[i][j] = poly[i]
        op = lin.get(op)
        print(str(op).replace("\n", ""), a)
        print()

    if argv.check:
        zero = field.zero
        div = {}
        for a in field.elements:
            for b in field.elements:
                c = a*b
                div[c, a] = b
                div[c, b] = a
    
        for a in field.elements:
            for b in field.elements:
                if b != zero:
                    assert (a, b) in div
Example #13
0
def main():

    #    for name in """desargues_graph petersen_graph
    #        dodecahedral_graph icosahedral_graph""".split():

    name = argv.next()
    if name is None:
        return

    if name == "cayley":

        n = argv.get("n", 3)
        items = range(n)
        gen = []
        for i in range(n - 1):
            perm = dict((item, item) for item in items)
            perm[items[i]] = items[i + 1]
            perm[items[i + 1]] = items[i]
            gen.append(perm)
        gen = [Perm(perm, items) for perm in gen]
        for g in gen:
            print(g)

        graph = cayley(gen)

    elif name == "transpositions":

        n = argv.get("n", 3)
        items = range(n)
        gen = []
        for i in range(n - 1):
            for j in range(i + 1, n):
                perm = dict((item, item) for item in items)
                perm[items[i]] = items[j]
                perm[items[j]] = items[i]
                gen.append(perm)
        gen = [Perm(perm, items) for perm in gen]

        print("gen:", len(gen))
        graph = cayley(gen)

    elif name == "cycles":

        n = argv.get("n", 3)
        items = range(n)
        gen = []
        for i in range(n):
            for j in range(i + 1, n):
                for k in range(j + 1, n):
                    perm = dict((item, item) for item in items)
                    perm[items[i]] = items[j]
                    perm[items[j]] = items[k]
                    perm[items[k]] = items[i]
                    gen.append(perm)
                    perm = dict((item, item) for item in items)
                    perm[items[i]] = items[k]
                    perm[items[k]] = items[j]
                    perm[items[j]] = items[i]
                    gen.append(perm)
        gen = [Perm(perm, items) for perm in gen]

        print("gen:", len(gen))
        graph = cayley(gen)

    else:

        builder = getattr(small, name, None)

        if builder is None:
            builder = getattr(classic, name, None)

        if builder is None:
            print(name, "not found")
            return

        n = argv.n
        if n is not None:
            graph = builder(n)
        else:
            graph = builder()

    print("|nodes|=%d, edges=|%d|" % (len(graph.nodes()), len(graph.edges())))

    if argv.visualize:
        from visualize import draw_graph
        draw_graph(graph)
        return

    if argv.spec:
        print("spec:", )
        spec = nx.adjacency_spectrum(graph)
        spec = [x.real for x in spec]
        spec.sort()
        print(' '.join("%5f" % x for x in spec))
        return

    G = get_autos(graph)
    print("|G|=%d" % len(G))

    if argv.all_subgroups:
        Hs = list(G.subgroups())
        Hs.sort(key=lambda H: len(H))
    else:
        Hs = [Group.generate([G.identity])]

    for H in Hs:
        print("|H|=%d" % len(H))

        A = build_orbigraph(graph, H)
        print(A)

        spec = numpy.linalg.eigvals(A)

        spec = [x.real for x in spec]
        spec.sort(reverse=True)
        s = ' '.join(("%5f" % x).rjust(9) for x in spec)
        s = s.replace(".000000", "")
        print("spec:", s)
        print
    return