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)
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
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]
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
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()
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)
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
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
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]
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
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]
def get_persistence(f): """ Args: f: filtration Returns: m: reduced boundary matrix """ m = d.homology_persistence(f) return m
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)
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
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
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
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
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
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
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
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
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)
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