def _3d_tetrahedrons(precision): points = 10 * np.random.rand(10, 3) alpha = gd.AlphaComplex(points=points, precision=precision) st_alpha = alpha.create_simplex_tree(default_filtration_value=False) # New AlphaComplex for get_point to work delaunay = gd.AlphaComplex(points=points, precision=precision) st_delaunay = delaunay.create_simplex_tree(default_filtration_value=True) delaunay_tetra = [] for sk in st_delaunay.get_skeleton(4): if len(sk[0]) == 4: tetra = [ delaunay.get_point(sk[0][0]), delaunay.get_point(sk[0][1]), delaunay.get_point(sk[0][2]), delaunay.get_point(sk[0][3]) ] delaunay_tetra.append(sorted(tetra, key=lambda tup: tup[0])) alpha_tetra = [] for sk in st_alpha.get_skeleton(4): if len(sk[0]) == 4: tetra = [ alpha.get_point(sk[0][0]), alpha.get_point(sk[0][1]), alpha.get_point(sk[0][2]), alpha.get_point(sk[0][3]) ] alpha_tetra.append(sorted(tetra, key=lambda tup: tup[0])) # Check the tetrahedrons from one list are in the second one assert len(alpha_tetra) == len(delaunay_tetra) for tetra_from_del in delaunay_tetra: assert tetra_from_del in alpha_tetra
def persistent_homology( data: np.ndarray, plot: bool = False, tikzplot: bool = False, maxEdgeLength: int = 42, maxDimension: int = 10, maxAlphaSquare: float = 1e12, homologyCoeffField: int = 2, minPersistence: float = 0, filtration: str = ["alphaComplex", "vietorisRips", "tangential"], ): """ **Create persistence diagram.** This function computes the persistent homology of a dataset upon a filtration of a chosen simplicial complex. It can be used for plotting or scientific displaying of persistent homology classes. + param **data**: data, type `np.ndarray`. + param **plot**: whether or not to plot the persistence diagram using matplotlib, type `bool`. + param **tikzplot**: whether or not to create a tikz file from persistent homology, type `bool`. + param **maxEdgeLength**: maximal edge length of simplicial complex, type `int`. + param **maxDimension**: maximal dimension of simplicial complex, type `int`. + param **maxAlphaSquare**: alpha square value for Delaunay complex, type `float`. + param **homologyCoeffField**: integers, cyclic moduli integers, rationals enumerated, type `int`. + param **minPersistence**: minimal persistence of homology class, type `float`. + param **filtration**: the used filtration to calculate persistent homology, type `str`. + return **np.ndarray**: data points, type `np.ndarray`. """ dataShape = data.shape elementSize = len(data[0].flatten()) reshapedData = data[0].reshape((int(elementSize / 2), 2)) if filtration == "vietorisRips": simComplex = gd.RipsComplex( points=reshapedData, max_edge_length=maxEdgeLength).create_simplex_tree( max_dimension=maxDimension) elif filtration == "alphaComplex": simComplex = gd.AlphaComplex(points=reshapedData).create_simplex_tree( max_alpha_square=maxAlphaSquare) elif filtration == "tangential": simComplex = gd.AlphaComplex(points=reshapedData, intrinsic_dimension=len(data.shape) - 1).compute_tangential_complex() persistenceDiagram = simComplex.persistence( homology_coeff_field=homologyCoeffField, min_persistence=minPersistence) if plot == True: gd.plot_persistence_diagram(persistenceDiagram) plt.show() elif tikzplot == True: gd.plot_persistence_diagram(persistenceDiagram) plt.title("Persistence landscape.") tikz.save("persistentHomology_" + filtration + ".tex") return persistenceDiagram
def compute_persistence_landscape( data: np.ndarray, res: int = 1000, persistenceIntervals: int = 1, maxAlphaSquare: float = 1e12, filtration: str = ["alphaComplex", "vietorisRips", "tangential"], maxDimensions: int = 10, edgeLength: float = 1, plot: bool = False, smoothen: bool = False, sigma: int = 3, ) -> np.ndarray: """ **A function for computing persistence landscapes for 2D images.** This function computes the filtration of a 2D image dataset, the simplicial complex, the persistent homology and then returns the persistence landscape as array. It takes the resolution of the landscape as parameter, the maximum size for `alphaSquare` and options for certain filtrations. + param **data**: data set, type `np.ndarray`. + param **res**: resolution, default is `1000`, type `int`. + param **persistenceIntervals**: interval for persistent homology, default is `1e12`,type `float`. + param **maxAlphaSquare**: max. parameter for delaunay expansion, type `float`. + param **filtration**: alphaComplex, vietorisRips, cech, delaunay, tangential, type `str`. + param **maxDimensions**: only needed for VietorisRips, type `int`. + param **edgeLength**: only needed for VietorisRips, type `float`. + param **plot**: whether or not to plot, type `bool`. + param **smoothen**: whether or not to smoothen the landscapes, type `bool`. + param **sigma**: smoothing factor for gaussian mixtures, type `int`. + return **landscapeTransformed**: persistence landscape, type `np.ndarray`. """ if filtration == "alphaComplex": simComplex = gd.AlphaComplex(points=data).create_simplex_tree( max_alpha_square=maxAlphaSquare) elif filtration == "vietorisRips": simComplex = gd.RipsComplex( points=data_A_sample, max_edge_length=edgeLength).create_simplex_tree( max_dimension=maxDimensions) elif filtration == "tangential": simComplex = gd.AlphaComplex(points=data, intrinsic_dimension=len(data.shape) - 1).compute_tangential_complex() persistenceDiagram = simComplex.persistence() landscape = gd.representations.Landscape(resolution=res) landscapeTransformed = landscape.fit_transform( [simComplex.persistence_intervals_in_dimension(persistenceIntervals)]) return landscapeTransformed
def _delaunay_complex(precision): point_list = [[0, 0], [1, 0], [0, 1], [1, 1]] filtered_alpha = gd.AlphaComplex(points=point_list, precision=precision) simplex_tree = filtered_alpha.create_simplex_tree( default_filtration_value=True) assert simplex_tree.num_simplices() == 11 assert simplex_tree.num_vertices() == 4 assert point_list[0] == filtered_alpha.get_point(0) assert point_list[1] == filtered_alpha.get_point(1) assert point_list[2] == filtered_alpha.get_point(2) assert point_list[3] == filtered_alpha.get_point(3) try: filtered_alpha.get_point(4) == [] except IndexError: pass else: assert False try: filtered_alpha.get_point(125) == [] except IndexError: pass else: assert False for filtered_value in simplex_tree.get_filtration(): assert math.isnan(filtered_value[1]) for filtered_value in simplex_tree.get_star([0]): assert math.isnan(filtered_value[1]) for filtered_value in simplex_tree.get_cofaces([0], 1): assert math.isnan(filtered_value[1])
def show(count): mlab.clf() directory = "Cech/%02d/" % count points = np.loadtxt(directory + "points.csv", delimiter=",") (low, up) = _get_threshold(directory + "threshold.txt") ac = gudhi.AlphaComplex(points) st = ac.create_simplex_tree(max_alpha_square=(low * low + up * up) / 2) [iA, iB, iC, iD, iX] = list(range(5)) triangles = [] triangles.append([iA, iB, iX]) # ABX triangles.append([iA, iC, iX]) # ACX triangles.append([iB, iD, iX]) # BDX triangles.append([iC, iD, iX]) # CDX # triangles = [s[0] for s in st.get_skeleton(2) if len(s[0])== 3] # print([s[0] for s in st.get_skeleton(2)]) # edges = [] # for s in st.get_skeleton(1): # e = s[0] # if len(e) == 2: # edges.append(points[[e[0], e[1]]]) edges = [] edges.append(points[[iA, iB]]) # AB edges.append(points[[iB, iC]]) # BC edges.append(points[[iC, iA]]) # CA edges.append(points[[iA, iX]]) # AX edges.append(points[[iX, iD]]) # XD edges.append(points[[iD, iC]]) # DC edges.append(points[[iC, iX]]) # CX edges.append(points[[iX, iB]]) # XB edges.append(points[[iB, iD]]) # BD mlab.triangular_mesh(points[:, 0], points[:, 1], points[:, 2], triangles) for e in edges: mlab.plot3d(e[:, 0], e[:, 1], e[:, 2], tube_radius=None)
def compareAlpha(): import gudhi np.random.seed(2) # Make a 4-sphere in 5 dimensions X = np.random.randn(100, 5) tic = time.time() Is1 = alpha_filtration(X) phattime = time.time() - tic print("Phat Time: %.3g" % phattime) tic = time.time() alpha_complex = gudhi.AlphaComplex(points=X.tolist()) simplex_tree = alpha_complex.create_simplex_tree(max_alpha_square=np.inf) pers = simplex_tree.persistence() gudhitime = time.time() - tic Is2 = convertGUDHIPD(pers, len(Is1)) print("GUDHI Time: %.3g" % gudhitime) I1 = Is1[len(Is1) - 1] I2 = Is2[len(Is2) - 1] plt.scatter(I1[:, 0], I1[:, 1]) plt.scatter(I2[:, 0], I2[:, 1], 40, marker="x") plt.show()
def compute_persistence(edge_length=max_edge_length, filtration='rips'): if filtration not in ('rips', 'alpha'): raise ValueError('Please indicate filtration = "rips" or filtration = "alpha"') a, b, c, labels = read_data() time_series = a + b + c simplex_trees = [0] * len(time_series) print('Computing persistence diagrams with {} filtration...'.format(filtration)) for i, ts in enumerate(time_series): if not i % 50: print('Computing persistence diagram {}/{}'.format(i, len(time_series))) if filtration is 'rips': cplx = gudhi.RipsComplex(points=ts, max_edge_length=edge_length) simplex_tree = cplx.create_simplex_tree(max_dimension=2) else: cplx = gudhi.AlphaComplex(points=ts) simplex_tree = cplx.create_simplex_tree() simplex_trees[i] = simplex_tree simplex_tree.persistence(persistence_dim_max=False) simplex_tree.write_persistence_diagram('intermediary_data/persistence_diagrams/{}'.format(i)) return simplex_trees
def ACPlotDiags(pt_cloud, homologyDegree = 1): alpha_complex = gd.AlphaComplex(points=pt_cloud) simplex_tree3 = alpha_complex.create_simplex_tree(max_alpha_square=60.0) diag3 = simplex_tree3.persistence(homology_coeff_field=2, min_persistence=0) gd.plot_persistence_diagram(diag3) diag = simplex_tree3.persistence_intervals_in_dimension(homologyDegree) return diag
def alpha_complex(pts): sc = gd.AlphaComplex(points = pts) st = sc.create_simplex_tree() points = np.array([sc.get_point(i) for i in range(st.num_vertices())]) return dict( points = points, simplex_tree = st )
def _3d_points_on_a_plane(precision, default_filtration_value): alpha = gd.AlphaComplex(off_file='alphacomplexdoc.off', precision=precision) simplex_tree = alpha.create_simplex_tree( default_filtration_value=default_filtration_value) assert simplex_tree.dimension() == 2 assert simplex_tree.num_vertices() == 7 assert simplex_tree.num_simplices() == 25
def StructureW(X, F, distances, edge_max, dimension_max = 2): ''' Compute the Rips-W filtration of a point cloud, weighted with the DTM values st = StructureW(X, F, distances, dimension_max = 2) Input: + X: a nxd numpy array representing n points in R^d + F: the values of a function over the set X + dim: the dimension of the skeleton of the Rips (dim_max = 1 or 2) Output: + st: a gd.SimplexTree with the constructed filtration (require Gudhi) ''' nPts = X.shape[0] alpha_complex = gd.AlphaComplex(points=X) st = alpha_complex.create_simplex_tree() stDTM = gd.SimplexTree() for simplex in st.get_filtration(): if len(simplex[0])==1: i = simplex[0][0] stDTM.insert([i], filtration = F[i]) if len(simplex[0])==2: i = simplex[0][0] j = simplex[0][1] if (j < i): filtr = (distances[i][j] + F[i] + F[j])/2 else: filtr = (distances[j][i] + F[i] + F[j])/2 stDTM.insert([i,j], filtration = filtr) stDTM.expansion(dimension_max) st = stDTM """ st = gd.SimplexTree() for i in range(nPts): st.insert([i], filtration = F[i]) for i in range(nPts): for j in range(i): if distances[i][j]<edge_max: val = (distances[i][j] + F[i] + F[j])/2 filtr = max([F[i], F[j], val]) st.insert([i,j], filtration = filtr) st.expansion(dimension_max) """ result_str = 'Complex W is of dimension ' + repr(st.dimension()) + ' - ' + \ repr(st.num_simplices()) + ' simplices - ' + \ repr(st.num_vertices()) + ' vertices.' return st
def construct_alpha(self, p): alpha_complex = gudhi.AlphaComplex(self.pts) alpha = alpha_complex.create_simplex_tree() val = alpha.get_filtration() simplices = set() for v in val: if np.sqrt( v[1] ) * 2 <= self.epsilon: #circumradius must be converted to diameter and within the filtration parameter simplices.add(tuple(v[0])) return simplices
def _infinite_alpha(precision): point_list = [[0, 0], [1, 0], [0, 1], [1, 1]] alpha_complex = gd.AlphaComplex(points=point_list, precision=precision) assert alpha_complex.__is_defined() == True simplex_tree = alpha_complex.create_simplex_tree() assert simplex_tree.__is_persistence_defined() == False assert simplex_tree.num_simplices() == 11 assert simplex_tree.num_vertices() == 4 assert list(simplex_tree.get_filtration()) == [ ([0], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0), ([0, 1], 0.25), ([0, 2], 0.25), ([1, 3], 0.25), ([2, 3], 0.25), ([1, 2], 0.5), ([0, 1, 2], 0.5), ([1, 2, 3], 0.5), ] assert simplex_tree.get_star([0]) == [ ([0], 0.0), ([0, 1], 0.25), ([0, 1, 2], 0.5), ([0, 2], 0.25), ] assert simplex_tree.get_cofaces([0], 1) == [([0, 1], 0.25), ([0, 2], 0.25)] assert point_list[0] == alpha_complex.get_point(0) assert point_list[1] == alpha_complex.get_point(1) assert point_list[2] == alpha_complex.get_point(2) assert point_list[3] == alpha_complex.get_point(3) try: alpha_complex.get_point(4) == [] except IndexError: pass else: assert False try: alpha_complex.get_point(125) == [] except IndexError: pass else: assert False
def _safe_alpha_persistence_comparison(precision): #generate periodic signal time = np.arange(0, 10, 1) signal = [math.sin(x) for x in time] delta = math.pi delayed = [math.sin(x + delta) for x in time] #construct embedding embedding1 = [[signal[i], -signal[i]] for i in range(len(time))] embedding2 = [[signal[i], delayed[i]] for i in range(len(time))] #build alpha complex and simplex tree alpha_complex1 = gd.AlphaComplex(points=embedding1, precision=precision) simplex_tree1 = alpha_complex1.create_simplex_tree() alpha_complex2 = gd.AlphaComplex(points=embedding2, precision=precision) simplex_tree2 = alpha_complex2.create_simplex_tree() diag1 = simplex_tree1.persistence() diag2 = simplex_tree2.persistence() for (first_p, second_p) in zip_longest(diag1, diag2): assert first_p[0] == pytest.approx(second_p[0]) assert first_p[1] == pytest.approx(second_p[1])
def alpha_animation(X, fps,triangle_sound,edge_sound,birth_sound,death_sound,scales): """ Create an animation of an alpha filtration of a 2D point cloud with the point cloud on the left and a plot on the right Parameters ---------- X: ndarray(N, 2) A point cloud scales: ndarray(T) Scales to use in each frame of the animation. If left blank, the program will choose 100 uniformly spaced scales between the minimum and maximum events in birth/death """ alpha_complex = gudhi.AlphaComplex(points=X) simplex_tree = alpha_complex.create_simplex_tree() filtration = [(f[0], np.sqrt(f[1])) for f in simplex_tree.get_filtration()] diag = simplex_tree.persistence() dgmsalpha = gudhi2persim(diag)[0:2] if scales.size == 0: # Choose some default scales based on persistence smin = min(np.min(dgmsalpha[0]), np.min(dgmsalpha[1])) smax = max(np.max(dgmsalpha[0][np.isfinite(dgmsalpha[0])]), np.max(dgmsalpha[1])) rg = smax-smin smin = max(0, smin-0.05*rg) smax += 0.05*rg scales = np.linspace(smin, smax, 100) audio = make_audio_array(scales,filtration,dgmsalpha[1],fps,triangle_sound,edge_sound,birth_sound,death_sound) # plt.figure(figsize=(12, 6)) # for frame, alpha in enumerate(scales): # plt.clf() # plt.subplot(121) # draw_alpha(X, filtration, alpha, True) # plt.title("$\\alpha = {:.3f}$".format(alpha)) # plt.subplot(122) # plot_diagrams(dgmsalpha) # plt.plot([-0.01, alpha], [alpha, alpha], 'gray', linestyle='--', linewidth=1, zorder=0) # plt.plot([alpha, alpha], [alpha, 1.0], 'gray', linestyle='--', linewidth=1, zorder=0) # plt.text(alpha+0.01, alpha-0.01, "{:.3f}".format(alpha)) # plt.title("Persistence Diagram") # plt.savefig("{}.png".format(frame), bbox_inches='tight') return audio
def _compute_pd(X, hdim=1, min_persistence=0.0001, mode="alpha", rotate=False): if mode == "alpha": ac = gd.AlphaComplex(points=X) st = ac.create_simplex_tree() elif mode == "rips": ac = gd.RipsComplex(points=X) st = ac.create_simplex_tree(max_dimension=2) pers = st.persistence(min_persistence=min_persistence) h1 = st.persistence_intervals_in_dimension(hdim) if mode == "alpha": h1 = np.sqrt(np.array(h1)) if rotate: h1[:, 1] = h1[:, 1] - h1[:, 0] return h1 else: return np.array(h1) / 2 # to make it comparable with Cech
def AlphaWeightedRipsFiltration(X, F, p, dimension_max=2, filtration_max=np.inf): ''' /!\ this is a heuristic method, to speed-up the computation It computes the weighted Rips filtration as a subset of the alpha complex Input: X: a nxd numpy array representing n points in R^d F: an array of length n, representing the values of a function on X p: a parameter in [0, +inf) or np.inf filtration_max: maximal filtration value of simplices when building the complex dimension_max: maximal dimension to expand the complex Output: st: a gudhi.SimplexTree ''' N_tot = X.shape[0] distances = euclidean_distances(X) # compute the pairwise distances st_alpha = gudhi.AlphaComplex(points=X).create_simplex_tree() st = gudhi.SimplexTree() # create an empty simplex tree for simplex in st_alpha.get_skeleton( 2): # add vertices with corresponding filtration value if len(simplex[0]) == 1: i = simplex[0][0] st.insert([i], filtration=F[i]) if len(simplex[0] ) == 2: # add edges with corresponding filtration value i = simplex[0][0] j = simplex[0][1] value = Filtration_value(p, F[i], F[j], distances[i][j]) st.insert([i, j], filtration=value) st.expansion(dimension_max) # expand the complex result_str = 'Alpha Weighted Rips Complex is of dimension '+repr(st.dimension())+' - '+ \ repr(st.num_simplices())+' simplices - '+ \ repr(st.num_vertices())+' vertices.'+ \ ' Filtration maximal value is '+str(filtration_max)+'.' print(result_str) return st
def AlphaDTMFiltration(X, m, p, dimension_max=2, filtration_max=np.inf): ''' /!\ this is a heuristic method, that speeds-up the computation. It computes the DTM-filtration seen as a subset of the Delaunay filtration. Input: X (np.array): size Nxn, representing N points in R^n. m (float): parameter of the DTM, in [0,1). p (float): parameter of the DTM-filtration, in [0, +inf) or np.inf. dimension_max (int, optional): maximal dimension to expand the complex. filtration_max (float, optional): maximal filtration value of the filtration. Output: st (gudhi.SimplexTree): the alpha-DTM filtration. ''' N_tot = X.shape[0] alpha_complex = gudhi.AlphaComplex(points=X) st_alpha = alpha_complex.create_simplex_tree() Y = np.array([alpha_complex.get_point(i) for i in range(N_tot)]) distances = euclidean_distances(Y) #computes the pairwise distances DTM_values = DTM( X, Y, m ) #/!\ in 3D, gudhi.AlphaComplex may change the ordering of the points st = gudhi.SimplexTree() #creates an empty simplex tree for simplex in st_alpha.get_skeleton( 2): #adds vertices with corresponding filtration value if len(simplex[0]) == 1: i = simplex[0][0] st.insert([i], filtration=DTM_values[i]) if len(simplex[0] ) == 2: #adds edges with corresponding filtration value i = simplex[0][0] j = simplex[0][1] value = WeightedRipsFiltrationValue(p, DTM_values[i], DTM_values[j], distances[i][j]) st.insert([i, j], filtration=value) st.expansion(dimension_max) #expands the complex result_str = 'Alpha Weighted Rips Complex is of dimension ' + repr(st.dimension()) + ' - ' + \ repr(st.num_simplices()) + ' simplices - ' + \ repr(st.num_vertices()) + ' vertices.' +\ ' Filtration maximal value is ' + str(filtration_max) + '.' print(result_str) return st
def computeSimplex(self, *args, **kwargs): import gudhi import random as r import numpy as np nPoints = kwargs.get('nPoints', self.nPoints) targetCluster = kwargs.get('targetCluster', [1]) pointListTemp = [] for point in self.points: if point.cluster in targetCluster: pointListTemp.append(np.array(point.coordinates)) pointList = [] for point in pointListTemp: random = r.random() if random <= nPoints/len(pointListTemp): pointList.append(point) if len(pointList) == 0: return [] point_complex = gudhi.AlphaComplex(points=pointList) simplex_tree = point_complex.create_simplex_tree() return simplex_tree
def _filtered_alpha(precision): point_list = [[0, 0], [1, 0], [0, 1], [1, 1]] filtered_alpha = gd.AlphaComplex(points=point_list, precision=precision) simplex_tree = filtered_alpha.create_simplex_tree(max_alpha_square=0.25) assert simplex_tree.num_simplices() == 8 assert simplex_tree.num_vertices() == 4 assert point_list[0] == filtered_alpha.get_point(0) assert point_list[1] == filtered_alpha.get_point(1) assert point_list[2] == filtered_alpha.get_point(2) assert point_list[3] == filtered_alpha.get_point(3) try: filtered_alpha.get_point(4) == [] except IndexError: pass else: assert False try: filtered_alpha.get_point(125) == [] except IndexError: pass else: assert False assert list(simplex_tree.get_filtration()) == [ ([0], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0), ([0, 1], 0.25), ([0, 2], 0.25), ([1, 3], 0.25), ([2, 3], 0.25), ] assert simplex_tree.get_star([0]) == [([0], 0.0), ([0, 1], 0.25), ([0, 2], 0.25)] assert simplex_tree.get_cofaces([0], 1) == [([0, 1], 0.25), ([0, 2], 0.25)]
def alpha_persistence_from_point_cloud(point_cloud, min_persistence=0): """Compute the persistence diagram of the alpha shape filtration built on top of a 3D point cloud. Parameters ---------- point_cloud : array, shape = [n_points, 3] 3D point cloud. min_persistence : int, optional Minimum persistence value to take into account. Returns ------- list(tuple) Persistence diagrams as a list of points and the corresponding dimension [(dim, (a, b))]. """ alpha_complex = gudhi.AlphaComplex(points=point_cloud) simplex_tree = alpha_complex.create_simplex_tree(max_alpha_square=60.0) diag = simplex_tree.persistence(homology_coeff_field=2, min_persistence=min_persistence) return diag
def AlphaComplex(X, filtration_max=np.inf): ''' Build the Delaunay filtration over X, until time filtration_max. Input: X (np.array): size (N x M), representing a point cloud of R^M. filtration_max (float): filtration maximal value. Output: st_alpha (gudhi.SimplexTree): the Delaunay filtration of X. Example: X = SampleOnCircleNormalCheck(N = 30, gamma=1, sd=0) st = velour.AlphaComplex(X) ---> Alpha-complex is of dimension 5 - 8551 simplices - 30 vertices. ''' st_alpha = gudhi.AlphaComplex( X).create_simplex_tree() #create an alpha-complex st_alpha.prune_above_filtration(filtration_max) result_str = 'Alpha-complex is of dimension ' + repr(st_alpha.dimension()) + ' - ' + \ repr(st_alpha.num_simplices()) + ' simplices - ' + \ repr(st_alpha.num_vertices()) + ' vertices.' print(result_str, flush=True) return st_alpha
def make_landscape(df, mas=50, xm=20, step=1000): # Alpha complex ----------------------------------------------------------- ac = gd.AlphaComplex(points=df.values) # Simplex tree, persistence ----------------------------------------------- simplex_tree = ac.create_simplex_tree(max_alpha_square=mas) pers = simplex_tree.persistence() # Discretize landscapes --------------------------------------------------- # First dimension D1 = landscapes_approx(simplex_tree.persistence_intervals_in_dimension(0), x_min=0, x_max=xm, nb_steps=step, nb_landscapes=3) # Second dimension D2 = landscapes_approx(simplex_tree.persistence_intervals_in_dimension(1), x_min=0, x_max=xm, nb_steps=step, nb_landscapes=3) L1, L2, L3 = D1 L4, L5, L6 = D2 # Combine L = np.concatenate([L1, L2, L3, L4, L5, L6]) return ({'land': L, 'pers': pers})
def example(self): import gudhi points = [1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17] alpha_complex = gudhi.AlphaComplex( points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]]) simplex_tree = alpha_complex.create_simplex_tree() result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) fmt = '%s:(%s):%.2f' for filtered_value in simplex_tree.get_filtration(): str_line = fmt % tuple( (filtered_value[0], "a,b,c", filtered_value[1])) qsimplex, point, filt = str_line.split(":") inner_simplex = qsimplex[1:-1] if inner_simplex.find(",") != -1: point = "" print(fmt % tuple((filtered_value[0], point, filtered_value[1]))) print("qsimplex = {0}, point = {1}, filt = {2}".format( qsimplex, point, filt))
def generate_diagrams_and_features(dataset, path_dataset=""): dataset_parameters = get_parameters(dataset) dataset_type = dataset_parameters["data_type"] if "REDDIT" in dataset: print("Unfortunately, REDDIT data are not available yet for memory issues.\n") print("Moreover, the link we used to download the data,") print("http://www.mit.edu/~pinary/kdd/datasets.tar.gz") print("is down at the commit time (May 23rd).") print("We will update this repository when we figure out a workaround.") return path_dataset = "./data/" + dataset + "/" if not len(path_dataset) else path_dataset if os.path.isfile(path_dataset + dataset + ".hdf5"): os.remove(path_dataset + dataset + ".hdf5") diag_file = h5py.File(path_dataset + dataset + ".hdf5", "w") list_filtrations = dataset_parameters["filt_names"] [diag_file.create_group(str(filtration)) for filtration in dataset_parameters["filt_names"]] if dataset_type == "graph": list_hks_times = np.unique([filtration.split("_")[1] for filtration in list_filtrations]) # preprocessing pad_size = 1 for graph_name in os.listdir(path_dataset + "mat/"): A = np.array(loadmat(path_dataset + "mat/" + graph_name)["A"], dtype=np.float32) pad_size = np.max((A.shape[0], pad_size)) feature_names = ["eval"+str(i) for i in range(pad_size)] + [name+"-percent"+str(i) for name, i in itertools.product([f for f in list_hks_times if "hks" in f], 10*np.arange(11))] features = pd.DataFrame(index=range(len(os.listdir(path_dataset + "mat/"))), columns=["label"] + feature_names) for idx, graph_name in enumerate((os.listdir(path_dataset + "mat/"))): name = graph_name.split("_") gid = int(name[name.index("gid") + 1]) - 1 A = np.array(loadmat(path_dataset + "mat/" + graph_name)["A"], dtype=np.float32) num_vertices = A.shape[0] label = int(name[name.index("lb") + 1]) L = csgraph.laplacian(A, normed=True) egvals, egvectors = eigh(L) eigenvectors = np.zeros([num_vertices, pad_size]) eigenvals = np.zeros(pad_size) eigenvals[:min(pad_size, num_vertices)] = np.flipud(egvals)[:min(pad_size, num_vertices)] eigenvectors[:, :min(pad_size, num_vertices)] = np.fliplr(egvectors)[:, :min(pad_size, num_vertices)] graph_features = [] graph_features.append(eigenvals) for fhks in list_hks_times: hks_time = float(fhks.split("-")[0]) filtration_val = hks_signature(egvectors, egvals, time=hks_time) dgmOrd0, dgmExt0, dgmRel1, dgmExt1 = apply_graph_extended_persistence(A, filtration_val) diag_file["Ord0_" + str(hks_time) + "-hks"].create_dataset(name=str(gid), data=dgmOrd0) diag_file["Ext0_" + str(hks_time) + "-hks"].create_dataset(name=str(gid), data=dgmExt0) diag_file["Rel1_" + str(hks_time) + "-hks"].create_dataset(name=str(gid), data=dgmRel1) diag_file["Ext1_" + str(hks_time) + "-hks"].create_dataset(name=str(gid), data=dgmExt1) graph_features.append(np.percentile(hks_signature(eigenvectors, eigenvals, time=hks_time), 10 * np.arange(11))) features.loc[gid] = np.insert(np.concatenate(graph_features), 0, label) features["label"] = features["label"].astype(int) elif dataset_type == "orbit": labs = [] count = 0 num_diag_per_param = 1000 if "5K" in dataset else 20000 for lab, r in enumerate([2.5, 3.5, 4.0, 4.1, 4.3]): print("Generating", num_diag_per_param, "orbits and diagrams for r = ", r, "...") for dg in range(num_diag_per_param): X = generate_orbit(num_pts_per_orbit=1000, param=r) alpha_complex = gd.AlphaComplex(points=X) st = alpha_complex.create_simplex_tree(max_alpha_square=1e50) st.persistence() diag_file["Alpha0"].create_dataset(name=str(count), data=np.array(st.persistence_intervals_in_dimension(0))) diag_file["Alpha1"].create_dataset(name=str(count), data=np.array(st.persistence_intervals_in_dimension(1))) orbit_label = {"label": lab, "pcid": count} labs.append(orbit_label) count += 1 labels = pd.DataFrame(labs) labels.set_index("pcid") features = labels[["label"]] features.to_csv(path_dataset + dataset + ".csv") return diag_file.close()
def ACSimplexTree(pt_cloud): alpha_complex = gd.AlphaComplex(points=pt_cloud) simplex_tree3 = alpha_complex.create_simplex_tree(max_alpha_square=60.0) diag3 = simplex_tree3.persistence(homology_coeff_field=2, min_persistence=0) return simplex_tree3
args = parser.parse_args() with open(args.file, "r") as f: first_line = f.readline() if (first_line == "OFF\n") or (first_line == "nOFF\n"): print( "#####################################################################" ) print("AlphaComplex creation from points read in a OFF file") message = "AlphaComplex with max_edge_length=" + repr( args.max_alpha_square) print(message) alpha_complex = gudhi.AlphaComplex(off_file=args.file) simplex_tree = alpha_complex.create_simplex_tree( max_alpha_square=args.max_alpha_square) message = "Number of simplices=" + repr(simplex_tree.num_simplices()) print(message) diag = simplex_tree.persistence() print("betti_numbers()=") print(simplex_tree.betti_numbers()) if args.no_diagram == False: gudhi.plot_persistence_diagram(diag, band=args.band) plot.show() else:
rips_stree = rips_complex.create_simplex_tree( max_dimension=args.max_dimension) message = "Number of simplices=" + repr(rips_stree.num_simplices()) print(message) rips_stree.compute_persistence() print("##############################################################") print("AlphaComplex creation from points read in a OFF file") message = "AlphaComplex with max_edge_length=" + repr(args.threshold) print(message) alpha_complex = gudhi.AlphaComplex(points=point_cloud) alpha_stree = alpha_complex.create_simplex_tree( max_alpha_square=(args.threshold * args.threshold) ) message = "Number of simplices=" + repr(alpha_stree.num_simplices()) print(message) alpha_stree.compute_persistence() max_b_distance = 0.0 for dim in range(args.max_dimension): # Alpha persistence values needs to be transform because filtration # values are alpha square values alpha_intervals = np.sqrt(alpha_stree.persistence_intervals_in_dimension(dim))
import gudhi import math as m import matplotlib.pyplot as plt L = [] for k in range(10): angle = 2 * m.pi * k / 10 L.append([m.cos(angle), m.sin(angle)]) alpha = gudhi.AlphaComplex(points=L) simplex = alpha.create_simplex_tree() diag = simplex.persistence() gudhi.plot_persistence_barcode(diag) gudhi.plot_persistence_diagram(diag) plt.show()
def _alpha_complex(self, points): alpha = gd.AlphaComplex(points=points) simplex_tree = alpha.create_simplex_tree( max_alpha_square=self.max_alpha_square) diag = simplex_tree.persistence() return diag