Esempio n. 1
0
    def remove_nodes(self, nodes, verbose=False):
        '''
        Remove nodes from the jusha output.

        @param nodes: list of nodes.
        @type nodes: list of integers
        '''
        nodes = list(nodes)
        if verbose:
            print("Cleanup: Remove the nodes {0}.".format(nodes))
        if len(nodes) == 0: return
        # update the level sets
        for ls in dict_values(self.levelsets):
            ls.nodes.difference_update(nodes)
        # make a map from old node indices to new indices
        nodes.sort()
        offset = 0
        c = nodes[offset]
        node_map = [None] * self.num_nodes
        for i in range(self.num_nodes):
            if i == c:
                offset += 1
                c = nodes[offset] if len(nodes) > offset else None
            else:
                node_map[i] = i - offset
        nm = lambda x: node_map[x]
        # update the simplicial complex
        D = dict()
        for s, v in dict_items(self.simplices.as_dict()):
            if node_map[s[0]] is not None:
                D[tuple(map(nm, s))] = v
        self.simplices = simpl_complex(D)

        # update the list of nodes
        self.nodes = [self.nodes[i] for i in range(self.num_nodes) \
                          if i not in nodes ]
Esempio n. 2
0
 def clear_nodes(self):
     self.nodes = []
     self.simplices = simpl_complex()
     for ls in dict_values(self.levelsets):
         ls.nodes = set()
Esempio n. 3
0
    def generate_complex(self,
                         cover=None,
                         verbose=False,
                         min_sizes=(),
                         max_dim=-1):
        '''
        Generate the simplicial complex from the intersections of the point
        sets for each node.

        The weight of each simplex is the number of data points in the
        intersection.

        This is a generic algorithm which works in every case but might not be
        fast. E.g. it tests every pair of nodes for intersecting point sets,
        wheres it is often known from the patch arrangement in the cover that
        many patches do not intersect. Feel free to use a different scheme
        when speed is an issue.

        @param verbose: print progress messages?
        @type verbose: bool
        '''
        '''
        The data scheme for the dictionary S: For v1<v2<...<vn,
        S[(v1,v2,...,v(n-1)][vn] stores the data points in the intersection of
        the patches U_v1, ..., U_vn if it is nonempty. This is exactly the
        condition that (v1,...,vn) form simplex. We iteratively generate this
        data, starting from S[()][i] = (data points for the node i).
        '''
        self.simplices = simpl_complex()
        dim = 0
        if verbose:
            print("There are {0} nodes.".format(self.num_nodes))
        min_nodesize = 1 if len(min_sizes) < 1 else min_sizes[0]
        S0 = dict()
        for i, n in enumerate(self.nodes):
            if n.points.size >= min_nodesize:
                S0[i] = n.points
                self.add_simplex((i, ), len(n.points))
        S = {(): S0}

        #S = {() : dict([(i, n.points) for i, n in enumerate(self.nodes) \
        #                    if n.points.size>=min_nodesize])}
        if verbose:
            print("Generate the simplicial complex.")
        while S:  # while S is not empty
            #@xl add a loop stopper for not computing on higher dimensions
            if dim > 2:
                break

            dim += 1
            if max_dim >= 0 and dim > max_dim: break
            min_simplexsize = 1 if len(min_sizes) <= dim else min_sizes[dim]
            if verbose:
                print("Collect simplices of dimension {0}:".format(dim))
            T = defaultdict(dict)
            for i1, Si1 in dict_items(S):
                for i2, i3 in combinations(Si1, 2):
                    intersection = intersect1d(Si1[i2],
                                               Si1[i3],
                                               assume_unique=True)
                    if intersection.size >= min_simplexsize:
                        if i2 > i3:  # ensure i2<i3
                            i2, i3 = i3, i2
                        self.add_simplex(i1 + (i2, i3),
                                         weight=intersection.size)
                        T[i1 + (i2, )][i3] = intersection
            S = T
            if verbose:
                print("There are {0} simplices of dimension {1}.".\
                          format(sum(map(len,dict_values(S))), dim) )