示例#1
0
文件: fil_.py 项目: Chen-Cai-OSU/Esme
    def epd(self, g__, pd_flag=False, debug_flag=False):
        w = -1
        values = nx.get_node_attributes(g__, 'fv')
        simplices = [[x[0], x[1]]
                     for x in list(g__.edges)] + [[x] for x in g__.nodes()]
        up_simplices = [
            d.Simplex(s, max(values[v] for v in s)) for s in simplices
        ]
        down_simplices = [
            d.Simplex(s + [w], min(values[v] for v in s)) for s in simplices
        ]
        if pd_flag == True:
            down_simplices = []  # mask the extended persistence here

        up_simplices.sort(key=lambda s1: (s1.dimension(), s1.data))
        down_simplices.sort(reverse=True,
                            key=lambda s: (s.dimension(), s.data))
        f = d.Filtration([d.Simplex([w], -float('inf'))] + up_simplices +
                         down_simplices)
        m = d.homology_persistence(f)
        dgms = d.init_diagrams(m, f)
        if debug_flag == True:
            print(
                'Calling compute_EPD here with success. Print first dgm in dgms'
            )
            print_dgm(dgms[0])
        return dgms
示例#2
0
    def build_filtrations(self):
        '''
        This method constructs a filtration given a cover and the data
        
        RETURNS
        -------
        filtration {dionysus.Filtration} a filtration of simplicial complices
        '''
        # Instantiate the filtration objects
        self.observer_filtration_ = d.Filtration()
        self.landmark_filtration_ = d.Filtration()

        # Set the end of the filtration to be the maximum visibility
        end = self.distances_.max()
        
        # Build iterative complexes and add simplices to filtration with the 
        # visibility threshold they were born
        for p in np.linspace(0,end):
            observer_complex, landmark_complex = self.build_complex(p)
            
            for simplex in observer_complex:
                self.observer_filtration_.append(d.Simplex(simplex, p))

            for simplex in landmark_complex:
                self.landmark_filtration_.append(d.Simplex(simplex, p))

        # Sort the filtrations
        self.observer_filtration_.sort()
        self.landmark_filtration_.sort()


        return self.observer_filtration_, self.landmark_filtration_
示例#3
0
 def collect_result(res):
     nonlocal id
     nonlocal f
     nonlocal nm
     nonlocal wm
     for enum in res:
         nodes = enum[0]
         weight = enum[1][0]
         if len(nodes) == 1:
             if nodes[0] not in nm:
                 nm[nodes[0]] = id
                 id += 1
                 f.append(dion.Simplex([nm[nodes[0]]], weight))
             else:
                 f.append(dion.Simplex([nm[nodes[0]]], weight))
         if len(nodes) == 2:
             act_weight = enum[1][1]
             if nodes[0] not in nm:
                 nm[nodes[0]] = id
                 id += 1
             if nodes[1] not in nm:
                 nm[nodes[1]] = id
                 id += 1
             wm[(nodes[0], nodes[1])] = act_weight
             f.append(dion.Simplex([nm[nodes[0]], nm[nodes[1]]],
                                   weight))
示例#4
0
def linear_filtration_static(f, h1, fc, h1_births, id_start_1, id_start_2, percentile=None, last=False):
    h1 = h1.cpu().detach().numpy()
    mat = fc.weight.data.cpu().detach().numpy()
    h2_births = np.zeros(mat.shape[0])

    if percentile is None:
        percentile_2 = 0
    else:
        percentile_2 = np.percentile(mat, percentile)
    gtzh1 = np.argwhere(h1 > 0)

    for xi in gtzh1:
        all_xis = np.absolute(mat[:,xi])
        max_xi = all_xis.max()
        if h1_births[xi] < max_xi:
            h1_births[xi] = max_xi
        gtpall_xis = np.argwhere(all_xis > percentile_2)[:,0]

        for mj in gtpall_xis:
            if h2_births[mj] < all_xis[mj]:
                h2_births[mj] = all_xis[mj]
            f.append(dion.Simplex([xi+id_start_1, mj+id_start_2], all_xis[mj]))


    # now add maximum birth time for each h1 hidden vertex to the filtration.
    for i in np.argwhere(h1_births > 0):
        f.append(dion.Simplex([i+id_start_1], h1_births[i]))

    # last linear layer in network, add final
    if last:
        for i in np.argwhere(h2_births > 0):
            f.append(dion.Simplex([i+id_start_2], h2_births[i]))
        return f
    return f, h2_births
示例#5
0
def EPH_mask(vertex_values, simplices):

    s2v_lst = [[
        sorted(s),
        sorted([[vertex_values[v], v] for v in s], key=lambda x: x[0])
    ] for s in simplices]
    f_ord = [dionysus.Simplex(s[0], s[1][-1][0]) for s in s2v_lst]  #takes max
    f_ext = [dionysus.Simplex([-1] + s[0], s[1][0][0])
             for s in s2v_lst]  #takes min

    ord_dict = {tuple(s[0]): s[1][-1][1] for s in s2v_lst}
    ext_dict = {tuple([-1] + s[0]): s[1][0][1] for s in s2v_lst}

    f_ord.sort(key=lambda s: (s.data, len(s)))
    f_ext.sort(key=lambda s: (-s.data, len(s)))

    #computes persistence
    f = dionysus.Filtration([dionysus.Simplex([-1], -float('inf'))] + f_ord +
                            f_ext)
    m = dionysus.homology_persistence(f)

    dgms = [[[], []], [[], []], [[], []], [[],
                                           []]]  #H0ord, H0ext, H1rel, H1ext

    for i in range(len(m)):

        dim = f[i].dimension()

        if m.pair(i) < i:
            continue  # skip negative simplices to avoid double counting
        if m.pair(
                i
        ) != m.unpaired:  #should be no unpaired apart from H0 from fictitious -1 vertex
            pos, neg = f[i], f[m.pair(i)]
            if pos.data != neg.data:  #off diagonal
                if -1 in pos and -1 in neg:  #rel1
                    dgms[2][0].append(ext_dict[tuple(neg)])
                    dgms[2][1].append(ext_dict[tuple(pos)])

                elif -1 not in pos and -1 not in neg:  #ord0
                    dgms[1][0].append(ord_dict[tuple(pos)])
                    dgms[1][1].append(ord_dict[tuple(neg)])

                else:
                    if dim == 0:  #H0ext
                        dgms[0][0].append(ord_dict[tuple(pos)])
                        dgms[0][1].append(ext_dict[tuple(neg)])

                    if dim == 1:  #H1ext
                        dgms[3][0].append(ext_dict[tuple(neg)])
                        dgms[3][1].append(ord_dict[tuple(pos)])

    return dgms
示例#6
0
    def from_simplices(self, simplices):

        if not isinstance(simplices, dionysus.Filtration):
            simplices = dionysus.Filtration(simplices)


 
        # import pdb; pdb.set_trace()
        # Add cone point to force homology to finite length; Dionysus only gives out cycles of finite intervals
        spxs = [dionysus.Simplex([-1])] + [c.join(-1) for c in simplices]
        for spx in spxs:
            spx.data = 1
            simplices.append(spx)

        # Compute persistence diagram
        persistence = dionysus.homology_persistence(simplices)
        diagrams = dionysus.init_diagrams(persistence, simplices)

        # Set all the results
        self._filtration = simplices
        self._diagram = diagrams[self.order]
        self._persistence = persistence
        self.barcode = np.array([(d.birth, d.death) for d in self._diagram])

        self._build_cycles()
示例#7
0
    def fit(self, data):
        """ Generate Rips filtration and cycles for data.
        """

        # Generate rips filtration 
        maxeps = np.max(data.std(axis=0)) # TODO: is this the best choice?
        cpx = dionysus.fill_rips(data, self.order+1, maxeps)

        # Add cone point to force homology to finite length; Dionysus only gives out cycles of finite intervals
        spxs = [dionysus.Simplex([-1])] + [c.join(-1) for c in cpx]
        for spx in spxs:
            spx.data = 1
            cpx.append(spx)

        # Compute persistence diagram
        persistence = dionysus.homology_persistence(cpx)
        diagrams = dionysus.init_diagrams(persistence, cpx)

        # Set all the results
        self._filtration = cpx
        self._diagram = diagrams[self.order]
        self._persistence = persistence
        self.barcode = np.array([(d.birth, d.death) for d in self._diagram])

        self._build_cycles()
示例#8
0
def dionysus_test():
    import dionysus as d
    simplices = [([0, 6], 0.0035655512881059928),
                 ([0, 5], 0.004388370816130452),
                 ([0, 4], 0.024136039488717488),
                 ([0, 3], 0.035381239705051776),
                 ([3, 5], 0.035381239705051776),
                 ([0, 1], 0.9824465164612051),
                 #([1, 1], 0.9824465164612051),
                 ([1, 3], 0.9824465164612051),
                 ([1, 4], 0.9824465164612051),
                 ([1, 5], 0.9824465164612051),
                 ([1, 6], 0.9824465164612051),
                 ([0, 2], 0.9999999997257268),
                 ([1, 2], 0.9999999997257268),
                 ([2, 2], 0.9999999997257268),
                 ([2, 3], 0.9999999997257268),
                 ([2, 4], 0.9999999997257268),
                 ([2, 5], 0.9999999997257268),
                 ([2, 6], 0.9999999997257268),
                 ([0], 0.0016456390560489196),
                 ([6], 0.0035655512881059928),
                 ([5], 0.004388370816130452),
                 ([4], 0.024136039488717488),
                 ([3], 0.035381239705051776),
                 ([1], 0.9824465164612051),
                 ([2], 0.9999999997257268)]
    f = d.Filtration()
    for vertices, time in simplices:
        f.append(d.Simplex(vertices, time))
    f.sort()
    m = d.homology_persistence(f)
    for i, c in enumerate(m):
        print(i, c)
示例#9
0
def fix_dio_vert_nums(Cplx, vertind):
    '''
    Helper function to adjust indexing of vertices in Dionysus from ``fill_rips`` function.

    Cplx: List of dio.Simplex's or a dio.Filtration
        Starting complex you want to adjust indices of

    vertind: int
        Starting index for vertices

    Returns
    -------
    New complex with vertex indices adjusted by vertind.

    '''
    New_Cplx = []
    for s in Cplx:
        # s.data = data
        vlist = []
        for v in s:
            vlist.append(v + vertind)
        s = dio.Simplex(vlist, s.data)

        New_Cplx.append(s)
    return New_Cplx
示例#10
0
def conv_filtration(f,
                    x,
                    conv_weight_data,
                    id_start_1,
                    id_start_2,
                    percentile=None,
                    h0_births=None,
                    stride=1):
    mat = conv_layer_as_matrix(conv_weight_data, x, stride)
    x = x.cpu().detach().numpy().reshape(-1)
    outer = np.absolute(mat * x)
    if h0_births is None:
        h0_births = np.zeros(x.shape)
    else:
        h0_births = h0_births.reshape(-1)

    if percentile is None:
        percentile_1 = 0
    else:
        percentile_1 = np.percentile(outer, percentile)
    gtzx = np.argwhere(x > 0)

    h1_births = np.zeros(mat.shape[0])
    # loop over each entry in the reshaped (column) x vector
    for xi in gtzx:
        # compute the product of each filter value with current x in iteration.
        all_xis = np.absolute(mat[:, xi] * x[xi])
        max_xi = all_xis.max()
        # set our x filtration as the highest product
        if h0_births[xi] < max_xi:
            h0_births[xi] = max_xi
            # f.append(dion.Simplex([xi], max_xi))
        gtpall_xis = np.argwhere(all_xis > percentile_1)[:, 0]
        # iterate over all products
        for mj in gtpall_xis:
            # if there is another filter-xi combination that has a higher
            # product, save this as the birth time of that vertex.
            if h1_births[mj] < all_xis[mj]:
                h1_births[mj] = all_xis[mj]
            f.append(
                dion.Simplex([xi + id_start_1, mj + id_start_2], all_xis[mj]))

    for i in np.argwhere(h0_births > 0):
        f.append(dion.Simplex([i + id_start_1], h0_births[i]))

    return f, h1_births
示例#11
0
def Link(sigma, X):
    # inputs:
    # sigma - dionysus simplex
    # X     - list of dionysus simplices
    link = []
    for tau in X:
        if set(sigma).issubset(set(tau)):
            tau_sub_gamma = set(tau).difference(set(sigma))
            link.append(d.Simplex(list(tau_sub_gamma)))
    return (link)
示例#12
0
    def compute_PD(self, simplices, sub=True, inf_flag='False'):
        def cmp(a, b):
            return (a > b) - (a < b)
        def compare(s1, s2, sub_flag=True):
            if sub_flag == True:
                if s1.dimension() > s2.dimension():
                    return 1
                elif s1.dimension() < s2.dimension():
                    return -1
                else:
                    return cmp(s1.data, s2.data)
            elif sub_flag == False:
                return -compare(s1, s2, sub_flag=True)


        node_simplices, edge_simplices = list(), list()
        for simplex, time in simplices:
            if len(simplex) == 1:
                node_simplices.append((simplex, time))
            elif len(simplex) == 2:
                edge_simplices.append((simplex, time))
            else:
                raise Exception('Expect Dim of simplex be either 1 or 2')


        f_node, f_edge = d.Filtration(), d.Filtration()
        for simplex, time in node_simplices:
            f_node.append(d.Simplex(simplex, time))
        f_node.sort()
        for simplex, time in edge_simplices:
            f_edge.append(d.Simplex(simplex, time))
        f_edge.sort(reverse=True)

        m = d.homology_persistence(f_node)
        dgms = d.init_diagrams(m, f_node)

        if inf_flag == 'False':
            dgms = self.del_inf(dgms)
        # for some degenerate case, return dgm(0,0)
        if (dgms == []) or (dgms == None):
            return d.Diagram([[0,0]])
        return dgms
示例#13
0
def load_filtration(file):
    """
    Load a filtration
    :param file:
    :return:
    """
    f = di.Filtration()
    simplices = np.load(file)
    for vertices, data in simplices:
        f.append(di.Simplex(vertices, data))
    return f
示例#14
0
def collect_result(res):
    global nm
    global id
    for enum in res:
        nodes = enum[0]
        weight = enum[1]
        if len(nodes) == 1:
            if nodes[0] not in nm:
                nm[nodes[0]] = id
                id += 1
                f.append(dion.Simplex([nm[nodes[0]]], weight))
            else:
                f.append(dion.Simplex([nm[nodes[0]]], weight))
        if len(nodes) == 2:
            if nodes[0] not in nm:
                nm[nodes[0]] = id
                id += 1
            if nodes[1] not in nm:
                nm[nodes[1]] = id
                id += 1
            f.append(dion.Simplex([nm[nodes[0]], nm[nodes[1]]], weight))
def init_freudenthal_2d(width, height):
    """
    Freudenthal triangulation of 2d grid
    """
    s = d.Filtration()
    # row-major format
    # 0-cells
    for i in range(height):
        for j in range(width):
            ind = i * width + j
            s.append(d.Simplex([ind]))
    # 1-cells
    for i in range(height):
        for j in range(width - 1):
            ind = i * width + j
            s.append(d.Simplex([ind, ind + 1]))
    for i in range(height - 1):
        for j in range(width):
            ind = i * width + j
            s.append(d.Simplex([ind, ind + width]))
    # 2-cells + diagonal 1-cells
    for i in range(height - 1):
        for j in range(width - 1):
            ind = i * width + j
            # diagonal
            s.append(d.Simplex([ind, ind + width + 1]))
            # 2-cells
            s.append(d.Simplex([ind, ind + 1, ind + width + 1]))
            s.append(d.Simplex([ind, ind + width, ind + width + 1]))
    return s
示例#16
0
    def compute_PD(self, simplices, sub=True, inf_flag='False', zigzag = False):
        def cmp(a, b):
            return (a > b) - (a < b)
        def compare(s1, s2, sub_flag=True):
            if sub_flag == True:
                if s1.dimension() > s2.dimension():
                    return 1
                elif s1.dimension() < s2.dimension():
                    return -1
                else:
                    return cmp(s1.data, s2.data)
            elif sub_flag == False:
                return -compare(s1, s2, sub_flag=True)
        def zigzag_less(x, y):
            # x, y are simplex
            dimx, datax = x.dimension(), x.data
            dimy, datay = y.dimension(), y.data
            if dimx == dimy == 0:
                return datax <= datay
            elif dimx == dimy == 1:
                return datax >= datay
            else:
                return dimx < dimy

        f = d.Filtration()
        for simplex, time in simplices:
            f.append(d.Simplex(simplex, time))

        if not zigzag:
            f.sort() if sub else f.sort(reverse=True)
        else:
            f.sort(zigzag_less, reverse=True)
            # print('After zigzag\n')
            # print_f(f)

            # simplices = [([2], 4), ([1, 2], 5), ([0, 2], 6),([0], 1), ([1], 2), ([0, 1], 3)]
            # f = d.Filtration()
            # for vertices, time in simplices:
            #     f.append(d.Simplex(vertices, time))
            # f.append(d.Simplex(vertices, time))
            # f.sort(cmp=zigzag_less,reverse=True)
            # print_f(f)

        m = d.homology_persistence(f)
        dgms = d.init_diagrams(m, f)

        if inf_flag == 'False':
            dgms = self.del_inf(dgms)
        # for some degenerate case, return dgm(0,0)
        if (dgms == []) or (dgms == None):
            return d.Diagram([[0,0]])
        return dgms
def build_filtered_complex(dims, indexes, time):
    """Build a filtered complex from dictionaries giving the dimensions, subsimplices, and times of entry

    :param dims: dictionary with keys giving simplex, values giving dimension
    :param indexes: Dictionary with keys giving the simplex, value giving the order in which simplex enters
    :param time: Dictionary with keys giving simplex, value giving time of entry
    :return:
    """
    sortedkeys = sorted(indexes, key=indexes.get)
    f = d.Filtration()
    for key in sortedkeys:
        if dims[key] == 0:
            f.append(d.Simplex([indexes[key]], time[key]))
        elif dims[key] == 1:
            verts = list(key)
            vertices = [indexes[v] for v in verts]
            f.append(d.Simplex(vertices, time[key]))
        elif dims[key] == 2:
            verts = list(key)
            vertices = [indexes[v] for v in verts]
            f.append(d.Simplex(vertices, time[key]))
    return f
def init_line_complex(p):
    """
    initialize 1D complex on the line
    Input:
        p - number of 0-simplices
    Will add (p-1) 1-simplices
    """
    f = d.Filtration()
    for i in range(p - 1):
        c = d.closure([d.Simplex([i, i + 1])], 1)
        for j in c:
            f.append(j)
    return f
示例#19
0
文件: plot.py 项目: shirtd/hsn
 def init_net(self, axis, net):
     list(map(axis.axis, ('equal', 'off')))
     self.plots['net'] = {}
     for i, s in enumerate(net.Salpha):
         s = dio.Simplex(*s)
         if s.dimension() == 0:
             x = net.plot_vertex(self.ax[0], s, False)
             self.plots['net'][i] = x[0] if isinstance(x, list) else x
         elif s.dimension() == 1:
             x = net.plot_edge(self.ax[0], s, False)
             self.plots['net'][i] = x[0] if isinstance(x, list) else x
         elif s.dimension() == 2:
             x = net.plot_triangle(self.ax[0], s, False, alpha=0.5)
             self.plots['net'][i] = x[0] if isinstance(x, list) else x
示例#20
0
 def filtration(self):
     if self._filtration != None:
         return self._filtration
     else:
         self._filtration = d.Filtration()
         nodes_so_far = []
         for year in self.years:
             nodes_now = self.nodes_for_year[year]
             nodes_so_far.extend(nodes_now)
             for clique in self.cliques:
                 if all([n in nodes_so_far for n in clique]):
                     self._filtration.append(d.Simplex(clique, year))
         self._filtration.sort()
         return self._filtration
示例#21
0
def get_verts(simp):
    '''
    Helper function to get all vertices of the input simplex

    Parameters
    -----------
    simp: dio.Simplex
        Instance of Dionysus simplex class

    Returns
    -------
    List of vertices in the simplex

    '''
    if simp.dimension == 2:
        return [dio.Simplex([v], 0) for v in t]
    else:
        return set([s for s in simp.boundary()])
示例#22
0
def test_issue47():
    # init the complex/filtration
    # any filtration that produces a diagram of only infinite points will work
    simplicies = [
        ([0], 0),
        ([1], 1),
    ]

    # create the filtration
    filtr = d.Filtration()
    for verts, idx in simplicies:
        simplex = d.Simplex(verts, idx)
        filtr.append(simplex)
    filtr.sort()

    # create the diagram
    m = d.homology_persistence(filtr)
    dgm = d.init_diagrams(m, filtr)

    d.plot.plot_diagram(dgm[0])
示例#23
0
def test_dionysus_modification():
    simplices = [([2], 4), ([1, 2], 5), ([0, 2], 6),
                 ([0], 1), ([1], 2), ([0, 1], 3)]
    f = d.Filtration()
    for vertices, time in simplices:
        f.append(d.Simplex(vertices, time))

    def compare(s1, s2, sub_flag=True):
        if sub_flag == True:
            if s1.dimension() > s2.dimension():
                return 1
            elif s1.dimension() < s2.dimension():
                return -1
            else:
                return cmp(s1.data, s2.data)
        elif sub_flag == False:
            return -compare(s1, s2, sub_flag=True)

    f.sort(cmp=compare)
    for s in f:
        print(s)
示例#24
0
def AlexanderDual(X):
    # input: list of dionysus simplices X
    # output: facets of the Alexander Dual
    V = set()
    dim = -1
    X = list(set(X))
    for s in X:
        V = V.union(set(s))
        dim = max(dim, s.dimension())
    Id = np.eye(len(V))
    M = np.zeros((len(X), len(V)))  # one row per simplex
    # form simplicial incidence matrix
    for i in range(len(X)):
        for j in X[i]:
            M[i, j] = 1
    # find maximal faces.  Entry (i,j) is the size of intersection of face i and j
    M_max = np.matmul(M, M.transpose())
    # entry (i,j) is true if face i is subset of face j
    M_max = M_max == np.sum(M, 1).reshape(M.shape[0], 1)
    nonfaces = []
    rV = range(len(V))
    Mt = M.transpose()
    for ix in range(2, dim + 2):
        combsMat = np.vstack(
            [np.sum(Id[list(x)], 0) for x in it.combinations(rV, ix)])
        M_max = np.matmul(combsMat, Mt)
        M_max = M_max == ix
        if nonfaces == []:
            nonfaces = combsMat[np.sum(M_max, 1) == 0]
        else:
            nonfaces = np.vstack([nonfaces, combsMat[np.sum(M_max, 1) == 0]])
    M = np.array(np.logical_not(nonfaces), dtype='float')
    M_max = np.matmul(M, M.transpose())
    M_max = M_max == np.sum(M, 1).reshape(M.shape[0], 1)
    M = M[np.sum(M_max, 1) == 1]
    maxSimplices = []
    for ix in range(M.shape[0]):
        maxSimplices.append(d.Simplex(list(np.where(M[ix] == 1)[0])))
    return (maxSimplices)
示例#25
0
    def compute_static_filtration(self, x, hiddens, percentile=None):
        x_id = 0

        f = dion.Filtration()
        mat = np.absolute(
            conv_layer_as_matrix(self.conv1.weight.data, x,
                                 self.conv1.stride[0]))
        x = x.cpu().detach().numpy().reshape(-1)

        if percentile is None:
            percentile_1 = 0
        else:
            percentile_1 = np.percentile(mat, percentile)
        gtzx = np.argwhere(x > 0)

        h1_id_start = x.shape[0]
        h1_births = np.zeros(mat.shape[0])
        # loop over each entry in the reshaped (column) x vector
        for xi in gtzx:
            # compute the product of each filter value with current x in iteration.
            all_xis = mat[:, xi]
            max_xi = all_xis.max()
            # set our x filtration as the highest product
            f.append(dion.Simplex([xi], max_xi))
            gtpall_xis = np.argwhere(all_xis > percentile_1)[:, 0]
            # iterate over all products
            for mj in gtpall_xis:
                # if there is another filter-xi combination that has a higher
                # product, save this as the birth time of that vertex.
                if h1_births[mj] < all_xis[mj]:
                    h1_births[mj] = all_xis[mj]
                f.append(dion.Simplex([xi, mj + h1_id_start], all_xis[mj]))

        h1 = hiddens[0].cpu().detach().numpy()
        h2_id_start = h1_id_start + h1.shape[0]
        mat = np.absolute(self.fc1.weight.data.cpu().detach().numpy())
        h2_births = np.zeros(mat.shape[0])

        if percentile is None:
            percentile_2 = 0
        else:
            percentile_2 = np.percentile(mat, percentile)
        gtzh1 = np.argwhere(h1 > 0)

        for xi in gtzh1:
            all_xis = mat[:, xi]
            max_xi = all_xis.max()
            if h1_births[xi] < max_xi:
                h1_births[xi] = max_xi
            gtpall_xis = np.argwhere(all_xis > percentile_2)[:, 0]

            for mj in gtpall_xis:
                if h2_births[mj] < all_xis[mj]:
                    h2_births[mj] = all_xis[mj]
                f.append(
                    dion.Simplex([xi + h1_id_start, mj + h2_id_start],
                                 all_xis[mj]))

        # now add maximum birth time for each h1 hidden vertex to the filtration.
        for i in np.argwhere(h1_births > 0):
            f.append(dion.Simplex([i + h1_id_start], h1_births[i]))

        h2 = hiddens[1].cpu().detach().numpy()
        h3_id_start = h2_id_start + h2.shape[0]
        mat = np.absolute(self.fc2.weight.data.cpu().detach().numpy())
        h3_births = np.zeros(mat.shape[0])

        if percentile is None:
            percentile_3 = 0
        else:
            percentile_3 = np.percentile(mat, percentile)
        gtzh2 = np.argwhere(h2 > 0)

        for xi in gtzh2:
            all_xis = mat[:, xi]
            max_xi = all_xis.max()
            if h2_births[xi] < max_xi:
                h2_births[xi] = max_xi
            gtpall_xis = np.argwhere(all_xis > percentile_3)[:, 0]

            for mj in gtpall_xis:
                if h3_births[mj] < all_xis[mj]:
                    h3_births[mj] = all_xis[mj]
                f.append(
                    dion.Simplex([xi + h2_id_start, mj + h3_id_start],
                                 all_xis[mj]))

        # now add maximum birth time for each h2 hidden vertex to the filtration.
        for i in np.argwhere(h2_births > 0):
            f.append(dion.Simplex([i + h2_id_start], h2_births[i]))

        # now add maximum birth time for each h3 hidden vertex to the filtration.
        for i in np.argwhere(h3_births > 0):
            f.append(dion.Simplex([i + h3_id_start], h3_births[i]))

        print('filtration size', len(f))
        print('Sorting filtration...')
        f.sort(reverse=True)
        return f
示例#26
0
                    #f.append(dio.Simplex(v, t))
                    simplices.append([(b_1, it[0], it[1]), t])

finish = time.time()

print('Time taken to create and add 0, 1, 2-simplices:', finish - start)

# Evaluate the persistence homologies
input(
    'Press key to add and sort simplices, and evaluate persistent homology by Dionysus2...'
)
# Create the blank filtration
f = dio.Filtration()

for i, simplex in enumerate(simplices):
    f.append(dio.Simplex(simplex[0], simplex[1]))
# Sort the simplices
f.sort()
start = time.time()
per_hom = dio.homology_persistence(f)
finish = time.time()
print('Time taken to evaluate persistent homology by Dionysus:',
      finish - start)

input(
    'Press key to add and sort simplices, and evaluate persistent homology by Manu...'
)
start = time.time()

all_columns = [[], [], []]
filtration_list = []
示例#27
0
    def setup_Zigzag(self, k=2):
        '''
        Helper function for ``run_Zigzag`` that sets up inputs needed for Dionysus' zigzag persistence function.
        This only works for a fixed radius r.

        Parameters
        ----------

        k: int, optional
            Max dimension for rips complex (default is 2)

        Returns
        -------
        filtration: dio.Filtration
            Dionysis filtration containing all simplices that exist in zigzag sequence

        times: list
            List of times, where times[i] is a list containing [a,b] where simplex i appears at time a, and disappears at time b

        '''

        # renames edges in the list based on the vert labels
        # so an edge [0,5] becomes [vert_labels[0], vert_labels[5]]
        def rename_edges(edge_list, vert_labels):
            vert_dict = {i: vert_labels[i] for i in range(len(vert_labels))}
            return np.vectorize(vert_dict.__getitem__)(edge_list)

        def make_undirected(A):
            for i in range(len(A)):
                for j in range(i):
                    if A[i, j] > 0 or A[j, i] > 0:
                        A[i, j] = 1
                        A[j, i] = 1
                    else:
                        A[i, j] = 0
                        A[j, i] = 0
            return A

        def fix_vert_nums(simp, labels):
            vlist = []
            for v in simp:
                vlist.append(labels[v])
            return vlist

        def get_tris(A, labels):
            A_u = make_undirected(A)

            A_u[A_u != 0] = 0.1
            A_u[A_u == 0] = 10
            np.fill_diagonal(A_u, 0)

            f = dio.fill_rips(squareform(A_u), k=2, r=1)
            tris = [fix_vert_nums(i, labels) for i in f if i.dimension() == 2]

            return tris

        simps_list = []
        times_list = []
        verts = np.unique(np.concatenate(self.vert_labels))
        num_verts = len(verts)

        # Handle vertices...
        for v in verts:
            simps_list.append(dio.Simplex([v], 0))

            s_times = []
            simp_in = False

            # Find time simplex enters filtration
            for i in range(len(self.networks)):
                if v in self.vert_labels[i] and simp_in == False:

                    if self.cplx_type == 'union':
                        if i == 0:
                            st = 0
                        else:
                            st = i - 0.5
                        s_times.append(st)
                    elif self.cplx_type == 'intersection':
                        s_times.append(i)
                    else:
                        print('cplx_type not recognized...\nQuitting')
                        return [], []

                    simp_in = True

                # Find time simplex exits filtration
                if v not in self.vert_labels[i] and simp_in == True:
                    if self.cplx_type == 'union':
                        s_times.append(i)
                    elif self.cplx_type == 'intersection':
                        s_times.append(i - 0.5)

                    else:
                        print('cplx_type not recognized...\nQuitting')
                        return [], []
                    simp_in = False
            times_list.append(s_times)

        if self.verbose:
            print(f"Added {num_verts} vertices to filtration.")

        # list of lists
        # edges_lists[i] contains the edges in network[i] with correct vert labels
        # note edges are sorted in vert label order so edges are no longer directed
        edges_lists = [
            np.sort(rename_edges(
                np.hstack([np.where(self.networks[i] != 0)]).T,
                self.vert_labels[i]),
                    axis=1).tolist() for i in range(len(self.networks))
        ]

        # list of unique edges across all networks
        unique_edges = np.unique(np.vstack(
            [np.array(es) for es in edges_lists]),
                                 axis=0).tolist()
        num_edges = len(unique_edges)

        # Handle edges...
        for e in unique_edges:
            simps_list.append(dio.Simplex(e, 0))

            s_times = []
            simp_in = False
            for i in range(len(self.networks)):
                if e in edges_lists[i] and simp_in == False:

                    if self.cplx_type == 'union':
                        if i == 0:
                            st = 0
                        else:
                            st = i - 0.5
                        s_times.append(st)
                    elif self.cplx_type == 'intersection':
                        s_times.append(i)
                    else:
                        print('cplx_type not recognized...\nQuitting')
                        return [], []

                    simp_in = True
                if not e in edges_lists[i] and simp_in == True:

                    if self.cplx_type == 'union':
                        s_times.append(i)
                    elif self.cplx_type == 'intersection':
                        s_times.append(i - 0.5)

                    simp_in = False
            times_list.append(s_times)

        if self.verbose:
            print(f"Added {num_edges} edges to filtration.")

        # Handle triangles...
        tri_lists = [
            get_tris(self.networks[i], self.vert_labels[i])
            for i in range(len(self.networks))
        ]

        unique_tris = np.unique(np.vstack(
            [np.array(ts) for ts in tri_lists if ts != []]),
                                axis=0).tolist()
        num_tris = len(unique_tris)

        for t in unique_tris:
            simps_list.append(dio.Simplex(t, 0))

            s_times = []
            simp_in = False
            for i in range(len(self.networks)):
                if t in tri_lists[i] and simp_in == False:

                    if self.cplx_type == 'union':
                        if i == 0:
                            st = 0
                        else:
                            st = i - 0.5
                        s_times.append(st)
                    elif self.cplx_type == 'intersection':
                        s_times.append(i)
                    else:
                        print('cplx_type not recognized...\nQuitting')
                        return [], []

                    simp_in = True
                if t not in tri_lists[i] and simp_in == True:
                    if self.cplx_type == 'union':
                        s_times.append(i)
                    elif self.cplx_type == 'intersection':
                        s_times.append(i - 0.5)

                    simp_in = False
            times_list.append(s_times)

        if self.verbose:
            print(f"Added {num_tris} triangles to filtration.")

        f_st = time.time()
        filtration = dio.Filtration(simps_list)
        f_end = time.time()

        return filtration, times_list
import dionysus as d
import numpy as np


if __name__ == '__main__':

    print('Testing a TDA output for Dionysus...')

    vertex1 = 0
    vertex2 = 1
    vertex3 = 2

    print('Making simplex from verts: ', vertex1, vertex2, vertex3)


    s=d.Simplex([vertex1,vertex2,vertex3])
    print("Here is the simplex: ", s)

    print("Its dimension is: ", s.dimension())

    print("And its boundary...")
    for sb in s.boundary():
        print(sb)

    


    print("Great - So we can work with simplecies, but we can also work with points")
    print("Here is an array (Must be numpy)")
    points = np.array([[0.0,1.0],[2.0,0.0],[0.0,0.0]])
    print(points)
示例#29
0
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(-1.1,1.1)
ax.set_ylim(-1.1,1.1)
ax.scatter(circ_data2[:,0],circ_data2[:,1],c="k")
ax.scatter(circ_data2[-1,0],circ_data2[-1,1],c="r")
ax.set_aspect("equal")
plt.show()

#get each barcode
#alpha filtration TDA
test_comp = circ_alpha1[0]
test_bts = circ_alpha1[1]
test_f = d.Filtration()
for j in range(len(test_comp)):
    test_f.append(d.Simplex(test_comp[j],test_bts[j]))
p = d.homology_persistence(test_f)
dgms1 = d.init_diagrams(p, test_f)

#scatters
d.plot.plot_diagram(dgms1[0])
d.plot.plot_diagram(dgms1[1])
plt.show()

#alpha filtration TDA
test_comp = circ_alpha2[0]
test_bts = circ_alpha2[1]
test_f = d.Filtration()
for j in range(len(test_comp)):
    test_f.append(d.Simplex(test_comp[j],test_bts[j]))
p = d.homology_persistence(test_f)
示例#30
0
    def compute_dynamic_filtration_no_inf(self,
                                          x,
                                          hiddens,
                                          percentile=0,
                                          return_nm=False):
        id = 0
        f = dion.Filtration()
        f.append(dion.Simplex([-1], 0))
        enums = []
        nm = {(-1, 0, 0): -1}
        params = self.params
        percentiles = np.zeros((len(params)))

        def collect_result(res):
            nonlocal id
            nonlocal f
            nonlocal nm
            for enum in res:
                nodes = enum[0]
                weight = enum[1]
                if len(nodes) == 1:
                    if nodes[0] not in nm:
                        nm[nodes[0]] = id
                        id += 1
                        f.append(dion.Simplex([nm[nodes[0]]], weight))
                    else:
                        f.append(dion.Simplex([nm[nodes[0]]], weight))
                    f.append(dion.Simplex([nm[nodes[0]], -1], 0))
                if len(nodes) == 2:
                    if nodes[0] not in nm:
                        nm[nodes[0]] = id
                        id += 1
                    if nodes[1] not in nm:
                        nm[nodes[1]] = id
                        id += 1
                    f.append(dion.Simplex([nm[nodes[0]], nm[nodes[1]]],
                                          weight))

        x = x.cpu().detach().numpy()
        num_channels = x.shape[0]
        l = 0
        percentiles[l] = np.percentile(
            np.absolute(hiddens[l].cpu().detach().numpy()), percentile)
        hn = hiddens[l].cpu().detach().numpy()
        nlc = hn.reshape((hn.shape[0], -1)).shape[1]
        stride = 1
        for c in range(num_channels):
            p = params[l].weight.data[:, c, :, :]
            mat = conv_layer_as_matrix(p, x[c], stride)
            m1, h0_births, h1_births = conv_filtration_fast2(
                x[c], mat, l, c, nlc, percentile=percentiles[l])
            # enums = m1
            # enums += [([spec_hash((l,c,i[0]))], h0_births[i].item()) for i in np.argwhere(h0_births > percentile)]
            enums = []
            enums += [([spec_hash(
                (l + 1, i[0] // nlc, i[0] % nlc))], h1_births[i].item())
                      for i in np.argwhere(h1_births > percentile)]
            collect_result(enums)

        h1 = hiddens[l].cpu().detach().numpy()
        l = 1
        percentiles[l] = np.percentile(
            np.absolute(hiddens[l].cpu().detach().numpy()), percentile)
        p = params[l]
        m1, h0_births, h1_births = linear_filtration_fast2(
            h1, p, l, 0, percentile=percentiles[l])
        enums += m1
        comp_percentile = percentiles[
            l - 1] if percentiles[l - 1] < percentiles[l] else percentiles[l]
        enums += [([spec_hash((l, c, i[0]))], h0_births[i])
                  for i in np.argwhere(h0_births > comp_percentile)]

        h1 = hiddens[l].cpu().detach().numpy()
        l = 2
        percentiles[l] = np.percentile(
            np.absolute(hiddens[l].cpu().detach().numpy()), percentile)
        p = params[l]
        m1, h0_births, h1_births_2 = linear_filtration_fast2(
            h1, p, l, 0, percentile=percentiles[l])
        enums += m1

        max1 = np.maximum.reduce([h0_births, h1_births])
        comp_percentile = percentiles[
            l - 1] if percentiles[l - 1] < percentiles[l] else percentiles[l]
        enums += [([spec_hash((l, 0, i[0]))], max1[i])
                  for i in np.argwhere(max1 > comp_percentile)]
        enums += [([spec_hash((l + 1, 0, i[0]))], h1_births_2[i])
                  for i in np.argwhere(h1_births_2 > percentiles[l])]

        collect_result(enums)

        # h1_id_start = x.cpu().detach().numpy().reshape(-1).shape[0]
        # print('h1_id_start', h1_id_start)
        # f, h1_births = conv_filtration(f, x[0], self.conv1.weight.data[:,0,:,:], 0, h1_id_start, percentile=percentile)
        #
        # h2_id_start = h1_id_start + hiddens[0].cpu().detach().numpy().shape[0]
        # print('h2_id_start', h2_id_start)
        # f, h2_births = linear_filtration(f, hiddens[0], self.fc1, h1_births, h1_id_start, h2_id_start, percentile=percentile, last=False)
        #
        # h3_id_start = h2_id_start + hiddens[1].cpu().detach().numpy().shape[0]
        # print('h3_id_start', h3_id_start)
        # f = linear_filtration(f, hiddens[1], self.fc2, h2_births, h2_id_start, h3_id_start, percentile=percentile, last=True)

        print('filtration size', len(f))
        f.sort(reverse=True)
        if return_nm:
            return f, nm
        else:
            return f