Search code examples
pythonpython-3.xscipyleast-squares

error in constraint of square fitting in scipy.optimize.minimize function


I am fitting my data to least sq fitting. I give constraints for the fitting though as shown below. 'Experiment_norm' is not defined but it is containing my data and calling my data to the code wasn't an issue so I did not put it in my question here. But one thing that I meant to ask in my constraints were to say that p[3], p[4], p[5], p[6], and p[7] to be less than 1. But when I call for the optimized parameters for p[3], p[4], p[5], p[6], and p[7], they are greater than 1. Am I doing something wrong?

def myerr(p, xdata, ydata):  
return sum((ydata - calculate_spectrum(p,xdata))**2)

con = ({'type': 'eq', 'fun': lambda p: p[11]+p[12]+p[13]-1}, {'type': 'ineq', 'fun': lambda p: p[11]}, {'type': 'ineq', 'fun': lambda p: p[12]},{'type': 'ineq', 'fun': lambda p: p[13]},{'type': 'ineq', 'fun': lambda p: p[3]-1},{'type': 'ineq', 'fun': lambda p: p[4]-1},{'type': 'ineq', 'fun': lambda p: p[5]-1},{'type': 'ineq', 'fun': lambda p: p[6]-1},{'type': 'ineq', 'fun': lambda p: p[7]-1})
p0 = [m,z,3000,0.3,0.3,0.1,0.2,0.3,0.4,0.4,0.4,0.2,0.5,0.6]
p_opt = scipy.optimize.minimize(myerr, p0, args=(mz,experiment_norm), constraints = con)

Solution

  • From the documentation:

    Equality constraint means that the constraint function result is to be zero whereas inequality means that it is to be non-negative.

    Let's look at one of your constraints:

    {'type': 'ineq', 'fun': lambda p: p[3]-1}
    

    Non-negative means that p[3] - 1 must be greater or equal to zero. So p[3] - 1 >= 0 or p[3] >= 1. You did not specify the contstraint to be less than one but to be greater than one! What you want instead is this:

    {'type': 'ineq', 'fun': lambda p: 1-p[3]}
    

    Note that you can also group multiple contstraints together for simpler code:

    {'type': 'ineq', 'fun': lambda p: [1-p[3], 1-p[4], 1-p[5], 1-p[6], 1-p[7]]}
    

    or if p is a numpy array:

    {'type': 'ineq', 'fun': lambda p: 1-p[3:8]}