I'm trying to run some curve fitting by using Scipy's Optimize. I don't do this with polyfit because I want to ensure the curves are monotonic, given the relationship I have. So suppose I have the following relationship between sulphur and temperature:
sulphur = array([ 71., 82., 50., 113., 153., 177., 394., 1239., 2070., 2662., 3516., 4000., 4954., 6314.])
temperature = array([ 70., 90., 140., 165., 210., 235., 265., 330., 350., 390., 410., 435., 540., 580.])
And I want to find a curve to fit this relationship which is monotonically increasing.
I have found bits of code around, and this is what I have: I calculate the polynomial and use it in the objective function, and I constraint the first derivative to be positive for every point. I also use polyfit values as x0 in order to speed up operations:
x = sul
y = temperature
initial = list(reversed(np.polyfit(sul, temperature, 3)))
Nfeval = 1
def polynomial(p, x):
return p[0]+p[1]*x+p[2]*x**2+p[3]*x**3
def constraint_1st_der(p, x):
return p[1]+2*p[2]*x+3*p[3]*x**2
def objective(p, x):
return ((polynomial(p, x) - y)**2).sum()
def f(p):
return objective(p, x)
def callback(p):
global Nfeval
print(Nfeval, p, constraint_1st_der(p, x))
Nfeval += 1
cons = {'type' : 'ineq', 'fun' : lambda p : constraint_1st_der(p, x)}
res = optimize.minimize(f, x0=np.array(initial), method='SLSQP', constraints=cons, callback = callback)
However, optimize always returns:
fun: 4.0156824919527855e+23
jac: array([0.00000000e+00, 0.00000000e+00, 7.02561542e+17, 3.62183986e+20])
message: 'Inequality constraints incompatible'
nfev: 6
nit: 1
njev: 1
status: 4
success: False
x: array([ -111.35802358, 1508.06894349, -2969.11149743, 2223.26354865])
I tried normalizing (say sul_norm = sul / max(sul) works), and by doing this the optimization goes on successfully, but I'd like to avoid doing that (I have to invert the function at one point, and then it can get messy with coming back to the original value). Also, it seems to me the relationship is pretty basic and the values between temperature and sulphur are not so extremely on a different scale. What could it be? Thanks!