Ejemplo n.º 1
0
def make_random_modular():
    ngens = 4
    a, ai, b, bi = range(ngens)
    rels = [
        (ai, a),
        (bi, b),
        (a, ) * 2,
        (
            a,
            b,
        ) * 3,
    ]  # modular group
    rels += [
        (b, ) * 7,
    ]  # 2,3,7 triangle group

    for _ in range(10000):
        graph = Schreier(ngens, rels)
        hgens = []
        for i in range(2):
            gen = tuple(randint(0, ngens - 1) for k in range(20))
            hgens.append(gen)
        if graph.build(hgens, maxsize=2000):
            if len(graph) < 3:
                continue
            #print("hgens:", hgens)
            gens = graph.get_gens()
            G = mulclose(gens, maxsize=10000)
            if len(G) < 10000:
                print(len(graph), end=" ", flush=True)
                print(len(G))
Ejemplo n.º 2
0
def build_gates(ring, i4, root2, i8):
    qubit = Space(2, ring)
    hom = Hom(qubit, qubit)

    I = Map.from_array([[1, 0], [0, 1]], hom)
    X = Map.from_array([[0, 1], [1, 0]], hom)
    Z = Map.from_array([[1, 0], [0, -1]], hom)
    H = (1/root2)*(X+Z)

    assert H*H == I

    S = Map.from_array([[1, 0], [0, i4]], hom)
    assert S*S == Z

    T = Map.from_array([[1, 0], [0, i8]], hom)
    assert S*S == Z

    #gen = [X, Z, S] # generates 32 elements
    gen = [X, Z, S, H] # generates 192 elements
    #gen = [X, Z, S, H, T]

    if argv.gap:
        print("G := Group(")
        ms = []
        for g in gen:
            m = gapstr(g)
            ms.append(m)
        print(",\n".join(ms)+");;")

    if ring.p <= 41:
        G = mulclose(gen)
        print("|G| =", len(G))
Ejemplo n.º 3
0
    def build():
        if argv.steane:
            zops = "1111111 1001011 0101101 0010111".split()
            xops = "1001011 0101101 0010111".split()
        elif argv.toric:
            zops = "111..1.. 1.11...1 .1..111.".split()
            #xops = "1.1..... .1...1.. 11.11... .111..1. 1...11.1".split()
            xops = "11.11... .111..1. 1...11.1".split()
        else:
            return

        stab = []
        for s in xops:
            s = s.replace("0", "I")
            s = s.replace(".", "I")
            gx = s.replace("1", "X")
            stab.append(Op("".join(gx)))
        for s in zops:
            s = s.replace("0", "I")
            s = s.replace(".", "I")
            gz = s.replace("1", "Z")
            stab.append(Op("".join(gz)))

        for g in stab:
          for h in stab:
            assert g*h == h*g
        G = mulclose(stab)
        print("|G| =", len(G))
    
        return G
Ejemplo n.º 4
0
 def __init__(self, perms=None, gen=None):
     if perms is None:
         assert gen is not None
         perms = list(mulclose(gen))
     else:
         perms = list(perms)
     #perms.sort()
     assert perms
     canonical = list(perms)
     canonical.sort()
     self.canonical = canonical
     #gen = list(gen)
     self.gens = list(gen or perms)
     self.perms = perms
     self.n = len(self.perms)
     self.rank = perms[0].rank
     self.lookup = dict(
         (perm, idx) for (idx, perm) in enumerate(self.perms))
     self.identity = Perm(list(range(self.rank)))
     self._str = str(self.canonical)
     self._hash = hash(self._str)
     self._subgroups = None  # cache
     assert len(self.lookup) == self.n
     if debug:
         self.do_check()
Ejemplo n.º 5
0
def test_hom():

    ring = element.Q
    n = argv.get("n", 3)

    V = Space(ring, n)

    # build action of symmetric group on the space V
    items = list(range(n))
    gen1 = []
    gen2 = []
    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]
        g = Perm(perm, items)
        gen1.append(g)
        A = elim.zeros(ring, n, n)
        for k, v in perm.items():
            A[v, k] = ring.one
        lin = Lin(V, V, A)
        gen2.append(lin)

    perms = mulclose(gen1)
    G = Group(perms, items)

    #print(G)

    action = mulclose_hom(gen1, gen2)
    for g in G:
        for h in G:
            assert action[g *
                          h] == action[g] * action[h]  # check it's a group hom
Ejemplo n.º 6
0
def main():

    # ----------------------------------
    # binary tetrahedral group ... maybe?

    field = CyclotomicField(4)
    i = field.x

    print(i)
    M = Linear(2, field)
    gen = [
        M.get([[(-1 + i) / 2, (-1 + i) / 2], [(1 + i) / 2, (-1 - i) / 2]]),
        M.get([[0, i], [-i, 0]])
    ]

    G = mulclose(gen)
    assert len(G) == 48  # ???

    # ----------------------------------
    # binary octahedral group

    field = CyclotomicField(8)
    x = field.x

    a = x - x**3  #sqrt(2)
    i = x**2

    print((1 + i) / a)  # FAIL

    M = Linear(2, field)
    gen = [
        M.get([[(-1 + i) / 2, (-1 + i) / 2], [(1 + i) / 2, (-1 - i) / 2]]),
        M.get([[(1 + i) / a, 0], [0, (1 - i) / a]])
    ]
    print(gen[0])
    print(gen[1])

    return

    G = mulclose(gen)
    print(len(G))
Ejemplo n.º 7
0
def main():

    desc = argv.next()
    assert desc

    print("constructing %s" % desc)
    assert "_" in desc, repr(desc)

    name, idx = desc.split("_")
    idx = int(idx)
    attr = getattr(Weyl, "build_%s" % name)
    G = attr(idx)

    print(G)

    e = G.identity
    gen = G.gen
    roots = G.roots
    els = G.generate()
    G = Group(els, roots)
    print("order:", len(els))

    ring = element.Z
    value = zero = Poly({}, ring)
    q = Poly("q", ring)
    for g in els:
        #print(g.word)
        value = value + q**(len(g.word))
    print(value.qstr())

    n = len(gen)
    Hs = []
    for idxs in all_subsets(n):
        print(idxs, end=" ")
        gen1 = [gen[i] for i in idxs] or [e]
        H = Group(mulclose(gen1), roots)
        Hs.append(H)
        gHs = G.left_cosets(H)
        value = zero
        for gH in gHs:
            items = list(gH)
            items.sort(key=lambda g: len(g.word))
            #for g in items:
            #    print(g.word, end=" ")
            #print()
            g = items[0]
            value = value + q**len(g.word)
        #print(len(gH))
        print(value.qstr())

    G = Group(els, roots)
    burnside(G, Hs)
Ejemplo n.º 8
0
def make_random_55():

    #seed(4)

    ngens = 6
    a, ai, b, bi, c, ci = range(ngens)
    i_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)
    rel1 = (3 * a1 + b1) * 3  # Bring's curve

    for _ in range(10000):
        rels = list(i_rels)
        for i in range(1):
            #gen = tuple([a, b, c][randint(0, 2)] for k in range(30))
            gen = ()
            for k in range(50):
                gen += choice([(a, b), (a, c), (b, c)])
            #gen = rel1
            rels.append(gen)
        graph = Schreier(ngens, rels)
        if graph.build(maxsize=1040000):
            print(".", flush=True, end="")
            n = len(graph)
            if n <= 1320:
                continue
            #print("rels:", rels)
            #graph.show()
            print(len(graph.neighbors))
            try:
                gens = graph.get_gens()
            except AssertionError:
                print("XXX")
                continue
            G = mulclose(gens, maxsize=10000)
            if len(G) < 10000:
                print(gen)
                print(len(graph), end=" ", flush=True)
                print(len(G))
            print()
Ejemplo n.º 9
0
 def subgroups(self, verbose=False):
     if self._subgroups is not None:
         #return list(self._subgroups)
         for H in self._subgroups:
             yield H
         return
     I = self.identity
     trivial = Group([I])
     cyclic = self.cyclic_subgroups()
     #if verbose:
     #    print "Group.subgroups: cyclic:", len(cyclic)
     n = len(self)  # order
     items = set(cyclic)
     items.add(trivial)
     items.add(self)
     for H in items:
         yield H
     bdy = set(G for G in cyclic if len(G) < n)
     while bdy:
         _bdy = set()
         # consider each group in bdy
         for G in bdy:
             # enlarge by a cyclic subgroup
             for H in cyclic:
                 perms = set(G.perms + H.perms)
                 k = len(perms)
                 if k == n or k == len(G) or k == len(H):
                     continue
                 #perms = mulclose(perms)
                 perms = mulclose(perms)
                 K = Group(perms)
                 if K not in items:
                     yield K
                     _bdy.add(K)
                     items.add(K)
                     if verbose:
                         print('.', flush=True, end="")
                 #else:
                 #    print('/')
         bdy = _bdy
         #if verbose:
         #    print "items:", len(items)
         #    print "bdy:", len(bdy)
     if verbose:
         print()
     items = list(items)
     #items.sort(key = len)
     self._subgroups = items
Ejemplo n.º 10
0
def specht(n, space):

    assert n >= 2
    d = len(space)
    ring = space.ring

    items = list(range(n))
    gen1 = []
    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]
        perm = Perm(perm, items)
        gen1.append(perm)
    perms = mulclose(gen1)
    G = Group(perms, items)

    #I = space.ident

    # tensor power of the space
    tensor = lambda x, y: x @ y
    tspace = reduce(tensor, [space] * n)

    # build action of symmetric group on the tensor power
    thom = Hom(tspace, tspace)
    gen2 = []
    for g in gen1:
        items = []
        for idxs in tspace.gen:
            jdxs = tuple(idxs[g[i]] for i in range(len(idxs)))
            items.append(((idxs, jdxs), ring.one))
            #print(idxs, "->", jdxs)
        #print()
        swap = Map(items, thom)
        gen2.append(swap)

    action = mulclose_hom(gen1, gen2)
    for g in G:
        for h in G:
            assert action[g *
                          h] == action[g] * action[h]  # check it's a group hom

    tp = Cat(G, ring)

    rep = Rep(action, tspace, tp)
    return rep
Ejemplo n.º 11
0
def test_render():
    x = Leaf()
    t = ((x*x)*x)*x
    s = ((x*x)*(x*x))

    #cvs = s.render(h=-1)
    #cvs.writePDFfile("tree.pdf")
    #return
    A = Assoc( (x*x)*x, x*(x*x) )
    B = Assoc( x*((x*x)*x), x*(x*(x*x)) )
    G = mulclose([A, B, ~A, ~B], maxsize=60)

    seed(2)

    question = Canvas().text(0, 0, "?", [Scale(7.)]+st_center)
    cvs = Canvas()
    x, y = 0, 0
    for i in range(4):
        f = choice(G)
        g = choice(G)
    
        row = [f.render(), r"$\times$", g.render(), r"$=$", (f*g).render()]
        #if i==0:
        #    row[-1] = question
        row = make_eq(row)
        cvs.insert(x, y, row)
        y += 1.1*row.get_bound_box().height

    bb = cvs.get_bound_box()
    bg = Canvas()
    m = 0.1
    bg.fill(path.rect(bb.llx-m, bb.lly-m, bb.width+2*m, bb.height+2*m), [white])
    cvs = bg.append(cvs)
    if 0:
        cvs.writePDFfile("tree-puzzle.pdf")
        cvs.writePNGfile("tree-puzzle.png")
    else:
        cvs.writePDFfile("tree-soln.pdf")
        cvs.writePNGfile("tree-soln.png")
Ejemplo n.º 12
0
Archivo: qu.py Proyecto: punkdit/bruhat
    def __init__(self, n, space):
        assert n >= 2
        d = len(space)
        ring = space.ring

        items = list(range(n))
        gen1 = []
        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]
            perm = Perm(perm, items)
            gen1.append(perm)

        perms = mulclose(gen1)
        G = Group(perms, items)

        #I = space.ident

        # tensor power of the space
        tensor = lambda x, y: x @ y
        tspace = reduce(tensor, [space] * n)

        # build action of symmetric group on the tensor power
        thom = Hom(tspace, tspace)
        gen2 = []
        for g in gen1:
            items = []
            for idxs in tspace.gen:
                jdxs = tuple(idxs[g[i]] for i in range(len(idxs)))
                items.append(((idxs, jdxs), ring.one))
                #print(idxs, "->", jdxs)
            #print()
            swap = Map(items, thom)
            gen2.append(swap)

        action = mulclose_hom(gen1, gen2)
        for g in G:
            for h in G:
                assert action[
                    g * h] == action[g] * action[h]  # check it's a group hom

        # Build the young symmetrizers
        projs = []
        parts = []
        for part in partitions(n):
            if len(part) > d:
                continue
            parts.append(part)
            t = Young(G, part)

            rowG = t.get_rowperms()
            colG = t.get_colperms()
            horiz = None
            for g in rowG:
                P = action[g]
                horiz = P if horiz is None else (horiz + P)

            vert = None
            for g in colG:
                P = action[g]
                s = g.sign()
                P = s * P
                vert = P if vert is None else (vert + P)
            A = vert * horiz + horiz * vert
            #A = horiz * vert

            assert vert * vert == len(colG) * vert
            assert horiz * horiz == len(rowG) * horiz
            #A = A.transpose()
            projs.append(A)

            #print(part)
            #print(t)
            #print(A)

        self.projs = projs
        self.parts = parts
Ejemplo n.º 13
0
Archivo: qu.py Proyecto: punkdit/bruhat
def main():

    #ring = element.Z
    ring = element.Q

    qubit = Space(2, ring)

    q2 = qubit @ qubit

    hom = Hom(qubit, qubit)

    I = Map.from_array([[1, 0], [0, 1]], hom)
    X = Map.from_array([[0, 1], [1, 0]], hom)
    Z = Map.from_array([[1, 0], [0, -1]], hom)
    H = X + Z
    E = Map.from_array([[0, 1], [0, 0]], hom)  # raising
    F = Map.from_array([[0, 0], [1, 0]], hom)  # lowering
    II = I @ I
    XI = X @ I
    IX = I @ X
    XX = X @ X
    assert XI * IX == XX

    CNOT = Map.from_array(
        [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]], hom @ hom)

    SWAP = Map.from_array(
        [[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]], hom @ hom)

    assert SWAP * SWAP == II
    assert CNOT * CNOT == II

    G = mulclose([XI, IX, CNOT])  # order 8
    G = mulclose([XI, IX, CNOT, SWAP])  # order 24.. must be S_4
    G = mulclose([CNOT, SWAP])
    #    print(len(G))
    #    for g in G:
    #        print(g)

    A = SWAP @ I
    B = I @ SWAP
    S_3 = list(mulclose([A, B]))
    assert len(S_3) == 6
    #    for g in G:
    #        print(g)
    #    print(g.hom)

    hom = A.hom
    space = hom.src
    N = 2**3
    basis = space.get_basis()
    orbits = set()
    for v in basis:
        v1 = space.zero_vector()
        for g in S_3:
            u = g * v
            v1 = v1 + u
        orbits.add(v1)
    orbits = list(orbits)
    #    for v in orbits:
    #        print(v)

    HHH = H @ H @ H
    v = basis[7]
    #print(v)
    #print(HHH * v)

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

    specht = Specht(4, qubit)

    for i, A in enumerate(specht.projs):
        print("part:", specht.parts[i])
        print("proj:")
        im = A.image()
        #im = A
        src, tgt = im.hom
        for i in src:
            for j in tgt:
                v = im[j, i]
                if v != ring.zero:
                    print("%s*%s" % (v, j), end=" ")
            print()

    return

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

    items = [0, 1, 2, 3]
    g1 = Perm({0: 1, 1: 0, 2: 2, 3: 3}, items)
    g2 = Perm({0: 0, 1: 2, 2: 1, 3: 3}, items)
    g3 = Perm({0: 0, 1: 1, 2: 3, 3: 2}, items)
    gen1 = [g1, g2, g3]

    s1 = SWAP @ I @ I
    s2 = I @ SWAP @ I
    s3 = I @ I @ SWAP
    gen2 = [s1, s2, s3]

    G = mulclose(gen1)
    hom = mulclose_hom(gen1, gen2)
    for g in G:
        for h in G:
            assert hom[g * h] == hom[g] * hom[h]  # check it's a group hom

    projs = []
    for part in [(4, ), (3, 1), (2, 2)]:
        t = Young(part)

        rowG = t.get_rowperms()
        colG = t.get_colperms()
        horiz = None
        for g in rowG:
            P = hom[g]
            horiz = P if horiz is None else (horiz + P)

        vert = None
        for g in colG:
            P = hom[g]
            s = g.sign()
            P = s * P
            vert = P if vert is None else (vert + P)
        A = vert * horiz
        #A = horiz * vert

        assert vert * vert == len(colG) * vert
        assert horiz * horiz == len(rowG) * horiz
        #print(t)
        #print(A)
        projs.append(A)

    for A in projs:
        for B in projs:
            assert A * B == B * A


#    print()
#    for A in projs:
#        for g in G:
#            P = hom[g]
#            if P*A != A*P:
#                print(P*A)
#                print(A*P)
#                return

    for A in projs:
        print("proj:")
        im = A.image()
        #im = A
        src, tgt = im.hom
        for i in src:
            for j in tgt:
                v = im[j, i]
                if v != ring.zero:
                    print("%s*%s" % (v, j), end=" ")
            print()
Ejemplo n.º 14
0
def main():

    # ----------------------------
    # Gaussian integers

    R = NumberRing((-1, 0))
    one = R.one
    i = R.i

    assert i * i == -one
    assert i**3 == -i

    assert (1 + i)**2 == 2 * i
    assert (2 + i) * (2 - i) == 5
    assert (3 + 2 * i) * (3 - 2 * i) == 13

    items = []
    i = R.i_find()
    while len(items) < 20:
        items.append(i.__next__())
    items.sort()
    #print(' '.join(str(x) for x in items))

    # reflection group
    i = R.i
    I = Mobius(R)
    a = Mobius(R, 1, 0, 0, 1, True)
    b = Mobius(R, i, 0, 0, 1, True)
    c = Mobius(R, -1, 0, 1, 1, True)
    d = Mobius(R, 0, 1, 1, 0, True)
    gens = [a, b, c, d]

    if 0:
        # yes, works...
        G = mulclose(gens, maxsize=100)
        for f in G:
            for g in G:
                for h in G:
                    assert f * (g * h) == (f * g) * h
        return

    # Coxeter reflection group: a--4--b--4--c--3--d
    for g in gens:
        assert g.order() == 2
    assert (a * b).order() == 4
    assert (a * c).order() == 2
    assert (a * d).order() == 2
    assert (b * c).order() == 4
    assert (b * d).order() == 2
    assert (c * d).order() == 3

    # rotation group
    a = Mobius(R, -i, 0, 0, 1)
    b = Mobius(R, -i, 0, i, 1)
    c = Mobius(R, 1, 1, -1, 0)

    assert a.order() == 4
    assert b.order() == 4
    assert c.order() == 3

    # ----------------------------
    # Eisenstein integers
    R = NumberRing((-1, -1))
    one = R.one
    i = R.i

    assert i**3 == 1
    assert 1 + i + i**2 == 0

    # ----------------------------
    # Kleinian integers
    R = NumberRing((-2, -1))
    one = R.one
    i = R.i

    assert i * (-1 - i) == 2
    assert i * (1 + i) == -2

    # ----------------------------
    # Golden (Fibonacci) integers
    R = NumberRing((1, 1))
    one = R.one
    i = R.i

    assert i**2 == i + 1
    assert i**3 == 2 * i + 1
    assert i**4 == 3 * i + 2

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

    R = NumberRing((-1, 0))
    I = Ideal(R, 2 - R.i)
    S = R / I

    zero, one, i = S.zero, S.one, S.i

    assert 1 + i != 0
    assert 2 - i == 0
    assert 2 + i != 0
    assert 1 - i == 2 + i

    V = Space(S, 2)
    SL = S.get_sl(V)
    GL = S.get_gl(V)

    def lin(a, b, c, d):
        a = S.promote(a)
        b = S.promote(b)
        c = S.promote(c)
        d = S.promote(d)
        return Lin(V, V, [[a, b], [c, d]])

    # generators for SL
    gen = lin(0, 1, -1, 0), lin(1, 0, 1, 1), lin(1, 0, i, 1)
    G = mulclose(gen)
    assert len(G) == 120

    i = S.i
    I = Mobius(S)

    if 0:
        # This just does not work over S
        a = Mobius(S, 1, 0, 0, 1, True)
        b = Mobius(S, i, 0, 0, 1, True)
        c = Mobius(S, -1, 0, 1, 1, True)
        d = Mobius(S, 0, 1, 1, 0, True)
        gens = [a, b, c, d]
        G = mulclose(gens)
        inv = {}
        for g in G:
            for h in G:
                if g * h == I:
                    inv[g] = h
                    inv[h] = g
                assert (g == h) == (hash(g) == hash(h))
                for f in G:
                    print(g)
                    print(h)
                    print(f)
                    assert (g * h) * f == g * (h * f)
                    print()
        assert len(G) == 240
        return

        G, hom = cayley(G)
        assert len(G) == 240
        G.do_check()

        return

        # rotation group
        gens = [a * b, b * c, c * d]
Ejemplo n.º 15
0
def main():

    d = argv.get("d", 3)
    assert d>=2

    double = argv.double

    if d==2:
        ring = CyclotomicRing(4)
        #ring = element.Z
        gamma = ring.x
        w = gamma**2
        assert w == -1
        double = True

    else:
        ring = CyclotomicRing(d**2)
        gamma = ring.x
        w = gamma**d

    I = numpy.zeros((d, d), dtype=object)
    wI = numpy.zeros((d, d), dtype=object)
    X = numpy.zeros((d, d), dtype=object)
    Z = numpy.zeros((d, d), dtype=object)
    Zdag = numpy.zeros((d, d), dtype=object)
    S = numpy.zeros((d, d), dtype=object)
    Sdag = numpy.zeros((d, d), dtype=object)
    T = numpy.zeros((d, d), dtype=object)
    Tdag = numpy.zeros((d, d), dtype=object)
    for j in range(d):
        I[j, j] = 1
        wI[j, j] = w
        X[j, (j+1)%d] = 1
        Z[j, j] = w**j
        Zdag[j, j] = w**(d-j)

        if d==2:
            val = gamma**(j**2)
            ival = gamma**(d**2 - (j**2)%(d**2))
        else:
            val = w**(j**2)
            ival = w**(d - (j**2)%d)
        assert val*ival == 1

        S[j, j] = val
        Sdag[j, j] = ival

        if d in [2, 3, 6]:
            val = gamma**(j**3)
            ival = gamma**(d**2 - (j**3)%(d**2))
        else:
            val = w**(j**3)
            ival = w**(d - (j**3)%d)
        assert val*ival == 1

        T[j, j] = val
        Tdag[j, j] = ival

    qu = Space(d, ring)
    hom = Hom(qu, qu)

    I = Map.from_array(I, hom)
    wI = Map.from_array(wI, hom)
    Xdag = Map.from_array(X.transpose(), hom)
    X = Xs = Map.from_array(X, hom)
    Z = Map.from_array(Z, hom)
    Zdag = Map.from_array(Zdag, hom)
    S = Map.from_array(S, hom)
    Sdag = Map.from_array(Sdag, hom)
    T = Map.from_array(T, hom)
    Tdag = Map.from_array(Tdag, hom)

    if d==2:
        Y = gamma*X*Z # ?
    else:
        Y = w*X*Z # ?

    assert S*Sdag == I

    assert Z*Zdag == I
    assert X*Xdag == I

    if d>2:
        for j in range(1, d+1):
            assert (j==d) == (X**j==I)
            assert (j==d) == (Z**j==I)
    else:
        assert X != I
        assert Z != I
        assert X*X == I
        assert Z*Z == I

    assert Z*X == (w**(d-1))*X*Z

    if double:
        pauli = mulclose([X, Z, gamma*I])
        names = mulclose_names([X, Z, gamma*I], "X Z i".split())

    else:
        pauli = mulclose([X, Z])
        names = mulclose_names([X, Z, Xdag, Zdag, -I], "X Z Xi Zi -I".split())

    pauli = set(pauli)
    print("pauli:", len(pauli))
    assert Zdag in pauli
    assert Xdag in pauli

    if d<6:
        # slow..
        lhs = atpow(X, d)
        rhs = atpow(Z, d)
        assert lhs * rhs == rhs * lhs
    
    lhs = X@X
    rhs = Z@Zdag
    assert lhs * rhs == rhs * lhs

    lhs = X@(X**(d-1))
    rhs = Z@Z
    assert lhs * rhs == rhs * lhs

    if 0:
        n = 5
        ops = [X, Xdag]
        lhs = []
        for op in cross([ops]*n):
            op = reduce(matmul, op)
            lhs.append(op) 
    
        ops = [Z, Zdag]
        rhs = []
        for op in cross([ops]*n):
            op = reduce(matmul, op)
            rhs.append(op) 
    
        for l in lhs:
          for r in rhs:
            if l*r == r*l:
                print("/", end=" ", flush=True)
            else:
                print(".", end=" ", flush=True)
        print()

    print("S =")
    print(S)
    print("XSX =")
    print(X*S*X)
    print("XSXS =")
    print(X*S*X*S)
    
    #print("Y =")
    #print(Y)
    #print("S*X*Sdag =")
    #print(S*X*Sdag)
    assert Y == S*X*Sdag

    def get_orbit(g, gi, v):
        orbit = [v]
        while 1:
            u = g*orbit[-1]*gi
            if u == orbit[0]:
                break
            orbit.append(u)
        return orbit

    print("S orbit:")
    for A in [X, Z]:
        print('\t', [''.join(names[op]) for op in get_orbit(S, Sdag, A)])

    U = X*S
    Ui = Sdag * Xdag
    assert U*Ui == I

    print("XS orbit:")
    for A in [X, Z]:
        print('\t', [''.join(names[op]) for op in get_orbit(U, Ui, A)])

    U = X*X*S
    Ui = Sdag * Xdag * Xdag
    assert U*Ui == I

    print("XXS orbit:")
    for A in [X, Z]:
        print('\t', [''.join(names[op]) for op in get_orbit(U, Ui, A)])

    return

    inverse = {}
    for g in pauli:
      for h in pauli:
        if g*h == I:
            inverse[g] = h
            inverse[h] = g

    def is_cliff(A, Ai):
        assert A*Ai == I
        for g in pauli:
            h = A*g*Ai
            if h not in pauli:
                return False
        return True
    print("S =")
    print(S)
    print("S**2 =")
    print(S**2)
    print("Sdag =")
    print(Sdag)
    assert is_cliff(S, Sdag)

    #print("is_cliff:", (S in pauli), is_cliff(S, Sdag))

    def is_third_level(A, Ai):
        assert A*Ai == I
        for g in pauli:
            gi = inverse[g]
            h = A*g*Ai*gi
            hi = g*A*gi*Ai
            if not is_cliff(h, hi):
                return False
        return True

    print("is_pauli(S)", S in pauli)
    print("is_cliff(S)", is_cliff(S, Sdag))
    #print("is_third_level(S)", is_third_level(S, Tdag))

    print("is_pauli(T)", T in pauli)
    print("is_cliff(T)", is_cliff(T, Tdag))
    print("is_third_level(T)", is_third_level(T, Tdag))
        

    print("OK")
Ejemplo n.º 16
0
def make_random_homogeneous_refl():

    seed(1)

    ngens = 6
    a, ai, b, bi, c, ci = range(ngens)
    i_rels = [
        (ai, a),
        (bi, b),
        (ci, c),
        (a, ) * 2,
        (b, ) * 2,
        (c, ) * 2,
        (a, b) * 5,
        (b, c) * 5,
        (a, c) * 2,
    ]

    while 1:
        rels = []
        for i in range(4):
            gen = ()
            for k in range(20):
                gen += choice([(a, b), (a, c), (b, c)])
            rels.append(gen)

        # G/H = 720/24 = 30, N(H)=24
        _rels = [(0, 2, 2, 4, 0, 4, 2, 4, 2, 4, 0, 4, 0, 4, 2, 4, 0, 2, 0, 4,
                  2, 4, 0, 4, 2, 4, 0, 2, 0, 2, 0, 2, 2, 4, 2, 4, 2, 4, 2, 4),
                 (0, 2, 2, 4, 0, 4, 2, 4, 0, 2, 0, 4, 0, 2, 0, 4, 0, 4, 0, 2,
                  0, 2, 0, 2, 0, 4, 0, 4, 2, 4, 0, 4, 0, 2, 0, 2, 2, 4, 0, 2),
                 (0, 2, 2, 4, 2, 4, 2, 4, 2, 4, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4,
                  0, 2, 0, 2, 0, 4, 0, 2, 0, 2, 2, 4, 0, 4, 0, 2, 0, 4, 0, 2),
                 (0, 2, 0, 4, 0, 4, 2, 4, 0, 4, 0, 2, 0, 2, 2, 4, 0, 4, 0, 4,
                  0, 2, 0, 4, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 0, 4, 0, 2)]

        # G/H = 9720/324 = 30, N(H)=1944
        _rels = [(0, 4, 0, 2, 0, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 0, 4, 0, 2,
                  0, 2, 0, 4, 2, 4, 0, 2, 0, 2, 0, 2, 2, 4, 0, 2, 0, 4, 0, 4),
                 (0, 4, 2, 4, 0, 2, 0, 2, 0, 2, 2, 4, 0, 2, 0, 2, 2, 4, 2, 4,
                  0, 4, 2, 4, 0, 4, 2, 4, 0, 4, 0, 2, 2, 4, 0, 2, 2, 4, 0, 2),
                 (0, 4, 0, 4, 0, 4, 0, 2, 0, 4, 0, 4, 2, 4, 0, 4, 0, 2, 0, 2,
                  0, 4, 0, 2, 0, 2, 0, 2, 0, 4, 0, 4, 0, 4, 2, 4, 0, 2, 2, 4),
                 (2, 4, 2, 4, 0, 4, 2, 4, 0, 2, 0, 4, 0, 4, 2, 4, 2, 4, 2, 4,
                  2, 4, 2, 4, 0, 4, 0, 4, 2, 4, 2, 4, 2, 4, 0, 4, 0, 2, 2, 4)]

        graph = Schreier(ngens, i_rels)
        if not graph.build(rels, maxsize=10400):
            print(choice("/\\"), end="", flush=True)
            continue

        n = len(graph)
        if n <= 24:
            continue

        print("\n[%d]" % n)  #, flush=True, end="")
        print(len(graph.neighbors)
              )  # how big did the graph get? compare with maxsize above

        try:
            gens = graph.get_gens()
        except AssertionError:
            print("** FAIL **")
            continue

        N = 10000
        perms = mulclose(gens, maxsize=N)
        if len(perms) >= N:
            print("|G| = ?")
            continue

        print(rels)
        items = list(range(n))
        G = Group(perms, items)
        G.gens = gens
        print("|G| =", len(G))
        print()

        break

    rels = [reduce(mul, [gens[i] for i in rel]) for rel in rels]
    H = Coset(mulclose(rels), items)
    print(len(H))
    print(len(G) / len(H))

    N = []
    for g in G:
        lhs = g * H
        rhs = H * g
        if lhs == rhs:
            N.append(g)
    print(len(N))
Ejemplo n.º 17
0
def clifford():

    p = argv.get("p", 17)
    
    field = FiniteField(p)
    #ring = PolynomialRing(field)
    #x = ring.x

    for fgen in range(1, p):
        items = set()
        j = fgen
        while j not in items:
            items.add(j)
            j = (j*fgen)%p
        if len(items) == p-1:
            break
    else:
        assert 0
    finv = {}
    for i in range(1, p):
      for j in range(1, p):
        if (i*j)%p == 1:
          finv[i] = j
          finv[j] = i
    assert len(finv) == p-1

    #print("fgen:", fgen)

    items = [field.promote(i) for i in range(p)]
    has_imag = [i for i in items if i*i == -1]
    
    #print(p, has_imag)
    if not has_imag:
        assert 0

    i4 = has_imag[0]
    assert -i4 == has_imag[1]

    has_root2 = [i for i in items if i*i == 2]
    if not has_root2:
        assert 0
    r2 = has_root2[0]
    assert -r2 == has_root2[1]

    has_i8 = [i for i in items if i*i == i4]
    if not has_i8:
        assert 0
    i8 = has_i8[0]
    assert -i8 == has_i8[1]

    print("p =", p)
    #print(i4, r2, i8)
    #print(has_imag, has_root2, has_i8)
    for i in items:
        if i*i8 == 1:
            i8_dag = i
    #print(i8_dag)

    # try to take a daggar... doesn't really work tho.
    assert p==17
    dag = {
        0:0, 1:1, 2:9, 3:3, 4:13, 5:12, 6:6, 7:7, 8:15,
        9:2, 10:10, 11:11, 12:5, 13:4, 14:14, 15:8, 16:16,  
    }
    for (k, v) in list(dag.items()):
        dag[k] = field.promote(v)
        dag[field.promote(k)] = field.promote(v)

    assert dag[i4] == -i4

    qubit = Space(2, field)
    hom = Hom(qubit, qubit)

    def getdag(A):
        items = [((j, i), dag[v]) for ((i, j), v) in A.items]
        return Map(items, hom)

    I = Map.from_array([[1, 0], [0, 1]], hom)
    X = Map.from_array([[0, 1], [1, 0]], hom)
    Z = Map.from_array([[1, 0], [0, -1]], hom)
    H = (1/r2)*(X+Z)

    assert H*H == I

    S = Map.from_array([[1, 0], [0, i4]], hom)
    Sdag = Map.from_array([[1, 0], [0, dag[i4]]], hom)
    assert S*S == Z
    assert S*Sdag == I
    assert getdag(S) == Sdag

    T = Map.from_array([[1, 0], [0, i8]], hom)
    assert S*S == Z

    C1 = mulclose([X, Z])
    assert len(C1) == 8

    # C1 is Pauli group + phases
    #P = fgen*I # phase
    P = i4*I
    C1 = mulclose([X, Z, P])  # add phases
#    assert len(C1) == 64, len(C1)
    assert len(C1) == 32, len(C1)
    C1_lookup = set(C1)

    #gen = [X, Z, S, H]
    #C2 = mulclose(gen)
    #assert len(C2) == 192

    G = []
    for a in range(p):
     for b in range(p):
      for c in range(p):
       for d in range(p):
        if (a*d - b*c)%p:
            G.append(Map.from_array([[a, b], [c, d]], hom))
    G_lookup = set(G)
    print("|GL(%d, 2)|=%d" % (p, len(G)))

    U = []
    for g in G:
        if g*getdag(g) == I:
            U.append(g)
    print("|U|=", len(U))

    gen = [X, Z, S, H, P]

    # Clifford group + phases
    C2 = mulclose(gen)
#    assert len(C2) == 384, len(C2)
    assert len(C2) == 192, len(C2)
    C2_lookup = set(C2)
    print("|C2| =", len(C2))

    print(C2_lookup == set(U))

    for g in C2:
        assert g in G_lookup
        #assert g*getdag(g) == I, str(g) # FAIL

#    inv = {I:I}
#    for a in G:
#      if a in inv:
#        continue
#      for b in G:
#        ab = a*b
#        ci = inv.get(ab)
#        if ci is None:
#            continue
#        inv[a] = b*ci
#        inv[b] = ci*a
#      print(len(inv), end=" ", flush=True)
#    print()

    inv = {I:I}
    remain = set(G)
    remain.remove(I)
    while remain:
        a = iter(remain).__next__()
        assert a not in inv
        for b in G:
            ab = a*b
            ci = inv.get(ab)
            if ci is None:
                continue
            if a not in inv:
                inv[a] = b*ci
                remain.remove(a)
            if b not in inv:
                inv[b] = ci*a
                remain.remove(b)
        print(len(inv), end=" ", flush=True)
    print()

    assert len(inv) == len(G)

    if 0:
        for g2 in C2:
            for g in C1:
                assert g2 * g * inv[g2] in C1
    
        C2 = []
        for g2 in G:
            for g in C1:
                if g2*g*inv[g2] not in C1_lookup:
                    break
            else:
                C2.append(g2)
        assert len(C2) == 384 # same as above
        C2_lookup = set(C2)

    C3 = []
    for g3 in G:
        for g in C1:
            if g3*g*inv[g3] not in C2_lookup:
                break
        else:
            C3.append(g3)
    print("|C3| =", len(C3))
    C3_lookup = set(C3)

    shuffle(C3)

#    count = 0
#    for a in C3:
#      for b in C3:
#        if a*b in C3_lookup:
#            count += 1
#    print(count)

    def src(a):
        return set([b for b in C3 if a*b in C3_lookup])

    def tgt(a):
        return set([b for b in C3 if b*a in C3_lookup])

    if 0:
        items = iter(C3)
        a = items.__next__()
    
        src_a = src(a)
        print("|src_a| =", len(src_a))

    srcs = []
    for b in C3:
        src_b = src(b)
        if src_b not in srcs:
            print("|src_b| = ", len(src_b))
            srcs.append(src_b)
        if len(srcs)==4: # there is only 4 of these to be found
            break

    obs = list(srcs)
    tgts = []
    for b in C3:
        tgt_b = tgt(b)
        if tgt_b not in obs:
            obs.append(tgt_b)
        if tgt_b not in tgts:
            print("|tgt_b| = ", len(tgt_b))
            tgts.append(tgt_b)
        if len(tgts)==4: # there is only 4 of these to be found
            break

    done = False
    while not done:
        done = True
        #print("obs:", len(obs))
    
        obs.sort(key = len, reverse=True)
        obs1 = list(obs)
        for s in obs:
          for t in obs:
            st = s.intersection(t)
            a = ' '
            if st not in obs1:
                a = '*'
                obs1.append(st)
                done = False
            #print("%4d"%(len(st)), end=a)
          #print()
        obs = obs1
        obs.sort(key = len, reverse=True)

    print("obs:", len(obs), [len(ob) for ob in obs])
    for ob in obs:
        #print(len(ob), end=" ")
        iob = [inv[a] for a in ob if inv[a] in ob]
        print((len(ob), len(iob)), end=" ")
            
    print()
Ejemplo n.º 18
0
def test_gaussian():
    # ----------------------------

    from bruhat.action import mulclose

    R = NumberRing((-1, 0))
    z = 2 + 3 * R.i  # |G| = 2184
    z = 3 * R.one  # |G| = 720
    z = 2 + 1 * R.i  # |G| = 120
    #z = -1+R.i # fail
    I = Ideal(R, z)
    S = R / I

    zero, one, i = S.zero, S.one, S.i

    a = Mobius(S, -i, 0, 0, 1)
    b = Mobius(S, -i, 0, i, 1)
    c = Mobius(S, 1, 1, -1, 0)

    gens = [a, b, c]
    assert a.order() == 4
    assert b.order() == 4
    assert c.order() == 3

    #print((a*b).order()) # == 2
    #print((b*a).order()) # == 2

    G = mulclose(gens)
    #assert len(G) == 120, len(G)
    print(len(G))
    #a, b, c = G[:3]
    #assert a.order() == 4
    #assert b.order() == 4
    #assert c.order() == 3

    G, hom = cayley(G)
    a, b, c = hom[a], hom[b], hom[c]
    assert a.order() == 4
    assert b.order() == 4
    assert c.order() == 3

    def make_cayley(a, b):
        H = Group.generate([a, b])
        print(len(H), len(G) // len(H))

        import string
        names = dict(zip(H, string.ascii_lowercase[:len(H)]))
        f = open("cayley_graph.dot", "w")
        print("digraph\n{\n", file=f)
        for g in H:
            print("    %s -> %s [color=red];" % (names[g], names[a * g]),
                  file=f)
            print("    %s -> %s [color=green];" % (names[g], names[b * g]),
                  file=f)
        print("}", file=f)
        f.close()

    if argv.cayley_graph:
        #make_cayley(a, b)
        make_cayley(c, b)

    if 0:
        H = Group.generate([b, c])
        gset = G.action_subgroup(H)
        print(gset.get_orbits())

    #H = Group.generate([c])
    #o_edges = G.left_cosets(H)
    #print(len(o_edges))

    if argv.burnside:
        burnside(G)

    for H in G.subgroups():
        if len(H) == 60:
            assert H.is_simple()
            break
Ejemplo n.º 19
0
def test_hw():
    # Heisenberg-Weyl group

    # copied from dev/qudit.py

    d = argv.get("d", 3)  # qudit dimension
    assert d >= 2
    assert is_prime(d)

    if d == 2:
        ring = CyclotomicRing(4)
        #ring = element.Z
        gamma = ring.x
        w = gamma**2
        assert w == -1
        argv.double = True
    elif 1:
        ring = CyclotomicRing(d**2)
        gamma = ring.x
        w = gamma**d
    else:
        ring = CyclotomicRing(d)
        w = ring.x

    I = Matrix(ring, d)
    wI = Matrix(ring, d)
    X = Matrix(ring, d)
    Z = Matrix(ring, d)
    Zdag = Matrix(ring, d)
    S = Matrix(ring, d)
    Sdag = Matrix(ring, d)
    T = Matrix(ring, d)
    Tdag = Matrix(ring, d)

    for j in range(d):
        I[j, j] = 1
        wI[j, j] = w
        X[j, (j + 1) % d] = 1
        Z[j, j] = w**j
        Zdag[j, j] = w**(d - j)

        if d == 2:
            val = gamma**(j**2)
            ival = gamma**(d**2 - (j**2) % (d**2))
        else:
            val = w**(j**2)
            ival = w**(d - (j**2) % d)
        assert val * ival == 1

        S[j, j] = val
        Sdag[j, j] = ival

        if d in [2, 3, 6]:
            val = gamma**(j**3)
            ival = gamma**(d**2 - (j**3) % (d**2))
        else:
            val = w**(j**3)
            ival = w**(d - (j**3) % d)
        assert val * ival == 1

        T[j, j] = val
        Tdag[j, j] = ival

    Y = w * X * Z  # ?
    Xdag = X.transpose()

    assert S * Sdag == I

    assert Z * Zdag == I
    assert X * Xdag == I

    if d > 2:
        for j in range(1, d + 1):
            assert (j == d) == (X**j == I)
            assert (j == d) == (Z**j == I)
    else:
        assert X != I
        assert Z != I
        assert X * X == I
        assert Z * Z == I

    assert Z * X == (w**(d - 1)) * X * Z

    if argv.double:
        pauli = mulclose([X, Z, gamma * I])
    else:
        pauli = mulclose([X, Z])
    print("pauli:", len(pauli))

    if d == 2:
        phases = mulclose([gamma * I])
    else:
        phases = mulclose([w * I])
    print("phases:", len(phases))

    assert Zdag in pauli
    assert Xdag in pauli

    if d <= 3:
        # slow..
        lhs = atpow(X, d)
        rhs = atpow(Z, d)
        assert lhs * rhs == rhs * lhs

    equ = {e: {g * e for g in phases} for e in pauli}

    G = []
    for i in range(d):
        for j in range(d):
            m = (X**i) * (Z**j)
            G.append(m)
    print(len(G))

    for g in G:
        for h in G:
            i = int(g * h == h * g)
            print(i or '.', end=" ")
        print()
Ejemplo n.º 20
0
def test(n):

    G = Weyl.build_A(n)

    #    print "%d roots" % len(G.roots)
    #    print G.roots
    #    for g in G.gen:
    #        print [g(root) for root in G.roots]

    gen = G.gen
    for i in range(n):
        for j in range(n):
            gi = gen[i]
            gj = gen[j]
            if i == j:
                assert gi * gj == G.identity
            elif abs(i - j) == 1:
                assert gi * gj != G.identity
                assert (gi * gj)**2 != G.identity
                assert (gi * gj)**3 == G.identity
            else:
                assert gi * gj != G.identity
                assert (gi * gj)**2 == G.identity

    if n < 5:
        assert len(mulclose(G.gen)) == factorial(n + 1)

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

    G = Weyl.build_B(n)

    gen = G.gen
    for g in gen:
        assert g * g == G.identity

    for i in range(n - 1):
        for j in range(i + 1, n - 1):
            gi = gen[i]
            gj = gen[j]
            if abs(i - j) == 1:
                assert gi * gj != G.identity
                assert (gi * gj)**2 != G.identity
                assert (gi * gj)**3 == G.identity
            else:
                assert gi * gj != G.identity
                assert (gi * gj)**2 == G.identity
            if i < n - 1:
                gj = gen[n - 1]
                assert gi * gj != G.identity
                assert (gi * gj)**2 == G.identity

    if n > 2:
        gi = gen[n - 2]
        gj = gen[n - 1]
        assert (gi * gj) != G.identity
        assert (gi * gj)**2 != G.identity
        assert (gi * gj)**3 != G.identity
        assert (gi * gj)**4 == G.identity

    if n < 5:
        assert len(mulclose(G.gen)) == (2**n) * factorial(n)

    # ---------------------------------------------------------
    G = Weyl.build_C(n)

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

    if n < 3:
        return  # <---------------------- return

    G = Weyl.build_D(n)

    gen = G.gen
    for i in range(n - 1):
        gi = gen[i]
        for j in range(i + 1, n - 1):
            gj = gen[j]
            if abs(i - j) == 1:
                assert gi * gj != G.identity
                assert (gi * gj)**2 != G.identity
                assert (gi * gj)**3 == G.identity
            else:
                assert gi * gj != G.identity
                assert (gi * gj)**2 == G.identity

        gj = gen[n - 1]
        if i < n - 3 or i == n - 2:
            assert gi * gj != G.identity
            assert (gi * gj)**2 == G.identity
        elif i == n - 3:
            assert gi * gj != G.identity
            assert (gi * gj)**2 != G.identity
            assert (gi * gj)**3 == G.identity

    if n < 5:
        assert len(mulclose(G.gen)) == (2**(n - 1)) * factorial(n)
Ejemplo n.º 21
0
def test_young0():
    ring = element.Q

    n = argv.get("n", 3)
    part = argv.get("part", (1, 1, 1))
    assert sum(part) == n

    V = Space(ring, n)

    # build action of symmetric group on the space V
    items = list(range(n))
    gen1 = []
    gen2 = []
    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]
        g = Perm(perm, items)
        gen1.append(g)
        A = elim.zeros(ring, n, n)
        for k, v in perm.items():
            A[v, k] = ring.one
        lin = Lin(V, V, A)
        gen2.append(lin)

    perms = mulclose(gen1)
    G = Group(perms, items)

    #print(G)

    action = mulclose_hom(gen1, gen2)
    for g in G:
        for h in G:
            assert action[g *
                          h] == action[g] * action[h]  # check it's a group hom

    young = Young(G, part)
    rowG = young.get_rowperms()
    print("rowG", len(rowG))
    colG = young.get_colperms()
    print("colG", len(colG))

    horiz = None
    for g in rowG:
        P = action[g]
        horiz = P if horiz is None else (horiz + P)

    vert = None
    for g in colG:
        P = action[g]
        s = g.sign()
        P = ring.promote(s) * P
        vert = P if vert is None else (vert + P)
    A = horiz * vert

    assert vert * vert == len(colG) * vert
    assert horiz * horiz == len(rowG) * horiz

    print("part:", part)
    print(young)
    print("rank:", A.rank())
    print("is_zero:", A.is_zero())
    print(A)
    #if not A.is_zero():
    #    print(A)

    print()
Ejemplo n.º 22
0
def test_young():
    # code ripped from qu.py

    d = argv.get("d", 2)
    n = argv.get("n", 3)
    p = argv.get("p")

    if p is None:
        ring = element.Q
    else:
        ring = element.FiniteField(p)
    print("ring:", ring)

    space = Space(ring, d)

    # tensor power of the space
    tspace = reduce(matmul, [space] * n)

    # build action of symmetric group on the tensor power
    items = list(range(n))
    gen1 = []
    gen2 = []
    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]
        g = Perm(perm, items)
        gen1.append(g)
        lin = tspace.get_swap([g[i] for i in items])
        #print(lin.hom)
        gen2.append(lin)

    perms = mulclose(gen1)
    G = Group(perms, items)

    #print(G)

    action = mulclose_hom(gen1, gen2)
    for g in G:
        for h in G:
            assert action[g *
                          h] == action[g] * action[h]  # check it's a group hom

    # Build the young symmetrizers
    projs = []
    part = argv.get("part")
    parts = list(partitions(n)) if part is None else [part]
    for part in parts:
        assert sum(part) == n

        t = Young(G, part)

        rowG = t.get_rowperms()
        colG = t.get_colperms()
        horiz = None
        for g in rowG:
            P = action[g]
            horiz = P if horiz is None else (horiz + P)

        vert = None
        for g in colG:
            P = action[g]
            s = g.sign()
            P = ring.promote(s) * P
            vert = P if vert is None else (vert + P)
        A = horiz * vert

        assert vert * vert == len(colG) * vert
        assert horiz * horiz == len(rowG) * horiz
        #A = A.transpose()
        projs.append(A)

        print("part:", part)
        print(t)
        print("rank:", A.rank())
        print("is_zero:", A.is_zero())
        #if not A.is_zero():
        #    print(A)

        print()
Ejemplo n.º 23
0
def make_random_homogeneous():
    # use rotation group

    #seed(1)

    ngens = 6
    a, ai, b, bi, c, ci = range(ngens)
    i_rels = [
        (ai, a),
        (bi, b),
        (ci, c),
        (a, ) * 5,
        (b, ) * 2,
        (c, ) * 4,
        (a, b, c),
    ]

    while 1:
        rels = []
        for i in range(argv.get("nwords", 2)):
            gen = tuple(
                choice([a, b, c]) for k in range(argv.get("wordlen", 100)))
            rels.append(gen)
            gen = (ci, ) + gen + (c, )
            rels.append(gen)
            gen = (ci, ) + gen + (c, )
            rels.append(gen)

        rels = [reduce_word(i_rels, rel) for rel in rels]

        graph = Schreier(ngens, i_rels)
        if not graph.build(rels, maxsize=10400):
            print(choice("/\\"), end="", flush=True)
            continue

        n = len(graph)
        if n <= argv.get("minsize", 12):
            print('.', end="", flush=True)
            continue

        print("[%d]" % n, flush=True, end="")

        # how big did the graph get? compare with maxsize above
        print("(%d) " % len(graph.neighbors), flush=True, end="")

        try:
            gens = graph.get_gens()
        except AssertionError:
            print("** FAIL **")
            continue

        items = list(range(n))
        print()
        break

        N = argv.get("N", 10000)
        perms = mulclose(gens, maxsize=N)
        if len(perms) >= N:
            #print("|G| = ?")
            continue

        print()
        print(rels)
        G = Group(perms, items)
        G.gens = gens
        print("|G| =", len(G))

        rels = [reduce(mul, [gens[i] for i in rel]) for rel in rels]
        H = Coset(mulclose(rels), items)
        print("|H| =", len(H))
        assert len(G) % len(H) == 0
        print("[H:G] = ", len(G) // len(H))

        N = []
        for g in G:
            lhs = g * H
            rhs = H * g
            if lhs == rhs:
                N.append(g)
        assert len(N) % len(H) == 0
        print("[H:N(H)] =", len(N) // len(H))

    print(rels)

    a, ai, b, bi, c, ci = gens
    assert (a**5).is_identity()
    assert (b**2).is_identity()
    assert (c**4).is_identity()
    assert (a * b * c).is_identity()

    print(a.fixed())
    print(b.fixed())
    print(c.fixed())

    print(a.orbits())
    print(b.orbits())
    print(c.orbits())
Ejemplo n.º 24
0
def make_homogeneous():
    # use rotation group

    ngens = 6
    a, ai, b, bi, c, ci = range(ngens)
    i_rels = [
        (ai, a),
        (bi, b),
        (ci, c),
        (a, ) * 5,
        (b, ) * 2,
        (c, ) * 4,
        (a, b, c),
    ]
    _rels = [(2, 4, 0, 4, 0, 0, 4, 0, 4, 4, 4, 2, 2, 2, 2, 2, 0, 4, 2, 0, 4, 4,
              2, 4, 0, 4, 0, 4, 4, 0, 2, 0, 4, 2, 4, 0, 2, 0, 4, 4),
             (0, 0, 0, 2, 2, 4, 2, 0, 4, 2, 0, 4, 0, 4, 4, 0, 0, 0, 4, 4, 2, 4,
              4, 4, 4, 4, 0, 2, 2, 2, 0, 4, 4, 0, 4, 0, 2, 4, 0, 4),
             (2, 0, 4, 4, 0, 2, 4, 4, 2, 0, 0, 2, 0, 2, 2, 2, 2, 2, 0, 4, 2, 2,
              0, 0, 2, 4, 0, 4, 4, 2, 2, 4, 2, 4, 0, 0, 2, 0, 0, 0)]

    # no fixed points, F,E,V = 12,30,16
    rels = [
        (2, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 0, 4, 2, 0, 4, 2, 0, 0, 4, 4,
         0, 4, 2, 0, 4, 4, 2, 0, 2, 0, 4, 4, 4),
        (5, 2, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 0, 4, 2, 0, 4, 2, 0, 0, 4,
         4, 0, 4, 2, 0, 4, 4, 2, 0, 2, 0),
        (5, 5, 2, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 0, 4, 2, 0, 4, 2, 0, 0,
         4, 4, 0, 4, 2, 0, 4, 4, 2, 0, 2, 0, 4),
        (0, 0, 4, 0, 0, 4, 0, 4, 4, 4, 0, 0, 4, 0, 4, 2, 0, 0, 0, 0, 4, 0, 4,
         0, 4, 4, 0, 4, 4, 2, 4, 4, 4, 2, 0, 4, 2, 4, 2, 4, 4, 0, 4, 4, 4),
        (5, 0, 0, 4, 0, 0, 4, 0, 4, 4, 4, 0, 0, 4, 0, 4, 2, 0, 0, 0, 0, 4, 0,
         4, 0, 4, 4, 0, 4, 4, 2, 4, 4, 4, 2, 0, 4, 2, 4, 2, 4, 4, 0),
        (5, 5, 0, 0, 4, 0, 0, 4, 0, 4, 4, 4, 0, 0, 4, 0, 4, 2, 0, 0, 0, 0, 4,
         0, 4, 0, 4, 4, 0, 4, 4, 2, 4, 4, 4, 2, 0, 4, 2, 4, 2, 4, 4, 0, 4)
    ]

    rels = [reduce_word(i_rels, word) for word in rels]
    print(rels)

    graph = Schreier(ngens, i_rels)
    if not graph.build(rels, maxsize=10400):
        assert 0

    words = graph.get_words()
    for w in words:
        assert reduce_word(conj_rels(i_rels + rels), w) == w
    #    print(w)
    print("words:", len(words))

    gens = graph.get_gens()

    N = argv.get("N", 10000)
    perms = mulclose(gens, maxsize=N)
    if len(perms) >= N:
        print("|G| = ?")
    else:
        print("|G| = ", len(perms))

    a, ai, b, bi, c, ci = gens
    assert (a**5).is_identity()
    assert (b**2).is_identity()
    assert (c**4).is_identity()
    assert (a * b * c).is_identity()

    print(a.fixed())
    print(b.fixed())
    print(c.fixed())

    print("faces:", len(a.orbits()))
    print("edges:", len(b.orbits()))
    print("vertices:", len(c.orbits()))

    from bruhat.disc import render_group
    rels = conj_rels(rels)
    render_group(5, 2, 4, words, rels)

    return

    #    edges = set()
    #    for tile in items:
    #        for g in [a, ai, c, ci]:
    #            edge = (tile, g(tile))
    #            edges.append(edge)

    def intersect(lhs, rhs):
        return bool(set(lhs).intersection(rhs))

    def eq(lhs, rhs):
        for i in lhs:
            if i not in rhs:
                return False
        for i in rhs:
            if i not in lhs:
                return False
        assert len(lhs) == len(rhs)
        return True

    def search(tiles, tiless):
        for rhs in tiless:
            if eq(tiles, rhs):
                return True

    faces = [tuple(face) for face in a.orbits()]
    print("faces:", faces)

    assert intersect(faces[0], faces[0])
    assert not intersect(faces[0], faces[1])

    flookup = {}
    for face in faces:
        for i in face:
            flookup[i] = face
    for face in faces:
        print(faces.index(face), ":", end=" ")
        for i in face:
            print(faces.index(flookup[c(i)]), end=" ")
        print()
Ejemplo n.º 25
0
def main():

    n = argv.n
    if n:
        test(n)

    elif argv.test:
        for n in range(2, 6):
            test(n)
        test_longest_element()

    if argv.test_longest_element:
        test_longest_element()

    G = None

    if argv.E_8:
        G = Weyl.build_E8()
        assert G.matrix() == {
            (0, 1): 3,
            (1, 2): 3,
            (2, 3): 3,
            (3, 4): 3,
            (4, 5): 3,
            (4, 6): 3,
            (6, 7): 3
        }

    if argv.E_7:
        G = Weyl.build_E7()
        assert G.matrix() == {
            (0, 6): 3,
            (1, 2): 3,
            (2, 3): 3,
            (3, 4): 3,
            (3, 5): 3,
            (5, 6): 3
        }

    if argv.E_6:
        G = Weyl.build_E6()
        assert G.matrix() == {
            (0, 1): 3,
            (1, 2): 3,
            (2, 3): 3,
            (2, 4): 3,
            (4, 5): 3
        }
        #items = mulclose(G.gen, verbose=True)
        #print("|E6|=", len(items))

    if argv.F_4:
        G = Weyl.build_F4()
        assert G.matrix() == {(0, 1): 3, (1, 2): 4, (2, 3): 3}
        #items = mulclose(G.gen, verbose=True)
        #print("|F4|=", len(items)) # == 1152

    if argv.G_2:
        G = Weyl.build_G2()
        assert G.matrix() == {(0, 1): 6}
        assert len(mulclose(G.gen)) == 12  # dihedral group D_6

    for arg in argv:
        if len(arg) < 3 or arg[1] != "_":
            continue
        try:
            n = int(arg[2:])
        except:
            continue

        print("constructing %s" % arg)
        if arg.startswith("A"):
            G = Weyl.build_A(n)
        if arg.startswith("B"):
            G = Weyl.build_B(n)
        if arg.startswith("C"):
            G = Weyl.build_C(n)
        if arg.startswith("D"):
            G = Weyl.build_D(n)

    if G is None:
        return

    print("roots:", len(G.roots))
    for root in G.roots:
        print("\t", root)
    print(len(G.build_group()))
    if argv.show_qpoly:
        show_qpoly(G)

    if argv.show:
        for g in G.gen:
            print(g)

    if argv.longest_element:
        g = G.longest_element()
        print(g)

    if argv.monoid:
        test_monoid(G)

    if argv.representation:
        representation(G)

    if argv.find_negi:
        find_negi(G)

    if argv.orders:
        G = G.build_group()
        orders = [g.order() for g in G]
        orders.sort()
        print(orders)

    if argv.orbiplex:
        G = G.build_group()
        action.orbiplex(G)
Ejemplo n.º 26
0
def test_tree():
    x = Leaf()
    lhs = x*(x*x)
    rhs = (x*x)*x
    #print(lhs, rhs)
    #for key in lhs.keys():
    #    print(key, lhs[key])
    #print(lhs.sup(rhs))
    lhs, rhs = x*((x*x)*x), (x*x)*x
    #print(lhs.sup(rhs))

    lhs, rhs = x*((x*x)*x), (x*x)*x
    ks = lhs.keys()
    assert ks == [(0,), (1, 0, 0), (1, 0, 1), (1, 0), (1, 1), (1,), ()]
    assert lhs.find_carets() == {3: (1,0)}

    s = ((x*x)*x)*x
    t = (x*x)*(x*x)

    assert t.find_carets() == {2: (0,), 4: (1,)}
    assert s.find_carets() == {2: (0, 0)}
    t, s = cancel_carets(t, s)
    assert t == x*(x*x), t
    assert s == (x*x)*x, s

    assert s.reassoc((0,)) == t
    assert t.reassoc((1,)) == s

    tree = s*s
    assert list(tree.internal_nodes()) == [(0, 0), (0,), (1, 0), (1,)]

    catalan = [1, 1, 2, 5, 14, 42, 132]
    for i in range(7):
        n = i+1
        trees = list(all_trees(n))
        assert len(trees) == catalan[i]
        for tree in trees:
            assert tree.nleaves() == n
            keys = list(tree.internal_nodes())
            assert len(keys) == max(0, n-2), (n, len(keys))
            for k in keys:
                other = tree.reassoc(k)
                assert other != tree
                assert other in trees

    I = Assoc( x, x )
    assert I == I
    assert I*I == I
    F = Assoc( (x*x)*x, (x*x)*x )
    assert F == I

    A = Assoc( (x*x)*x, x*(x*x) )
    B = Assoc( x*((x*x)*x), x*(x*(x*x)) )
    #print(A, B)

    assert A*A == Assoc( (((x*x)*x)*x), (x*(x*(x*x))) )

    assert I*A == A
    assert A*I == A
    assert A*~A == I
    assert ~A*A == I

    lhs = bracket( A*~B, ~A*B*A )
    rhs = bracket( A*~B, (~A)*(~A)*B*A*A )
    assert lhs == rhs

    G = mulclose([A, B, ~A, ~B], maxsize=100)
    assert len(G) >= 100

    #for g in G:
    #    print(g.diamond_str())

    for n in range(1, 6):
        trees = list(all_trees(n))
        found = []
        for src in trees:
            for k in src.internal_nodes():
                tgt = src.reassoc(k)
                f = Assoc(tgt, src)
                found.append(f)
        uniq = set(found)
        #print(len(trees), len(found), len(set(found)))
        assert len(uniq) == max(0, 2**(n-1) - 2) # woah !
        uniq = list(uniq)
        uniq.sort(key = str)
        for f in uniq:
            assert ~f in uniq
Ejemplo n.º 27
0
def make_dicyclic(n, debug=False):
    # Binary dihedral group
    # https://people.maths.bris.ac.uk/~matyd/GroupNames/dicyclic.html

    p = cyclotomic(PolynomialRing(Z), 4 * n)
    ring = PolynomialRing(Z) / p
    rzeta = ring.x
    zeta = rzeta**2
    izeta = zeta**(2 * n - 1)  # inverse

    for k in range(1, 6 * n):
        if zeta**k == 1:
            break
    assert k == 2 * n

    if n == 3:
        assert zeta - 1 == zeta**2

    i = rzeta**n
    assert i != 1
    assert i**2 == -1
    assert i**3 == -i
    assert i**4 == 1

    assert zeta**(2 * n) == 1
    assert izeta != 1
    assert zeta * izeta == 1

    def is_real(v):  # this is a total hack
        assert ring.promote(v) is v
        x = exp(2.j * pi / (4 * n))
        s = str(v)
        v = eval(s, locals())
        return abs(v.imag) < EPSILON

    for k in range(1, 6 * n):
        assert is_real(rzeta**k) == (k % (2 * n) == 0)

    assert is_real(zeta + izeta)

    # we use the natural 2-dim representation
    GL = Linear(2, ring)
    e = GL.get([[1, 0], [0, 1]])
    r = GL.get([[zeta, 0], [0, izeta]])
    s = GL.get([[0, -1], [1, 0]])

    Di = mulclose([r, s])
    Di = list(Di)
    assert len(Di) == 4 * n

    eidx = Di.index(e)
    ridx = Di.index(r)
    sidx = Di.index(s)

    G = cayley(Di)
    e = G[eidx]
    r = G[ridx]
    s = G[sidx]

    assert r**(2 * n) == e
    assert s**2 == r**n
    assert r * s * r == s

    # complex characters ----------------------------------------------------

    # build the transpose of the character table.
    cols = []
    elems = []  # group elements with order the cols
    cgy = []  # element of each cgy class
    kidxs = range(2, n)

    desc = []

    # class: e, size 1
    elems.append(e)
    cgy.append(e)
    desc.append("e")
    cols.append([1, 1, 1, 1, 2] + [2 for k in kidxs])

    # class: s^2, size 1
    cols.append([1, 1, (-1)**n, (-1)**n, -2] + [((-1)**k) * 2 for k in kidxs])
    elems.append(s * s)
    cgy.append(s * s)
    desc.append("s^2")

    for idx in range(1, n):
        # class: r**idx, size 2
        col = [1, 1, (-1)**idx, (-1)**idx, zeta**idx + izeta**idx
               ] + [zeta**(idx * k) + izeta**(idx * k) for k in kidxs]
        cols.append(col)
        cols.append(col)
        elems.append(r**idx)
        cgy.append(r**idx)
        desc.append("r^%d" % idx)
        elems.append(r**(2 * n - idx))

    for idx in range(n):
        # class: s, size n
        cols.append([1, -1, i**n, -i**n, 0] + [0 for k in kidxs])
        elems.append(s * (r**(2 * idx)))
    cgy.append(s)
    desc.append("s")

    for idx in range(n):
        # class: s*r, size n
        cols.append([1, -1, -i**n, i**n, 0] + [0 for k in kidxs])
        elems.append(s * (r**(2 * idx + 1)))
    cgy.append(s * r)
    desc.append("sr")

    #print(i, -i, i**n, -i**n)

    assert len(set(elems)) == len(elems) == len(G)
    assert set(elems) == set(G)

    for col in cols:
        assert len(col) == n + 3, len(col)

    if debug:
        print()
        for s in desc:
            s = "%10s" % s
            print(s, end=" ")
        print()
        c_chars = []
        for k in range(n + 3):
            chi = dict((elems[i], cols[i][k]) for i in range(4 * n))
            f = CFunc(G, chi)
            for g in cgy:
                s = "%10s" % (f[g])
                print(s, end=" ")
            print()
            c_chars.append(f)
        print()

        for f in c_chars:
            for g in c_chars:
                val = f.dot(g, normalize=False)
                #assert (f == g) == (val == 1)
                print(val, end=" ")
            print()

    else:
        c_chars = []
        for k in range(n + 3):
            chi = dict((elems[i], cols[i][k]) for i in range(4 * n))
            f = CFunc(G, chi)
            c_chars.append(f)

        for f in c_chars:
            for g in c_chars:
                val = f.dot(g)
                assert (f == g) == (val == 1)

    G.c_chars = c_chars

    # complex reps ----------------------------------------------------

    c_reps = []

    e = G[eidx]
    r = G[ridx]
    s = G[sidx]

    tp = Cat(G, ring)

    def mk_rep(gen, reps):
        assert reps
        f = reps[0]
        V = f.hom.src
        send_perms = mulclose_hom(gen, reps)
        rep = Rep(send_perms, V, tp)
        return rep

    # 1-dim irreps
    V = Space(1, ring)
    hom = Hom(V, V)

    f_1 = Map.from_array([[1]], hom)
    f_n1 = Map.from_array([[-1]], hom)

    c_reps.append(mk_rep([r, s], [f_1, f_1]))  # Triv
    c_reps.append(mk_rep([r, s], [f_1, f_n1]))  # 1A

    f_r = Map.from_array([[-1]], hom)
    f_s = Map.from_array([[i**n]], hom)
    c_reps.append(mk_rep([r, s], [f_r, f_s]))  # 1B

    f_s = Map.from_array([[-i**n]], hom)
    c_reps.append(mk_rep([r, s], [f_r, f_s]))  # 1C

    # 2-dim irreps
    V = Space(2, ring)
    hom = Hom(V, V)

    for k in range(1, n):
        rho_r = Map.from_array([[zeta**k, 0], [0, izeta**k]], hom)
        rho_s = Map.from_array([[0, 1], [(-1)**k, 0]], hom)
        c_reps.append(mk_rep([r, s], [rho_r, rho_s]))  # rho_k

    for idx, rep in enumerate(c_reps):
        rep.check()
        char = c_chars[idx]
        tr = rep.trace()
        tr = CFunc(G, tr)
        #        print(tr, end=" ")
        #        val = tr.frobenius_schur()
        #        if val == -1:
        #            print("quaternionic")
        #        elif val == 0:
        #            print("complex")
        #        elif val == 1:
        #            print("real")
        #        else:
        #            assert 0, val

        for g in G:
            lhs, rhs = tr[g], char[g]
            assert lhs == rhs, "%d: %s != %s" % (idx, lhs, rhs)

    assert len(c_reps) == n + 3
    G.c_reps = c_reps

    # real characters ----------------------------------------------------

    r_chars = []

    r_chars.append(c_chars[0])  # Triv
    r_chars.append(c_chars[1])  # 1A

    if n % 2 == 0:
        assert c_chars[2].frobenius_schur() == 1  # real
        assert c_chars[3].frobenius_schur() == 1  # real
        r_chars.append(c_chars[2])  # 1B
        r_chars.append(c_chars[3])  # 1C
    else:
        assert c_chars[2].frobenius_schur() == 0  # complex
        assert c_chars[3].frobenius_schur() == 0  # complex
        r_chars.append(c_chars[2] + c_chars[3])  # 1B+1C

    for idx, rep in enumerate(c_reps):
        if idx < 4:
            continue
        char = c_chars[idx]
        val = char.frobenius_schur()
        if val == 1:
            r_chars.append(char)
        elif val == -1:
            r_chars.append(2 * char)
        else:
            assert 0

    G.r_chars = r_chars

    return G
Ejemplo n.º 28
0
def main():

    Z = element.Z
    ring = element.CyclotomicRing(8)
    x = ring.x
    r2 = x + x**7
    assert r2**2 == 2

    qubit = Space(2, ring)

    q2 = qubit @ qubit

    hom = Hom(qubit, qubit)

    I = Map.from_array([[1, 0], [0, 1]], hom)
    X = Map.from_array([[0, 1], [1, 0]], hom)
    Z = Map.from_array([[1, 0], [0, -1]], hom)
    Y = Map.from_array([[0, x**6], [x**2, 0]], hom)
    assert Y * Y == I
    assert Y == (x**2) * X * Z

    II = I @ I
    XI = X @ I
    IX = I @ X
    XX = X @ X
    ZI = Z @ I
    IZ = I @ Z

    assert XI * IX == XX
    T = Map.from_array([[1, 0], [0, x]], hom)
    Td = Map.from_array([[1, 0], [0, x**7]], hom)
    S = T * T
    Sd = Td * Td
    assert Z == S * S
    assert T * Td == I
    assert S * Sd == I
    assert S * Z == Z * S
    assert T * Z == Z * T

    assert (Z * X * Z) == -X
    assert ((Z @ Z) * (X @ X) * (Z @ Z)) == X @ X
    assert ((S @ S) * (X @ X) * (Sd @ Sd)) == atpow((S * X * Sd), 2)

    SXSd = S * X * Sd
    TXTd = T * X * Td
    lhs = r2 * TXTd
    i = x**2
    assert (lhs == X + i * X * Z)

    if 0:
        names = mulclose_names([X, Z, x * I], "X Z xI".split())
        #print("SXSd:", "*".join(names[SXSd]))

        names = mulclose_names([XI, IX, ZI, IZ], "XI IX ZI IZ".split())
        g = atpow(SXSd, 2)
        #print("*".join(names[g]))

        gen = [
            X @ I @ I @ I, I @ X @ I @ I, I @ I @ X @ I, I @ I @ I @ X,
            Z @ I @ I @ I, I @ Z @ I @ I, I @ I @ Z @ I, I @ I @ I @ Z,
            x * (I @ I @ I @ I)
        ]
        names = "XIII IXII IIXI IIIX ZIII IZII IIZI IIIZ wIIII".split()
        names = mulclose_names(gen, names)
        g = atpow(SXSd, 4)
        #print("*".join(names[g]))
        g = atpow(TXTd, 4)
        assert g not in names

    I8, X8, Z8 = atpow(I, 8), atpow(X, 8), atpow(Z, 8)
    T8 = atpow(T, 8)
    #print(T8.str(hide_zero=True, sep=""))
    Td8 = atpow(Td, 8)
    G = mulclose([X8, Z8])
    P = I8 + X8 + Z8 + X8 * Z8
    assert P * P == 4 * P
    lhs = P
    rhs = T8 * P * Td8
    assert (rhs * rhs == 4 * rhs)

    #T1 = reduce(matmul, [T, Td]*4)
    #T2 = reduce(matmul, [Td, T]*4)
    #print(T1*P*T2)
    #return

    Q = P @ P

    RM14 = """
    1111111111111111
    .1.1.1.1.1.1.1.1
    ..11..11..11..11
    ....1111....1111
    ........11111111
    """.strip().split()
    RM14.pop(0)

    def interp(row, op):
        ops = [op if s == "1" else I for s in row]
        A = reduce(matmul, ops)
        return A

    RM14 = [row[1:] for row in RM14]  # puncture
    n = len(RM14[0])
    Sx = [interp(row, X) for row in RM14]
    Sz = [interp(row, Z) for row in RM14]

    if 0:
        print("mulclose...")
        G = mulclose(Sx + Sz, maxsize=2**len(Sx + Sz))  # too slow :-(
        print(len(G))
        P = reduce(add, G)
        assert P * P == len(G) * P

        Tn = atpow(T, n)
        Tdn = atpow(Td, n)
        print(P == Tn * P * Tdn)

    #print(lhs.str(hide_zero=True, sep=""))
    #print()
    #print()
    #print()
    #print(rhs.str(hide_zero=True, sep=""))

    gen = [
        X @ I @ I @ I @ I @ I @ I @ I, I @ X @ I @ I @ I @ I @ I @ I,
        I @ I @ X @ I @ I @ I @ I @ I, I @ I @ I @ X @ I @ I @ I @ I,
        I @ I @ I @ I @ X @ I @ I @ I, I @ I @ I @ I @ I @ X @ I @ I,
        I @ I @ I @ I @ I @ I @ X @ I, I @ I @ I @ I @ I @ I @ I @ X,
        Z @ I @ I @ I @ I @ I @ I @ I, I @ Z @ I @ I @ I @ I @ I @ I,
        I @ I @ Z @ I @ I @ I @ I @ I, I @ I @ I @ Z @ I @ I @ I @ I,
        I @ I @ I @ I @ Z @ I @ I @ I, I @ I @ I @ I @ I @ Z @ I @ I,
        I @ I @ I @ I @ I @ I @ Z @ I, I @ I @ I @ I @ I @ I @ I @ Z,
        x * (I @ I @ I @ I @ I @ I @ I @ I)
    ]
    names = """
        XIIIIIII IXIIIIII IIXIIIII IIIXIIII IIIIXIII IIIIIXII IIIIIIXI IIIIIIIX 
        ZIIIIIII IZIIIIII IIZIIIII IIIZIIII IIIIZIII IIIIIZII IIIIIIZI IIIIIIIZ 
        wIIIIIIII
    """.strip().split()
    gen.pop(-1)
    names.pop(-1)

    if 0:
        g = atpow(TXTd, 8)
        for i in range(8):
            print(g == (x**i) * atpow(X * Z, 8))
        return

    if 0:
        names = mulclose_names(gen, names)
        g = atpow(TXTd, 8)
        for i in range(8):
            print(names.get((x**i) * g, "?"))

    #for i in [1, 2, 4]:
    #    print(atpow(TXTd, i))

    if 0:
        #print(Td*X*T)
        X4 = X @ X @ X @ X
        T4 = T @ T @ T @ T
        Td4 = Td @ Td @ Td @ Td
        print(Td4 * X4 * T4)

    H = X + Z
    E = Map.from_array([[0, 1], [0, 0]], hom)  # raising
    F = Map.from_array([[0, 0], [1, 0]], hom)  # lowering

    CNOT = Map.from_array(
        [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]], hom @ hom)

    SWAP = Map.from_array(
        [[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]], hom @ hom)

    assert SWAP * SWAP == II
    assert CNOT * CNOT == II

    G = mulclose([XI, IX, CNOT])  # order 8
    G = mulclose([XI, IX, CNOT, SWAP])  # order 24.. must be S_4
    G = mulclose([CNOT, SWAP])
    #    print(len(G))
    #    for g in G:
    #        print(g)

    A = SWAP @ I
    B = I @ SWAP
    S_3 = list(mulclose([A, B]))
    assert len(S_3) == 6
    #    for g in G:
    #        print(g)
    #    print(g.hom)

    hom = A.hom
    space = hom.src
    N = 2**3
    basis = space.get_basis()
    orbits = set()
    for v in basis:
        v1 = space.zero_vector()
        for g in S_3:
            u = g * v
            v1 = v1 + u
        orbits.add(v1)
    orbits = list(orbits)
    #    for v in orbits:
    #        print(v)

    HHH = H @ H @ H
    v = basis[7]
    #print(v)
    #print(HHH * v)

    print("OK")
Ejemplo n.º 29
0
def main():

    d = 2

    ring = CyclotomicRing(8)
    #ring = element.Z
    e = ring.x
    gamma = e**2
    w = gamma**2
    assert w == -1

    I = numpy.zeros((d, d), dtype=object)
    wI = numpy.zeros((d, d), dtype=object)
    X = numpy.zeros((d, d), dtype=object)
    Z = numpy.zeros((d, d), dtype=object)
    Zdag = numpy.zeros((d, d), dtype=object)
    S = numpy.zeros((d, d), dtype=object)
    Sdag = numpy.zeros((d, d), dtype=object)
    T = numpy.zeros((d, d), dtype=object)
    Tdag = numpy.zeros((d, d), dtype=object)
    for j in range(d):
        I[j, j] = 1
        wI[j, j] = w
        X[j, (j + 1) % d] = 1
        Z[j, j] = w**j
        Zdag[j, j] = w**(d - j)

        val = [1, gamma][j]
        ival = [1, -gamma][j]
        assert val * ival == 1

        S[j, j] = val
        Sdag[j, j] = ival

        val = [1, e][j]
        ival = [1, e**7][j]
        assert val * ival == 1

        T[j, j] = val
        Tdag[j, j] = ival

    qu = Space(d, ring)
    hom = Hom(qu, qu)

    I = Map.from_array(I, hom)
    wI = Map.from_array(wI, hom)
    Xdag = Map.from_array(X.transpose(), hom)
    X = Xs = Map.from_array(X, hom)
    Z = Map.from_array(Z, hom)
    Zdag = Map.from_array(Zdag, hom)
    S = Map.from_array(S, hom)
    Sdag = Map.from_array(Sdag, hom)
    T = Map.from_array(T, hom)
    Tdag = Map.from_array(Tdag, hom)

    Y = w * X * Z  # ?

    assert S * Sdag == I
    assert S * S == Z
    assert T * T == S

    assert Z * Zdag == I
    assert X * Xdag == I

    if d > 2:
        for j in range(1, d + 1):
            assert (j == d) == (X**j == I)
            assert (j == d) == (Z**j == I)
    else:
        assert X != I
        assert Z != I
        assert X * X == I
        assert Z * Z == I

    assert Z * X == (w**(d - 1)) * X * Z

    pauli = mulclose([X, Z, gamma * I])
    pauli = set(pauli)
    print("pauli:", len(pauli))
    assert Zdag in pauli
    assert Xdag in pauli

    if d < 6:
        # slow..
        lhs = atpow(X, d)
        rhs = atpow(Z, d)
        assert lhs * rhs == rhs * lhs

    lhs = X @ X
    rhs = Z @ Zdag
    assert lhs * rhs == rhs * lhs

    lhs = X @ (X**(d - 1))
    rhs = Z @ Z
    assert lhs * rhs == rhs * lhs

    if 0:
        n = 5
        ops = [X, Xdag]
        lhs = []
        for op in cross([ops] * n):
            op = reduce(matmul, op)
            lhs.append(op)

        ops = [Z, Zdag]
        rhs = []
        for op in cross([ops] * n):
            op = reduce(matmul, op)
            rhs.append(op)

        for l in lhs:
            for r in rhs:
                if l * r == r * l:
                    print("/", end=" ", flush=True)
                else:
                    print(".", end=" ", flush=True)
        print()

    #print(Z@Z@Z)

    #print(Y)
    #print(S*X*Sdag)
    #print(Y == S*X*Sdag)
    if d == 3:
        assert (Y == S * X * Sdag)

    inverse = {}
    for g in pauli:
        for h in pauli:
            if g * h == I:
                inverse[g] = h
                inverse[h] = g

    def is_cliff(A, Ai):
        assert A * Ai == I
        for g in pauli:
            h = A * g * Ai
            if h not in pauli:
                return False
        return True

    print(S)
    print(Sdag)
    assert is_cliff(S, Sdag)

    #print("is_cliff:", (S in pauli), is_cliff(S, Sdag))

    def is_third_level(A, Ai):
        assert A * Ai == I
        for g in pauli:
            gi = inverse[g]
            h = A * g * Ai * gi
            hi = g * A * gi * Ai
            if not is_cliff(h, hi):
                return False
        return True

    print("is_pauli(S)", S in pauli)
    print("is_cliff(S)", is_cliff(S, Sdag))
    #print("is_third_level(S)", is_third_level(S, Tdag))

    print("is_pauli(T)", T in pauli)
    print("is_cliff(T)", is_cliff(T, Tdag))
    print("is_third_level(T)", is_third_level(T, Tdag))

    #C2 = mulclose([X, T, H])

    print("OK")
Ejemplo n.º 30
0
def test():

    f = FiniteField(5)
    one = f.one
    zero = f.zero

    assert one==1
    assert str(one) == "1"

    a = zero
    for i in range(1000):
        a = one + a
        if a==zero:
            break
    assert i==4, i

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

    one = Z.one
    two = one + one
    assert one/one == one
    assert two/two == one
    assert two/(-one) == -two

    ring = PolynomialRing(Z)

    one = ring.one
    assert ring.x == Polynomial({1:1}, ring)
    x = ring.x

    assert (x+one)**5 == x**5+5*x**4+10*x**3+10*x**2+5*x+1
    assert str((x+one)**3) == "x**3+3*x**2+3*x+1"

    assert ring.content(10*x + 2) == 2
    assert ring.content(5*x**2 + 10*x + 2) == 1

    for (a, b) in [
        (4, 10),
        (4, 10*x),
        (2*x+1, 3*x),
        (x**3 + x + 1, x**6),
    ]:
        a = ring.promote(a)
        b = ring.promote(b)
        div, rem = a.reduce(b)
        assert a*div + rem == b
        #print("(%s) * (%s) + %s = %s" % (a, div, rem, b))

        c = ring.gcd(a, b)
        #print("gcd(%s, %s) == %s"%(a, b, c))

    #return

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

    field = FiniteField(5)
    ring = PolynomialRing(field)

    one = ring.one
    x = ring.x

    assert (x+one)**5 == x**5+1

    assert x**0 == one

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

    # check we can build galois field GF(8)

    field = FiniteField(2)
    ring = PolynomialRing(field)

    one = ring.one
    x = ring.x

    f = x**3 - x - 1
    assert f == x**3+x+1
    assert f(0) != 0
    assert f(1) != 0
    
    b = x**5
    div, rem = f.reduce(b)
    assert f*div + rem == b

    group = []
    for i in range(2):
     for j in range(2):
      for k in range(2):
        a = i + j*x + k*x**2
        if a != 0:
            group.append(a)

    div = {}
    for a in group:
      for b in group:
        c = f.reduce(a*b)[1]
        div[c, a] = b
        div[c, b] = a

    # all non-zero pairs elements of GF(8) should be divisable:
    assert len(div) == 49

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

    # GF(4)
    x = ring.x
    GF = GaloisField(ring, (x**2 + x + 1))

    x = GF.x
    one = GF.one
    a, b = x, x+one
    assert a*a == b
    assert a*b == b*a
    assert a*b == one
    assert b*b == a

    assert one/x == one+x

    frobenius = lambda a : a**2
    assert frobenius(one) == one
    assert frobenius(one+one) == one+one
    assert frobenius(x) == x+1
    assert frobenius(x+1) == x

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

    # GF(8)
    x = ring.x
    GF = GaloisField(ring, (x**3 + x + 1))

    one = GF.one
    x = GF.x

    assert one/x == x**2+1

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

    # GF(64)
    x = ring.x
    GF = GaloisField(ring, (x**6 + x + 1))

    one = GF.one
    x = GF.x

    assert len(GF.elements) == 64

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

    p = 7
    field = FiniteField(p)
    ring = PolynomialRing(field)
    x = ring.x

    if p % 4 == 3:
        r = p-1
    else:
        assert 0

    GF = GaloisField(ring, x**2 - r)

    one = GF.one
    x = GF.x

    for a in GF.elements:
        b = a**(p+1)
        assert b.deg <= 0, repr(b)

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

    Z2 = FiniteField(2)
    for GL in [Linear(1, Z), Linear(2, Z), Linear(2, Z2)]:

        one = GL.one
        zero = GL.zero
        
        assert one-one == zero
        assert zero+one == one
        assert one+one != one
        assert one*one == one
        assert zero*one == zero
        assert one+one == 2*one

        if GL.base == Z2:
            assert one+one == zero
    
    GL2 = Linear(2, Z)
    A = GL2.get([[1, 1], [0, 1]])

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

    field = FiniteField(2)
    GL = Linear(3, field)

    gen = [
        [[1, 1, 0], [0, 1, 0], [0, 0, 1]],
        [[1, 0, 0], [0, 1, 1], [0, 0, 1]],
        [[1, 0, 0], [1, 1, 0], [0, 0, 1]],
        [[1, 0, 0], [0, 1, 0], [0, 1, 1]],
    ]
    gen = [GL.get(g) for g in gen]

    GL3_2 = mulclose(gen)
    assert len(GL3_2) == 168

    if argv.GL3_2:
        burnside(cayley(GL3_2)) # high memory usage

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

    ring = Z
    GL = Linear(3, ring)

    gen = [
        [[0, 0, -1], [0, 1, 0], [1, 0, 0]],
        [[1, 0, 0], [0, 0, 1], [0, -1, 0]],
    ]
    gen = [GL.get(g) for g in gen]

    B_3 = mulclose(gen)
    assert len(B_3) == 24
    if argv.B_3:
        B_3 = cayley(B_3)
        burnside(B_3)

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

    field = FiniteField(3)
    GL = Linear(2, field)
    A = GL.get([[1, 1], [0, 1]])
    B = GL.get([[1, 0], [1, 1]])

    # AKA. binary tetrahedral group
    SL2_3 = mulclose([A, B])
    assert len(SL2_3) == 24

    if argv.SL2_3:
        burnside(cayley(SL2_3))

    # -------------------------
    # https://people.maths.bris.ac.uk/~matyd/GroupNames/1/GL(2,3).html

    C = GL.get([[2, 0], [0, 1]])
    D = GL.get([[1, 0], [0, 2]])

    GL2_3 = mulclose([A, B, C, D])
    assert len(GL2_3) == 48

    if argv.GL2_3:
        burnside(cayley(GL2_3))

    # -------------------------
    # https://people.maths.bris.ac.uk/~matyd/GroupNames/1/Q8.html
    # quaternion group, Q_8 

    A = GL.get([[2, 2], [2, 1]])
    B = GL.get([[0, 2], [1, 0]])

    Q8 = mulclose([A, B])
    assert(len(Q8)) == 8

    if argv.Q8 or argv.Q_8:
        burnside(cayley(Q8))

    # -------------------------
    # https://people.maths.bris.ac.uk/~matyd/GroupNames/97/SL(2,5).html
    # aka binary icosahedral group

    field = FiniteField(5)
    GL = Linear(2, field)

    A = GL.get([[4, 2], [4, 1]])
    B = GL.get([[3, 3], [4, 1]])

    SL2_5 = mulclose([A, B])
    assert len(SL2_5) == 120

    if argv.SL2_5:
        burnside(cayley(SL2_5))

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

    field = FiniteField(7)
    GL = Linear(2, field)
    A = GL.get([[1, 1], [0, 1]])
    B = GL.get([[1, 0], [1, 1]])

    SL2_7 = mulclose([GL.one, A, B])
    assert len(SL2_7) == 336 == 168*2


    # https://people.maths.bris.ac.uk/~matyd/GroupNames/1/CSU(2,3).html
    # aka binary octahedral group
    A = GL.get([[2, 1], [2, 5]])
    B = GL.get([[1, 2], [6, 6]])
    C = GL.get([[4, 0], [2, 2]])
    D = GL.get([[2, 5], [6, 5]])

    BO = mulclose([A, B, C, D])
    assert len(BO) == 48
    if argv.BO:
        burnside(cayley(BO))

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

    ring = PolynomialRing(Z)
    x = ring.x
    assert cyclotomic(ring, 1) == x-1
    assert cyclotomic(ring, 2) == x+1
    assert cyclotomic(ring, 3) == x**2+x+1
    assert cyclotomic(ring, 4) == x**2+1
    assert cyclotomic(ring, 5) == x**4+x**3+x**2+x+1
    assert cyclotomic(ring, 6) == x**2-x+1
    assert cyclotomic(ring, 7) == x**6+x**5+x**4+x**3+x**2+x+1
    assert cyclotomic(ring, 8) == x**4+1
    assert cyclotomic(ring, 9) == x**6+x**3+1
    assert cyclotomic(ring, 10) == x**4-x**3+x**2-x+1
    assert cyclotomic(ring, 24) == x**8-x**4+1

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

    for n in range(2, 20):

        p = cyclotomic(PolynomialRing(Z), 2*n)
    
        ring = PolynomialRing(Z) / p
        x = ring.x
        assert x*1 == x
    
        x1 = x**(2*n-1) # inverse
        
        assert x**(2*n) == 1
        assert x1 != 1
    
        # ----------------------------
        # Binary dihedral group
        # https://people.maths.bris.ac.uk/~matyd/GroupNames/dicyclic.html
    
        GL = Linear(2, ring)
    
        A = GL.get([[x, 0], [0, x1]])
        B = GL.get([[0, -1], [1, 0]])
    
        Di = mulclose([A, B])
        assert len(Di) == 4*n

        if argv.Dic and n==argv.get("n"):
            print("order =", len(Di))
            burnside(cayley(Di))
            return

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

    one = Q.one
    two = one+one
    assert two*one == two
    half = one/two
    assert 2*half == 1

    assert 4*one/4 == one
    assert str(18*one/4) == "9/2"

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

    ring = PolynomialRing(Z)
    field = FieldOfFractions(ring)
    one = field.one
    two = one+one
    assert two*one == two
    half = one/two
    assert 2*half == 1
    assert 4*one/4 == one

    # -------------------------
    # Gaussian integers
    # http://math.ucr.edu/home/baez/week216.html

    ring = PolynomialRing(Z)
    x = ring.x
    gints = ring / (x**2 + 1)

    one = gints.one
    i = gints.x

    assert i*i == -one
    assert i**3 == -i

    assert (1+i)**2 == 2*i
    assert (2+i)*(2-i) == 5
    assert (3+2*i)*(3-2*i) == 13

    # -------------------------
    # Eisenstein integers
    
    ring = PolynomialRing(Z)
    x = ring.x
    ints = ring / cyclotomic(ring, 3)

    one = ints.one
    i = ints.x

    assert i**3 == 1

    # -------------------------
    # Kleinian integers
    
    ring = PolynomialRing(Z)
    x = ring.x
    ints = ring / (x**2 + x + 2)

    one = ints.one
    i = ints.x

    assert i * (-1-i) == 2
    assert i * (1+i) == -2

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

    ring = PolynomialRing(Z)
    p = cyclotomic(PolynomialRing(Z), 8)
    ring = ring / p
    field = FieldOfFractions(ring)

    x = field.promote(ring.x)
    one = field.one

    r2 = x + x**7
    assert r2**2 == 2  # sqrt(2)

    i = x**2
    assert i**2 == -one # sqrt(-1)

    GL = Linear(2, field)
    I = GL.get([[1, 0], [0, 1]])
    J = GL.get([[1, 0], [0, i]])
    
    M = (r2/2) * GL.get([[1, 1], [1, -1]]) # Hadamard

    assert J**4 == I
    assert M**2 == I
    
    G = mulclose([J, M])
    assert len(G) == 192

    assert M in G

    def get_order(A):
        count = 1
        B = A
        while B!=I:
            B = A*B
            count += 1
        return count
            
    #for g in G:
    #    if get_order(g)==4:
    #        print(g)
    assert get_order(M)==2

    # Metaplectic Hadamard
    M1 = GL.get([[1, -i], [-i, 1]])
    r = x / r2
    M1 = r*M1

    assert get_order(M1)==4

#    #G = cayley(G)
#    #orders = [g.order() for g in G]
#    orders = [get_order(A) for A in G]
#    orders.sort()
#    print(orders)


    i_actually_know_what_im_doing = False

    if i_actually_know_what_im_doing:

        # -------------------------
        # Q[i]
    
        ring = PolynomialRing(Q)
        x = ring.x
        gints = ring / (x**2 + 1)
    
        one = gints.one
        i = gints.x
    
        assert i*i == -one
        assert i**3 == -i
    
        assert (1+i)**2/i == 2
        assert (2+i)*(2-i)/5 == 1
        assert (3+2*i)*(3-2*i)/13 == 1