Python scipy.optimize.shgo ValueError:包含多个元素的数组的真值不明确。使用a.any()或a.all()

Python scipy.optimize.shgo ValueError:包含多个元素的数组的真值不明确。使用a.any()或a.all(),python,scipy,curve-fitting,Python,Scipy,Curve Fitting,我试图拟合一个函数y(x,T,p),得到系数a,b,c,d,e,f。已知y、x、T、p的数据。有了全局优化器,我想找到一个好的起点shgo似乎是唯一接受约束的人 import numpy as np import matplotlib.pyplot as plt from scipy.optimize import shgo # test data x = np.array([0.1,0.2,0.3,1]) T = np.array([300,300,300,300]) p = np.arra

我试图拟合一个函数
y(x,T,p)
,得到系数
a
b
c
d
e
f
。已知
y
x
T
p
的数据。有了全局优化器,我想找到一个好的起点
shgo
似乎是唯一接受
约束的人

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import shgo

# test data
x = np.array([0.1,0.2,0.3,1])
T = np.array([300,300,300,300])
p = np.array([67.2,67.2,67.2,67.2])
y = np.array([30,50,55,67.2])

# function
def func(pars,x,T,p):
    a,b,c,d,e,f = pars
    return x*p+x*(1-x)*(a+b*T+c*T**2+d*x+e*x*T+f*x*T**2)*p

# residual
def resid(pars):
    return ((func(pars,x,T,p) - y) ** 2).sum()

# constraint: derivation is positive in every data point
def der(pars):
    a,b,c,d,e,f = pars
    return -p*((3*f*T**2+3*e*T+3*d)*x**2+((2*c-2*f)*T**2+(2*b-2*e)*T-2*d+2*a)*x-c*T**2-b*T-a-1)

con1 = ({'type':'ineq', 'fun':der})

# minimizer shgo
bounds = [(-1,1),(-1,1),(-1,1),(-1,1),(-1,1),(-1,1)]
res = shgo(resid, bounds, constraints=con1)
print("a = %f , b = %f, c = %f, d = %f, e = %f, f = %f" % (res[0], res[1], res[2], res[3], res[4], res[5]))

# plotting
x0 = np.linspace(0, 1, 100)
fig, ax = plt.subplots()
fig.dpi = 80
ax.plot(x,y,'ro',label='data')
for i,txt in enumerate(T):
    ax.annotate(txt,(x[i],y[i]))
ax.plot(x0, func(res.x, x0, 300,67.2), '-', label='fit1')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()
通过这一点,我得到了
ValueError:包含多个元素的数组的真值是不明确的。使用a.any()或a.all()
我不知道这个错误意味着什么,而具有相同错误的其他线程并不能真正帮助我理解。当我使用局部极小值(
scipy.optimize.minimize
方法
cobyla
)时,不会出现错误

有人能帮我理解我的问题,甚至帮我解决它吗? 谢谢

编辑:

回溯(最近一次呼叫最后一次):
文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo\u lib\triangulation.py”,第759行,在u getitem中__
返回self.cache[x]
KeyError:(0,0,0,0,0,0,0)
在处理上述异常期间,发生了另一个异常:
回溯(最近一次呼叫最后一次):
文件“C:/Users/../test.py”,第70行,在
res=shgo(剩余、边界、约束=con1)
shgo中第423行的文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo.py”
shc.Construction_complex()
文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo.py”,第726行,在construct\u complex中
self.iterate()
文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo.py”,第869行,在iterate中
self.iterate_complex()
文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo.py”,第890行,在迭代超立方体中
self.g_args)
文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo\u lib\triangulation.py”,第121行,在u init中__
self.n_立方体(尺寸,对称=对称)
文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo\u lib\triangulation.py”,第172行,在n\u cube中
self.C0.add_顶点(self.V[origintuple])
文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo\u lib\triangulation.py”,第767行,在u getitem中__
索引=自索引)
文件“C:\Users\…\Python\Python36\site packages\scipy\optimize\\u shgo\u lib\triangulation.py”,第681行,在u init中__
如果g(self.x_a,*args)<0.0:
ValueError:包含多个元素的数组的真值不明确。使用a.any()或a.all()

问题是,
der
返回一个数组而不是标量值。改变

con1 = ({'type':'ineq', 'fun':der})


删除错误。这会将
der
的每个输出转换为其自身的不等式约束。

如果要测试除shgo之外的其他优化器,可以尝试在函数中实现“砖墙”,以在违反任何给定约束时返回一个大错误,例如1.0E10。虽然初始参数估计必须在允许优化器开始的约束范围内,但这种简单的技术有时在实践中非常有用。如果您显示了错误回溯,则会有所帮助,以便我们(并且您)可以看到错误发生的位置。在简单的真/假测试中使用数组时,会发生类似这样的错误。我怀疑它与
con1
约束有关,例如
def
返回一个数组而不是单个值。但我们真的需要追踪。我已经编辑了我的帖子。
con1 = ({'type':'ineq', 'fun':der})
con_list = [{'type':'ineq', 'fun': lambda x: der(x)[i_out]} for i_out in range(T.shape[0])]