def testIdentityDDLocal(self): splitting = PMCSplitting(linearPMC(2), [(1, 4)]) local_pmc = splitting.local_pmc id_local = identityDALocal(local_pmc) extended_id = ExtendedDAStructure(id_local, splitting, splitting) id_dd = extended_id.tensorDD(identityDD(linearPMC(2))) self.assertTrue(id_dd.compareDDStructures(identityDD(linearPMC(2))))
def __init__(self, genus, c_pair): """Specifies genus of the starting pmc and the id of the pair of anti-braid resolution. """ self.genus = genus self.c_pair = c_pair self.start_pmc = linearPMC(genus) self.end_pmc = self.start_pmc self.n = 4 * genus self.c1, self.c2 = self.start_pmc.pairs[c_pair] if self.c2 == self.c1 + 3: self.is_degenerate = False else: assert self.c2 == self.c1 + 2 assert self.c1 == 0 or self.c2 == self.n - 1 self.is_degenerate = True if self.is_degenerate: # One position between c1 and c2, called p self.p = self.c1 + 1 self.p_pair = self.start_pmc.pairid[self.p] else: # Two positions between c1 and c2, for (d)own and (u)p self.d = self.c1 + 1 self.u = self.c1 + 2 self.d_pair = self.start_pmc.pairid[self.d] self.u_pair = self.start_pmc.pairid[self.u]
def testAbsGrading(self): def testOneAlgebra(alg, test_op = True): abs_gr = AbsZ2Grading(alg) for gen in alg.getGenerators(): # Test asserts in getAbsGrading abs_gr.getAbsGrading(gen) if not test_op: return # Test differential and multiplication for a in alg.getGenerators(): for term in a.diff(): a_gr, da_gr = [abs_gr.getAbsGrading(gen) for gen in a, term] assert (a_gr - 1) % 2 == da_gr for a in alg.getGenerators(): for b in alg.getGenerators(): if a * b != 0: a_gr, b_gr, ab_gr = [abs_gr.getAbsGrading(gen) for gen in a, b, (a*b).getElt()] assert (a_gr + b_gr) % 2 == ab_gr for pmc in [splitPMC(1), splitPMC(2), linearPMC(2)]: testOneAlgebra(pmc.getAlgebra()) for pmc in [antipodalPMC(2), splitPMC(3)]: testOneAlgebra(pmc.getAlgebra(), test_op = False) for (pmc, idem_size) in [(splitPMC(1), 1), (splitPMC(1), 2), (splitPMC(2), 1), (splitPMC(2), 2)]: testOneAlgebra(PreStrandAlgebra(F2, pmc, idem_size)) for (pmc, idem_size) in [(splitPMC(2), 3), (splitPMC(2), 4), (splitPMC(3), 2)]: testOneAlgebra(PreStrandAlgebra(F2, pmc, idem_size), test_op = False)
def testGetIntervalOrdering(self): tests = [(splitPMC(1), [0,1,2]), (splitPMC(2), [4,5,6,3,0,1,2]), (antipodalPMC(2), [2,5,0,3,6,1,4]), (linearPMC(2), [4,0,1,3,5,6,2])] for pmc, order in tests: self.assertEqual(_getIntervalOrdering(pmc), order)
def __init__(self, genus, c_pair, orientation): """Specifies genus of the starting pmc, id of the pair of Dehn twist, and orientation of the twist (POS or NEG). """ self.genus = genus self.orientation = orientation self.start_pmc = linearPMC(genus) self.end_pmc = self.start_pmc self.n = 4 * genus self.c1, self.c2 = self.start_pmc.pairs[c_pair] self.c_pair = c_pair if self.c2 == self.c1 + 3: self.is_degenerate = False else: assert self.c2 == self.c1 + 2 assert self.c1 == 0 or self.c2 == self.n - 1 self.is_degenerate = True if not self.is_degenerate: # Two positions between c1 and c2, for (d)own and (u)p self.d = self.c1 + 1 self.u = self.c1 + 2 self.splitting = PMCSplitting(self.start_pmc, [(self.c1, self.c2)]) self.local_pmc = self.splitting.local_pmc
def testGeneralOverslideDown(self): slides_to_test = [ Arcslide(splitPMC(1), 3, 2), Arcslide(splitPMC(2), 3, 2), Arcslide(splitPMC(2), 4, 3), Arcslide(splitPMC(2), 7, 6), Arcslide(linearPMC(2), 3, 2), Arcslide(linearPMC(2), 5, 4), Arcslide(linearPMC(2), 7, 6), Arcslide(antipodalPMC(2), 5, 4), Arcslide(antipodalPMC(2), 6, 5), Arcslide(antipodalPMC(2), 7, 6), ] for slide in slides_to_test: print slide dastr = ArcslideDA(slide).toSimpleDAStructure() self.assertTrue(dastr.testDelta())
def testGrading(self): slides_to_test = [ Arcslide(splitPMC(1), 1, 0), Arcslide(splitPMC(2), 4, 3), Arcslide(linearPMC(2), 1, 0), ] for slide in slides_to_test: dastr = ArcslideDA(slide) dastr.toSimpleDAStructure().checkGrading()
def testToDStructure(self): ddstr = identityDD(linearPMC(1)) dstr = ddstr.toDStructure() hochchild = dstr.morToD(dstr) self.assertEqual(len(hochchild), 18) hochchild.simplify(find_homology_basis = True) self.assertEqual(len(hochchild), 4) meaning_len = [len(gen.prev_meaning) for gen in hochchild.getGenerators()] self.assertEqual(sorted(meaning_len), [1,1,1,2])
def testShortUnderslideDown(self): slides_to_test = [ Arcslide(splitPMC(1), 1, 0), Arcslide(splitPMC(1), 2, 1), Arcslide(splitPMC(2), 1, 0), Arcslide(splitPMC(2), 6, 5), Arcslide(linearPMC(2), 1, 0), Arcslide(linearPMC(2), 6, 5), Arcslide(PMC([(0, 2), (1, 6), (3, 5), (4, 7)]), 1, 0), Arcslide(PMC([(0, 3), (1, 6), (2, 4), (5, 7)]), 6, 5), Arcslide(splitPMC(2), 2, 1), Arcslide(splitPMC(2), 5, 4), Arcslide(PMC([(0, 2), (1, 6), (3, 5), (4, 7)]), 4, 3), Arcslide(PMC([(0, 3), (1, 6), (2, 4), (5, 7)]), 3, 2), ] for slide in slides_to_test: print slide dastr = ArcslideDA(slide).toSimpleDAStructure() self.assertTrue(dastr.testDelta())
def testIdentityDiagram(self): pmc_to_test = [splitPMC(1), splitPMC(2), linearPMC(2), antipodalPMC(2)] pmc_to_test.append(PMC([(0, 2), (1, 6), (3, 5), (4, 7)])) pmc_to_test += [splitPMC(3), antipodalPMC(4)] genus_to_size = [2, 6, 20, 70] for pmc in pmc_to_test: diagram = getIdentityDiagram(pmc) self.assertEqual(diagram.getPMCs(), [pmc.opp(), pmc]) expected_size = genus_to_size[pmc.genus - 1] self.assertEqual(len(diagram.getHFGenerators()), expected_size) self.assertEqual(len(diagram.getPeriodicDomains()), pmc.genus * 2)
def testOverslideAgreesWithDD(self): # This is not guaranteed (since there is choice involved in type DD for # overslides, but appears to work slides_to_test = [ # General overslides down Arcslide(splitPMC(1), 3, 2), Arcslide(splitPMC(2), 3, 2), Arcslide(splitPMC(2), 4, 3), Arcslide(splitPMC(2), 7, 6), Arcslide(linearPMC(2), 3, 2), Arcslide(linearPMC(2), 5, 4), Arcslide(linearPMC(2), 7, 6), Arcslide(antipodalPMC(2), 5, 4), Arcslide(antipodalPMC(2), 6, 5), Arcslide(antipodalPMC(2), 7, 6), # General overslides up Arcslide(splitPMC(1), 0, 1), Arcslide(splitPMC(2), 0, 1), Arcslide(splitPMC(2), 3, 4), Arcslide(splitPMC(2), 4, 5), Arcslide(linearPMC(2), 0, 1), Arcslide(linearPMC(2), 2, 3), Arcslide(linearPMC(2), 4, 5), Arcslide(antipodalPMC(2), 0, 1), Arcslide(antipodalPMC(2), 1, 2), Arcslide(antipodalPMC(2), 2, 3), ] for slide in slides_to_test: dastr = ArcslideDA(slide) ddstr = dastr.tensorDD(identityDD(slide.end_pmc)) ori_ddstr = slide.getDDStructure() self.assertTrue(ddstr.compareDDStructures(ori_ddstr))
def testUnderslideAgreesWithDD(self): slides_to_test = [ # Short underslides down Arcslide(splitPMC(1), 1, 0), Arcslide(linearPMC(2), 6, 5), Arcslide(PMC([(0, 2), (1, 6), (3, 5), (4, 7)]), 1, 0), # General underslides down Arcslide(antipodalPMC(2), 1, 0), Arcslide(PMC([(0, 2), (1, 4), (3, 6), (5, 7)]), 4, 3), # Short underslides up Arcslide(splitPMC(1), 1, 2), Arcslide(linearPMC(2), 1, 2), Arcslide(PMC([(0, 2), (1, 6), (3, 5), (4, 7)]), 4, 5), # General underslides up Arcslide(antipodalPMC(2), 6, 7), Arcslide(PMC([(0, 3), (1, 6), (2, 4), (5, 7)]), 2, 3), ] for slide in slides_to_test: dastr = ArcslideDA(slide) ddstr = dastr.tensorDD(identityDD(slide.end_pmc)) ori_ddstr = slide.getDDStructure() self.assertTrue(ddstr.compareDDStructures(ori_ddstr))
def setUp(self): self.pmc = linearPMC(2) self.splitting = PMCSplitting(self.pmc, [(1, 4)]) # Correspondence between points in pmc and local / outer pmc: # pmc - 0 1 2 3 4 5 6 7 # local_pmc - 0* 1 2 3 4 5* # outer_pmc - 0 1* 2* 3 4 5 local_pmc = self.splitting.local_pmc outer_pmc = self.splitting.outer_pmc # Construct the local generators. In local_pmc, idempotent 0 is (1, 4), # idempotent 1 is (2,), idempotent 2 is (3,). local_da = LocalDAStructure( F2, local_pmc.getAlgebra(), local_pmc.getAlgebra(), single_idems1=[1, 2], single_idems2=[1, 2] ) idems = {"x1": ([0], [1]), "x2": ([0], [2]), "x3": ([0, 2], [1, 2]), "x4": ([0, 1], [1, 2])} gens = {} for name, (l_idem, r_idem) in idems.items(): gens[name] = SimpleDAGenerator( local_da, LocalIdempotent(local_pmc, l_idem), LocalIdempotent(local_pmc, r_idem), name ) local_da.addGenerator(gens[name]) local_da.auto_u_map() for name_from, name_to, algs_a, alg_d in [ # Some examples of local DA actions ("x4", "x3", [], [1, (2, 3)]), ("x1", "x2", [[(2, 3)]], [1]), ]: local_da.addDelta( gens[name_from], gens[name_to], local_pmc.sd(alg_d), [local_pmc.sd(alg_a) for alg_a in algs_a], 1 ) self.extended_da = ExtendedDAStructure(local_da, self.splitting, self.splitting) mod_gens = self.extended_da.getGenerators() # Set up short names for the extended generators. Here y_i is the unique # extension of x_i. extended_idems = { "y1": ([1, 3], [0, 3]), "y2": ([1, 3], [2, 3]), "y3": ([1, 2], [0, 2]), "y4": ([0, 1], [0, 2]), } self.extended_gens = {} for name, (l_idem, r_idem) in extended_idems.items(): for gen in mod_gens: if gen.idem1 == Idempotent(self.pmc, l_idem) and gen.idem2 == Idempotent(self.pmc, r_idem): self.extended_gens[name] = gen
def platTypeD(genus): """Returns the type D structure for the plat handlebody of a given genus. """ pmc = linearPMC(genus) algebra = pmc.getAlgebra() dstr = SimpleDStructure(F2, algebra) idem = pmc.idem([4*i+1 for i in range(genus-1)]+[4*genus-3]) genx = SimpleDGenerator(dstr, idem, "x") dstr.addGenerator(genx) strands = [(4*i+1,4*i+4) for i in range(genus-1)]+[(4*genus-3, 4*genus-1)] for st in strands: sd = StrandDiagram(algebra, idem, [st]) dstr.addDelta(genx, genx, sd, 1) dstr.registerHDiagram(getPlatDiagram(genus), genx) return dstr
def __init__(self, genus, c_pair, orientation): """Specifies genus of the starting pmc, id of the pair of Dehn twist, and orientation of the twist (POS or NEG). """ self.genus = genus self.orientation = orientation self.start_pmc = linearPMC(genus) self.end_pmc = self.start_pmc self.n = 4 * genus self.c1, self.c2 = self.start_pmc.pairs[c_pair] self.c_pair = c_pair assert self.c2 == self.c1 + 3 # Two positions between c1 and c2, for (d)own and (u)p self.d = self.c1 + 1 self.u = self.c1 + 2 self.d_pair = self.start_pmc.pairid[self.d] self.u_pair = self.start_pmc.pairid[self.u]
def __init__(self, genus, c_pair): """Specifies genus of the starting PMC and the ID of the pair of anti-braid resolution. """ self.genus = genus self.c_pair = c_pair self.pmc = linearPMC(genus) self.n = 4 * genus self.c1, self.c2 = self.pmc.pairs[c_pair] if self.c2 == self.c1 + 3: self.is_degenerate = False else: assert self.c2 == self.c1 + 2 assert self.c1 == 0 or self.c2 == self.n - 1 self.is_degenerate = True if self.is_degenerate: # One position between c1 and c2, called p self.p = self.c1 + 1 self.p_pair = self.pmc.pairid[self.p] else: # Two positions between c1 and c2, for (d)own and (u)p self.d = self.c1 + 1 self.u = self.c1 + 2 self.d_pair = self.pmc.pairid[self.d] self.u_pair = self.pmc.pairid[self.u] # Necessary to get local DA structure. self.splitting = PMCSplitting(self.pmc, [(self.c1, self.c2)]) self.local_pmc = self.splitting.local_pmc self.mapping = self.splitting.local_mapping # Local DA Structure self.local_da = self.getLocalDAStructure() ### Uncomment to use autocompleteda to construct arrows from seeds. # autoCompleteDA(self.local_da, ([])) # Initiate the ExtendedDAStructure ExtendedDAStructure.__init__(self, self.local_da, self.splitting, self.splitting)
def testHochschildCohomology(self): # Check HH^*(A) # Rank 4 is right for HH^* of A in genus 1 case pmc = splitPMC(1) ddstr = identityDD(pmc) cx = ddstr.hochschildCochains() cx.simplify() self.assertEqual(len(cx), 4) # Rank 1 in the extremal strands grading pmc = splitPMC(2) ddstr = identityDD(pmc, 0) cx = ddstr.hochschildCochains() cx.simplify() self.assertEqual(len(cx), 1) # Rank should be indepdendent of PMC (equals 16) for pmc in [splitPMC(2), linearPMC(2), PMC([(0,2),(1,6),(3,5),(4,7)])]: ddstr = identityDD(pmc) cx = ddstr.hochschildCochains() cx.simplify() self.assertEqual(len(cx), 16)
def __init__(self, cob): """Specifies the cobordism to use. cob should be of type Cobordism, with cob.side == RIGHT. """ assert cob.side == RIGHT self.n, self.genus, self.c_pair = cob.n, cob.genus, cob.c_pair start_pmc = linearPMC(self.genus-1) # Divide into four cases like in CobordismDALeft if self.c_pair == 0: # Bottom case: self.start_da = SimpleCobordismDA(start_pmc, 1) self.slides = [(0, 1)] elif self.c_pair == 2*self.genus-2: # Next to top case: self.start_da = SimpleCobordismDA(start_pmc, self.n-5) self.slides = [(self.n-1, self.n-2)] elif self.c_pair == 2*self.genus-1: # Top case: self.start_da = SimpleCobordismDA(start_pmc, self.n-5) self.slides = [(self.n-2, self.n-3), (self.n-1, self.n-2)] else: # Middle case self.c1 = cob.c1 self.start_da = SimpleCobordismDA(start_pmc, self.c1) self.slides = [(self.c1+4, self.c1+3), (self.c1+1, self.c1), (self.c1+2, self.c1+1), (self.c1+5, self.c1+4)] self.da_list = [self.start_da] for b1, c1 in self.slides: self.da_list.append( ArcslideDA(Arcslide(self.da_list[-1].pmc2, b1, c1))) ComposedDAStructure.__init__(self, self.da_list)
def __init__(self, num_strands): """Specifies the number of strands in the braid.""" self.num_strands = num_strands self.genus = (num_strands - 2)/2 self.pmc = linearPMC(self.genus)
def __init__(self, genus, c_pair, side): """Specifies the genus of the larger (linear PMC), the c-pair at which the cobordism occurred, and the side of the larger PMC (LEFT or RIGHT). """ self.genus = genus # genus of larger PMC self.n = 4 * self.genus # number of points in the larger PMC self.c_pair = c_pair self.side = side # LEFT or RIGHT if c_pair == 0 or c_pair == 2*self.genus-1: self.is_degenerate = True else: self.is_degenerate = False self.large_pmc = linearPMC(self.genus) self.small_pmc = linearPMC(self.genus-1) # Some special points and pairs self.c1, self.c2 = self.large_pmc.pairs[self.c_pair] if self.is_degenerate: assert self.c2 == self.c1 + 2 self.p = self.c1 + 1 self.p_pair = self.large_pmc.pairid[self.p] else: assert self.c2 == self.c1 + 3 self.d, self.u = self.c1 + 1, self.c1 + 2 self.d_pair = self.large_pmc.pairid[self.d] self.u_pair = self.large_pmc.pairid[self.u] # Construct the to_s dictionary. Keys are points on the large PMC that # match points on the small PMC. Value is the point that it matches. self.to_s = dict() cur_pt = 0 for i in range(self.n): if self.is_degenerate: pair_i = self.large_pmc.pairid[i] if pair_i == self.c_pair or pair_i == self.p_pair: continue else: if self.c1 <= i <= self.c2: continue self.to_s[i] = cur_pt cur_pt += 1 # The pair_to_s dictionary is similar, but for pairs. The c-pair does # not match to anything. In the non-degenerate case, the u and d pairs # both match the (u',d') pair on the left. In the degenerate case, the # p-pair also does not match anything. self.pair_to_s = dict() for i in range(self.n/2): for p in self.large_pmc.pairs[i]: if p in self.to_s: self.pair_to_s[i] = self.small_pmc.pairid[self.to_s[p]] if not self.is_degenerate: # Special pair on the small PMC self.du_pair = self.pair_to_s[self.d_pair] assert self.du_pair == self.pair_to_s[self.u_pair] if self.side == LEFT: self.start_pmc, self.end_pmc = self.large_pmc, self.small_pmc else: self.start_pmc, self.end_pmc = self.small_pmc, self.large_pmc