我正在使用NumPy通过大盒子和小盒子之间的光圈来寻找Y截距。我在大盒子里有超过100,000颗颗粒,在小盒子里有大约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几乎相同
答案 0 :(得分:3)
也许我有错误的结局,但在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
的导数。 unconverged_mask
表示当前迭代的结果仅适用于那些尚未收敛的值。
请注意,在这种情况下,不需要迭代,Newton-Raphson会在第一次迭代中给出正确的答案,因为我们正在处理直线。你所拥有的是一个精确的解决方案。
第二次更新
好的,所以你没有使用Newton-Raphson。要一次性计算YD_zero
(y截距),您可以使用
YD_zero = YD + (XD - X0) * dYdX
其中dYdX
是渐变,在您的情况下似乎是
dYdX = (YD - oldYD) / (XD - oldXD)
我假设XD
和YD
是粒子的当前x,y值,oldXD
和oldYD
是粒子的先前x,y值, X0
是光圈的x值。
仍然不完全清楚为什么你必须遍历所有粒子,Numpy可以同时对所有粒子进行计算。
答案 1 :(得分:2)
答案 2 :(得分:0)
我肯定会去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)")