计算-numpython错误

计算-numpython错误,python,matlab,numpy,bug-tracking,Python,Matlab,Numpy,Bug Tracking,我用NumPy做了一些计算,通过一个大盒子和一个小盒子之间的一个小孔,找到Y截距。大盒子里有超过10万个粒子,小盒子里大约有1000个。这样做需要很多时间。所有的self.YD,self.XD都是非常大的数组,我将它们相乘 PS:ind是需要乘以的值的索引。在代码中的那一行之前,我有一个非零条件 你知道我该如何用更简单的方法进行计算吗 YD_zero = self.oldYD[ind] - ((self.oldYD[ind]-self.YD[ind]) * self.oldXD[ind])/(s

我用NumPy做了一些计算,通过一个大盒子和一个小盒子之间的一个小孔,找到Y截距。大盒子里有超过10万个粒子,小盒子里大约有1000个。这样做需要很多时间。所有的self.YD,self.XD都是非常大的数组,我将它们相乘

PS:ind是需要乘以的值的索引。在代码中的那一行之前,我有一个非零条件

你知道我该如何用更简单的方法进行计算吗

YD_zero = self.oldYD[ind] - ((self.oldYD[ind]-self.YD[ind]) * self.oldXD[ind])/(self.oldXD[ind]-self.XD[ind])
谢谢

更新

会用乘法,除法,减法和所有的Numpy。快一点? 或者如果我分开计算。比如说

首先要做到这一点:

    YD_zero = self.oldYD[ind] - ((self.oldYD[ind]-self.YD[ind])*self.oldXD[ind])
然后下一行是:

    YD_zero /= (self.oldXD[ind]-self.XD[ind])
有什么建议吗

更新2

一段时间以来,我一直在试图弄明白这一点,但进展不大。我担心的是分母:

    self.oldXL[ind]-self.XL[ind] == 0
我得到了一些奇怪的结果


另一个是非零函数。我已经测试了一段时间了。有谁能告诉我,它几乎和Matlab中的find一样,因为所有的计算都是按元素进行的,所以重新编写表达式应该很容易。这将避免在执行
oldYD
等操作时创建的所有非常大的临时数组


另一种可能性是。

也许我搞错了,但在Numpy中,你可以执行矢量化计算。移除封闭的
while
循环,然后运行此

YD_zero=self.oldYD-((self.oldYD-self.YD)*self.oldXD)/(self.oldXD-self.XD)

应该快得多

更新:使用Newton-Raphson方法迭代寻根

unconverged_mask = np.abs(f(y_vals)) > CONVERGENCE_VALUE:
while np.any(unconverged_mask):
    y_vals[unconverged_mask] = y_vals[unconverged_mask] - f(y_vals[unconverged_mask]) / f_prime(y_vals[unconverged_mask])
    unconverged_mask = np.abs(f(y_vals)) > CONVERGENCE_VALUE:
这段代码只是说明性的,但它展示了如何将使用矢量化代码的迭代过程应用于任何函数
f
,您可以找到
f_prime
的导数。
untererged_mask
意味着当前迭代的结果将仅应用于那些尚未收敛的值

注意,在这种情况下,不需要迭代,牛顿·拉斐逊将在第一次迭代中给出正确答案,因为我们处理的是直线。你得到的是一个精确解

第二次更新

好吧,你没有用牛顿·拉弗森。要一次性计算y轴截距,可以使用

YD_zero=YD+(XD-X0)*dYdX

其中,
dYdX
是梯度,在您的例子中

dYdX=(YD-oldYD)/(XD-oldXD)

我假设
XD
YD
是粒子的当前x,y值,
oldXD
oldYD
是粒子先前的x,y值,
X0
是光圈的x值


仍然不完全清楚为什么必须迭代所有粒子,Numpy可以一次计算所有粒子。

我肯定会选择
numexpr
。我不确定
numexpr
是否可以处理索引,但我打赌以下(或类似的)方法会起作用:

import numexpr as ne

yold = self.oldYD[ind]
y = self.YD[ind]
xold = self.oldXD[ind]
x = self.XD[ind]
YD_zero = ne.evaluate("yold - ((yold - y) * xold)/(xold - x)")

如果您尝试修剪点集,精度损失是否显著?我需要真正准确的数据。更简单的说,您的意思是在更少的cpu周期内?我在while循环中进行了此操作,并且在一次运行中至少执行16000次。所以,无论什么都可以使计算速度更快。如果你对它进行矢量化,它还允许以后在你真的需要速度的情况下移动到GPU。我确实对它进行了矢量化,但我还有很多其他事情要做。我认为这比其他任何事情都需要更长的时间。因为我在没有这个的情况下运行了它,速度快了很多。我相信循环不是在索引上,而是在迭代牛顿算法上。啊,对了,那么你是在用牛顿-拉斐逊方法来寻找函数中的零?如果是这样的话,更新的代码可能会有所帮助。还要注意,因为我们处理的是直线,所以不需要多次应用牛顿-拉斐逊方程,它在第一次迭代时是正确的。我如何用Numexpr或Cython乘以两个数组?!你更愿意推荐Cython还是Numexpr?@theSun:乘法中有什么特别的地方会引起混淆?至于
Cython
vs
numexpr
,后者应该更容易正确。然而,我个人只使用了前者,因此在
numexpr
中可能存在一些我不知道的微妙之处。