Пример #1
0
    def deltaPrefix(self, MGen, algGens):
        # Preliminary tests
        if len(algGens) == 0:
            return True
        if algGens[0].left_idem != MGen.idem2:
            return False
        if any([algGens[i].right_idem != algGens[i+1].left_idem
                for i in range(len(algGens)-1)]):
            return False

        assignment, algs_local, prod_d = self.getAssignments(MGen, algGens)
        if assignment is None:
            return E0

        local_MGen = MGen.local_gen
        dbls = [self.single_idems2[i] for i in range(self.num_singles)
                if assignment[i] == self.DOUBLE]
        for to_remove in subset(dbls):
            if len(to_remove) != 0:
                cur_algs_local = tuple([alg.removeSingleHor(to_remove)
                                        for alg in algs_local])
            else:
                cur_algs_local = algs_local
            if self.testPrefix(local_MGen, cur_algs_local):
                return True
        return False
Пример #2
0
        def search(cur_strands):
            """Search starting with the given list of strands. May only add
            strands after the end position of the last strand.

            """
            # First, check if the current list of strands is valid.
            left_occupied = [0] * self.num_pair
            right_occupied = [0] * self.num_pair
            for start, end in cur_strands:
                start_id, end_id = self.pairid[start], self.pairid[end]
                if start_id != -1:
                    left_occupied[start_id] += 1
                if end_id != -1:
                    right_occupied[end_id] += 1
            if any([n >= 2 for n in left_occupied + right_occupied]):
                # There should not be two strands starting or ending at points
                # in the same pair.
                return

            # Enumerate all possible ways of adding idempotents.
            empty_idems = [i for i in range(self.num_pair)
                           if left_occupied[i] == 0 and right_occupied[i] == 0]
            left_idem = [i for i in range(self.num_pair)
                         if left_occupied[i] > 0]
            for idems_to_add in subset(empty_idems):
                result.append(LocalStrandDiagram(
                    algebra, left_idem + list(idems_to_add), cur_strands))

            # Now enumerate all ways of adding more strands.
            last_end = 0
            if len(cur_strands) > 0:
                last_end = cur_strands[-1][1]
            for start in range(last_end, self.n):
                for end in range(start + 1, self.n):
                    if self.pairid[start] == -1 and self.pairid[end] == -1 and \
                       end == start + 1:
                        # Exclude cases where a strand goes from an
                        # end-boundary-point to a start-boundary-point
                        break
                    search(cur_strands + [(start, end)])
                    if self.pairid[end] == -1:
                        # No strand should go beyond an end-boundary-point.
                        break
Пример #3
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
 def sGOfTGrad(t):
     return -gOfTGrad(subset(L, sampleSize),
                      alpha * sampleSize / n,
                      t, eta)
Пример #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
Пример #6
0
        def search(start_gen, cur_dgen, algs, last_assign, algs_local,
                   last_prod_d):
            """Searching for an arrow in the box tensor product.
            - start_gen: starting generator in the box tensor product. The
              resulting arrow will start from here.
            - cur_dgen: current location in the type D structure.
            - algs: current list of A-side inputs to the type DA structure (or
              alternatively, list of algebra outputs produced by the existing
              path through the type D structure).
            - algs_local: current list of local restrictions of algs.
            - last_assign: a list of length self.num_singles. For each split
              idempotent, specify the single assignments at the last algebra
              input.
            - prod_d: product of the outer restrictions, except for the last
              algebra input.

            """
            start_dagen, start_dgen = start_gen
            local_MGen = start_dagen.local_gen

            # Preliminary tests
            if len(algs) > 0:
                assert algs[0].left_idem == start_dagen.idem2
            for i in range(len(algs)-1):
                assert algs[i].right_idem == algs[i+1].left_idem
            if any(alg.isIdempotent() for alg in algs):
                return

            # First, adjust local module generator, and check for delta.
            if len(algs_local) > 0:
                local_MGen = self.adjustLocalMGen(local_MGen, algs_local[0])
                if local_MGen is None:
                    return
            local_delta = self.local_da.delta(local_MGen, tuple(algs_local))
            has_delta = (local_delta != E0)

            # Second, check for delta prefix.
            has_delta_prefix = False
            if len(algs) == 0:
                has_delta_prefix = True
            else:
                dbls = [self.single_idems2[i] for i in range(self.num_singles)
                        if last_assign[i] == self.DOUBLE]
                for to_remove in subset(dbls):
                    if len(to_remove) != 0:
                        cur_algs_local = tuple([alg.removeSingleHor(to_remove)
                                                for alg in algs_local])
                    else:
                        cur_algs_local = algs_local
                    if self.testPrefix(local_MGen, cur_algs_local):
                        has_delta_prefix = True
                        break

            if (not has_delta) and (not has_delta_prefix):
                return

            # Now, compute new prod_d.
            if len(algs) > 0:
                prod_d = self.getNewProdD(last_assign, algs[-1], last_prod_d)
            else:
                prod_d = last_prod_d
            if prod_d is None:
                return

            # If has_delta is True, add to delta
            for (local_d, local_y), ring_coeff in local_delta.items():
                alg_d, y = self.joinOutput(local_d, local_y, prod_d)
                if alg_d is not None:
                    dstr_result.addDelta(start_gen, DATensorDGenerator(
                        dstr_result, y, cur_dgen), alg_d, 1)

            if not has_delta_prefix:
                return
            for (new_alg, dgen_to), ring_coeff in dstr.delta(cur_dgen).items():
                new_assign, new_local, last_prod_d = self.extendRestrictions(
                    last_assign, algs_local, prod_d, new_alg)
                if new_assign is not None:
                    search(start_gen, dgen_to, algs + [new_alg],
                           new_assign, new_local, last_prod_d)