Laura
Laura

Reputation: 1872

why is scipy.minimize ignoring my constraints?

I have a constrained optimization problem that I am trying to solve using scipy.optimize.minimize.

Basically, I am fitting one parameter, f, to a system of ODEs with the constraint: f >0 and

f*1000< 500

I wrote a MWE below. In this simple case, it is obvious that 0<f<0.5, but in my real problem, it is not obvious the a-priori upper bound, hence the inequality contraint.

from __future__ import division
import numpy as np
from scipy.integrate import odeint
from scipy.optimize import minimize

def myeqs(y,t,beta, gamma,N):
    dy0 = -(beta/N)*y[0]*y[1]
    dy1 = (beta/N)*y[0]*y[1] - gamma*y[1]
    dy2 = gamma*y[1]

    return [dy0,dy1,dy2]

def runModel(f, extraParams):
    [beta, gamma, N, initCond, time]= extraParams
    S0 = (1-f)*initCond[0]
    I0 = initCond[1]
    R0 = f*initCond[0]
    tspan = np.linspace(time[0], time[1], int(time[1] - time[0]))
    sol = odeint(myeqs, [S0,I0,R0], tspan, args=(beta, gamma, N))
    return sol

y0 = [1000, 1, 0]
extraParams = [0.5, 0.25, 1000, y0, [0,150]]


def computeSimple(f, extraParams):
   sol = runModel(f, extraParams)
   return np.abs((sol[-1,2] - sol[0,2]))


def c1(f):
    return f*1000.0 - 500.0


cons = ({'type': 'ineq', 'fun': c1})

#cons = ({'type': 'ineq',
 #  'fun': lambda x: x[0]*1000 - 500}, )

res = minimize(computeSimple, 0.2, args=(extraParams, ), method='SLSQP',       bounds=((0,1.5), ), constraints=cons)
print res.x

print c1(res.x)

If you run this, you will see that res.x is always the upper bound of bounds, regardless of the contraints... Where is my mistake? thanks in advance

Upvotes: 2

Views: 919

Answers (1)

user2357112
user2357112

Reputation: 280778

You got your constraint backward. This constraint:

def c1(f):
    return f*1000.0 - 500.0

is constraining f to be at least 0.5, instead of at most 0.5

Upvotes: 2

Related Questions