def test_minimize(self): """ Tests maximizing a function with and without constraints, taken from the scipy `minimize` tutorial. Compare the symfit result with the scipy result. https://docs.scipy.org/doc/scipy-0.18.1/reference/tutorial/optimize.html#constrained-minimization-of-multivariate-scalar-functions-minimize """ x = Parameter(-1.0) y = Parameter(1.0) z = Variable() model = {z: 2*x*y + 2*x - x**2 - 2*y**2} constraints = [ Ge(y - 1, 0), # y - 1 >= 0, Eq(x**3 - y, 0), # x**3 - y == 0, ] def func(x, sign=1.0): """ Objective function """ return sign*(2*x[0]*x[1] + 2*x[0] - x[0]**2 - 2*x[1]**2) def func_deriv(x, sign=1.0): """ Derivative of objective function """ dfdx0 = sign*(-2*x[0] + 2*x[1] + 2) dfdx1 = sign*(2*x[0] - 4*x[1]) return np.array([ dfdx0, dfdx1 ]) cons = ( {'type': 'eq', 'fun' : lambda x: np.array([x[0]**3 - x[1]]), 'jac' : lambda x: np.array([3.0*(x[0]**2.0), -1.0])}, {'type': 'ineq', 'fun' : lambda x: np.array([x[1] - 1]), 'jac' : lambda x: np.array([0.0, 1.0])}) # Unconstrained fit res = minimize(func, [-1.0,1.0], args=(-1.0,), jac=func_deriv, method='SLSQP', options={'disp': False}) fit = Maximize(model) fit_result = fit.execute() self.assertAlmostEqual(fit_result.value(x), res.x[0]) self.assertAlmostEqual(fit_result.value(y), res.x[1]) # Same test, but with constraints in place. res = minimize(func, [-1.0,1.0], args=(-1.0,), jac=func_deriv, constraints=cons, method='SLSQP', options={'disp': False}) fit = Maximize(model, constraints=constraints) self.assertEqual(fit.constraints[0].constraint_type, Ge) self.assertEqual(fit.constraints[1].constraint_type, Eq) fit_result = fit.execute() self.assertAlmostEqual(fit_result.value(x), res.x[0]) self.assertAlmostEqual(fit_result.value(y), res.x[1])
def test_constraint_types(self): x = Parameter(-1.0) y = Parameter(1.0) z = Variable() model = {z: 2 * x * y + 2 * x - x**2 - 2 * y**2} # These types are not allowed constraints. for relation in [Lt, Gt, Ne]: with self.assertRaises(ModelError): Maximize(model, constraints=[relation(x, y)]) # Should execute without problems. for relation in [Eq, Ge, Le]: Maximize(model, constraints=[relation(x, y)]) fit = Maximize(model, constraints=[Le(x, y)]) # Le should be transformed to Ge self.assertIs(fit.constraints[0].constraint_type, Ge) # Redo the standard test as a Le constraints = [ Le(-y + 1, 0), # y - 1 >= 0, Eq(x**3 - y, 0), # x**3 - y == 0, ] std_constraints = [ Ge(y - 1, 0), # y - 1 >= 0, Eq(x**3 - y, 0), # x**3 - y == 0, ] fit = Maximize(model, constraints=constraints) std_fit = Maximize(model, constraints=std_constraints) self.assertEqual(fit.constraints[0].constraint_type, Ge) self.assertEqual(fit.constraints[1].constraint_type, Eq) fit_result = fit.execute() std_result = std_fit.execute() self.assertAlmostEqual(fit_result.value(x), std_result.value(x)) self.assertAlmostEqual(fit_result.value(y), std_result.value(y))
def test_constraint_types(self): x = Parameter(-1.0) y = Parameter(1.0) z = Variable() model = {z: 2*x*y + 2*x - x**2 - 2*y**2} # These types are not allowed constraints. for relation in [Lt, Gt, Ne]: with self.assertRaises(ModelError): Maximize(model, constraints=[relation(x, y)]) # Should execute without problems. for relation in [Eq, Ge, Le]: Maximize(model, constraints=[relation(x, y)]) fit = Maximize(model, constraints=[Le(x, y)]) # Le should be transformed to Ge self.assertIs(fit.constraints[0].constraint_type, Ge) # Redo the standard test as a Le constraints = [ Le(- y + 1, 0), # y - 1 >= 0, Eq(x**3 - y, 0), # x**3 - y == 0, ] std_constraints = [ Ge(y - 1, 0), # y - 1 >= 0, Eq(x**3 - y, 0), # x**3 - y == 0, ] fit = Maximize(model, constraints=constraints) std_fit = Maximize(model, constraints=std_constraints) self.assertEqual(fit.constraints[0].constraint_type, Ge) self.assertEqual(fit.constraints[1].constraint_type, Eq) fit_result = fit.execute() std_result = std_fit.execute() self.assertAlmostEqual(fit_result.value(x), std_result.value(x)) self.assertAlmostEqual(fit_result.value(y), std_result.value(y))
def test_minimize(self): """ Tests maximizing a function with and without constraints, taken from the scipy `minimize` tutorial. Compare the symfit result with the scipy result. https://docs.scipy.org/doc/scipy-0.18.1/reference/tutorial/optimize.html#constrained-minimization-of-multivariate-scalar-functions-minimize """ x = Parameter(-1.0) y = Parameter(1.0) z = Variable() model = {z: 2 * x * y + 2 * x - x**2 - 2 * y**2} constraints = [ Ge(y - 1, 0), # y - 1 >= 0, Eq(x**3 - y, 0), # x**3 - y == 0, ] def func(x, sign=1.0): """ Objective function """ return sign * (2 * x[0] * x[1] + 2 * x[0] - x[0]**2 - 2 * x[1]**2) def func_deriv(x, sign=1.0): """ Derivative of objective function """ dfdx0 = sign * (-2 * x[0] + 2 * x[1] + 2) dfdx1 = sign * (2 * x[0] - 4 * x[1]) return np.array([dfdx0, dfdx1]) cons = ({ 'type': 'eq', 'fun': lambda x: np.array([x[0]**3 - x[1]]), 'jac': lambda x: np.array([3.0 * (x[0]**2.0), -1.0]) }, { 'type': 'ineq', 'fun': lambda x: np.array([x[1] - 1]), 'jac': lambda x: np.array([0.0, 1.0]) }) # Unconstrained fit res = minimize(func, [-1.0, 1.0], args=(-1.0, ), jac=func_deriv, method='SLSQP', options={'disp': False}) fit = Maximize(model) fit_result = fit.execute() self.assertAlmostEqual(fit_result.value(x), res.x[0]) self.assertAlmostEqual(fit_result.value(y), res.x[1]) # Same test, but with constraints in place. res = minimize(func, [-1.0, 1.0], args=(-1.0, ), jac=func_deriv, constraints=cons, method='SLSQP', options={'disp': False}) fit = Maximize(model, constraints=constraints) self.assertEqual(fit.constraints[0].constraint_type, Ge) self.assertEqual(fit.constraints[1].constraint_type, Eq) fit_result = fit.execute() self.assertAlmostEqual(fit_result.value(x), res.x[0]) self.assertAlmostEqual(fit_result.value(y), res.x[1])