示例#1
0
def LandscapePnorm(ts,
                   p,
                   ts2=None,
                   dim=1,
                   maxrad=1,
                   t_min=None,
                   t_max=None,
                   n_points=100):
    # compute L^p norm of all landscapes from multidimensional timeseries (or just set of points)
    # input:
    # ts - m x d numpy array, one timeseries (or just point coordinates) per column (d series), m samples per series
    # p - integer (type of L^p norm to compute)
    # ts2 - m x d numpy array, one timeseries (or just point coordinates) per column (d series), m samples per series
    #     if this is set, then the L^p distance will be returned
    # dim - dimension of the persistence diagram from which to derive the landscape
    # maxrad - max distance between pairwise points to consider for the Rips complex
    # t_min, t_max (int or None) - same as inputs to dgm2landscape; if universal start/stop radii are desired for computing landscapes
    #                              setting these to fixed values might reduce computation time a little bit
    # n_points (int) - same as input to dgm2landscape; number of data points for landscape functions
    # output:
    # float32 - the L^p norm of the landscapes or difference
    # need to go one dim up, above the one we want, as otherwise get free hom group at the top of the chains.
    frips = d.fill_rips(np.array(ts, dtype='float32'), dim + 1, maxrad)
    mrips = d.homology_persistence(frips)
    dgms = d.init_diagrams(mrips, frips)
    # acquire birth/death pairs
    if len(dgms) <= dim:
        # set the only birth/death pair to (0.0,0.0) if no gens found
        bd = np.zeros((1, 2))
    else:
        bd = dgm2array(dgms[dim])
    # acquire landscape functions
    landscapes, rstart, rend = dgm2landscape(bd,
                                             t_min=t_min,
                                             t_max=t_max,
                                             n_points=n_points)
    if ts2 is not None:
        frips2 = d.fill_rips(np.array(ts2, dtype='float32'), dim + 1, maxrad)
        mrips2 = d.homology_persistence(frips2)
        dgms2 = d.init_diagrams(mrips2, frips2)
        if len(dgms2) <= dim:
            # set the only birth/death pair to (0.0,0.0) if no gens found
            bd2 = np.zeros((1, 2))
        else:
            bd2 = dgm2array(dgms2[dim])
        landscapes2, rstart2, rend2 = dgm2landscape(bd2,
                                                    t_min=t_min,
                                                    t_max=t_max,
                                                    n_points=n_points)
        # compute L^p distances
        lpnorms = LpNorms(landscapes,
                          min(rstart, rstart2),
                          max(rend, rend2),
                          landscapes2=landscapes2,
                          p=p)
    else:
        # compute L^p norms
        lpnorms = LpNorms(landscapes, rstart, rend, p=p)
    normie = LandscapeLpNorm(lpnorms, p=p)
    return (normie)
示例#2
0
 def get_upper_star(pcpds_obj):
     f = d.fill_freudenthal(pcpds_obj.get_point_cloud().astype('f4'), False)
     m = d.homology_persistence(f)
     diagram = d.init_diagrams(m, f)
     pcpds_obj.set_persistance_diagram(diagram)
     pcpds_obj.set_filtration_used(Filtration.get_upper_star, "upper_star")
     return pcpds_obj
示例#3
0
def compare_diagrams(n=16, negate=False, n_threads=4, seed=1, top_dim=2):
    # no wrap in Dionysus
    wrap = False

    # generate random grid data
    np.random.seed(seed)
    a = np.random.randn(n**3).reshape((n, n, n))

    # compute diagrams with Oineus
    oin_dgms = oin.compute_diagrams_ls(a, negate, wrap, top_dim, n_threads)

    # compute diagrams with Dionysis
    fil_us = dion.fill_freudenthal(a, reverse=negate)
    p = dion.homology_persistence(fil_us)
    dion_dgms = dion.init_diagrams(p, fil_us)

    dist = 0.0

    for dim in range(top_dim):
        # convert Oineus diagram to Dionysus format
        oin_dgm = dion.Diagram(oin_dgms[dim])
        dion_dgm = dion_dgms[dim]
        dist += dion.bottleneck_distance(oin_dgm, dion_dgm)

    print("total dist: ", dist)
    assert (dist < 0.001)
def compute_dgm_from_edges(
    all_edges_for_diagrams, astuple: bool = True, negate: bool = True
):
    _prepare_edges_for_diagram(all_edges_for_diagrams)

    # Dionysus computations (persistent diagrams)
    # logger.info(f"Before filtration")
    #logger.info(f"len all_edges_for_diagrams = {len(all_edges_for_diagrams)}")

    f = Filtration()
    for vertices, weight in all_edges_for_diagrams:
        if negate:
            timing = -weight.round(3)
        else:
            timing = weight.round(3)
        f.append(Simplex(vertices, timing))
    f.sort()
    #logger.info(f"{f}")
    m = homology_persistence(f)
    dgms = init_diagrams(m, f)
    dgm = dgms[0]

    if not astuple:
        return dgm
    else:
        ret = list()
        for pt in dgm:
            # ret.append((pt.birth, pt.death if not np.isposinf(pt.death) else 2**64))
            ret.append((round(pt.birth, 2), round(pt.death, 2)))
        return ret
def create_sample_graph(f):
    m = dion.homology_persistence(f)
    dgms = dion.init_diagrams(m, f)
    subgraphs = {}
    for i, c in enumerate(m):
        if len(c) == 2:
            if f[c[0].index][0] in subgraphs:
                subgraphs[f[c[0].index][0]].add_edge(f[c[0].index][0],
                                                     f[c[1].index][0],
                                                     weight=f[i].data)
            else:
                eaten = False
                for k, v in subgraphs.items():
                    if v.has_node(f[c[0].index][0]):
                        v.add_edge(f[c[0].index][0],
                                   f[c[1].index][0],
                                   weight=f[i].data)
                        eaten = True
                        break
                if not eaten:
                    g = nx.Graph()
                    g.add_edge(f[c[0].index][0],
                               f[c[1].index][0],
                               weight=f[i].data)
                    subgraphs[f[c[0].index][0]] = g

    return subgraphs, dgms[0]
示例#6
0
def test_homology(args, model, device, test_loader, epoch, res_df):

    model.eval()
    test_loss = 0
    correct = 0
    # capture a hidden state to use later, we don't care about its values though
    hiddens = None
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output, hiddens = model(data, hiddens=True)
            test_loss += F.nll_loss(
                output, target, reduction='sum').item()  # sum up batch loss
            pred = output.max(
                1, keepdim=True)[1]  # get the index of the max log-probability
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)
    print(
        '\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
            test_loss, correct, len(test_loader.dataset),
            100. * correct / len(test_loader.dataset)))

    this_hiddens = [hiddens[0][0], hiddens[1][0], hiddens[2][0]]
    f = model.compute_static_filtration(data[0, 0], this_hiddens)
    m = dion.homology_persistence(f)
    dgms = dion.init_diagrams(m, f)
    row = {
        'diagrams': dgms,
        'loss': test_loss,
        'epoch': epoch,
        'accuracy': 100. * correct / len(test_loader.dataset)
    }
    res_df.append(row)
    return res_df
示例#7
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()
示例#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)
def compute_ph_boundary_using_graph_distance(gexfile, districtid, latstring,
                                             lonstring):
    """ Computes the persistent homology of an boundary outward march with graph distance

    :param gexffile: location of input gexf
    :param districtid: identifier for the district whose boundary we're examining
    :param latstring: string ID for latitude field of centroid
    :param lonstring: string ID for longitude field of centroid
    :return:
    """
    G = nx.read_gexf(gexfile)

    get_dist_to_boundary(G, districtid)

    nbr_list = gen_cclockwise_neighbors(G, lonstring, latstring)
    faces = find_faces(G, nbr_list)
    dims, idxs, time = get_dims_and_idx(G, G.edges(), faces)

    filtration = build_filtered_complex(dims, idxs, time)

    plot_simplexes_from_boundary(G, lonstring, latstring, time, dims)

    m = d.homology_persistence(filtration)

    dgms = d.init_diagrams(m, filtration)
    d.plot.plot_bars(dgms[1], show=True)
示例#10
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
示例#11
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()
def generate_rv_complex(PointsArray, Dimension):
    dists = pdist(PointsArray)
    # adjacentDist = [norm(PointsArray[i,:] - PointsArray[i+1,:]) for i in range(len(PointsArray)-1)]
    Alpha = max(dists)
    rips = d.fill_rips(dists, Dimension, Alpha)
    m = d.homology_persistence(rips)
    dgms = d.init_diagrams(m, rips)
    return rips, m, dgms
示例#13
0
def computePD(i):
    # print('Process %s' % i)
    # np.random.seed(42)
    f1 = d.fill_rips(np.random.random((i + 10, 2)), 2, 1)
    m1 = d.homology_persistence(f1)
    dgms1 = d.init_diagrams(m1, f1)
    # return [(p.birth, p.death) for p in dgms1[1]]  # advice from Dmitriy
    return dgms1[1]
示例#14
0
 def get_rips_diagram(pcpds_obj):
     f = d.fill_rips(pcpds_obj.get_point_cloud().astype('f4'),
                     pcpds_obj.get_skeleton(), pcpds_obj.get_distance())
     m = d.homology_persistence(f)
     diagram = d.init_diagrams(m, f)
     pcpds_obj.set_persistance_diagram(diagram)
     pcpds_obj.set_filtration_used(Filtration.get_rips_diagram, "rips")
     return pcpds_obj
示例#15
0
def PersistentDiagram(nparray,dim=1,skeletondim=2):
    stime=timer()
    DisM=distance.pdist(nparray,'euclidean')
    M=DisM.max()
    VRC=d.fill_rips(nparray,skeletondim,M)
    ph=d.homology_persistence(VRC)
    dgms=d.init_diagrams(ph,VRC)
    timer(stime)
    return dgms[dim]
示例#16
0
def get_persistence(f):
    """
    Args:
        f: filtration
    Returns:
        m: reduced boundary matrix
    """
    m = d.homology_persistence(f)
    return m
示例#17
0
def create_diagrams(args, model):
    use_cuda = not args.no_cuda and torch.cuda.is_available()
    device = torch.device("cuda" if use_cuda else "cpu")
    kwargs = {'num_workers': 1, 'pin_memory': True}
    test_loader = torch.utils.data.DataLoader(datasets.MNIST(
        '../data',
        train=False,
        download=True,
        transform=transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize((0.1307, ), (0.3081, ))
        ])),
                                              batch_size=args.test_batch_size,
                                              shuffle=False,
                                              **kwargs)

    df_filename = model.save_string()
    df_filename = str(
        args.up_to) + '_' + df_filename[:df_filename.find('.pt')] + '.pkl'
    df_loc = os.path.join(args.diagram_directory, df_filename)

    model.eval()
    test_loss = 0
    correct = 0
    t = 0
    res_df = []
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output, hiddens = model(data, hiddens=True)
            test_loss += F.nll_loss(
                output, target, reduction='sum').item()  # sum up batch loss
            pred = output.max(
                1, keepdim=True)[1]  # get the index of the max log-probability
            correct += pred.eq(target.view_as(pred)).sum().item()
            for s in range(data.shape[0]):
                # check if this makes sense
                this_hiddens = [hiddens[0][s], hiddens[1][s], hiddens[2][s]]
                print('Filtration: {}'.format(s + t))
                f = model.compute_dynamic_filtration(data[s, 0], this_hiddens)
                #
                m = dion.homology_persistence(f)
                dgms = dion.init_diagrams(m, f)
                row = {
                    'diagrams': dgms,
                    'loss': output.cpu().numpy()[s][0],
                    'class': target.cpu().numpy()[s],
                    'prediction': pred.cpu().numpy()[s][0]
                }
                res_df.append(row)

            t += args.test_batch_size
            if t >= args.up_to:
                break

    res_df = pd.DataFrame(res_df)
    res_df.to_pickle(df_loc)
def run_simple_example():
    """runs a simple illustrative example"""
    Gspatial = nx.Graph()
    Gspatial.add_nodes_from(range(9))
    Gspatial.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (3, 6),
                             (3, 8), (4, 5), (5, 6), (5, 7), (6, 7), (7, 8)])
    xcoord = {
        0: 0.,
        1: 1.,
        2: 0.,
        3: 1.,
        4: 4.,
        5: 3.,
        6: 2.,
        7: 2.,
        8: 1.,
    }
    ycoord = {
        0: 0.,
        1: 0.,
        2: -1.,
        3: -1.,
        4: -1.,
        5: -2.,
        6: -2.,
        7: -3.,
        8: -4.
    }
    pos = {k: np.array([xcoord[k], ycoord[k]]) for k in xcoord.keys()}
    nx.set_node_attributes(Gspatial, xcoord, 'xcoord')
    nx.set_node_attributes(Gspatial, ycoord, 'ycoord')
    nx.set_node_attributes(Gspatial, pos, 'pos')

    Gdem = nx.Graph()
    Gdem.add_nodes_from(range(9))
    Gdem.add_weighted_edges_from([(0, 1, .1), (0, 2, .1), (0, 3, .2),
                                  (1, 3, .1), (2, 3, 0.1), (3, 4, .1),
                                  (4, 8, 0.1), (3, 8, .1), (5, 6, .2),
                                  (5, 7, .1), (6, 7, .1)])
    nx.set_node_attributes(Gdem, xcoord, 'xcoord')
    nx.set_node_attributes(Gdem, ycoord, 'ycoord')
    nx.set_node_attributes(Gdem, pos, 'pos')
    nbr_list = gen_cclockwise_neighbors(Gspatial, 'xcoord', 'ycoord')
    nbr_list = {k: [int(i) for i in v] for k, v in nbr_list.items()}
    faces_spatial = find_faces(Gspatial, nbr_list)
    tris_spatial = triangulate_faces(faces_spatial)

    dims, idxs, times = get_dims_and_idx_from_multiple(Gdem, tris_spatial, 1.,
                                                       20)
    plot_simplexes_from_multiple(Gdem, dims, times)

    filtration = build_filtered_complex(dims, idxs, times)

    m = d.homology_persistence(filtration)

    dgms = d.init_diagrams(m, filtration)
    d.plot.plot_bars(dgms[1], show=True)
示例#19
0
def compute_diagrams(data, k_filt=3, to_return=2):

    diagrams = []
    for i in range(len(data)):
        # print("Processing data: " + str(i) + "\n")
        filtration = dion.fill_rips(data[i], k_filt, 3.0)
        homology = dion.homology_persistence(filtration)
        diagram = dion.init_diagrams(homology, filtration)

        diagrams.append(diagram[to_return])

    return diagrams
示例#20
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
示例#21
0
def geomill(arr,dim=1,cutoff=2,elevation=45,azimuth=30):
    #E3view(arr,elevation,azimuth)
    #VR complex
    stime=timer()
    skeletondim=dim+1
    filtration = d.fill_rips(arr, skeletondim, cutoff)
    #persistent homology
    ph = d.homology_persistence(filtration)
    dgms = d.init_diagrams(ph, filtration)
    d.plot.plot_bars(dgms[dim], show = True)
    timer(stime)
    return dgms
示例#22
0
def create_sample_graphs(res_df, ids, wms):
    sample_graphs = []
    dgms = []
    lifetimes = []
    for s in range(res_df.shape[0]):
        print(s)
        wm = wms[s]
        tnms = ids[s]
        subgraphs = {}
        f = res_df['filtration'].iloc[s]
        m = dion.homology_persistence(f)
        dgm = dion.init_diagrams(m, f)[0]
        dgms.append(dgm)
        for i, c in enumerate(m):
            if len(c) == 2:
                w = f[i].data
                if (tnms[f[c[0].index][0]], tnms[f[c[1].index][0]]) in wm:
                    w = wm[(tnms[f[c[0].index][0]], tnms[f[c[1].index][0]])]
                elif (tnms[f[c[1].index][0]], tnms[f[c[0].index][0]]) in wm:
                    w = wm[(tnms[f[c[1].index][0]], tnms[f[c[0].index][0]])]
#                 else:
#                     print((tnms[f[c[0].index][0]],tnms[f[c[1].index][0]]))
#                     raise Exception('NO WM!')
                if False:  #tnms[f[c[0].index][0]] in subgraphs:
                    subgraphs[tnms[f[c[0].index][0]]].add_edge(
                        tnms[f[c[0].index][0]],
                        tnms[f[c[1].index][0]],
                        weight=w)
                else:
                    eaten = False
                    for k, v in subgraphs.items():
                        if v.has_node(tnms[f[c[0].index][0]]):
                            if tnms[f[c[1].index][0]] in subgraphs:
                                v.add_node(tnms[f[c[1].index][0]])


#                                 subgraphs[k] = nx.union(v, subgraphs[tnms[f[c[1].index][0]]])
                            else:
                                v.add_edge(tnms[f[c[0].index][0]],
                                           tnms[f[c[1].index][0]],
                                           weight=w)
                            eaten = True
                            break
                    if not eaten:
                        g = nx.Graph()
                        g.add_edge(tnms[f[c[0].index][0]],
                                   tnms[f[c[1].index][0]],
                                   weight=w)
                        subgraphs[tnms[f[c[0].index][0]]] = g

        sample_graphs.append(subgraphs)
        lifetimes.append(create_lifetimes(f, subgraphs, dgm, ids[s]))
    return sample_graphs, dgms, lifetimes
示例#23
0
def compute_diagrams(data):

    diagrams = []
    for i in range(len(data)):
        # print("Processing data: " + str(i))
        filtration = dion.fill_rips(data[i], 2, 3.0)
        homology = dion.homology_persistence(filtration)
        diagram = dion.init_diagrams(homology, filtration)
        diagrams.append(diagram[1])
    # print()

    return diagrams
示例#24
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 persistent(self):
        """
        This method is used to create dionysus persistent homology
        implementation of given vectors
        :return: dionysus diagrams
        """
        vectors = self._get_vectors()

        f_lower_star = dn.fill_freudenthal(vectors)
        p = dn.homology_persistence(f_lower_star)
        dgms = dn.init_diagrams(p, f_lower_star)

        return dgms
示例#26
0
    def persistent(self):

        """
        This method is used to create dionysus persistent homology
        implementation of given vectors
        :return: dionysus diagrams
        """
        vectors = self._get_vectors()

        f_lower_star = dn.fill_freudenthal(vectors)
        p = dn.homology_persistence(f_lower_star)
        dgms = dn.init_diagrams(p, f_lower_star)

        return dgms
示例#27
0
def geomill(arr, skeletondim=2, elevation=45, azimuth=30):
    #3D illustration
    fig = pyplot.figure()
    ax = Axes3D(fig)
    ax.view_init(elev=elevation, azim=azimuth)
    ax.scatter(arr[:, 0], arr[:, 1], arr[:, 2])
    pyplot.show()
    #VR complex
    filtration = d.fill_rips(circ, skeletondim, 2)
    #persistent homology
    ph = d.homology_persistence(filtration)
    dgms = d.init_diagrams(ph, filtration)
    d.plot.plot_bars(dgms[1], show=True)
    return ax, dgms
示例#28
0
    def random_choice_homology(self,
                               choice_size=1,
                               replace_bool=False,
                               root=None,
                               plot=None,
                               show=True):
        colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k']
        if root == None:
            choice_index = np.random.choice(len(self.dim2_fill_list),
                                            size=choice_size,
                                            replace=replace_bool)
            dim2_fill_list = [self.dim2_fill_list[i] for i in choice_index]
            dim2_fill_lens = np.array(
                [len(dim2_fill) for dim2_fill in dim2_fill_list])
            axes_depo = [
                np.sum(dim2_fill_lens[:i])
                for i in range(len(dim2_fill_lens) + 1)
            ]
            dgms_lists = []
            for count, dim2_fill in enumerate(dim2_fill_list):
                print(f'loading dim2_fill {count}')
                fig, axes = plt.subplots(4, 4, figsize=(12, 20))
                one_dim_axes = axes.ravel()
                dim2_fill_dgms = []
                for i, fill in enumerate(dim2_fill):
                    p = d.homology_persistence(fill)
                    dgms = d.init_diagrams(p, fill)
                    dim2_fill_dgms.append(dgms)
                    for k, dgm in enumerate(dgms):
                        style = {'color': colors[k]}
                        if fill == dim2_fill[-1]:
                            style = {
                                'color': colors[k],
                                'label': 'dim = ' + str(k)
                            }

                        try:
                            d.plot.plot_diagram(dgm,
                                                ax=one_dim_axes[i],
                                                pt_style=style)

                        except ValueError:
                            continue
                dgms_lists.append(dim2_fill_dgms)
                fig.legend()
            if show == True:
                plt.show()

        return dgms_lists
示例#29
0
def EPH_fast(vertex_values, simplices):

    N = len(vertex_values)
    order2vertex = np.argsort(vertex_values)
    vertex2order = np.empty(N, dtype=int)
    vertex2order[order2vertex] = np.arange(N)

    f_ord = [(s, max(vertex2order[v] for v in s))
             for s in simplices]  #takes max
    f_ext = [([-1] + s, min(vertex2order[v] for v in s))
             for s in simplices]  #takes min

    f_ord.sort(key=lambda s: (s[1], len(s[0])))
    f_ext.sort(key=lambda s: (-s[1], len(s[0])))

    full_filtration = [([-1], -float('inf'))] + f_ord + f_ext

    f = dionysus.Filtration(full_filtration)
    m = dionysus.homology_persistence(f)

    dgms = dionysus.init_diagrams(m, f)

    H0 = list(dgms[0])
    H0.remove(max(H0, key=lambda x: x.death))
    Dgm0b = [order2vertex[int(pt.birth)] for pt in H0]
    Dgm0d = [order2vertex[int(pt.death)] for pt in H0]

    H1 = list(dgms[1])
    index_cutoff = len(f_ord) + 1

    Dgm1extb = [
        order2vertex[int(pt.birth)] for pt in H1 if pt.data < index_cutoff
    ]
    Dgm1extd = [
        order2vertex[int(pt.death)] for pt in H1 if pt.data < index_cutoff
    ]

    Dgm0b += [
        order2vertex[int(pt.birth)] for pt in H1 if pt.data >= index_cutoff
    ]
    Dgm0d += [
        order2vertex[int(pt.death)] for pt in H1 if pt.data >= index_cutoff
    ]

    return [[Dgm0b, Dgm0d], [Dgm1extd, Dgm1extb]]
def compute_ph_spatial_edge_dem_face_from_percent(spatial_gexf,
                                                  dem_csv,
                                                  idstring,
                                                  xstring,
                                                  ystring,
                                                  attrstrings,
                                                  numfils=20):
    """runs persistent homology on the simplicial complex with edges from a spatial graph and faces from demographic distance. Requires
    demographic data to be percentile

    :param spatial_gexf: path to gexf of rook adjacency
    :param dem_csv: path to csv with demographic data
    :param idstring:
    :param xstring:
    :param ystring:
    :param attrstrings: list of desired demographic attributes
    :param numfils:
    :return:
    """
    Gspatial = nx.read_gexf(spatial_gexf)
    Gdem = build_adj_matrix_percent(dem_csv, idstring, xstring, ystring,
                                    attrstrings)
    pos = nx.get_node_attributes(Gdem, 'pos')
    xcoord = {k: u for k, (u, v) in pos.items()}
    ycoord = {k: v for k, (u, v) in pos.items()}

    nx.set_node_attributes(Gspatial, pos, 'pos')
    nx.set_node_attributes(Gspatial, xcoord, 'xcoord')
    nx.set_node_attributes(Gspatial, ycoord, 'ycoord')
    build_spatial_graph_with_weights(Gspatial, 'xcoord', 'ycoord')

    weights = nx.get_edge_attributes(Gspatial, 'weight')
    maxfil = np.median([w for w in weights.values()]) / 10.
    faces_dem = get_faces_from_distance(Gdem, maxfil)

    dims, idxs, times = get_dims_and_idx_from_multiple(Gspatial, faces_dem,
                                                       maxfil, numfils)
    plot_simplexes_from_multiple(Gdem, dims, times)

    filtration = build_filtered_complex(dims, idxs, times)

    m = d.homology_persistence(filtration)

    dgms = d.init_diagrams(m, filtration)
    d.plot.plot_bars(dgms[1], show=True)
示例#31
0
def EPH_fast3(vertex_values, simplices):

    N = len(vertex_values)
    order2vertex = np.argsort(vertex_values)
    vertex2order = np.empty(N, dtype=int)
    vertex2order[order2vertex] = np.arange(N)

    f_ord = [(s, max(vertex2order[v] for v in s))
             for s in simplices]  #takes max
    f_ext = [([-1] + s, min(vertex2order[v] for v in s))
             for s in simplices]  #takes min

    f_ord.sort(key=lambda s: (s[1], len(s[0])))
    f_ext.sort(key=lambda s: (-s[1], len(s[0])))

    full_filtration = [([-1], -float('inf'))] + f_ord + f_ext

    f = dionysus.Filtration(full_filtration)
    m = dionysus.homology_persistence(f)

    dgms = dionysus.init_diagrams(m, f)

    H0 = list(dgms[0])
    H0.remove(max(H0, key=lambda x: x.death))
    Dgm0, Dgm1 = [[], []], [[], []]

    for pt in H0:

        Dgm0[0].append(order2vertex[int(pt.birth)])
        Dgm0[1].append(order2vertex[int(pt.death)])

    H1 = list(dgms[1])
    index_cutoff = len(f_ord) + 1

    for pt in H1:
        if pt.data < index_cutoff:
            Dgm1[0].append(order2vertex[int(pt.death)])
            Dgm1[1].append(order2vertex[int(pt.birth)])
        else:
            Dgm0[0].append(order2vertex[int(pt.death)])
            Dgm0[1].append(order2vertex[int(pt.birth)])

    return Dgm0, Dgm1