2014-07-14 11 views
10

SciPy wrapper for QHull kullanarak bir dizi noktanın dışbükey gövdesi'un hacmini almaya çalışıyorum.QHull'lu dışbükey gövde hacmi SciPy'den

documentation of QHull'a göre, toplam yüzey alanını ve ses düzeyini elde etmek için "FA" seçeneğini atlamalıyım.

İşte elde ettiğim şey .. Ne yanlış yapıyorum?

> pts 
    [(494.0, 95.0, 0.0), (494.0, 95.0, 1.0) ... (494.0, 100.0, 4.0), (494.0, 100.0, 5.0)] 


> hull = spatial.ConvexHull(pts, qhull_options="FA") 

> dir(hull) 

    ['__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_qhull', '_update', 'add_points', 'close', 'coplanar', 'equations', 'max_bound', 'min_bound', 'ndim', 'neighbors', 'npoints', 'nsimplex', 'points', 'simplices'] 

> dir(hull._qhull) 
    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 
+1

Sorunuzu gerçek bir soruyla güncellemeye çalışın ("İşte burada ne var" değil). Uygun bir şekilde sağladığınız gerçeğine rağmen, toplam alanın ve hacminin bulunamayacağını anlamak biraz zaman aldı. seçeneği. –

+0

Benim vahşi tahminim, SciPy'nin bu özel seçenek bayrağını sarmaması. –

+0

Zor olan yolu uygulamaktır: http://wiki.scipy.org/Cookbook/Finding_Convex_Hull –

cevap

14

ne olursa olsun geçmek parametreleri ne, peşinde doğrudan sonuç alma herhangi bariz bir yol olarak görünmüyor. ConvexHull yerine, eğer kendinizi hesaplamak çok zor olmamalı, seni Delaunay'u kullanın (bu da dışbükey gövdeyle ilgili bilgilerin çoğunu sağlar).

def tetrahedron_volume(a, b, c, d): 
    return np.abs(np.einsum('ij,ij->i', a-d, np.cross(b-d, c-d)))/6 

from scipy.spatial import Delaunay 

pts = np.random.rand(10, 3) 
dt = Delaunay(pts) 
tets = dt.points[dt.simplices] 
vol = np.sum(tetrahedron_volume(tets[:, 0], tets[:, 1], 
           tets[:, 2], tets[:, 3])) 

yorum göre DÜZENLEME, dışbükey hacmini elde etmenin daha hızlı yolları şunlardır: Bazı oluşan verilerle

def convex_hull_volume(pts): 
    ch = ConvexHull(pts) 
    dt = Delaunay(pts[ch.vertices]) 
    tets = dt.points[dt.simplices] 
    return np.sum(tetrahedron_volume(tets[:, 0], tets[:, 1], 
            tets[:, 2], tets[:, 3])) 

def convex_hull_volume_bis(pts): 
    ch = ConvexHull(pts) 

    simplices = np.column_stack((np.repeat(ch.vertices[0], ch.nsimplex), 
           ch.simplices)) 
    tets = ch.points[simplices] 
    return np.sum(tetrahedron_volume(tets[:, 0], tets[:, 1], 
            tets[:, 2], tets[:, 3])) 

, ikinci yöntem hakkında olduğu görülüyor 2x daha hızlı ve sayısal doğruluk çok daha iyi görünmekle birlikte (15 ondalık basamak!) Çok daha fazla patolojik durum olmasına rağmen:

pts = np.random.rand(1000, 3) 

In [26]: convex_hull_volume(pts) 
Out[26]: 0.93522518081853867 

In [27]: convex_hull_volume_bis(pts) 
Out[27]: 0.93522518081853845 

In [28]: %timeit convex_hull_volume(pts) 
1000 loops, best of 3: 2.08 ms per loop 

In [29]: %timeit convex_hull_volume_bis(pts) 
1000 loops, best of 3: 1.08 ms per loop 
+0

Bu harika. Hesaplama süresinden tasarruf etmek için qhull'daki ses bilgisini arıyordum, ancak Python'da sürümünüzden daha hızlı bir şekilde yapılabileceğini sanmıyorum. Bu yüzden, sadece onaylamak için, Delaunay dışbükey gövdenin mozaikleştirmesini yapar, doğru mu? Ayrıca, bu küçük bir şey, bu 'einsum' ... Bunu bilmiyordum. :) – Diana

+1

Delaunay çok yavaş çıktı, bu yüzden ConvexHull'u kullandım, ekstremite noktalarını (gövdede olanlar) aldım ve sadece bu noktalarda Delaunay'ı çalıştırdım. Verilerimde bu şekilde 1-2 buyruk daha hızlıdır. – Diana

+0

Bu gerçekten akıllı ... Daha fazla gelişmeyebilir, ancak 'Delaunay' çağrısını tamamen atlamayı deneyebilir ve gövdedeki bir noktayı seçerek dışbükey gövdesinin üçgenini oluşturabilir ve daha sonra Bu noktayı içeren tüm tetrahedralar ve dışbükey gövdenin basitliklerinin (yani ConvexHull nesnelerinin ".simplices" özniteliğinin her birindeki noktalar). Daha uzun tetrahedra üretecek, bu yüzden sayısal olarak daha az kararlı olabilir. Ama daha hızlı olmalı. – Jaime

5

Bu soru ikinci doğum gününü kutsa da, şimdi, scipy sarmalayıcısının otomatik olarak Qhull tarafından hesaplanan birimi (ve alanı) bildirdiğine dikkat çekmek isterim.

+0

Not: Bunun çalışması için en azından scipy sürümü 0.17.0'a ihtiyacınız var. – awakenting

İlgili konular