def connectSumTypeD(dstr1, dstr2): """Form the connect sum of two type D structures.""" algebra1, algebra2 = dstr1.algebra, dstr2.algebra assert algebra1.mult_one == algebra2.mult_one pmc1, pmc2 = algebra1.pmc, algebra2.pmc pmc = connectSumPMC(pmc1, pmc2) algebra = pmc.getAlgebra(mult_one = algebra1.mult_one) dstr = SimpleDStructure(F2, algebra) # Maps pairs of generators in dstr1 and dstr2 to a generator in dstr, and # vice versa. pair_map = dict() rev_pair_map = dict() for gen1 in dstr1.getGenerators(): for gen2 in dstr2.getGenerators(): assert all([isinstance(x, SimpleDGenerator) for x in (gen1, gen2)]) idem = list(gen1.idem) + [p+pmc1.num_pair for p in gen2.idem] idem = Idempotent(pmc, idem) gen = SimpleDGenerator(dstr, idem, gen1.name + gen2.name) dstr.addGenerator(gen) pair_map[(gen1, gen2)] = gen rev_pair_map[gen] = (gen1, gen2) for gen in dstr.getGenerators(): gen1, gen2 = rev_pair_map[gen] for (a, y), coeff in gen1.delta().items(): new_strands = Strands(pmc, a.strands) new_a = StrandDiagram(algebra, gen.idem, new_strands) dstr.addDelta(gen, pair_map[(y, gen2)], new_a, coeff) for (a, y), coeff in gen2.delta().items(): new_strands = Strands( pmc, [(p+pmc1.n, q+pmc1.n) for p,q in a.strands]) new_a = StrandDiagram(algebra, gen.idem, new_strands) dstr.addDelta(gen, pair_map[(gen1, y)], new_a, coeff) return dstr
def _getAbsGrading(self, ddstr, abs_gr_info, expand_after = True): """Find absolute grading for type DD structure (to replace finding a relative grading). It can be shown that value of expand_after does not matter. """ # Find grading of elements: # Create Heegaard diagram for the expanded arcslide. genus = self.start_pmc.genus if expand_after: ex_start_pmc = connectSumPMC(self.start_pmc, splitPMC(genus)) ex_slide = Arcslide(ex_start_pmc, self.b1, self.c1) else: ex_start_pmc = connectSumPMC(splitPMC(genus), self.start_pmc) ex_slide = Arcslide(ex_start_pmc, 4*genus+self.b1, 4*genus+self.c1) ex_end_pmc = ex_slide.end_pmc ex_hdiagram = getArcslideDiagram(ex_slide) hgens = ex_hdiagram.getHFGenerators() # First step, find grading of two extreme generators, using one of # which as the base generator. base_idem = [Idempotent(ex_start_pmc, range(2*genus)), Idempotent(ex_end_pmc.opp(), range(2*genus))] base_idem2 = [Idempotent(ex_start_pmc, range(2*genus, 4*genus)), Idempotent(ex_end_pmc.opp(), range(2*genus, 4*genus))] if abs_gr_info == 0: base_gen = ex_hdiagram.getGeneratorByIdem(base_idem, True) else: base_gen = ex_hdiagram.getGeneratorByIdem(base_idem2, True) ex_gr_set, ex_grs = ex_hdiagram.computeDDGrading(base_gen) # Second step # # print ex_gr_set # base_gr1 = ex_grs[base_gen] # base_gr2 = ex_grs[base_gen2] # # print base_gr1, base_gr2 # spinc11, spinc12 = base_gr1.data[0].spinc, base_gr1.data[1].spinc # spinc21, spinc22 = base_gr2.data[0].spinc, base_gr2.data[1].spinc # spincmavg1 = [-(a+b)/Fraction(2) for a,b in zip(spinc11, spinc21)] # spincmavg2 = [-(a+b)/Fraction(2) for a,b in zip(spinc12, spinc22)] # maslovavg = base_gr1.data[0].maslov + base_gr2.data[0].maslov + \ # base_gr1.data[1].maslov + base_gr2.data[1].maslov # mavg1 = SmallGradingElement( # base_gr1.data[0].parent, -maslovavg, spincmavg1) # mavg2 = SmallGradingElement( # base_gr2.data[0].parent, -Fraction(1,16), spincmavg2) # ex_gr_set, ex_grs = ex_hdiagram.computeDDGrading(base_gen, # (mavg1, mavg2)) # # print ex_gr_set # # print ex_grs[base_gen], ex_grs[base_gen2] # Form the grading set for the original arcslide from the extended one periodic_domains = [] for ex_gr1, ex_gr2 in ex_gr_set.periodic_domains: ex_spinc1, ex_spinc2 = ex_gr1.spinc, ex_gr2.spinc if expand_after: spinc1, spinc2 = ex_spinc1[0:2*genus], ex_spinc2[2*genus:] else: spinc1, spinc2 = ex_spinc1[2*genus:], ex_spinc2[0:2*genus] if not (all([n == 0 for n in spinc1]) and all([n == 0 for n in spinc2])): gr1 = self.start_pmc.small_gr(ex_gr1.maslov, spinc1) gr2 = self.end_pmc.opp().small_gr(ex_gr2.maslov, spinc2) periodic_domains.append([gr1, gr2]) ddstr.gr_set = SimpleDbGradingSet( SmallGradingGroup(self.start_pmc), ACTION_LEFT, SmallGradingGroup(self.end_pmc.opp()), ACTION_LEFT, periodic_domains) # Now obtain the grading of generators ddstr.grading = dict() for hgen, ex_gr in ex_grs.items(): ex_idem1, ex_idem2 = hgen.getDIdem() ex_gr1, ex_gr2 = ex_gr.data if expand_after: pairs1 = [n for n in ex_idem1 if n < 2*genus] pairs2 = [n-2*genus for n in ex_idem2 if n >= 2*genus] else: pairs1 = [n-2*genus for n in ex_idem1 if n >= 2*genus] pairs2 = [n for n in ex_idem2 if n < 2*genus] if len(pairs1) == genus: # Get the corresponding generator in ddstr cur_idem = [Idempotent(self.start_pmc, pairs1), Idempotent(self.end_pmc.opp(), pairs2)] cur_gen = [gen for gen in ddstr.getGenerators() if [gen.idem1, gen.idem2] == cur_idem] assert len(cur_gen) == 1 cur_gen = cur_gen[0] # Finally get the grading ex_spinc1, ex_spinc2 = ex_gr1.spinc, ex_gr2.spinc if expand_after: for i in range(2*genus): assert ex_spinc2[i] == ex_spinc1[4*genus-i-1] spinc1 = ex_spinc1[0:2*genus] spinc2 = ex_spinc2[2*genus:] else: for i in range(2*genus, 4*genus): assert ex_spinc2[i] == ex_spinc1[4*genus-i-1] spinc1 = ex_spinc1[2*genus:] spinc2 = ex_spinc2[0:2*genus] gr = SimpleDbGradingSetElement( ddstr.gr_set, [self.start_pmc.small_gr(ex_gr1.maslov, spinc1), self.end_pmc.opp().small_gr(ex_gr2.maslov, spinc2)]) if cur_gen in ddstr.grading: assert ddstr.grading[cur_gen] == gr else: ddstr.grading[cur_gen] = gr ddstr.checkGrading() return ddstr