Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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
Example #6
0
    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