计算-numpython错误
我用NumPy做了一些计算,通过一个大盒子和一个小盒子之间的一个小孔,找到Y截距。大盒子里有超过10万个粒子,小盒子里大约有1000个。这样做需要很多时间。所有的self.YD,self.XD都是非常大的数组,我将它们相乘 PS:ind是需要乘以的值的索引。在代码中的那一行之前,我有一个非零条件 你知道我该如何用更简单的方法进行计算吗计算-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
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
vsnumexpr
,后者应该更容易正确。然而,我个人只使用了前者,因此在numexpr
中可能存在一些我不知道的微妙之处。