def test_new_sos_polynomial(self): # Fit free polynomial in 2 points, and minimize value at a third. for Vector in Vectors: # Normal polynomial. prog = SosProgram() basis = Vector.construct_basis(self.x, 3) poly, gram, cons = prog.add_sos_polynomial(basis) prog.add_linear_cost(poly(self.zero)) prog.add_linear_constraint(poly(self.one) == 1) prog.add_linear_constraint(poly(self.two) == 2) prog.solve() poly_opt = prog.substitute_minimizer(poly) self.assertAlmostEqual(prog.minimum(), 0, places=4) self.assertAlmostEqual(poly_opt(self.zero), 0, places=4) self.assertAlmostEqual(poly_opt(self.one), 1, places=4) self.assertAlmostEqual(poly_opt(self.two), 2, places=4) # Reconstruct polynomial from Gram matrix. gram_opt = prog.substitute_minimizer(gram) self.assertTrue(self._is_psd(gram_opt)) poly_opt_gram = Polynomial.quadratic_form(basis, gram_opt) self.assertAlmostEqual(poly_opt, poly_opt_gram) # Even polynomial. prog = SosProgram() poly, gram, cons = prog.add_even_sos_polynomial(basis) prog.add_linear_cost(poly(self.zero)) prog.add_linear_constraint(poly(self.one) == 1) prog.add_linear_constraint(poly(self.two) == 2) prog.solve() poly_opt = prog.substitute_minimizer(poly) self.assertAlmostEqual(prog.minimum(), 0, places=4) self.assertAlmostEqual(poly_opt(self.zero), 0, places=4) self.assertAlmostEqual(poly_opt(self.one), 1, places=4) self.assertAlmostEqual(poly_opt(self.two), 2, places=4) # Reconstruct polynomial from Gram matrices. gram_opt_e, gram_opt_o = [ prog.substitute_minimizer(gi) for gi in gram ] self.assertTrue(self._is_psd(gram_opt_e)) self.assertTrue(self._is_psd(gram_opt_o)) basis_e = [v for v in basis if v.is_even()] basis_o = [v for v in basis if v.is_odd()] poly_opt_gram = Polynomial.quadratic_form(basis_e, gram_opt_e) poly_opt_gram += Polynomial.quadratic_form(basis_o, gram_opt_o) self.assertAlmostEqual(poly_opt, poly_opt_gram, places=4)
def test_quadratic_form(self): for Vector in Vectors: x = Variable.multivariate('x', 2) basis = Vector.construct_basis(x, 1) Q = np.array([[1, 2, 3], [2, 4, 5], [3, 5, 6]]) p = Polynomial.quadratic_form(basis, Q) p_target = basis[0] * basis[0] + (basis[0] * basis[1]) * 4 + \ (basis[0] * basis[2]) * 6 + (basis[1] * basis[1]) * 4 + \ (basis[1] * basis[2]) * 10 + (basis[2] * basis[2]) * 6 self.assertEqual(p, p_target)
def add_sos_polynomial(self, basis, name='Q'): gram, cons = self.add_psd_variable(len(basis), name) poly = Polynomial.quadratic_form(basis, gram) return poly, gram, cons
def test_add_sos_constraint(self): # Fit free polynomial in 2 points, and minimize value at a third. for Vector in Vectors: # Normal polynomial. prog = SosProgram() basis = Vector.construct_basis(self.x, 6) poly, coef = prog.add_polynomial(basis) gram = prog.add_sos_constraint(poly)[1] prog.add_linear_cost(poly(self.zero)) prog.add_linear_constraint(poly(self.one) == 1) prog.add_linear_constraint(poly(self.two) == 2) prog.solve() poly_opt = prog.substitute_minimizer(poly) self.assertAlmostEqual(prog.minimum(), 0, places=4) self.assertAlmostEqual(poly_opt(self.zero), 0, places=4) self.assertAlmostEqual(poly_opt(self.one), 1, places=4) self.assertAlmostEqual(poly_opt(self.two), 2, places=4) # Reconstruct polynomial from Gram matrix. gram_opt = prog.substitute_minimizer(gram) self.assertTrue(self._is_psd(gram_opt)) basis_half = Vector.construct_basis(self.x, 3) poly_opt_gram = Polynomial.quadratic_form(basis_half, gram_opt) self.assertAlmostEqual(poly_opt, poly_opt_gram) # Even polynomial. prog = SosProgram() basis = Vector.construct_basis(self.x, 6, odd=False) poly, coef = prog.add_polynomial(basis) gram = prog.add_sos_constraint(poly)[1] prog.add_linear_cost(poly(self.zero)) prog.add_linear_constraint(poly(self.one) == 1) prog.add_linear_constraint(poly(self.two) == 2) prog.solve() poly_opt = prog.substitute_minimizer(poly) self.assertAlmostEqual(prog.minimum(), 0, places=4) self.assertAlmostEqual(poly_opt(self.zero), 0, places=4) self.assertAlmostEqual(poly_opt(self.one), 1, places=4) self.assertAlmostEqual(poly_opt(self.two), 2, places=4) # Reconstruct polynomial from Gram matrices. gram_opt_e, gram_opt_o = [ prog.substitute_minimizer(gi) for gi in gram ] self.assertTrue(self._is_psd(gram_opt_e)) self.assertTrue(self._is_psd(gram_opt_o)) basis = Vector.construct_basis(self.x, 3) basis_e = [v for v in basis if v.is_even()] basis_o = [v for v in basis if v.is_odd()] poly_opt_gram = Polynomial.quadratic_form(basis_e, gram_opt_e) poly_opt_gram += Polynomial.quadratic_form(basis_o, gram_opt_o) self.assertAlmostEqual(poly_opt, poly_opt_gram, places=4) # Polynomial of odd degree. prog = SosProgram() basis = Vector.construct_basis(self.x, 3) poly, c = prog.add_polynomial(basis) with self.assertRaises(ValueError): prog.add_sos_constraint(poly) # Polynomial of length 0. prog = SosProgram() poly = Polynomial({}) with self.assertRaises(ValueError): prog.add_sos_constraint(poly)