def getLocalDAStructure(self): """Returns the local type DA structure associated to the anti-braid resolution. """ if self.is_degenerate: if self.c1 == 0: patterns_raw = self._get_patterns_bottom() else: assert self.c2 == self.n - 1 patterns_raw = self._get_patterns_top() else: patterns_raw = self._get_patterns_middle() arrow_patterns = {} for pattern in patterns_raw: start_class, end_class = pattern[0], pattern[1] coeffs_a = [] for i in range(2, len(pattern)-1): coeffs_a.append(self.local_pmc.sd(pattern[i])) key = (start_class, end_class, tuple(coeffs_a)) if key not in arrow_patterns: arrow_patterns[key] = [] arrow_patterns[key].append(self.local_pmc.sd(pattern[-1])) # Now start construction of the local DA structure. alg = LocalStrandAlgebra(F2, self.local_pmc) local_c_pair = 0 # Compute the set of local generators. Generators of class 0 has # idempotents (l_idem, r_idem) where l_idem has the c_pair and # r_idem has one of the u or d pairs (with the rest being the same). # Generators of class 1 and 2 has l_idem = r_idem such that c_pair # is in both. if self.is_degenerate: single_idems = [1] # local p_pair da_idems_0 = [([0], [1])] else: # Non-degenerate case single_idems = [1, 2] # local d_pair and local u_pair da_idems_0 = [([0], [1]), ([0], [2]), ([0, 1], [1, 2]), ([0, 2], [1, 2])] # class 0 local_da = LocalDAStructure( F2, alg, alg, single_idems1 = single_idems, single_idems2 = single_idems) for i in range(len(da_idems_0)): # class 0 l_idem, r_idem = da_idems_0[i] local_da.addGenerator(SimpleDAGenerator( local_da, LocalIdempotent(self.local_pmc, l_idem), LocalIdempotent(self.local_pmc, r_idem), "0_%d" % i)) all_idems = subset(range(self.local_pmc.num_pair)) # class 1 and 2 for i in range(len(all_idems)): idem = LocalIdempotent(self.local_pmc, all_idems[i]) if local_c_pair in idem: local_da.addGenerator( SimpleDAGenerator(local_da, idem, idem, "1_%d" % i)) local_da.addGenerator( SimpleDAGenerator(local_da, idem, idem, "2_%d" % i)) mod_gens = local_da.getGenerators() # Have to take care of u_map. It is sufficient to know that u_map musst # preserve class of generators. for i in range(len(single_idems)): idem = single_idems[i] for local_gen in mod_gens: idem1, idem2 = local_gen.idem1, local_gen.idem2 if idem in idem1 and idem in idem2: # local_gen is eligible for u_maps[i] target_idem1 = idem1.removeSingleHor([idem]) target_idem2 = idem2.removeSingleHor([idem]) target_gen = [target for target in mod_gens if target.idem1 == target_idem1 and target.idem2 == target_idem2 and target.name[0] == local_gen.name[0]] assert len(target_gen) == 1 local_da.add_u_map(i, local_gen, target_gen[0]) # Check all u_map has been filled. local_da.auto_u_map() # Add arrows according to arrow_pattern. for key in arrow_patterns.keys(): start_class, end_class, coeffs_a = key if len(coeffs_a) == 1 and coeffs_a[0].isIdempotent(): continue for coeff_d in arrow_patterns[key]: used = False for x, y in itertools.product(mod_gens, mod_gens): if x.name[0] == "%d" % start_class and \ y.name[0] == "%d" % end_class and \ DAStructure.idemMatchDA(x, y, coeff_d, coeffs_a): local_da.addDelta(x, y, coeff_d, coeffs_a, 1) used = True if not used: print "Warning: unused arrow: %s %s" % (coeffs_a, coeff_d) return local_da
def getLocalMorphism(self): """Returns the morphism (element of MorDAtoDAComplex, consisting of MorDAtoDAGenerators) between identity and anti-braid corresponding to this Dehn surgery. """ id_local_da = identityDALocal(self.local_pmc) ab_local_da = AntiBraidDA(self.genus, self.c_pair).getLocalDAStructure() if self.orientation == NEG: source = id_local_da target = ab_local_da else: source = ab_local_da target = id_local_da source_gens = source.getGenerators() target_gens = target.getGenerators() morphism_cx = LocalMorDAtoDAComplex(F2, source, target) alg = self.local_pmc.getAlgebra() cobar_alg = CobarAlgebra(alg) tensor_alg = TensorDGAlgebra((alg, cobar_alg)) morphism = E0 if self.is_degenerate: if self.c1 == 0: patterns_raw = self._get_patterns_bottom() else: assert self.c2 == self.n - 1 patterns_raw = self._get_patterns_top() else: patterns_raw = self._get_patterns_middle() arrow_patterns = dict() for pattern in patterns_raw: start_class, end_class = pattern[0], pattern[1] coeffs_a = [] for i in range(2, len(pattern)-1): coeffs_a.append(self.local_pmc.sd(pattern[i])) key = (start_class, end_class, tuple(coeffs_a)) if key not in arrow_patterns: arrow_patterns[key] = [] arrow_patterns[key].append(self.local_pmc.sd(pattern[-1])) # Add arrows according to arrow_pattern. for key in arrow_patterns.keys(): s_class, e_class, coeffs_a = key if len(coeffs_a) == 1 and coeffs_a[0].isIdempotent(): continue for coeff_d in arrow_patterns[key]: used = False for x, y in itertools.product(source_gens, target_gens): if (s_class == -1 or x.name[0] == "%d" % s_class) and \ (e_class == -1 or y.name[0] == "%d" % e_class) and \ DAStructure.idemMatchDA(x, y, coeff_d, coeffs_a): morphism += 1 * MorDAtoDAGenerator( morphism_cx, coeff_d, coeffs_a, x, y) used = True if not used: print "Warning: unused arrow: %s %s" % (coeffs_a, coeff_d) ### Uncomment to use autocompleteda to construct arrows from seeds. # autoCompleteMorphism(source, target, morphism) return morphism
def getLocalDAStructure(self): """Returns the local type DA structure associated to this simple cobordism. """ # Construct arrow_patterns if self.case == self.MIDDLE: patterns_raw = self._patterns_middle() else: patterns_raw = self._patterns_next_bottom() arrow_patterns = dict() for pattern in patterns_raw: start_class, end_class = pattern[0], pattern[1] coeffs_a = [] for i in range(2, len(pattern)-1): coeffs_a.append(self.local_pmc2.sd(pattern[i])) key = (start_class, end_class, tuple(coeffs_a)) if key not in arrow_patterns: arrow_patterns[key] = [] arrow_patterns[key].append(self.local_pmc1.sd(pattern[-1])) alg1 = LocalStrandAlgebra(F2, self.local_pmc1) alg2 = LocalStrandAlgebra(F2, self.local_pmc2) local_da = LocalDAStructure(F2, alg1, alg2) # The original part da_idems = [([], [2]), ([0], [0, 2])] for i in range(len(da_idems)): l_idem, r_idem = da_idems[i] local_da.addGenerator(SimpleDAGenerator( local_da, LocalIdempotent(self.local_pmc1, l_idem), LocalIdempotent(self.local_pmc2, r_idem), "0_%d" % i)) # Part added due to finger-push da_idems_id = [([], [1]), ([0], [0, 1])] for i in range(len(da_idems_id)): l_idem, r_idem = da_idems_id[i] for gen_type in [1, 2]: local_da.addGenerator(SimpleDAGenerator( local_da, LocalIdempotent(self.local_pmc1, l_idem), LocalIdempotent(self.local_pmc2, r_idem), "%d_%d" % (gen_type, i))) mod_gens = local_da.getGenerators() # Manually take care of u_maps single_idems1 = local_da.single_idems1 single_idems2 = local_da.single_idems2 for i in range(len(single_idems1)): i1, i2 = single_idems1[i], single_idems2[i] for local_gen in mod_gens: idem1, idem2 = local_gen.idem1, local_gen.idem2 if i1 in idem1 and i2 in idem2: # local_gen is eligible for u_maps[i] target_idem1 = idem1.removeSingleHor([i1]) target_idem2 = idem2.removeSingleHor([i2]) target_gen = [target for target in mod_gens if target.idem1 == target_idem1 and target.idem2 == target_idem2 and target.name[0] == local_gen.name[0]] assert len(target_gen) == 1 local_da.add_u_map(i, local_gen, target_gen[0]) # Check all u_map have been filled local_da.auto_u_map() # Add arrows according to arrow_pattern for key in arrow_patterns.keys(): start_class, end_class, coeffs_a = key if len(coeffs_a) == 1 and coeffs_a[0].isIdempotent(): continue for coeff_d in arrow_patterns[key]: used = False for x, y in itertools.product(mod_gens, mod_gens): if x.name[0] == "%d" % start_class and \ y.name[0] == "%d" % end_class and \ DAStructure.idemMatchDA(x, y, coeff_d, coeffs_a): local_da.addDelta(x, y, coeff_d, coeffs_a, 1) used = True if not used: print "Warning: unused arrow: %s %s" % \ (coeffs_a, coeff_d) return local_da
def getLocalDAStructure(self): """Returns the local type DA structure associated to this cobordism.""" # Compute the set of arrow patterns if self.case == self.MIDDLE: patterns_raw = self._patterns_left_middle() elif self.case == self.NEXT_TOP: patterns_raw = self._patterns_left_next_top() elif self.case == self.TOP: patterns_raw = self._patterns_left_top() else: assert self.case == self.BOTTOM patterns_raw = self._patterns_left_bottom() arrow_patterns = dict() for pattern in patterns_raw: coeffs_a = [] for i in range(len(pattern)-1): coeffs_a.append(self.local_pmc2.sd(pattern[i])) coeffs_a = tuple(coeffs_a) if coeffs_a not in arrow_patterns: arrow_patterns[coeffs_a] = [] arrow_patterns[coeffs_a].append(self.local_pmc1.sd(pattern[-1])) # Start construction of the local DA structure. alg1 = LocalStrandAlgebra(F2, self.local_pmc1) alg2 = LocalStrandAlgebra(F2, self.local_pmc2) if self.case == self.MIDDLE: local_dastr = LocalDAStructure( F2, alg1, alg2, single_idems1 = [1, 3], single_idems2 = [1, 0]) else: local_dastr = LocalDAStructure(F2, alg1, alg2) # Compute the set of local generators. if self.case == self.MIDDLE: # 0 is the c-pair. u-d pairs are 1 and 2 at left and 1 at # right. 3 at left corresponds to 0 at right is free. da_idems = [([0], []), ([0, 2], [1]), ([0, 1], [1]), ([0, 3], [0]), ([0, 2, 3], [0, 1]), ([0, 1, 3], [0, 1])] elif self.case == self.NEXT_TOP: da_idems = [([0], []), ([0, 2], [0]), ([0, 1], [0])] elif self.case == self.TOP: da_idems = [([2], []), ([1, 2], [0])] else: da_idems = [([0], []), ([0, 2], [0])] for i in range(len(da_idems)): l_idem, r_idem = da_idems[i] local_dastr.addGenerator(SimpleDAGenerator( local_dastr, LocalIdempotent(self.local_pmc1, l_idem), LocalIdempotent(self.local_pmc2, r_idem), "%d" % i)) mod_gens = local_dastr.getGenerators() # After having added all generators, create u_map: local_dastr.auto_u_map() # Add arrows according to arrow_pattern. for coeffs_a in arrow_patterns.keys(): if len(coeffs_a) == 1 and coeffs_a[0].isIdempotent(): continue for coeff_d in arrow_patterns[coeffs_a]: for x, y in itertools.product(mod_gens, mod_gens): if DAStructure.idemMatchDA(x, y, coeff_d, coeffs_a): local_dastr.addDelta(x, y, coeff_d, coeffs_a, 1) return local_dastr
def getLocalDAStructure(self, seeds_only = False): """Returns the local type DA structure associated to slide. If seeds_only is set to True, get a local DA structure with incomplete da_action, that can be completed using the autocompleteda module. """ # Compute the set of arrow patterns patterns_raw = self.patterns_fun(seeds_only = seeds_only) if self.translator is not None: patterns_raw = ArcslideDA._restrict_local_arrows( patterns_raw, self.translator[0], self.translator[1]) arrow_patterns = {} for pattern in patterns_raw: coeffs_a = [] for i in range(len(pattern)-1): coeffs_a.append(self.local_pmc2.sd(pattern[i])) coeffs_a = tuple(coeffs_a) if coeffs_a not in arrow_patterns: arrow_patterns[coeffs_a] = [] arrow_patterns[coeffs_a].append(self.local_pmc1.sd(pattern[-1])) # Now start construction of the local DA structure. alg1 = LocalStrandAlgebra(F2, self.local_pmc1) alg2 = LocalStrandAlgebra(F2, self.local_pmc2) local_dastr = LocalDAStructure(F2, alg1, alg2) # Mappings between local starting and ending PMC. slide = self.slide local_to_r = dict() for i in range(slide.start_pmc.n): if i in self.mapping1: # to_r[i] must be in mapping2 local_to_r[self.mapping1[i]] = self.mapping2[slide.to_r[i]] local_pair_to_r = dict() for i in range(self.local_pmc1.n): if i not in self.local_pmc1.endpoints: local_pair_to_r[self.local_pmc1.pairid[i]] \ = self.local_pmc2.pairid[local_to_r[i]] b1, c1 = self.slide.b1, self.slide.c1 local_b1, local_c1 = self.mapping1[b1], self.mapping1[c1] b_pair1 = self.local_pmc1.pairid[local_b1] c_pair1 = self.local_pmc1.pairid[local_c1] # Compute the set of local generators. This includes all # (l_idem, r_idem) where l_idem = r_idem (under the usual identification # of pairs), or where l_idem has the c_pair and r_idem has the b_pair. da_idems = [] num_pair = self.local_pmc1.num_pair for idem in subset(range(num_pair)): da_idems.append((list(idem), [local_pair_to_r[p] for p in idem])) for idem in subset([p for p in range(num_pair) if p != b_pair1 and p != c_pair1]): da_idems.append((list(idem) + [c_pair1], [local_pair_to_r[p] for p in (list(idem) + [b_pair1])])) for i in range(len(da_idems)): l_idem, r_idem = da_idems[i] local_dastr.addGenerator(SimpleDAGenerator( local_dastr, LocalIdempotent(self.local_pmc1, l_idem), LocalIdempotent(self.local_pmc2, r_idem), "%d" % i)) mod_gens = local_dastr.getGenerators() # After having added all generators, create u_map: local_dastr.auto_u_map() # Add arrows according to arrow_pattern. for coeffs_a in arrow_patterns.keys(): if len(coeffs_a) == 1 and coeffs_a[0].isIdempotent(): continue for coeff_d in arrow_patterns[coeffs_a]: for x, y in itertools.product(mod_gens, mod_gens): if DAStructure.idemMatchDA(x, y, coeff_d, coeffs_a): local_dastr.addDelta(x, y, coeff_d, coeffs_a, 1) return local_dastr
def __init__(self, local_da, splitting1, splitting2): """Specifies the local type DA structure (local_da, of type DAStructure), and splittings of the two full PMCs on the two sides (of type PMCSplitting). The parameters should be consistent in the following way: self.local_pmc1 = splitting1.local_pmc = local_da.algebra1.local_pmc self.local_pmc2 = splitting2.local_pmc = local_da.algebra2.local_pmc self.outer_pmc = splitting1.outer_pmc = splitting2.outer_pmc """ self.local_da = local_da self.splitting1 = splitting1 self.splitting2 = splitting2 self.pmc1, self.pmc2 = splitting1.pmc, splitting2.pmc self.outer_pmc = splitting1.outer_pmc assert self.outer_pmc == splitting2.outer_pmc self.local_pmc1 = local_da.algebra1.local_pmc self.local_pmc2 = local_da.algebra2.local_pmc assert self.local_pmc1 == splitting1.local_pmc assert self.local_pmc2 == splitting2.local_pmc self.mapping1 = splitting1.local_mapping self.mapping2 = splitting2.local_mapping self.outer_mapping1 = splitting1.outer_mapping self.outer_mapping2 = splitting2.outer_mapping self.idem_size1 = self.pmc1.genus self.idem_size2 = self.pmc2.genus # Possible values of single assignments, for use in tensorD, delta and # deltaPrefix (through the function getSingleAssignments). self.NONE, self.LOCAL, self.OUTER, self.DOUBLE = 0, 1, 2, 3 # Record the local and outer single idempotents. # Everything is indexed by 0 ... self.num_single-1 self.single_idems1 = self.local_da.single_idems1 # idems in local_pmc1 self.single_idems2 = self.local_da.single_idems2 # idems in local_pmc2 self.num_singles = len(self.single_idems1) assert self.num_singles == len(self.single_idems2) self.smeared_idems1 = [] # idems in pmc1 self.smeared_idems2 = [] # idems in pmc2 self.single_idems_outer = [] # idems in outer_pmc self.single_pts_outer = [] # pts in outer_pmc for i in range(self.num_singles): # Fill in data, and verify that the correspondence of idempotents on # the two sides is consistent on the outer PMC. single_idems1 = self.single_idems1[i] single_idems2 = self.single_idems2[i] single_pt1 = self.local_pmc1.pairs[single_idems1][0] single_pt2 = self.local_pmc2.pairs[single_idems2][0] for p in range(self.pmc1.n): if p in self.mapping1 and self.mapping1[p] == single_pt1: self.smeared_idems1.append(self.pmc1.pairid[p]) q = self.pmc1.otherp[p] assert q in self.outer_mapping1 q_outer = self.outer_mapping1[q] self.single_pts_outer.append(q_outer) self.single_idems_outer.append( self.outer_pmc.pairid[q_outer]) for p in range(self.pmc2.n): if p in self.mapping2 and self.mapping2[p] == single_pt2: self.smeared_idems2.append(self.pmc2.pairid[p]) q = self.pmc2.otherp[p] assert q in self.outer_mapping2 assert self.single_pts_outer[-1] == self.outer_mapping2[q] # Initiate the DA structure DAStructure.__init__(self, F2, algebra1 = self.pmc1.getAlgebra(), algebra2 = self.pmc2.getAlgebra(), side1 = ACTION_LEFT, side2 = ACTION_RIGHT) # Obtain the set of extended generators, and create a map self.gen_index # from (local_gen, outer_idem) to the extended generators. self.generators = [] local_gens = self.local_da.getGenerators() outer_idems = [idem for idem in self.outer_pmc.getIdempotents() if all(single_idem_outer not in idem for single_idem_outer in self.single_idems_outer)] self.gen_index = dict() for local_gen in local_gens: cur_count = 0 # number of generators so far with local_gen for outer_idem in outer_idems: if len(local_gen.idem1) + len(outer_idem) != self.idem_size1: continue assert len(local_gen.idem2) + len(outer_idem) == self.idem_size2 cur_gen = ExtendedDAGenerator( self, local_gen, outer_idem, "%s%%%d" % (local_gen.name, cur_count)) cur_count += 1 if hasattr(local_gen, "filtration"): cur_gen.filtration = local_gen.filtration self.generators.append(cur_gen) self.gen_index[(local_gen, outer_idem)] = cur_gen