Мне было интересно, можно ли оптимизировать следующее с помощью 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
где g
- вектор длины n
, b
- это матрица n
x n
, dt
- число итераций, а t1
и t2
- скаляры.
Я быстро исчерпал идеи о том, как оптимизировать это дальше, потому что p
используется в цикле во всех трех терминах уравнения: при добавлении к себе; в точечном продукте; и в скалярном умножении.
Но, возможно, есть другой способ представить эту функцию или есть другие трюки, чтобы повысить ее эффективность. Если возможно, я бы предпочел не использовать Cython
и т.д., Но я был бы готов использовать его, если бы улучшения скорости были значительными. Заранее спасибо, и извиняюсь, если вопрос вне сферы видимости.
Обновление:
Представленные ответы до сих пор более сфокусированы на том, какие значения ввода/вывода могут быть во избежание ненужных операций. Теперь я обновил MWE с правильными значениями инициализации для переменных (я не ожидал, что идеи оптимизации придут с этой стороны - извинения). g
будет находиться в диапазоне [-1, 1]
, а b
будет находиться в диапазоне [-infinity, infinity]
. Аппроксимация вывода не является опцией, потому что возвращенные векторы позже передаются функции оценки - аппроксимация может возвращать один и тот же вектор для довольно аналогичного ввода, поэтому это не вариант.
MWE:
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)))