sud*_*sei 11 python math performance numpy
我想知道是否有可能优化以下使用Numpy或数学技巧.
def f1(g, b, dt, t1, t2):
p = np.copy(g)
for i in range(dt):
p += t1*np.tanh(np.dot(p, b)) + t2*p
return p
Run Code Online (Sandbox Code Playgroud)
其中g是长度向量n,b是nx n矩阵,dt是迭代次数,t1并且t2是标量.
我已经很快就没有关于如何进一步优化这个的想法,因为p在循环中使用,在等式的所有三个术语中:当添加到自身时; 在点积; 并且在标量乘法中.
但也许有不同的方式来表示这个功能,或者有其他技巧来提高它的效率.如果可能的话,我宁愿不使用Cython等,但如果速度提升很重要,我愿意使用它.在此先感谢,如果问题超出范围,我会道歉.
到目前为止提供的答案更侧重于输入/输出的值可以避免不必要的操作.我现在用适当的变量初始化值更新了MWE(我没想到优化思想来自那个方面 - 道歉).g将在范围内[-1, 1],b并将在范围内[-infinity, infinity].近似输出不是一个选项,因为返回的向量后来被赋予评估函数 - 近似可以为相当类似的输入返回相同的向量,因此它不是一个选项.
import numpy as np
import timeit
iterations = 10000
setup = """
import numpy as np
n = 100
g = np.random.uniform(-1, 1, (n,)) # Updated.
b = np.random.uniform(-1, 1, (n,n)) # Updated.
dt = 10
t1 = 1
t2 = 1/2
def f1(g, b, dt, t1, t2):
p = np.copy(g)
for i in range(dt):
p += t1*np.tanh(np.dot(p, b)) + t2*p
return p
"""
functions = [
"""
p = f1(g, b, dt, t1, t2)
"""
]
if __name__ == '__main__':
for function in functions:
print(function)
print('Time = {}'.format(timeit.timeit(function, setup=setup,
number=iterations)))
Run Code Online (Sandbox Code Playgroud)
要让代码运行得更快而不需要cython或jit将非常困难,一些数学技巧可能是更简单的方法。在我看来,如果我们在正 N 中定义一个k(g, b) = f1(g, b, n+1, t1, t2)/f1(g, b, n, t1, t2)for ,该函数应该有一个限制(还没有可靠的证明,只是直觉;这可能是 E(g)=0 & E(p)=0 也。)。对于和,似乎很快就会接近极限,对于,它几乎是 的常数。nkt1+t2t1=1t2=0.5k()N>1001.5
所以我认为数值近似方法应该是最简单的方法。
In [81]:
t2=0.5
data=[f1(g, b, i+2, t1, t2)/f1(g, b, i+1, t1, t2) for i in range(1000)]
In [82]:
plt.figure(figsize=(10,5))
plt.plot(data[0], '.-', label='1')
plt.plot(data[4], '.-', label='5')
plt.plot(data[9], '.-', label='10')
plt.plot(data[49], '.-', label='50')
plt.plot(data[99], '.-', label='100')
plt.plot(data[999], '.-', label='1000')
plt.xlim(xmax=120)
plt.legend()
plt.savefig('limit.png')
In [83]:
data[999]
Out[83]:
array([ 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,
1.5])
Run Code Online (Sandbox Code Playgroud)