def get_g(self, grade): # chain map, from critical cells --> cells chain = self.chain src = self.get_critical(grade) tgt = chain.get_cells(grade) g = Matrix(tgt, src, {}, self.ring) A = self.get_down_match(grade) # grade --> grade-1 --> grade C = Matrix.inclusion(tgt, src, self.ring) while C.nonzero(): g += C C = A * C return g
def get_f(self, grade): # chain map, from cells --> critical cells chain = self.chain src = chain.get_cells(grade) tgt = self.get_critical(grade) f = Matrix(tgt, src, {}, self.ring) A = self.get_up_match(grade) # grade --> grade+1 --> grade C = Matrix.retraction(tgt, src, self.ring) while C.nonzero(): f += C C = C * A return f
def get_bdymap(self, grade): # grade --> grade-1 chain = self.chain src = self.get_critical(grade) # CM_grade tgt = self.get_critical(grade - 1) # CM_{grade-1} bdy = Matrix(tgt, src, {}, self.ring) # CM_grade --> CM_{grade-1} A = self.get_down_match(grade) # C_grade --> C_grade-1 --> C_grade B = chain.get_bdymap(grade) # C_grade --> C_grade-1 cells = chain.get_cells(grade) cells_1 = chain.get_cells(grade - 1) L = Matrix.retraction(tgt, cells_1, self.ring) # C_grade-1 --> CM_grade-1 B = L * B R = Matrix.inclusion(cells, src, self.ring) # CM_grade --> C_grade while R.nonzero(): bdy += B * R R = A * R return bdy
def get_homotopy(self, grade): # grade --> grade+1 ring = self.ring chain = self.chain tgt = chain.get_cells(grade + 1) src = chain.get_cells(grade) A = self.get_match(grade) B = self.get_down_match(grade + 1) chi = Matrix(tgt, src, {}, ring) while A.nonzero(): chi += A A = B * A return chi
def get_bdymap(self, grade): # warning: needs to return new object # grade -> grade-1 cols = self.get_cells(grade) rows = self.get_cells(grade - 1) bdys = self.bdys A = Matrix(rows, cols, {}, self.ring, grade, grade - 1) zero = self.zero one = self.one for col in cols: assert col.grade == grade bdy = bdys[col] #for row in col: for row, value in bdy.items(): assert row.grade == grade - 1 assert A[row, col] == zero A[row, col] = value return A
def get_match(self, grade): " return linear op: C_grade --> C_{grade+1} " chain = self.chain zero = self.zero one = self.one bdy = chain.get_bdymap(grade + 1) # grade+1 --> grade src = chain.get_cells(grade) tgt = chain.get_cells(grade + 1) A = Matrix(tgt, src, {}, self.ring) # C_grade --> C_{grade+1} pairs = self.get_pairs(grade) for src, tgt in pairs: # grade --> grade+1 assert src.grade == grade assert A[tgt, src] == zero value = bdy[src, tgt] assert value != zero, "cannot match non-bdy" A[tgt, src] = -one / value return A
def test_surface(): ring = element.FiniteField(2) one = ring.one C0 = [Cell(0, i) for i in [0]] C1 = [Cell(1, i) for i in [0, 1]] C2 = [Cell(2, i) for i in [0]] Sx = Matrix(C1, C2, {}, ring) Sx[C1[0], C2[0]] = one Sz = Matrix(C0, C1, {}, ring) Sz[C0[0], C1[1]] = one src = Chain({0: C0, 1: C1, 2: C2}, {1: Sz, 2: Sx}, ring, check=True) Sx = Matrix(C1, C2, {}, ring) Sx[C1[0], C2[0]] = one Sx[C1[1], C2[0]] = one Sz = Matrix(C0, C1, {}, ring) Sz[C0[0], C1[0]] = one Sz[C0[0], C1[1]] = one tgt = Chain({0: C0, 1: C1, 2: C2}, {1: Sz, 2: Sx}, ring, check=True) f0 = Matrix.identity(C0, ring) f1 = Matrix.identity(C1, ring) f1[C1[1], C1[0]] = one f2 = Matrix.identity(C2, ring) hom = Hom(src, tgt, {0: f0, 1: f1, 2: f2}, ring, check=True) #tgt, cnot = src.cnot(0, 1) # ---- Higgott encoder ---- C0 = [Cell(0, i) for i in range(2)] C1 = [Cell(1, i) for i in range(5)] C2 = [Cell(2, i) for i in range(2)] Sx = Matrix(C1, C2, {}, ring) Sx[C1[1], C2[0]] = one Sx[C1[3], C2[1]] = one Sz = Matrix(C0, C1, {}, ring) Sz[C0[0], C1[0]] = one Sz[C0[1], C1[4]] = one src = Chain({0: C0, 1: C1, 2: C2}, {1: Sz, 2: Sx}, ring, check=True) src.dump() chain = src for i, j in [(2, 0), (1, 4), (2, 4), (3, 0), (3, 2), (1, 2)]: chain, hom = chain.transvect(i, j) chain.dump() # ------------------------- m, n = 3, 2 ambly = Assembly.build_surface(ring, (0, 0), (m, n), open_top=True, open_bot=True) chain = ambly.get_chain() #chain.dump() tgt, hom = chain.transvect(1, 2) #tgt.dump() tgt, hom = tgt.transvect(1, 2)
def main(): ring = element.Q #ring = element.FiniteField(2) # tetra-hedron face map: M = parse(""" 1.1..1 11.1.. .11.1. ...111 """) chain = Chain.from_array(M, ring) chain.check() M = chain.get_bdymap(1) print(M) rows, cols = M.rows, M.cols flow = Flow(chain) #flow.build() # match goes from src:grade-1 --> tgt:grade # rows are faces, cols are edges assert flow.accept(rows[1], cols[0]) flow.add(rows[1], cols[0]) assert flow.accept(rows[2], cols[1]) flow.add(rows[2], cols[1]) assert flow.accept(rows[3], cols[4]) flow.add(rows[3], cols[4]) print(flow) A = flow.get_bdymap(2) # 2 --> 1 B = flow.get_bdymap(1) # 1 --> 0 print(A, A.shape) print(B, B.shape) print(B.cols, B.rows) C = B * A assert C.is_zero() f0 = flow.get_f(0) f1 = flow.get_f(1) f2 = flow.get_f(2) assert f0 * chain.get_bdymap(1) == B * f1 assert f1 * chain.get_bdymap(2) == A * f2 g0 = flow.get_g(0) g1 = flow.get_g(1) g2 = flow.get_g(2) assert chain.get_bdymap(1) * g1 == g0 * B assert chain.get_bdymap(2) * g2 == g1 * A fs = [f0, f1, f2] gs = [g0, g1, g2] chi0 = flow.get_homotopy(0) chi1 = flow.get_homotopy(1) chi2 = flow.get_homotopy(2) chis = [chi0, chi1, chi2] for i in [1, 2]: cells = chain.get_cells(i) I = Matrix.identity(cells, ring) lhs = gs[i] * fs[i] - I rhs = chain.get_bdymap(i + 1) * chis[i] + chis[i - 1] * chain.get_bdymap(i) assert lhs == rhs #print(lhs) cells = flow.get_critical(i) I = Matrix.identity(cells, ring) lhs = fs[i] * gs[i] #print(lhs) #print(I) assert lhs == I print() for grade in range(2): print("grade =", grade) print("f =") print(fs[grade]) print("g =") print(gs[grade]) print("chi =") print(chis[grade]) #print("rows:", chis[grade].rows) #print("cols:", chis[grade].cols) print("fg =") print(fs[grade] * gs[grade]) print("gf =") print(gs[grade] * fs[grade]) print() print(flow.get_bdymap(1))
def test_chain(chain): chain.check() ring = chain.ring #print(chain.get_bdymap(1)) # return # # # FIX TODO TODO # # FIX TODO TODO # # FIX TODO TODO # # FIX TODO TODO # # FIX TODO TODO # # FIX TODO TODO # # FIX TODO TODO flow = Flow(chain) flow.build() #print(flow) A = flow.get_bdymap(2) # 2 --> 1 B = flow.get_bdymap(1) # 1 --> 0 #print(A) #print(B) C = B * A assert C.is_zero() #for grade in [0, 1, 2]: # for cell in flow.get_critical(grade): # print(cell) f0 = flow.get_f(0) f1 = flow.get_f(1) f2 = flow.get_f(2) assert f0 * chain.get_bdymap(1) == B * f1 assert f1 * chain.get_bdymap(2) == A * f2 g0 = flow.get_g(0) g1 = flow.get_g(1) g2 = flow.get_g(2) assert chain.get_bdymap(1) * g1 == g0 * B assert chain.get_bdymap(2) * g2 == g1 * A fs = [f0, f1, f2] gs = [g0, g1, g2] #print() #for grade in range(3): # print("grade =", grade) # f = flow.get_f(grade) # print(f) chi0 = flow.get_homotopy(0) chi1 = flow.get_homotopy(1) chi2 = flow.get_homotopy(2) chis = [chi0, chi1, chi2] for i in [1, 2]: cells = chain.get_cells(i) I = Matrix.identity(cells, ring) lhs = gs[i] * fs[i] - I rhs = chain.get_bdymap(i + 1) * chis[i] + chis[i - 1] * chain.get_bdymap(i) assert lhs == rhs #print(lhs) cells = flow.get_critical(i) I = Matrix.identity(cells, ring) lhs = fs[i] * gs[i] #print(lhs) #print(I) assert lhs == I