def tensorDoubleD(self, d_graph1, d_graph2): """Computes the chain complex D1 * CFAA(Id) * D2, where D1, D2 are type D structures with graphs d_graph1, d_graph2, and CFAA(Id) is represented by this graph. Both D1 and D2 are left type D structures. The algebra acting on D1 is opposite of self.pmc_alg, and the algebra acting on D2 is the same as self.pmc_alg """ assert d_graph1.algebra.opp() == self.pmc_alg assert d_graph2.algebra == self.pmc_alg cx = SimpleChainComplex(F2) # Generators of the chain complex: for node1 in d_graph1.getNodes(): for node2 in d_graph2.getNodes(): if node1.idem == node2.idem.opp().comp(): cur_gen = ATensorDGenerator(cx, node1.dgen, node2.dgen) cx.addGenerator(cur_gen) # Search the graphs for edges in the chain complex for gen_start in cx.getGenerators(): dgen1, dgen2 = gen_start d1_pos = d_graph1.graph_node[dgen1] d2_pos = d_graph2.graph_node[dgen2] aa_pos = self.homology_node[dgen1.idem.opp()] pos = [(d1_pos, d2_pos, aa_pos)] end_states = self._searchDoubleD(d_graph1, d_graph2, pos)[0] for d1_end, d2_end, aa_end in end_states: gen_end = ATensorDGenerator(cx, d1_end.dgen, d2_end.dgen) cx.addDifferential(gen_start, gen_end, 1) return cx
def morToDD(self, other): """Compute the chain complex of type DD structure morphisms from self to other. Note ``other`` must be a type DD structure over the same two PMC's in the same order. Currently does not keep track of gradings. """ assert self.algebra1 == other.algebra1 assert self.algebra2 == other.algebra2 alg1_gens = self.algebra1.getGenerators() alg2_gens = self.algebra2.getGenerators() # Type of coefficients of the morphism tensor_alg = TensorDGAlgebra((self.algebra1, self.algebra2)) xlist = self.getGenerators() ylist = other.getGenerators() gens = list() cx = SimpleChainComplex(F2) genType = MorDDtoDDGenerator # For computing differentials only mor_cx = MorDDtoDDComplex(F2, self, other) # Prepare rev_delta for the last step in computing differentials rev_delta = self.getReverseDelta() # Get the list of generators for x in xlist: for a1 in alg1_gens: for a2 in alg2_gens: for y in ylist: if x.idem1 == a1.getLeftIdem() and \ y.idem1 == a1.getRightIdem() and \ x.idem2 == a2.getLeftIdem() and \ y.idem2 == a2.getRightIdem(): a = TensorGenerator((a1, a2), tensor_alg) gens.append(genType(cx, x, a, y)) for gen in gens: cx.addGenerator(gen) # Get the differentials of type DD structure maps for gen in gens: for term, coeff in mor_cx.diff(gen).items(): cx_term = genType(cx, term.source, term.coeff, term.target) cx.addDifferential(gen, cx_term, coeff) return cx
def morToD(self, other): """Compute the chain complex of morphisms from self to other.""" assert self.algebra == other.algebra alg_gens = self.algebra.getGenerators() xlist = self.getGenerators() ylist = other.getGenerators() gens = list() cx = SimpleChainComplex(F2) genType = MorDtoDGenerator def morGradingSet(): """Find the grading set of the new chain complex.""" return GeneralGradingSet([self.gr_set.inverse(), other.gr_set]) def morGrading(gr_set, x, a, y): """Find the grading of the generator x -> ay in the morphism complex. The grading set need to be provided as gr_set. """ gr = [self.grading[x].inverse(), other.grading[y] * a.getGrading()] return GeneralGradingSetElement(gr_set, gr) # Prepare rev_delta for the last step in computing differentials rev_delta = dict() for x in xlist: rev_delta[x] = [] for p in xlist: for (b, q), coeff in p.delta().items(): rev_delta[q].append(((b, p), coeff)) # Get the list of generators for x in xlist: for a in alg_gens: for y in ylist: if x.idem == a.getLeftIdem() and \ y.idem == a.getRightIdem(): gens.append(genType(cx, x, a, y)) for gen in gens: cx.addGenerator(gen) # Get differentials for gen in gens: # Differential of ay in (x -> ay) x, a, y = gen.source, gen.coeff, gen.target day = a * y.delta() + a.diff() * y for (b, q), coeff in day.items(): cx.addDifferential(gen, genType(cx, x, b, q), coeff) # For each p such that b*x is in dp, add p->(ba)y for (b, p), coeff1 in rev_delta[x]: for ba_gen, coeff2 in (b*a).items(): cx.addDifferential( gen, genType(cx, p, ba_gen, y), coeff1*coeff2) # Find grading set and grading of elements if hasattr(self, "gr_set") and hasattr(other, "gr_set"): cx.gr_set = morGradingSet() cx.grading = dict() for gen in gens: cx.grading[gen] = morGrading(cx.gr_set, gen.source, gen.coeff, gen.target) return cx