我有一个优化问题(1d)以2种方式编码 - 一个使用for循环,另一个使用numpy数组。 for循环版本工作正常但是numpy版本失败了。 实际上它有点复杂,它可以使用不同的起点(!!)或者如果我选择其他优化算法,如CG。
2个版本(函数和渐变)给出了相同的结果,返回的类型也尽可能相同。
这是我的例子,我错过了什么?
import numpy as np
from scipy.optimize import minimize
# local params
v1 = np.array([1., 1.])
v2 = np.array([1., 2.])
# local functions
def f1(x):
s = 0
for i in range(len(v1)):
s += (v1[i]*x-v2[i])**2
return 0.5*s/len(v1)
def df1(x):
g = 0
for i in range(len(v1)):
g += v1[i]*(v1[i]*x-v2[i])
return g/len(v1)
def f2(x):
return 0.5*np.sum((v1*x-v2)**2)/len(v1)
def df2(x):
return np.sum(v1*(v1*x-v2))/len(v1)
x0 = 10. # x0 = 2 works
# tests...
assert np.abs(f1(x0)-f2(x0)) < 1.e-6 and np.abs(df1(x0)-df2(x0)) < 1.e-6 \
and np.abs((f1(x0+1.e-6)-f1(x0))/(1.e-6)-df1(x0)) < 1.e-4
# BFGS for f1: OK
o = minimize(f1, x0, method='BFGS', jac=df1)
if not o.success:
print('FAILURE', o)
else:
print('SUCCESS min = %f reached at %f' % (f1(o.x[0]), o.x[0]))
# BFGS for f2: failure
o = minimize(f2, x0, method='BFGS', jac=df2)
if not o.success:
print('FAILURE', o)
else:
print('SUCCESS min = %f reached at %f' % (f2(o.x[0]), o.x[0]))
我得到的错误是
A1 = I - sk[:, numpy.newaxis] * yk[numpy.newaxis, :] * rhok
IndexError: invalid index to scalar variable.
但我并没有真正帮助我,因为它可以与其他一些起始值一起使用。
我正在使用全新的python安装(python 3.5.2,scipy 0.18.1和numpy 1.11.3)。
答案 0 :(得分:0)
求解器期望jacobian df2的返回值与其输入x相同。即使您在此处传递了标量,它实际上也已转换为单个元素ndarray。由于使用了np.sum,因此结果变成标量,这会导致发生奇怪的事情。
用np.array封装df2的标量结果,您的代码应该可以工作。