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)
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
def zero(cls, tgt, src): assert isinstance(tgt, Space), tgt assert isinstance(src, Space), src assert tgt.ring is src.ring ring = tgt.ring A = elim.zeros(ring, tgt.n, src.n) return Lin(tgt, src, A)
def __matmul__(self, other): src = self.src @ other.src tgt = self.tgt @ other.tgt ring = self.ring A, B = self.A, other.A if 0 in A.shape or 0 in B.shape: C = elim.zeros(ring, A.shape[0] * B.shape[0], A.shape[1] * B.shape[1]) else: #print("kron", A.shape, B.shape) C = numpy.kron(A, B) #print("\t", C.shape) return Lin(tgt, src, C)
def _dot(ring, A, B): #C = numpy.dot(self.A, other.A) # argh... #print("dot", A.shape, B.shape) assert len(A.shape) == len(B.shape) == 2 m, n = A.shape assert B.shape[0] == n l = B.shape[1] C = elim.zeros(ring, m, l) for i in range(m): for j in range(l): for k in range(n): C[i, j] += A[i, k] * B[k, j] return C
def copy(src): assert isinstance(src, Space) n = src.n tgt = src @ src ring = src.ring one = ring.one A = elim.zeros(ring, tgt.n, src.n) for i in range(n): for j in range(n): for k in range(n): if i == j == k: A[i + n * j, k] = 1 lin = Lin(tgt, src, A) return lin
def __init__(self, tgt, src, A=None): assert tgt.ring is src.ring self.ring = tgt.ring self.tgt = tgt self.src = src self.grade = none_sub(tgt.grade, src.grade) if A is None: A = elim.zeros(self.ring, tgt.n, src.n) if type(A) is list: A = elim.array(A) #for row in A: # assert None not in row assert A.shape == (tgt.n, src.n), "%s != %s" % (A.shape, (tgt.n, src.n)) self.hom = (tgt, src) # yes it's backwards, just like shape is. self.shape = A.shape self.A = A.copy()
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])
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)
def get_swap(self, perm=(1, 0)): perm = tuple(perm) items = self.items assert len(perm) == len(items), ("len(%s)!=%d" % (perm, len(items))) assert set(perm) == set(range(len(items))) tgt = reduce(add, [items[i] for i in perm]) N = len(items) rows = [] for i in perm: row = [] for j in range(N): if i == j: A = elim.identity(self.ring, items[i].n) else: A = elim.zeros(self.ring, items[i].n, items[j].n) row.append(A) rows.append(row) rows = [numpy.concatenate(row, axis=1) for row in rows] A = numpy.concatenate(rows) return Lin(tgt, self, A)
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()
def zeros(self, *args): return elim.zeros(self.ring, *args)