Python 使用numpy加速顶点距离计算的方法

Python 使用numpy加速顶点距离计算的方法,python,numpy,Python,Numpy,我一直在努力研究一种与3d三角形向量进行比较的算法。不幸的是,它在某些地方非常缓慢,我反复尝试不同的方法来改进它。我正在努力解决的一件事是加速距离计算 我有两组三角形,它们被分解成三个点,每个点都有一个3d浮点向量(xyz)。我使用的计算是: diffverts = numpy.zeros( ( ntris*3, ntesttris*3, 3 ), dtype = 'float32') diffverts += triverts.reshape(ntris*3, 1, 3 )

我一直在努力研究一种与3d三角形向量进行比较的算法。不幸的是,它在某些地方非常缓慢,我反复尝试不同的方法来改进它。我正在努力解决的一件事是加速距离计算

我有两组三角形,它们被分解成三个点,每个点都有一个3d浮点向量(xyz)。我使用的计算是:

    diffverts = numpy.zeros( (  ntris*3, ntesttris*3, 3 ), dtype = 'float32')
    diffverts += triverts.reshape(ntris*3, 1, 3 )
    diffverts -= ttriverts.reshape(1, ntesttris*3, 3 )
    vertdist = ( diffverts[:,:,0]**2 + diffverts[:,:,1]**2 + diffverts[:,:,2]**2 ) ** 0.5
此计算速度快于:

    diffverts = triverts.reshape(ntris*3, 1, 3 ) - ttriverts.reshape(1, ntesttris*3, 3 )
    vertdist = ( diffverts[:,:,0]**2 + diffverts[:,:,1]**2 + diffverts[:,:,2]**2 ) ** 0.5
是否有更快的方法填充diff vert部分(耗时最长)和/或距离部分(也相当耗时)?由于要测试的组的数量,此代码被调用了很多次。此外,尝试仅对顶点的索引执行此操作会在尝试返回到一些布尔测试时导致进一步计算的其他问题(即,这只是一组计算中的一个,因此保持三点级别效果最好)


我使用的是numpy和python

问题是对所有三角形进行暴力测试需要二次时间。最好使用专门用于执行此类计算的数据结构。幸运的是,scipy包含一个


请看scipy.spatial.cKDTree。帮助应该是不言自明的。

我认为diffverts占用了足够的内存,导致缓存未命中。不幸的是,虽然此解决方案非常优雅,但您可能最好一次计算整个距离,以避免保存n*m*3中间值数组。尽管它很难看,我只会做嵌套循环。

嗨,谢谢你的回答。我会看一下。但是,在每个三点上进行3种角度计算的计算速度大约是速度的十分之一。这里向量减法的基本总体是最耗时的。我不知道是否有更好的方法设置。如果你使用cKDTree,每个点相对于所有其他点的整个蛮力减法永远不会发生。你有没有一个例子说明如何使用cKDTree在设定的距离内获得a)点。b) 实际距离和c)一个布尔数组triverts*ttriverts的大小来说明哪些是有效的?除非我能做到这三个步骤,否则恐怕没有多大用处。我需要b稍后使用,我需要c与其他3个角度测试进行比较。我查看了cKDTree Decription,但最后尝试了scipy.spatial.distance。这似乎为我创建了合适大小的vertdist,然后我可以对其进行测试。最后,使用该方法的时间与仅进行垂直距离计算的时间大致相同,即不包括差异垂直距离计算。所以它给了我60%的改善。我需要测试最终结果才能确定。也不确定问题的一部分是否与内存有关,因此也将尝试分块以降低大小。如果您确实需要每个向量之间的每个距离,那么它将是二次时间。我对numpy不太了解,但如果您只需要相对距离,则不需要平方根。一般来说,平方根运算速度相当慢。另外,我不确定它是如何优化的,但有时“pow(n,2)”类的东西比“n*n”慢。你好,谢谢Hans,是的,我可能可以省去平方根,不过我需要在soem表单中应用距离,以稍后的结果。然而,我不认为这对速度有多大帮助(相对而言)。在这个例子中,通过我正在经历的基本循环集(即所有组),diff verts部分的设置约为时间的60-70%,实际距离部分约为30-40%,您使用的是哪种尺寸?这是一种混合,大多数可能是每一组TRI中的大约100个,但可以变化到1000+我还使用一些内部计算来计算出三个角度的计算。对于相同的尺寸,它们大约快10*。我之前也对一些嵌套循环进行了一些测试,但速度较慢。事实上,被测试的组数是嵌套的,以便将循环分块。当我疲于与原始组进行比较时(请参见第一个答案中的注释),我得到了一个内存错误,因此您可能是对的,部分问题与大小有关。我会记下来看看是否有用。