是否可以用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值的2D数组,其中每个值都是优化的。我现在的内容如下(注意,新的函数定义和域如下所示)
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矢量化来加速它呢?
发布于 2017-01-22 03:37:42
当要执行的计算精确地提前知道时,可以适用于矢量化。比如“取两个数字数组,然后成对地将它们相乘”。
当计算适应于给定的数据时,向量化不适用。任何一种优化算法都是自适应的,因为在哪里寻找最小值取决于函数返回的内容。如果您有一组函数,并且需要找到每个函数的最小值,则必须在一个循环中每次最小化一个函数。如果这个过程很慢,那是因为最小化一组函数需要很长时间,而不是因为程序中有一个for循环。
关于您的程序,我将尝试使用一些SciPy方法进行最小化和根查找。有一个函数min_of_f(z),它为参数z的给定值找到最小值,可能使用minimize_scalar。然后将min_of_f提供给寻根例程。它们的耐受性参数(xtol和其他参数)可以控制它们所需的时间。
OP编辑:我想把这个归功于正确的答案,但仍然提供了更多的信息。
最后,我使用numpy.vectorize对问题进行矢量化,而不对问题进行重构。虽然numpy.vectorize并不是为了提高性能,但在我的具体用例中,性能是提高两个性能的一个适度因素。将同样的方法应用于问题中的原始问题,结果几乎没有提高100x100向量的速度,所以YMMV。
尽管由于上面给出的原因,我无法从速度方面向量化这个问题,但是能够使用普通的向量语法而不是嵌套的for循环在我的代码中是很有用的。
https://stackoverflow.com/questions/41786683
复制相似问题