我试图拟合一个函数y(x,T,p)
来得到系数a
,b
,c
,d
,e
,f
。p
是已知的。使用全局优化器,我想找到一个好的起点。shgo
似乎是唯一一个接受constraints
的。
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: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我不知道这个错误意味着什么,其他线程有同样的错误并没有真正帮助我理解.当我使用一个局部极小化(scipy.optimize.minimize
与方法cobyla
)的错误没有出现.
有没有人能帮助我了解我的问题,甚至帮助解决它?谢谢
编辑:
Traceback (most recent call last):
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 759, in __getitem__
return self.cache[x]
KeyError: (0, 0, 0, 0, 0, 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/.../test.py", line 70, in <module>
res = shgo(resid, bounds, constraints=con1)
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo.py", line 423, in shgo
shc.construct_complex()
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo.py", line 726, in construct_complex
self.iterate()
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo.py", line 869, in iterate
self.iterate_complex()
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo.py", line 890, in iterate_hypercube
self.g_args)
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 121, in __init__
self.n_cube(dim, symmetry=symmetry)
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 172, in n_cube
self.C0.add_vertex(self.V[origintuple])
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 767, in __getitem__
index=self.index)
File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 681, in __init__
if g(self.x_a, *args) < 0.0:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
2条答案
按热度按时间5gfr0r5j1#
问题是,
der
返回的是数组而不是标量值。至
移除错误。这会将
der
的每个输出转换成它自己的不等式限制。zdwk9cvp2#
此外,由于您的约束都被写为
der(x)>=0
,因此可以简单地保留具有向量输出的oyur约束的定义,然后获取输出的最小值,即,取标量值约束x -> \min (der(x))
。