def test_incremental(self, name): # Test incremental construction of the triangulation if INCREMENTAL_DATASETS[name][0][0].shape[1] > 3: # too slow (testing of the result --- qhull is still fast) return chunks, opts = INCREMENTAL_DATASETS[name] points = np.concatenate(chunks, axis=0) obj = qhull.Voronoi(chunks[0], incremental=True, qhull_options=opts) for chunk in chunks[1:]: obj.add_points(chunk) obj2 = qhull.Voronoi(points) obj3 = qhull.Voronoi(chunks[0], incremental=True, qhull_options=opts) if len(chunks) > 1: obj3.add_points(np.concatenate(chunks[1:], axis=0), restart=True) # -- Check that the incremental mode agrees with upfront mode assert_equal(len(obj.point_region), len(obj2.point_region)) assert_equal(len(obj.point_region), len(obj3.point_region)) # The vertices may be in different order or duplicated in # the incremental map for objx in obj, obj3: vertex_map = {-1: -1} for i, v in enumerate(objx.vertices): for j, v2 in enumerate(obj2.vertices): if np.allclose(v, v2): vertex_map[i] = j def remap(x): if hasattr(x, '__len__'): return tuple(set([remap(y) for y in x])) try: return vertex_map[x] except KeyError as e: raise AssertionError( "incremental result has spurious vertex at %r" % (objx.vertices[x], )) from e def simplified(x): items = set(map(sorted_tuple, x)) if () in items: items.remove(()) items = [x for x in items if len(x) > 1] items.sort() return items assert_equal(simplified(remap(objx.regions)), simplified(obj2.regions)) assert_equal(simplified(remap(objx.ridge_vertices)), simplified(obj2.ridge_vertices))
def _compare_qvoronoi(self, points, output, **kw): """Compare to output from 'qvoronoi o Fv < data' to Voronoi()""" # Parse output output = [list(map(float, x.split())) for x in output.strip().splitlines()] nvertex = int(output[1][0]) vertices = list(map(tuple, output[3:2+nvertex])) # exclude inf nregion = int(output[1][1]) regions = [[int(y)-1 for y in x[1:]] for x in output[2+nvertex:2+nvertex+nregion]] ridge_points = [[int(y) for y in x[1:3]] for x in output[3+nvertex+nregion:]] ridge_vertices = [[int(y)-1 for y in x[3:]] for x in output[3+nvertex+nregion:]] # Compare results vor = qhull.Voronoi(points, **kw) def sorttuple(x): return tuple(sorted(x)) assert_allclose(vor.vertices, vertices) assert_equal(set(map(tuple, vor.regions)), set(map(tuple, regions))) p1 = list(zip(list(map(sorttuple, ridge_points)), list(map(sorttuple, ridge_vertices)))) p2 = list(zip(list(map(sorttuple, vor.ridge_points.tolist())), list(map(sorttuple, vor.ridge_vertices)))) p1.sort() p2.sort() assert_equal(p1, p2)
def test_ridges(self, name): # Check that the ridges computed by Voronoi indeed separate # the regions of nearest neighborhood, by comparing the result # to KDTree. points = DATASETS[name] tree = KDTree(points) vor = qhull.Voronoi(points) for p, v in vor.ridge_dict.items(): # consider only finite ridges if not np.all(np.asarray(v) >= 0): continue ridge_midpoint = vor.vertices[v].mean(axis=0) d = 1e-6 * (points[p[0]] - ridge_midpoint) dist, k = tree.query(ridge_midpoint + d, k=1) assert_equal(k, p[0]) dist, k = tree.query(ridge_midpoint - d, k=1) assert_equal(k, p[1])