Example #1
0
    def test_FH_Square_vector_weight(self):
        # now the weight is a vector
        w = np.random.rand(29, 2)
        obj = SquareLoss(self.theta, self.ode, self.x0, self.t[0], self.t[1::],
                         self.solution[1::, :], ['V', 'R'], w)

        s = ((self.r * np.array(w))**2).sum()

        self.assertTrue(np.allclose(obj.cost(), s))
Example #2
0
    def test_FH_Square_scalar_weight(self):
        # weight for each component
        w = [2.0, 3.0]

        s = 0
        for i in range(2):
            s += ((self.r[:, i] * w[i])**2).sum()

        obj = SquareLoss(self.theta, self.ode, self.x0, self.t[0], self.t[1::],
                         self.solution[1::, :], ['V', 'R'], w)

        self.assertTrue(np.allclose(obj.cost(), s))
Example #3
0
    def test_FH_Obj(self):
        # initial values
        x0 = [-1.0, 1.0]
        t0 = 0
        # params
        paramEval = [('a', 0.2), ('b', 0.2),('c', 3.0)]

        ode = common_models.FitzHugh().setParameters(paramEval).setInitialValue(x0, t0)
        # the time points for our observations
        t = numpy.linspace(1, 20, 30).astype('float64')
        # Standard.  Find the solution which we will be used as "observations later"
        solution,output = ode.integrate(t, full_output=True)
        # initial guess
        theta = [0.5,0.5,0.5]

        #objFH = squareLoss(theta,ode,x0,t0,t,solution[1::,1],'R')
        objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,:], ['V','R'])
        
        g1 = objFH.adjoint(theta)
        #g2 = objFH.adjointInterpolate1(theta)
        #g3 = objFH.adjointInterpolate2(theta)
        g4 = objFH.sensitivity(theta)

        EPSILON = numpy.sqrt(numpy.finfo(numpy.float).eps)

        boxBounds = [
            (EPSILON, 5.0),
            (EPSILON, 5.0),
            (EPSILON, 5.0)
            ]

        res = scipy.optimize.minimize(fun=objFH.cost,
                                      jac=objFH.sensitivity,
                                      x0=theta,
                                      bounds=boxBounds,
                                      method='L-BFGS-B')

        res2 = scipy.optimize.minimize(fun=objFH.cost,
                                      jac=objFH.adjoint,
                                      x0=theta,
                                      bounds=boxBounds,
                                      method='L-BFGS-B')

        target = numpy.array([0.2, 0.2, 3.0])
        if numpy.any(abs(target-res['x']) >= 1e-2):
            raise Exception("Failed!")

        if numpy.any(abs(target-res2['x']) >= 1e-2):
            raise Exception("Failed!")
Example #4
0
    def test_FH_IV(self):
        # initial values
        x0 = [-1.0, 1.0]
        t0 = 0
        # params
        paramEval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]

        ode = common_models.FitzHugh().setParameters(
            paramEval).setInitialValue(x0, t0)
        # the time points for our observations
        t = numpy.linspace(1, 20, 30).astype('float64')
        # Standard.  Find the solution.
        solution, output = ode.integrate(t, full_output=True)
        # initial guess
        theta = [0.5, 0.5, 0.5]

        objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::, :], ['V', 'R'])

        EPSILON = numpy.sqrt(numpy.finfo(numpy.float).eps)

        boxBounds = [(EPSILON, 5.0), (EPSILON, 5.0), (EPSILON, 5.0),
                     (None, None), (None, None)]

        res = scipy.optimize.minimize(fun=objFH.costIV,
                                      jac=objFH.sensitivityIV,
                                      x0=theta + [-0.5, 0.5],
                                      bounds=boxBounds,
                                      method='L-BFGS-B')

        target = numpy.array([0.2, 0.2, 3.0, -1.0, 1.0])
        if numpy.any(abs(target - res['x']) >= 1e-2):
            raise Exception("Failed!")
Example #5
0
    def test_FH_Square_1State_Fail(self):
        totalFail = 0
        expectedFail = 4
        # initial values
        x0 = [-1.0, 1.0]
        # the time points for our observations
        t = numpy.linspace(0, 20, 30).astype('float64')
        # params
        paramEval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]

        ode = common_models.FitzHugh().setParameters(
            paramEval).setInitialValue(x0, t[0])

        # Standard.  Find the solution which we will be used as "observations later"
        solution, output = ode.integrate(t[1::], full_output=True)
        # initial guess
        theta = [0.5, 0.5, 0.5]

        wList = list()

        wList.append([-1.])
        wList.append([0])
        wList.append([2.0, 3.0])
        wList.append(numpy.random.rand(30))

        for w in wList:
            try:
                objFH = SquareLoss(theta, ode, x0, t[0], t[1::],
                                   solution[1::, :], 'R', w)
            except:
                totalFail += 1

        if totalFail != expectedFail:
            raise Exception("We passed some of the illegal input...")
Example #6
0
    def test_SIR_Estimate_SquareLoss_Adjoint(self):
        # define the model and parameters
        ode = common_models.SIR({'beta': 0.5, 'gamma': 1.0 / 3.0})

        # the initial state, normalized to zero one
        x0 = [1, 1.27e-6, 0]
        # set the time sequence that we would like to observe
        t = numpy.linspace(0, 150, 100)
        # Standard.  Find the solution.
        solution = scipy.integrate.odeint(ode.ode, x0, t)

        y = copy.copy(solution[:, 1:3])
        # initial value
        theta = [0.2, 0.2]

        objSIR = SquareLoss(theta, ode, x0, t[0], t[1::], y[1::, :],
                            ['I', 'R'])

        # constraints
        EPSILON = numpy.sqrt(numpy.finfo(numpy.float).eps)

        boxBounds = [(EPSILON, 5), (EPSILON, 5)]

        resQP = scipy.optimize.minimize(fun=objSIR.cost,
                                        jac=objSIR.adjoint,
                                        x0=theta,
                                        method='SLSQP',
                                        bounds=boxBounds)

        target = numpy.array([0.5, 1.0 / 3.0])
        if numpy.any(abs(resQP['x'] - target) >= 1e-2):
            raise Exception("Failed!")
Example #7
0
    def test_FH_Obj(self):
        # initial values
        x0 = [-1.0, 1.0]
        t0 = 0
        # params
        paramEval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]

        ode = common_models.FitzHugh().setParameters(
            paramEval).setInitialValue(x0, t0)
        # the time points for our observations
        t = numpy.linspace(1, 20, 30).astype('float64')
        # Standard.  Find the solution which we will be used as "observations later"
        solution, output = ode.integrate(t, full_output=True)
        # initial guess
        theta = [0.5, 0.5, 0.5]

        #objFH = squareLoss(theta,ode,x0,t0,t,solution[1::,1],'R')
        objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::, :], ['V', 'R'])

        g1 = objFH.adjoint(theta)
        #g2 = objFH.adjointInterpolate1(theta)
        #g3 = objFH.adjointInterpolate2(theta)
        g4 = objFH.sensitivity(theta)

        EPSILON = numpy.sqrt(numpy.finfo(numpy.float).eps)

        boxBounds = [(EPSILON, 5.0), (EPSILON, 5.0), (EPSILON, 5.0)]

        res = scipy.optimize.minimize(fun=objFH.cost,
                                      jac=objFH.sensitivity,
                                      x0=theta,
                                      bounds=boxBounds,
                                      method='L-BFGS-B')

        res2 = scipy.optimize.minimize(fun=objFH.cost,
                                       jac=objFH.adjoint,
                                       x0=theta,
                                       bounds=boxBounds,
                                       method='L-BFGS-B')

        target = numpy.array([0.2, 0.2, 3.0])
        if numpy.any(abs(target - res['x']) >= 1e-2):
            raise Exception("Failed!")

        if numpy.any(abs(target - res2['x']) >= 1e-2):
            raise Exception("Failed!")
Example #8
0
 def test_single_state_func(self):
     """
     Just to see if the functions manage to run at all
     """
     y = self.solution[1::, 2]
     # test out whether the single state function 'ok'
     sir_obj = SquareLoss(self.theta, self.ode, self.x0, self.t[0],
                          self.t[1::], y, 'R')
     sir_obj.cost()
     sir_obj.gradient()
     sir_obj.hessian()
Example #9
0
    def setUp(self):
        # initial values
        self.x0 = [-1.0, 1.0]
        # params
        self.param_eval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]
        # the time points for our observations
        self.t = np.linspace(0, 20, 30).astype('float64')
        self.ode = common_models.FitzHugh(self.param_eval)
        self.ode.initial_values = (self.x0, self.t[0])

        # Standard.  Find the solution which we will be used as
        # "observations later"
        self.solution = self.ode.integrate(self.t[1::])
        # initial guess
        self.theta = [0.5, 0.5, 0.5]

        obj = SquareLoss(self.theta, self.ode, self.x0, self.t[0], self.t[1::],
                         self.solution[1::, :], ['V', 'R'])
        self.r = obj.residual()
Example #10
0
class TestFHEstimate(TestCase):

    def setUp(self):
        # initial values
        x0 = [-1.0, 1.0]
        # params
        param_eval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]
        self.target = np.array([0.2, 0.2, 3.0])
        # the time points for our observations
        t = np.linspace(0, 20, 30).astype('float64')
        ode = common_models.FitzHugh(param_eval)
        ode.initial_values = (x0, t[0])
        solution = ode.integrate(t[1::])
        self.theta = np.array([0.5, 0.5, 0.5])

        self.obj = SquareLoss(self.theta, ode, x0, t[0],
                              t[1::], solution[1::, :], ['V', 'R'])

        g = self.obj.gradient()
        assert np.linalg.norm(g) > 0

        EPSILON = np.sqrt(np.finfo(np.float).eps)

        self.box_bounds = [(EPSILON, 5.0)]*len(self.theta)

    def test_FH_sensitivity(self):
        res = minimize(fun=self.obj.cost,
                       jac=self.obj.sensitivity,
                       x0=self.theta,
                       bounds=self.box_bounds,
                       method='L-BFGS-B')

        self.assertTrue(np.allclose(self.target, res['x'], 1e-2, 1e-2))

    def test_FH_adjoint(self):
        res = minimize(fun=self.obj.cost,
                       jac=self.obj.adjoint,
                       x0=self.theta,
                       bounds=self.box_bounds,
                       method='L-BFGS-B')

        self.assertTrue(np.allclose(self.target, res['x'], 1e-2, 1e-2))

    def test_FH_IV(self):
        box_bounds = self.box_bounds + [(None, None)]*2

        res = minimize(fun=self.obj.costIV,
                       jac=self.obj.sensitivityIV,
                       x0=self.theta.tolist() + [-0.5, 0.5],
                       bounds=box_bounds,
                       method='L-BFGS-B')

        target = np.array([0.2, 0.2, 3.0, -1.0, 1.0])
        self.assertTrue(np.allclose(res['x'], target, 1e-2, 1e-2))
Example #11
0
class TestFHEstimate(TestCase):
    def setUp(self):
        # initial values
        x0 = [-1.0, 1.0]
        # params
        param_eval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]
        self.target = np.array([0.2, 0.2, 3.0])
        # the time points for our observations
        t = np.linspace(0, 20, 30).astype('float64')
        ode = common_models.FitzHugh(param_eval)
        ode.initial_values = (x0, t[0])
        solution = ode.integrate(t[1::])
        self.theta = np.array([0.5, 0.5, 0.5])

        self.obj = SquareLoss(self.theta, ode, x0, t[0], t[1::],
                              solution[1::, :], ['V', 'R'])

        g = self.obj.gradient()
        assert np.linalg.norm(g) > 0

        EPSILON = np.sqrt(np.finfo(np.float).eps)

        self.box_bounds = [(EPSILON, 5.0)] * len(self.theta)

    def test_FH_sensitivity(self):
        res = minimize(fun=self.obj.cost,
                       jac=self.obj.sensitivity,
                       x0=self.theta,
                       bounds=self.box_bounds,
                       method='L-BFGS-B')

        self.assertTrue(np.allclose(self.target, res['x'], 1e-2, 1e-2))

    def test_FH_adjoint(self):
        res = minimize(fun=self.obj.cost,
                       jac=self.obj.adjoint,
                       x0=self.theta,
                       bounds=self.box_bounds,
                       method='L-BFGS-B')

        self.assertTrue(np.allclose(self.target, res['x'], 1e-2, 1e-2))

    def test_FH_IV(self):
        box_bounds = self.box_bounds + [(None, None)] * 2

        res = minimize(fun=self.obj.costIV,
                       jac=self.obj.sensitivityIV,
                       x0=self.theta.tolist() + [-0.5, 0.5],
                       bounds=box_bounds,
                       method='L-BFGS-B')

        target = np.array([0.2, 0.2, 3.0, -1.0, 1.0])
        self.assertTrue(np.allclose(res['x'], target, 1e-2, 1e-2))
Example #12
0
    def test_SIR_Estimate_SquareLoss(self):
        y = self.solution[1::, 1:3]
        sir_obj = SquareLoss(self.theta, self.ode, self.x0, self.t[0],
                             self.t[1::], y, ['I', 'R'])

        res_QP = scipy.optimize.minimize(fun=sir_obj.cost,
                                         jac=sir_obj.sensitivity,
                                         x0=self.theta,
                                         method='SLSQP',
                                         bounds=self.box_bounds)

        self.assertTrue(np.allclose(res_QP['x'], self.target, 1e-2, 1e-2))
Example #13
0
 def test_single_state_func(self):
     """
     Just to see if the functions manage to run at all
     """
     y = self.solution[1::, 2]
     # test out whether the single state function 'ok'
     sir_obj = SquareLoss(self.theta, self.ode, self.x0, self.t[0],
                          self.t[1::], y, 'R')
     sir_obj.cost()
     sir_obj.gradient()
     sir_obj.hessian()
Example #14
0
    def setUp(self):
        # initial values
        x0 = [-1.0, 1.0]
        # params
        param_eval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]
        self.target = np.array([0.2, 0.2, 3.0])
        # the time points for our observations
        t = np.linspace(0, 20, 30).astype('float64')
        ode = common_models.FitzHugh(param_eval)
        ode.initial_values = (x0, t[0])
        solution = ode.integrate(t[1::])
        self.theta = np.array([0.5, 0.5, 0.5])

        self.obj = SquareLoss(self.theta, ode, x0, t[0], t[1::],
                              solution[1::, :], ['V', 'R'])

        g = self.obj.gradient()
        assert np.linalg.norm(g) > 0

        EPSILON = np.sqrt(np.finfo(np.float).eps)

        self.box_bounds = [(EPSILON, 5.0)] * len(self.theta)
Example #15
0
    def test_FH_Square(self):
        # initial values
        x0 = [-1.0, 1.0]
        # params
        paramEval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]
        # the time points for our observations
        t = numpy.linspace(0, 20, 30).astype('float64')
        ode = common_models.FitzHugh().setParameters(
            paramEval).setInitialValue(x0, t[0])
        # Standard.  Find the solution which we will be used as "observations later"
        solution, output = ode.integrate(t[1::], full_output=True)
        # initial guess
        theta = [0.5, 0.5, 0.5]

        #objFH = squareLoss(theta,ode,x0,t0,t,solution[1::,1],'R')
        objFH = SquareLoss(theta, ode, x0, t[0], t[1::], solution[1::, :],
                           ['V', 'R'])

        r = objFH.residual()

        # weight for each component
        w = [2.0, 3.0]

        s1 = 0
        for i in range(2):
            s1 += ((r[:, i] * w[i])**2).sum()

        objFH1 = SquareLoss(theta, ode, x0, t[0], t[1::], solution[1::, :],
                            ['V', 'R'], w)

        # now the weight is a vector
        w = numpy.random.rand(29, 2)
        objFH2 = SquareLoss(theta, ode, x0, t[0], t[1::], solution[1::, :],
                            ['V', 'R'], w)

        s2 = ((r * numpy.array(w))**2).sum()

        if abs(objFH1.cost() - s1) >= 1e-2:
            raise Exception("Failed!")

        if abs(objFH2.cost() - s2) >= 1e-2:
            raise Exception("Failed!")
Example #16
0
    def test_SIR_Estimate_SquareLoss(self):
        # define the model and parameters
        ode = common_models.SIR({'beta':0.5,'gamma':1.0/3.0})

        # the initial state, normalized to zero one
        x0 = [1, 1.27e-6, 0]
        # set the time sequence that we would like to observe
        t = numpy.linspace(0, 150, 100)
        # Standard.  Find the solution.
        solution = scipy.integrate.odeint(ode.ode, x0, t)

        # y = copy.copy(solution[:,1:3])
        # initial value
        theta = [0.2, 0.2]

        # test out whether the single state function 'ok'
        objSIR = SquareLoss(theta, ode, x0, t[0], t[1::],
                            solution[1::,2], 'R')
        objSIR.cost()
        objSIR.gradient()
        objSIR.hessian()

        # now we go on the real shit
        objSIR = SquareLoss(theta, ode, x0, t[0], t[1::],
                            solution[1::,1:3], ['I','R'])

        # constraints
        EPSILON = numpy.sqrt(numpy.finfo(numpy.float).eps)

        boxBounds = [(EPSILON, 5), (EPSILON, 5)]

        resQP = scipy.optimize.minimize(fun=objSIR.cost,
                                        jac=objSIR.sensitivity,
                                        x0=theta,
                                        method='SLSQP',
                                        bounds=boxBounds)

        target = numpy.array([0.5, 1.0/3.0])
        if numpy.any(abs(resQP['x']-target) >= 1e-2):
            raise Exception("Failed!")
Example #17
0
    def setUp(self):
        # initial values
        x0 = [-1.0, 1.0]
        # params
        param_eval = [('a', 0.2), ('b', 0.2), ('c', 3.0)]
        self.target = np.array([0.2, 0.2, 3.0])
        # the time points for our observations
        t = np.linspace(0, 20, 30).astype('float64')
        ode = common_models.FitzHugh(param_eval)
        ode.initial_values = (x0, t[0])
        solution = ode.integrate(t[1::])
        self.theta = np.array([0.5, 0.5, 0.5])

        self.obj = SquareLoss(self.theta, ode, x0, t[0],
                              t[1::], solution[1::, :], ['V', 'R'])

        g = self.obj.gradient()
        assert np.linalg.norm(g) > 0

        EPSILON = np.sqrt(np.finfo(np.float).eps)

        self.box_bounds = [(EPSILON, 5.0)]*len(self.theta)
Example #18
0
    def test_FH_Square(self):
        # initial values
        x0 = [-1.0, 1.0]
        # params
        paramEval = [('a', 0.2), ('b', 0.2),('c', 3.0)]
        # the time points for our observations
        t = numpy.linspace(0, 20, 30).astype('float64')
        ode = common_models.FitzHugh().setParameters(paramEval).setInitialValue(x0, t[0])
        # Standard.  Find the solution which we will be used as "observations later"
        solution, output = ode.integrate(t[1::], full_output=True)
        # initial guess
        theta = [0.5, 0.5, 0.5]

        #objFH = squareLoss(theta,ode,x0,t0,t,solution[1::,1],'R')
        objFH = SquareLoss(theta, ode, x0, t[0], t[1::], solution[1::,:], ['V','R'])

        r = objFH.residual()

        # weight for each component
        w = [2.0, 3.0]

        s1 = 0
        for i in range(2): s1 += ((r[:,i]*w[i])**2).sum()

        objFH1 = SquareLoss(theta, ode, x0, t[0], t[1::], solution[1::,:],
                   ['V','R'], w)

        # now the weight is a vector
        w = numpy.random.rand(29, 2)
        objFH2 = SquareLoss(theta, ode, x0, t[0], t[1::], solution[1::,:],
                   ['V','R'], w)

        s2 = ((r * numpy.array(w))**2).sum()

        if abs(objFH1.cost() - s1) >= 1e-2:
            raise Exception("Failed!")
        
        if abs(objFH2.cost() - s2) >= 1e-2:
            raise Exception("Failed!")
Example #19
0
import scipy.optimize

x0 = [-1.0,1.0]
t0 = 0
# params
paramEval = [('a',0.2), ('b',0.2),('c',3.0)]

ode = common_models.FitzHugh().setParameters(paramEval).setInitialValue(x0,t0)
# the time points for our observations
t = numpy.linspace(1, 20, 100).astype('float64')
# Standard.  Find the solution.
solution,output = ode.integrate(t,full_output=True)

theta = [0.5,0.5,0.5]

objFH = SquareLoss(theta,ode,x0,t0,t,solution[1::,:],['V','R'])

res = scipy.optimize.minimize(fun=objFH.cost,
                              jac=objFH.sensitivity,
                              hess=objFH.jtj,
                              x0 = theta,
                              method = 'dogleg',
                              options = {'disp':True},
                              callback=objFH.thetaCallBack)

boxBounds = [
    (1e-4,5.0),
    (1e-4,5.0),
    (1e-4,5.0)
    ]
boxBoundsArray = numpy.array(boxBounds)
Example #20
0

x0 = [-1.0,1.0]
t0 = 0
# params
paramEval = [('a',0.2), ('b',0.2),('c',3.0)]

ode = common_models.FitzHugh().setParameters(paramEval).setInitialValue(x0,t0)
# the time points for our observations
t = numpy.linspace(1, 20, 100).astype('float64')
# Standard.  Find the solution.
solution,output = ode.integrate(t,full_output=True)

theta = [0.5,0.5,0.5]

objFH = SquareLoss(theta,ode,x0,t0,t,solution[1::,:],['V','R'])

boxBounds = [
    (1e-4,5.0),
    (1e-4,5.0),
    (1e-4,5.0)
    ]
boxBoundsArray = numpy.array(boxBounds)

xhat = objFH.fit(theta,lb=boxBoundsArray[:,0],ub=boxBoundsArray[:,1])

from cvxopt import solvers, matrix
solvers.options['abstol'] = 1e-4
solvers.options['reltol'] = 1e-4

def odeObj(obj, theta, boxBounds):
Example #21
0
Q = list(df['Q'])
C = list(df['C'])
R = list(df['R'])
y = []
t = []
for i in range(1, len(S)):
    y.append([S[i], E[i], I[i], Q[i], R[i]])
    t.append(i)

states = ['S', 'E', 'I', 'Q', 'C', 'R']
params = ['A', 'q', 'mu1', 'mu2', 'mu3', 'd1', 'd2','d3', 'delta', 'delta1', 'delta2', 'p1', 'alpha', 'beta']
odeList = [ Transition(origin='S',equation='A - (delta*S) - (beta*S*I) - (alpha*C*S) - q*S',transition_type=TransitionType.ODE),
           Transition(origin='E',equation='(beta*I*S) - (delta*E) - (delta1*E) + (alpha*C*S)',transition_type=TransitionType.ODE),
           Transition(origin='I',equation='delta1*E - (delta*I) - (delta2*I) - (mu1*I) - (d1*I)',transition_type=TransitionType.ODE),
           Transition(origin='Q',equation='(p1*delta2*I) - (delta*Q) - (mu2*Q) - (d2*Q)',transition_type=TransitionType.ODE),
           Transition(origin='C',equation='(delta2*I*(1-p1)) - (delta*C) - (mu3*C) - (d3*C)',transition_type=TransitionType.ODE),
           Transition(origin='R',equation='mu1*I + mu2*Q + mu3*C - delta*R',transition_type=TransitionType.ODE)]
model = DeterministicOde (states, params, ode =odeList)
init_state = [60461803,2703,94, 127, 2948,1]
param_eval =  [('A', 0.007896),('q',0.01), ('mu1', 0.4554), ('mu2', 1.21382), ('mu3', 0.1325), ('d1',0.24203), ('d2', 0.55586),('d3', 0.07849), ('delta', 0.000213), ('delta1',0.196), ('delta2',0.996), ('alpha',0.000000196), ('beta', 0.000034196), ('p1',0.96)]
model.intial_values = (init_state, [0])
model.parameters = param_eval
# sol = odeint(model.ode, init_state, t[1:])
# print(sol)
# print(sol.size)
theta = [0.5, 0.9, 0.05, 0.05]
bounds = [(0,1),(0,1),(0,1),(0,1)]

objFH = SquareLoss(theta=theta, ode=model, x0=init_state, t0=[0], t=t, y=y, state_name=['S', 'E', 'I', 'Q', 'R'], target_param = ['delta2', 'p1', 'alpha', 'beta'])
res = minimize(fun=objFH.cost, jac=objFH.sensitivity, x0=theta, bounds = bounds, options={'disp': True})