Можно ли векторизовать (или иным образом ускорить) поэлементную оптимизацию с помощью NumPy (и SciPy)?
В самом абстрактном смысле у меня есть функция y, которая имеет параболическую форму и может быть выражена в основном как y=x^2+b*x+z, где x — массив известных значений, и я хочу найти z, при котором минимальное значение y равно нулю ( Другими словами, я хочу найти значение z, при котором моя парабола будет иметь только один ноль). Для этого я решил реализовать простой метод, похожий на деление пополам. Код для этого ниже:
import numpy as np
def find_single_root():
x = np.arange(-5, 6,0.1) # domain
z = 1 # initial guess
delta = 1 # initial step size
tol = 0.001 # tolerance
while True:
y = x**2-5*x+z
minimum = np.nanmin(y)
# update z
print(delta)
print(z)
if minimum > 0:
if delta > 0:
delta = -1*delta/2
z += delta
else:
if delta < 0:
delta = -1*delta/2
z += delta
# check if step is smaller than tolerance
if np.abs(delta) < tol:
return z
Теперь скажем x(v,w), и я хочу создать двумерный массив значений z, где каждое из них оптимизировано. То, что у меня есть сейчас, приведено ниже (обратите внимание, новое определение функции и домен следующие)
def find_single_root(v, w):
x = np.arange(-5*v/w, 6*w,0.1) # domain
... # rest of the function
vs = np.arange(1,5)
ws = np.arange(1,5)
zs = np.zeros((len(vs),len(ws)))
for i, v in enumerate(vs):
for j, w in enumerate(ws):
zs[i][j] = find_single_root(v,w)
Прямо сейчас у меня есть эти простые вложенные циклы for, но есть ли способ, которым я могу подойти к этому по-другому или ускорить его с помощью векторизации NumPy?