4

I'm trying to compute the convex hull of 9 points in 10 dimensional space. Through the scipy interface, I'm calling scipy.spatial.ConvexHull(points) and getting QH6214 qhull input error: not enough points(9) to construct initial simplex (need 12)

I think the definition of convex hull is well defined regardless of the dimension. What is going on here? Is there a different function I can call that might fix this?

Mark
  • 4,584
  • 5
  • 35
  • 61
  • 1
    A non-degenerate convex-hull in `n`-dimensional space is defined by at least `n+1`points, e.g. a segment in 1D space, a triangle in 2D space, or a tetrahedron in 3D space. Your 9 points in 10 dimensional space define an 8-dimensional subspace. If you refer your points to it, you should have no problem in computing the convex hull of the 9 points in this new 8-dimensional subspace. You can then convert the resulting convex hull back to the 10-dimensional space. – Jaime Oct 16 '14 at 16:13
  • Or, if you are happy with knowing the vertices of degenerate convex hulls: if there are fewer than `ndim+1` points, all of them are in the convex hull. – pv. Oct 16 '14 at 16:15
  • @pv. Let's say I'm working in R^100, and I have 3 points, all colinear. In that case my convex hull should only be specified by the two extremal points, not all 3. – Mark Oct 16 '14 at 18:29

1 Answers1

3

Maybe projecting the points on a hyperplane before computing the hull will do the trick.

Use for example the Principal Component Analysis class sklearn.decomposition.PCA from the scikit-learn toolkit, to reduce dimension.

vertices = np.random.randn(9, 10)
from sklearn.decomposition import PCA
model = PCA(n_components=8).fit(vertices)

You can now transform back and forth from your vertices to the projected using model.transform and model.inverse_transform.

proj_vertices = model.transform(vertices)
hull_kinda = ConvexHull(proj_vertices)
hull_kinda.simplices

This outputs something like this

array([[6, 4, 3, 8, 0, 7, 5, 1],
       [2, 4, 3, 8, 0, 7, 5, 1],
       [2, 6, 3, 8, 0, 7, 5, 1],
       [2, 6, 4, 8, 0, 7, 5, 1],
       [2, 6, 4, 3, 0, 7, 5, 1],
       [2, 6, 4, 3, 8, 7, 5, 1],
       [2, 6, 4, 3, 8, 0, 5, 1],
       [2, 6, 4, 3, 8, 0, 7, 1],
       [2, 6, 4, 3, 8, 0, 7, 5]], dtype=int32)

Use now the model.inverse_transform to get the simplices back in your 10 dimensions.