Пример #1
0
 def counit(A):
     assert isinstance(A, Cell1)
     src = A * A.dual
     tgt = Cell1.identity(A.tgt)
     assert tgt.hom == src.hom
     shape = tgt.shape
     n = shape[0]
     assert n == shape[1]
     rig = A.rig
     ring = rig.ring
     linss = []
     for i in range(n):
         lins = []  # row
         for k in range(n):
             t, s = tgt[i, k], src[i, k]
             if i != k:
                 lin = Lin.zero(t, s)
             else:
                 # argh... why can't we direct_sum the Lin.counit's ?
                 a = elim.zeros(ring, t.n, s.n)
                 idx = 0
                 for j in range(A.shape[1]):
                     counit = Lin.counit(rig.one, A[i, j])
                     a[:, idx:idx + counit.shape[1]] = counit.A
                     idx += counit.shape[1]
                 assert idx == s.n
                 lin = Lin(t, s, a)
             lins.append(lin)
         linss.append(lins)
     return Cell2(tgt, src, linss)
Пример #2
0
def randchain(ring, n, m):
    V = Space(ring, n, 1, "V")
    U = Space(ring, m, 0, "U")
    B = Lin.rand(U, V)

    A = B.kernel()
    A = Lin(A.tgt, A.src.asgrade(2), A.A)  # yikes
    assert (B * A).is_zero()

    C = B.cokernel()
    C = Lin(C.tgt.asgrade(-1), C.src, C.A)
    assert (C * B).is_zero()

    c = Chain([A, B, C])
    return c
Пример #3
0
 def zero(cls, tgt, src):  # tgt <---- src
     assert isinstance(tgt, Cell1)
     assert isinstance(src, Cell1)
     assert tgt.rig == src.rig
     assert tgt.hom == src.hom
     rig = tgt.rig
     rows, cols = tgt.shape
     linss = [[Lin.zero(tgt[i, j], src[i, j]) for j in range(cols)]
              for i in range(rows)]
     return Cell2(tgt, src, linss)
Пример #4
0
    def mk_ising(m, n):
        U = Space(ring, m, 0, "U")
        V = Space(ring, n, 1, "V")

        A = Lin(U, V)  # U <--- V
        for i in range(m):
            A[i, i] = one
            if i + 1 < n:
                A[i, i + 1] = -one
        return A
Пример #5
0
 def get_sl(self, V):
     assert V.n == 2, "todo.."
     lins = []
     for a in self:
         for b in self:
             for c in self:
                 for d in self:
                     if a * d - b * c == 1:
                         f = Lin(V, V, [[a, b], [c, d]])
                         lins.append(f)
     return lins
Пример #6
0
 def right_unitor(cls, cell1, inverse=False):
     m, n = cell1.hom
     I_n = Cell1.identity(n)
     tgt, src = cell1, cell1 * I_n
     if inverse:
         tgt, src = src, tgt
     # Bit of a hack just using .iso here!
     # Should use MulSpace.unitor, etc. etc. XXX
     rows, cols = cell1.shape
     A = [[Lin.iso(tgt[i, j], src[i, j]) for j in range(cols)]
          for i in range(rows)]
     return Cell2(tgt, src, A)
Пример #7
0
 def __add__(left, right):
     "direct_sum of 2-morphisms's"
     right = Cell2.promote(right)
     tgt = left.tgt + right.tgt
     src = left.src + right.src
     rig = left.rig
     zero = Lin(rig.zero, rig.zero)
     A = numpy.empty(tgt.shape, dtype=object)
     A[:] = [[zero]]
     A[:left.shape[0], :left.shape[1]] = left.A
     A[left.shape[0]:, left.shape[1]:] = right.A
     return Cell2(tgt, src, A)
Пример #8
0
def test_chain_tensor():
    #p = argv.get("p", 3)
    #ring = element.FiniteField(p)
    ring = element.Q

    space = Space(ring)

    m = argv.get("m", 3)
    n = argv.get("n", 4)

    one = ring.one
    if argv.toric:
        V = Space(ring, n, 1, "V")
        U = Space(ring, m, 0, "U")

        A = Lin(U, V)
        for i in range(m):
            A[i, i] = one
            A[i, (i + 1) % m] = -one
    elif argv.surface:
        V = Space(ring, m, 1, "V")
        U = Space(ring, m - 1, 0, "U")

        A = Lin(U, V)
        for i in range(m - 1):
            A[i, i] = one
            A[i, (i + 1) % m] = -one
    else:
        V = Space(ring, n, 1, "V")
        U = Space(ring, m, 0, "U")
        A = Lin.rand(U, V)

    c = Chain([A])
    print(c)

    c.dump()
Пример #9
0
def test_gf():
    ring = GF(4)
    x = ring.x
    space = Space(ring)

    m = argv.get("m", 3)
    n = argv.get("n", 4)

    one = ring.one
    A = elim.zeros(ring, m, n)
    for i in range(m):
        for j in range(n):
            A[i, j] = choice(ring.elements)

    H = Lin(Space(ring, m, 0), Space(ring, n, 1), A)
    #print(H)

    c = Chain([H])
Пример #10
0
    def __init__(self, lhs, rhs):
        assert lhs.lins
        assert rhs.lins
        assert lhs.ring is rhs.ring
        ring = lhs.ring
        self._init()
        for g in rhs.lins:  # cols
            for f in lhs.lins:  # rows
                self._addlin(f @ g.src.identity())  # vertical arrow
                sign = -1 if f.src.grade % 2 else 1
                self._addlin(sign * f.src.identity() @ g)  # _horizontal arrow
            sign = -1 if f.tgt.grade % 2 else 1
            self._addlin(sign * f.tgt.identity() @ g)  # _horizontal arrow

        for f in lhs.lins:  # rows
            self._addlin(f @ g.tgt.identity())  # vertical arrow

        keys = list(self.grades.keys())
        keys.sort(reverse=True)
        #print(keys)

        N = len(keys)
        lins = []
        for idx in range(N - 1):
            i = keys[idx]
            assert keys[idx + 1] == i - 1, keys
            tgt = AddSpace(ring, *self.grades[i - 1])
            src = AddSpace(ring, *self.grades[i])
            #print(tgt)
            #print(src)
            A = elim.zeros(ring, tgt.n, src.n)
            #print(shortstr(A))
            for s in src.items:
                for lin in self.srcs[s]:
                    assert lin.src is s
                    cols = src.get_slice(lin.src)
                    rows = tgt.get_slice(lin.tgt)
                    A[rows, cols] = lin.A
            #print(shortstr(A))
            lin = Lin(tgt, src, A)
            #print(repr(lin))
            lins.append(lin)
            #print()
        Chain.__init__(self, lins)
Пример #11
0
 def __init__(self, tgt, src, lins=None, check=True):
     assert isinstance(tgt, Chain)
     assert isinstance(src, Chain)
     n = len(src)
     assert len(tgt) == n
     if lins is None:
         # zero map
         lins = [Lin(tgt.get(i), src.get(i)) for i in range(n + 1)]
     assert len(lins) == n + 1
     for i in range(n):
         assert src[i].src == lins[i].src
         assert tgt[i].src == lins[i].tgt
     if n:
         assert src[n - 1].tgt == lins[n].src
         assert tgt[n - 1].tgt == lins[n].tgt
     self.ring = tgt.ring
     self.tgt = tgt
     self.src = src
     self.hom = (tgt, src)  # yes it's backwards, just like shape is.
     self.lins = list(lins)
     if check:
         self._check()
Пример #12
0
    def reassociate(A, B, C, inverse=False):
        "A*(B*C) <--- (A*B)*C"

        assert C.tgt == B.src
        assert B.tgt == A.src
        m, n = A.shape
        p, q = C.shape

        if n * p == 0:
            tgt, src = A * (B * C), (A * B) * C
            if inverse:
                tgt, src = src, tgt
            return Cell2.zero(tgt, src)

        rig = A.rig
        ring = rig.ring

        def add(items):
            items = list(items)
            assert len(items)
            if len(items) == 1:
                return items[0]
            return AddSpace(ring, *items)

        #ABC = numpy.empty((m, n, p, q), dtype=object)
        #for i in range(m):
        # for j in range(n):
        #  for k in range(p):
        #   for l in range(q):
        #    ABC[i,j,k,l] = A[i,j]@B[j,k]@C[k,l]

        # src
        AB_C = numpy.empty((m, q), dtype=object)
        ab_c = numpy.empty((m, q), dtype=object)
        for i in range(m):
            for l in range(q):
                AB_C[i, l] = add(
                    add(A[i, j] @ B[j, k] for j in range(n)) @ C[k, l]
                    for k in range(p))
                items = [
                    Lin.right_distributor(
                        add(A[i, j] @ B[j, k] for j in range(n)), C[k, l])
                    for k in range(p)
                ]
                #rd = reduce(Lin.direct_sum, items or [rig.zero.identity()]) # will need nullitor's ?
                rd = reduce(Lin.direct_sum, items)
                assert rd.src == AB_C[i,
                                      l], ("%s != %s" % (rd.src, AB_C[i, l]))
                ab_c[i, l] = rd
        src = Cell1(A.tgt, C.src, AB_C)
        cell1 = Cell1(A.tgt, C.src,
                      [[ab_c[i, l].tgt for l in range(q)] for i in range(m)])
        ab_c = Cell2(cell1, src, ab_c)

        # tgt
        A_BC = numpy.empty((m, q), dtype=object)
        a_bc = numpy.empty((m, q), dtype=object)
        for i in range(m):
            for l in range(q):
                A_BC[i, l] = add(A[i, j] @ add(B[j, k] @ C[k, l]
                                               for k in range(p))
                                 for j in range(n))
                items = [
                    Lin.left_distributor(A[i, j],
                                         add(B[j, k] @ C[k, l]
                                             for k in range(p)),
                                         inverse=True) for j in range(n)
                ]
                #ld = reduce(Lin.direct_sum, items or [rig.zero.identity()]) # will need nullitor's ?
                ld = reduce(Lin.direct_sum, items)
                assert ld.tgt == A_BC[i, l]
                a_bc[i, l] = ld
        tgt = Cell1(A.tgt, C.src, A_BC)
        cell1 = Cell1(A.tgt, C.src,
                      [[a_bc[i, l].src for l in range(q)] for i in range(m)])
        a_bc = Cell2(tgt, cell1, a_bc)

        lookup = {}
        for k in range(p):
            for j in range(n):
                lookup[(j, k)] = len(lookup)
        perm = tuple(lookup[j, k] for j in range(n) for k in range(p))

        def get_swap(u):
            assert isinstance(u, AddSpace), (u, perm)
            f = u.get_swap(perm)
            return f

        if len(perm) > 1:
            s = Cell2.send(ab_c.tgt, get_swap)
            assert s.tgt == a_bc.src
        else:
            s = Cell2.identity(ab_c.tgt)
            assert s.tgt == a_bc.src

        f = a_bc * s * ab_c
        assert f.src == src
        assert f.tgt == tgt
        if inverse:
            f = f.transpose2()
        return f
Пример #13
0
 def rand(cls, tgt, src):
     assert tgt.hom == src.hom
     shape = tgt.shape
     lins = [[Lin.rand(tgt[i, j], src[i, j]) for j in range(shape[1])]
             for i in range(shape[0])]
     return Cell2(tgt, src, lins)
Пример #14
0
def test_chainmap():

    p = argv.get("p", 2)
    ring = element.FiniteField(p)
    #ring = element.Q

    one = ring.one

    space = Space(ring)

    def mk_ising(m, n):
        U = Space(ring, m, 0, "U")
        V = Space(ring, n, 1, "V")

        A = Lin(U, V)  # U <--- V
        for i in range(m):
            A[i, i] = one
            if i + 1 < n:
                A[i, i + 1] = -one
        return A

    A = mk_ising(3, 4)
    c = Chain([A])

    f = c.identity()
    zero = ChainMap(c, c)
    assert f != zero
    assert f == f
    assert f != 2 * f
    assert f + f == 2 * f
    assert f - f == zero

    B = mk_ising(2, 2)
    d = Chain([B])

    fn = Lin(A.src, B.src)
    for i in range(len(B.src)):
        fn[i, i] = one

    fm = Lin(A.tgt, B.tgt)
    for i in range(len(B.tgt)):
        fm[i, i] = one

    f = ChainMap(c, d, [fn, fm])

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

    m, n = 8, 10
    V1 = Space(ring, n, 1, "V1")
    V0 = Space(ring, m, 0, "V0")
    A = Lin.rand(V0, V1)  # V0 <--- V1

    c = Chain([A])

    U0 = Space(ring, m, 0, "U0")
    f0 = Lin.rand(V0, U0)

    f1, B = A.pullback(f0)
    d = Chain([B])
    f = ChainMap(c, d, [f1, f0])

    # -----------------------------------
    # construct a chain map (and a chain) from a
    # pullback of a grade zero map.

    m, n, p = 5, 6, 1
    V1 = Space(ring, n, 1, "V1")
    V0 = Space(ring, m, 0, "V0")
    #A = Lin.rand(V0, V1) # V0 <--- V1
    A = Lin(V0, V1)
    for i in range(m):
        A[i, i] = one
        A[i, (i + 1)] = one

    a = Chain([A])
    #print("A:")
    #print(A)

    U0 = Space(ring, p, 0, "U0")
    f0 = Lin(V0, U0)
    for i in range(p):
        f0[i, i] = one

    f1, B = A.pullback(f0)
    b = Chain([B])
    #print("B:")
    #print(B)
    f = ChainMap(a, b, [f1, f0])
    #print(f0)
    #print(f1)

    g = ChainMap(a, b)
    h = f.coequalizer(g)
    #print(h)
    #print(h[0])
    #print(h[1])
    c = h.tgt
    C = c[0]
    #print(C.shape, C.rank())
    #print(C)

    # -----------------------------------
    # construct a 'puncture' of a repitition code
    # as a cokernel

    m, n, p = 5, 6, 1
    V1 = Space(ring, n, 1, "V1")
    V0 = Space(ring, m, 0, "V0")
    #A = Lin.rand(V0, V1) # V0 <--- V1
    A = Lin(V0, V1)
    for i in range(m):
        A[i, i] = one
        A[i, (i + 1)] = one

    a = Chain([A])

    U1 = Space(ring, 1, 1, "U1")
    U0 = Space(ring, 2, 0, "U0")
    B = Lin(U0, U1)
    B[0, 0] = one
    B[1, 0] = one
    b = Chain([B])

    offset = 2  # where to puncture

    f0 = Lin(V0, U0)
    f0[0 + offset, 0] = one
    f0[1 + offset, 1] = one

    f1 = Lin(V1, U1)
    f1[offset + 1, 0] = one

    f = ChainMap(a, b, [f1, f0])
    h = f.cokernel()
    c = h.tgt

    # -----------------------------------
    # Here we puncture a bit from a parity check matrix
    # by using a cokernel. This deletes that column,
    # as well as all the rows with support therein.

    m, n, p = 5, 6, 1
    V1 = Space(ring, n, 1, "V1")
    V0 = Space(ring, m, 0, "V0")
    A = Lin.rand(V0, V1)  # V0 <--- V1

    a = Chain([A])
    #print(A)
    col = 0
    rows = []
    for i in range(V0.n):
        if A[i, col]:
            rows.append(i)

    U1 = Space(ring, 1, 1, "U1")
    U0 = Space(ring, len(rows), 0, "U0")
    B = Lin(U0, U1)
    for i in range(U0.n):
        B[i, 0] = one
    b = Chain([B])
    #print(B)

    f0 = Lin(V0, U0)
    for i, row in enumerate(rows):
        f0[row, i] = one
    #print(f0)

    f1 = Lin(V1, U1)
    f1[col, 0] = one

    f = ChainMap(a, b, [f1, f0])
    h = f.cokernel()
    c = h.tgt
Пример #15
0
 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]])