Performance numpy:计算矩阵中的函数,在计算下一个数组时使用上一个数组作为参数
我有一个Performance numpy:计算矩阵中的函数,在计算下一个数组时使用上一个数组作为参数,performance,numpy,differential-equations,difference-equations,Performance,Numpy,Differential Equations,Difference Equations,我有一个mxn数组:a,其中整数m>1E6,而n稍快一些。您的第一列基本上是2^n。为n计算2^n(最多1000000个)将溢出。。第二列更糟 def calc(arr, t0=1E-6): u = arr[0] dt = 1E-6 h = lambda x: np.random.random(1)*50.0 def firstColGen(uStart): u = uStart while True: u
mxn
数组:a
,其中整数m>1E6
,而n稍快一些。您的第一列基本上是2^n。为n计算2^n(最多1000000个)将溢出。。第二列更糟
def calc(arr, t0=1E-6):
u = arr[0]
dt = 1E-6
h = lambda x: np.random.random(1)*50.0
def firstColGen(uStart):
u = uStart
while True:
u += u
yield u
def secondColGen(uStart, A):
u = uStart
while True:
u += u*A
yield u
def thirdColGen(uStart):
u = uStart
while True:
u += np.cos(u)
yield u
def fourthColGen(uStart, h, t0, dt):
u = uStart
t = t0
while True:
u += h(u) * dt
t += dt
yield u
first = firstColGen(u[0])
second = secondColGen(u[1], A)
third = thirdColGen(u[2])
fourth = fourthColGen(u[3], h, t0, dt)
for i in xrange(1, len(arr)):
arr[i] = [first.next(), second.next(), third.next(), fourth.next()]
这种事情在努比很难做到。如果我们按列查看,我们会看到一些更简单的解决方案
a[:,0]
非常简单:
col0 = np.ones((1000))*2
col0[0] = 1 #Or whatever start value.
np.cumprod(col0, out=col0)
np.allclose(col0, a[:1000,0])
True
如前所述,这将很快溢出a[:,1]
可以按照同样的思路进行
我不相信有一种方法可以在numpy中单独快速完成接下来的两个专栏。我们可以求助于numba:
from numba import auotojit
def python_loop(start, count):
out = np.zeros((count), dtype=np.double)
out[0] = start
for x in xrange(count-1):
out[x+1] = out[x] + np.cos(out[x+1])
return out
numba_loop = autojit(python_loop)
np.allclose(numba_loop(3,1000),a[:1000,2])
True
%timeit python_loop(3,1000000)
1 loops, best of 3: 4.14 s per loop
%timeit numba_loop(3,1000000)
1 loops, best of 3: 42.5 ms per loop
尽管值得指出的是,它收敛到pi/2的速度非常快,对于任何起始值,计算超过20个值的递归几乎没有意义。这将返回与双点精度完全相同的答案-我没有费心寻找截止点,但它远小于50:
%timeit tmp = np.empty((1000000));
tmp[:50] = numba_loop(3,50);
tmp[50:] = np.pi/2
100 loops, best of 3: 2.25 ms per loop
您可以对第四列执行类似的操作。当然,您可以autojit
所有功能,但这会根据numba的使用情况提供几种不同的选项供您尝试:
对前两列使用cumprod
对第3列(和可能的第4列)使用近似值,其中仅计算前几次迭代
使用autojit
将所有内容包装在autojit循环中(最佳选项)
您在~200之后的所有行中显示该值的方式将是np.inf
或np.pi/2
。利用这一点
你的问题不完全有道理。。。如果u是先前计算的行,则公式永远不会使用当前行。我猜您的意思是类似于F**(*v,G**(*u,t)),其中u是计算最后一行的结果,v是当前行,但请确认并定义如何处理第一行,其中没有“先前计算的行”。而且,更重要的是,在不知道F和G是做什么的情况下,我怀疑任何人都能给你一个满意的答案。不,据我所知,我键入的是我想做的。我将添加更多信息。您能为一个缓慢但正确的实现添加代码吗?第二列可以是np.cumprod([o0,a+1,a+1,…])。对于另外两个,您必须定制UFUNC。。。但是numba是一个很好的建议!使用numbapro,您甚至可以将其并行化:)
%timeit tmp = np.empty((1000000));
tmp[:50] = numba_loop(3,50);
tmp[50:] = np.pi/2
100 loops, best of 3: 2.25 ms per loop