«scipy.optimize.minimize» игнорирует ограничение, деривация везде положительная - PullRequest
0 голосов
/ 03 марта 2019

У меня есть функция z(T,x,p).С моими заданными точками данных я хочу соответствовать функции и получить коэффициенты функции.Мое ограничение заключается в том, что вывод z после x должен быть положительным везде dz/dx > 0.Но в моем следующем коде ограничение не работает, и я не знаю почему.

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

T = np.array([262,257,253,261,260,243,300,283,282], dtype=float)
p = np.array([25,22,19,24,24,14,62,45,44], dtype=float)
x = np.array([0.1,0.1,0.2,0.2,0.3,0.3,1,0.3,0.2], dtype=float)
z = np.array([10,9,13,16,20,12,62,37,28], dtype=float)

def func(pars, T, x, p):    #my actual function
    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

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

def der(pars): # constraint function: Derivation of func() after x positive everywhere
    a,b,c,d,e,f = pars
    return p+p*(2*x*a+2*x*b*T+2*x*c*T**2+3*x**2*d+3*x**2*e*T+3*x**2*f*T**2)+p*(a+b*T+c*T**2+2*x*d+2*e*x*T+2*f*x*T**2)

con1 = (dict(type='ineq', fun=der))
pars0 = np.array([0,0,0,0,0,0])
res = minimize(resid, pars0, method='cobyla',options={'maxiter': 5000000}, constraints=con1)
print("a = %f , b = %f, c = %f, d = %f, e = %f, f = %f" % (res.x[0], res.x[1], res.x[2], res.x[3], res.x[4], res.x[5]))

Попытка построить пример:

x0 = np.linspace(0, 1, 100) # plot two example graphs z(x) for a certain T and p
fig, ax = plt.subplots()
fig.dpi = 80
ax.plot(x,z,'ro', label='data')
ax.plot(x0, func(res.x, 300, x0, 62), '-', label='fit T=300, p=62')
ax.plot(x0, func(res.x, 283, x0, 45), '-', label='fit T=283, p=45')
plt.xlabel('x')
plt.ylabel('z')
plt.legend()
plt.show()

examplePlot

Как видите, деривация (градиент) не везде положительна.Я не знаю, почему ограничение игнорируется.Может быть, кто-то может мне помочь.

...