def calculate(self, points): """ :param points: numpy array of (n + 1, m) points correctly defining an n-dimensional simplex in m dimensions """ self.volume, self.circumradius = utils.cayley_menger_vr( np.array(points)) self.centroid = np.mean(points, axis=0)
def test_AlphaCluster_structure(): """ Testing ground for structure of cluster code Uses AlphaCluster objects """ p = get_test_data() tri = Delaunay(p) ndim = p.shape[1] triangle_coords = p[tri.simplices, :] cr_array, vol_array = utils.cayley_menger_vr(triangle_coords) simp_sorted_idxs = np.argsort(cr_array) simp_lookup = [None]*tri.simplices.shape[0] for simp_idx in simp_sorted_idxs: neighbors = [simp_lookup[n_idx] for n_idx in tri.neighbors[simp_idx]] included = set(n.root for n in neighbors if n is not None) cr = cr_array[simp_idx] if len(included) == 0: # simplex is isolated assigned_cluster = alphac.AlphaCluster(simp_idx, cr) elif len(included) == 1: # simplex borders exactly one existing cluster assigned_cluster = included.pop() assigned_cluster.add(simp_idx, cr) else: # included in 2 or more clusters assigned_cluster = alphac.AlphaCluster(simp_idx, cr, *included) simp_lookup[simp_idx] = assigned_cluster clusters = set(simp_lookup) root = simp_lookup[0].root root.freeze(root) all_root = {x.root for x in simp_lookup} def census(c, s): s.add(c) for sc in c.children: census(sc, s) init_clusters = set() census(root, init_clusters) print() assert root is next(iter(all_root)) print("roots", len(all_root)) print("clusters: ", len(clusters)) # printcluster(clusters[0]) root.collapse() remaining_clusters = set() census(root, remaining_clusters) print() print("initial clusters", len(init_clusters)) print("remaining clusters", len(remaining_clusters)) # lsi = [len(x.members) for x in init_clusters] lsr = [len(x.members) for x in remaining_clusters] plt.plot(lsr, '.') plt.show() return
def test_basic_structure(): """ Simple version that uses nested sets to outline concept """ p = get_test_data() print(p.shape) tri = Delaunay(p) print(tri.simplices.shape) ndim = p.shape[1] triangle_coords = p[tri.simplices, :] cr_array, vol_array = utils.cayley_menger_vr(triangle_coords) simp_sorted_idxs = np.argsort(cr_array) print("xxxxxxxxx") clusters = [] for simp_idx in simp_sorted_idxs: neighbors = list(tri.neighbors[simp_idx]) included = [] # list is faster to build than deque for cluster in clusters: if any(adj_simp in cluster for adj_simp in neighbors): included.append(cluster) if len(included) == 0: # this simplex is isolated right now clusters.append({simp_idx}) # make new set for cluster elif len(included) == 1: # this simplex borders exactly one existing cluster included.pop().add(simp_idx) else: # included in 2 or more clusters; merge! largest_cluster = max(included, key=len) # for now, add the smaller cluster(s) as elements of the largest for cluster in included: if cluster is not largest_cluster: clusters.remove(cluster) largest_cluster |= cluster largest_cluster.add(frozenset(cluster)) # print(clusters) print("clusters: ", len(clusters)) def printcluster(c, prefix=""): print(prefix+"---{ cluster size: ", end="") print(len([x for x in c if not isinstance(x, frozenset)])) subclusters = [x for x in c if isinstance(x, frozenset)] for sc in subclusters: printcluster(sc, prefix=prefix+"| ") print(prefix+" }")
def test_cayley_menger(): a = np.array([[0, 0], [1, 0], [0, 1]], dtype=np.float64) v, r = apy.cayley_menger_vr(a) print("Volume", v, "Circumradius", r) data = get_carina()[:100, :] apy.QUIET = False apy.ORPHAN_TOLERANCE = 150 apy.ALPHA_STEP = 0.97 apy.PERSISTENCE_THRESHOLD = 3 apy.MAIN_CLUSTER_THRESHOLD = 51 apy.initialize(data) v, r = zip(*[(s.volume, s.circumradius) for s in apy.KEY.simplices()]) plt.plot(r, v, '.') sr = np.array(sorted(list(r))) coeff = (1 + np.sin(np.pi / 6)) * np.cos(np.pi / 6) plt.plot(sr, (sr**2) * coeff, label="Equilateral triangle volume: upper bound on $v(r)$") plt.xscale('log') plt.yscale('log') plt.xlabel("Circumradius") plt.ylabel("Volume") plt.legend() plt.show()
def get_test_data(): # Some really basic test data srcfile = "../../PyAlpha_drafting/test_data/Ssets/s1.txt" return np.genfromtxt(srcfile)[::500] # Get test data set p = get_test_data() # Print shape of test data set print(p.shape) # Boilerplate Delaunay setup tri = utils.Delaunay(p) ndim = p.shape[1] triangle_coords = p[tri.simplices, :] cr_array, vol_array = utils.cayley_menger_vr(triangle_coords) simp_sorted_idxs = np.argsort(cr_array) # Lookup table for every single simplex # Will contain some sort of quick mapping to clusters simp_lookup = [None] * tri.simplices.shape[0] # See v4idea.readme for the algorithm description # Staging area may have multiple clusters, will grow and shrink. staging_area = [] # Cluster area will have multiple clusters while growing, but should end with # just one, the root. cluster_area = [] # Loop through simplices in sorted order for simp_idx in simp_sorted_idxs: print(simp_idx) # Get all ndim+1 neighbors of this simplex included_neighbors = [
def test_AlphaCluster(): """ Testing ground for structure of cluster code Uses AlphaCluster objects """ p = get_test_data() # print(p.shape) # return # plt.plot(p[:, 0], p[:, 1], '.') # plt.show() # return tri = Delaunay(p) ndim = p.shape[1] triangle_coords = p[tri.simplices, :] cr_array, vol_array = utils.cayley_menger_vr(triangle_coords) simp_sorted_idxs = np.argsort(cr_array) simp_lookup = [None]*tri.simplices.shape[0] for simp_idx in simp_sorted_idxs: if -1 in tri.neighbors[simp_idx]: # do not involve edge simplices continue # all neighboring clusters of this simplex neighbors = (simp_lookup[n_idx] for n_idx in tri.neighbors[simp_idx]) # included if already counted by some cluster included = set(n.root for n in neighbors if n is not None) # circumradius of this simplex cr = cr_array[simp_idx] if len(included) == 0: # simplex is isolated assigned_cluster = alphac.AlphaCluster() else: # included in at least 1 cluster (assigned to largest/only cluster) assigned_cluster = max(included, key=len) included.remove(assigned_cluster) if any(len(x) < alphac.MINIMUM_MEMBERSHIP for x in included): # some small clusters need to be absorbed too_small_clusters = [x for x in included if len(x) < alphac.MINIMUM_MEMBERSHIP] for small_cluster in too_small_clusters: assigned_cluster.engulf(small_cluster) assert small_cluster.isleaf() for m in small_cluster.members: simp_lookup[m] = assigned_cluster included.remove(small_cluster) # for clusters that are large enough, add as children assigned_cluster.add_all_children(included, cr) # add this simplex to its assigned cluster assigned_cluster.add(simp_idx, cr) simp_lookup[simp_idx] = assigned_cluster # all simplices should have the same root clusters = set(x.root for x in simp_lookup if x) root = max(clusters, key=len) clusters.remove(root) print("JOINING {} CLUSTERS".format(len(clusters))) root.add_all_children(clusters, max(max(x.alpha_map.keys()) for x in list(clusters)+[root])) root.freeze(root) fig = plt.figure() d_ax, m_ax, surface_plotter = utils.prepare_plots(fig, ndim) rectangles, base_width, lims = utils.dendrogram(root) for r in rectangles: d_ax.add_artist(r) d_ax.set_xlim((-0.05*base_width, base_width*1.05)) d_ax.set_ylim((lims[0]*0.9, lims[1]*1.1)) d_ax.invert_yaxis() d_ax.set_yscale('log') d_ax.set_xlabel("Relative cluster size") d_ax.set_ylabel("Alpha") d_ax.set_xticklabels([]) surface_list, points_list = utils.alpha_surfaces(root, tri, 2e7) for s in surface_list: surface_plotter(s) for points, color, opacity in points_list: m_ax.plot(*points, marker='.', color=color, alpha=opacity, linestyle='None', markersize=1) # m_ax.set_xlim([4., 16]) # m_ax.set_ylim([21, 22]) # m_ax.set_zlim([20, 22]) # for setter, i in zip((m_ax.set_xlim, m_ax.set_ylim, m_ax.set_zlim), range(3)): # setter(np.sort(p[:, i])[(0, -1),]) plt.show() return root
def test_proto_circumradius(): a = np.array([[0, 0], [1.5, 1], [0, 55]], dtype=np.float64) print(prototype_circumradius(a)) print(apy.old_vr(a)[1]) print(apy.cayley_menger_vr(a)[1])
def test_cm_vs_old_vr(): a = np.array([[0, 0], [1, 0], [0, 1]], dtype=np.float64) v, r = apy.cayley_menger_vr(a) v2, r2 = apy.old_vr(a) print("Volume", v, "Circumradius", r) print("Volume2", v2, "Circumradius2", r2)
def run_fn(sx): utils.cayley_menger_vr(sx)