Beispiel #1
0
 def test_pcp_2(self):
     # TODO: reformulate with SolverTestHelper
     """
     Reformulate
         max  (x**0.2)*(y**0.8) + z**0.4 - x
         s.t. x + y + z/2 == 2
              x, y, z >= 0
     Into
         max  x3 + x4 - x0
         s.t. x0 + x1 + x2 / 2 == 2,
              (x0, x1, x3) in Pow3D(0.2)
              (x2, 1.0, x4) in Pow3D(0.4)
     """
     x = cl.Variable(shape=(3,))
     hypos = cl.Variable(shape=(2,))
     objective = -cl.sum(hypos) + x[0]
     con1_expr = cl.hstack((x[0], x[1], hypos[0]))
     con1_weights = np.array([0.2, 0.8, -1.0])
     con2_expr = cl.hstack((x[2], 1.0, hypos[1]))
     con2_weights = np.array([0.4, 0.6, -1.0])
     constraints = [
         x[0] + x[1] + 0.5 * x[2] == 2,
         PowCone(con1_expr, con1_weights),
         PowCone(con2_expr, con2_weights)
     ]
     opt_objective = -1.8073406786220672
     opt_x = np.array([0.06393515, 0.78320961, 2.30571048])
     prob = cl.Problem(cl.MIN, objective, constraints)
     prob.solve(solver='CP')
     self.assertAlmostEqual(prob.value, opt_objective)
     assert np.allclose(x.value, opt_x, atol=1e-3)
Beispiel #2
0
 def test_pcp_1(self):
     #TODO: reformulate with SolverTestHelper
     """
     Use a 3D power cone formulation for
     min 3 * x[0] + 2 * x[1] + x[2]
     s.t. norm(x,2) <= y
          x[0] + x[1] + 3*x[2] >= 1.0
          y <= 5
     """
     x = cl.Variable(shape=(3,))
     y_square = cl.Variable()
     epis = cl.Variable(shape=(3,))
     constraints = [PowCone(cl.hstack((1.0, x[0], epis[0])), np.array([0.5, -1, 0.5])),
                    PowCone(cl.hstack((1.0, x[1], epis[1])), np.array([0.5, -1, 0.5])),
                    PowCone(cl.hstack((x[2], 1.0, epis[2])), np.array([-1, 0.5, 0.5])),
                     # Could have done PowCone(cl.hstack((1.0, x[2], epis[2])), np.array([0.5, -1, 0.5])).
                    cl.sum(epis) <= y_square,
                    x[0] + x[1] + 3 * x[2] >= 1.0,
                    y_square <= 25]
     objective = 3 * x[0] + 2 * x[1] + x[2]
     expect_x = np.array([-3.874621860638774, -2.129788233677883, 2.33480343377204])
     expect_epis = expect_x ** 2
     expect_x = np.round(expect_x, decimals=5)
     expect_epis = np.round(expect_epis, decimals=5)
     expect_y_square = 25
     expect_objective = -13.548638904065102
     prob = cl.Problem(cl.MIN, objective, constraints)
     prob.solve(solver='CP')
     self.assertAlmostEqual(prob.value, expect_objective, delta=1e-4)
     self.assertAlmostEqual(y_square.value, expect_y_square, delta=1e-4)
     concat = cl.hstack((x.value, epis.value))
     expect_concat = cl.hstack((expect_x, expect_epis))
     for i in range(5):
         self.assertAlmostEqual(concat[i], expect_concat[i], delta=1e-2)
     pass
Beispiel #3
0
 def test_redundant_components(self):
     # create problems where some (but not all) components of a vector variable
     # participate in the final conic formulation.
     x = cl.Variable(shape=(4,))
     cons = [0 <= x[1:], cl.sum(x[1:]) <= 1]
     objective = x[1] + 0.5 * x[2] + 0.25 * x[3]
     prob = cl.Problem(cl.MAX, objective, cons)
     prob.solve(solver='ECOS', verbose=False)
     assert np.allclose(x.value, np.array([0, 1, 0, 0]))
     pass
Beispiel #4
0
    def test_parse_integer_constraints(self):
        x = Variable(shape=(3,), name='my_name_x')
        y = Variable(shape=(3,), name='my_name_y')
        z = Variable(shape=(3,), name='my_name_z')
        invalid_lst = [2, 4, 6]
        self.assertRaises(ValueError, Problem._parse_integer_constraints, x, invalid_lst)
        valid_lst = [x, y, z]

        prob = cl.Problem(cl.MIN, cl.sum(x), [x==1,  y == 0, z == -1])
        prob.variable_map = {'my_name_x': np.array([0, 1]),
            'my_name_y': np.array([1, 2]),
            'my_name_z': np.array([2, 3])
            }
        prob._parse_integer_constraints(valid_lst)
        int_indices_expected = [0, 1, 1, 2, 2, 3]
        assert Expression.are_equivalent(int_indices_expected, prob._integer_indices)
        prob1 = cl.Problem(cl.MIN, cl.sum(x), [x==1,  y == 0, z[:-1] == -1])
        self.assertRaises(ValueError, Problem._parse_integer_constraints, prob1, valid_lst)
        z_part = z[:-1]
        self.assertRaises(ValueError, Problem._parse_integer_constraints, prob1, [x, y, z_part])
Beispiel #5
0
 def pcp_4(ceei: bool = True):
     """
     A power cone formulation of a Fisher market equilibrium pricing model.
     ceei = Competitive Equilibrium from Equal Incomes
     """
     # Generate test data
     np.random.seed(0)
     n_buyer = 4
     n_items = 6
     V = np.random.rand(n_buyer, n_items)
     X = cl.Variable(shape=(n_buyer, n_items))
     u = cl.sum(V * X, axis=1)
     z = cl.Variable()
     if ceei:
         b = np.ones(n_buyer) / n_buyer
         expect_X = np.array([[9.16311051e-01, 2.71146000e-09, 6.44984275e-10, 0.00000000e+00,
                             1.85098676e-09, 6.66541059e-01],
                            [0.00000000e+00, 0.00000000e+00, 5.30793141e-01, 0.00000000e+00,
                             9.99999995e-01, 1.35828851e-09],
                            [9.78080132e-10, 9.99999998e-01, 0.00000000e+00, 0.00000000e+00,
                             1.16278780e-09, 3.33458937e-01],
                            [8.36889514e-02, 0.00000000e+00, 4.69206858e-01, 1.00000001e+00,
                             7.80694090e-10, 8.26483799e-10]])
         pow_objective = (-z, -1.179743761485325)
     else:
         b = np.array([0.3, 0.15, 0.2, 0.35])
         expect_X = np.array([[9.08798195e-01, 0.00000000e+00, 0.00000000e+00, 2.67738456e-10,
                         3.44073780e-09, 9.58119833e-01],
                        [0.00000000e+00, 1.92431554e-10, 3.91981663e-09, 0.00000000e+00,
                         9.99999991e-01, 0.00000000e+00],
                        [0.00000000e+00, 9.99999993e-01, 0.00000000e+00, 0.00000000e+00,
                         0.00000000e+00, 4.18801652e-02],
                        [9.12018094e-02, 1.09687013e-08, 1.00000000e+00, 1.00000001e+00,
                         5.94724468e-09, 6.99603695e-09]])
         pow_objective = (-z, -1.2279371987281384)
     pow_cons = [(cl.sum(X, axis=0) <= 1, None),
                 (PowCone(cl.hstack((u, z)), np.hstack((b, -1))), None),
                 (X >= 0, None)]
     pow_vars = [(X, expect_X)]
     sth = SolverTestHelper(pow_objective, pow_vars, pow_cons)
     return sth
Beispiel #6
0
def sage_multiplier_search(f, level=1, X=None):
    """
    Constructs a coniclifts maximization Problem which is feasible if ``f`` can be certified as nonnegative
    over ``X``, by using an appropriate X-SAGE modulating function.

    Parameters
    ----------
    f : Polynomial
        We want to test if ``f`` is nonnegative over ``X``.
    level : int
        Controls the complexity of the X-SAGE modulating function. Must be a positive integer.
    X : PolyDomain or None
        If ``X`` is None, then we test nonnegativity of ``f`` over :math:`R^{\\texttt{f.n}}`.

    Returns
    -------
    prob : sageopt.coniclifts.Problem

    Notes
    -----
    This function provides an alternative to moving up the reference SAGE hierarchy, for the
    goal of certifying nonnegativity of a polynomial ``f`` over some set ``X`` where ``|X|``
    is log-convex. In general, the approach is to introduce a polynomial

        ``mult = Polynomial(alpha_hat, c_tilde)``

    where the rows of alpha_hat are all "level"-wise sums of rows from ``f.alpha``, and ``c_tilde``
    is a coniclifts Variable defining a nonzero SAGE polynomial. Then we can check if
    ``f_mod = f * mult`` is SAGE for any choice of ``c_tilde``.
    """
    constraints = []
    # Make the multiplier polynomial (and require that it be SAGE)
    mult_alpha = hierarchy_e_k([f], k=level)
    c_tilde = cl.Variable(shape=(mult_alpha.shape[0], ), name='c_tilde')
    mult = Polynomial(mult_alpha, c_tilde)
    temp_cons = primal_sage_poly_cone(mult,
                                      name=(c_tilde.name + ' domain'),
                                      log_AbK=X)
    constraints += temp_cons
    constraints.append(cl.sum(c_tilde) >= 1)
    # Make "f_mod := f * mult", and require that it be SAGE.
    f_mod = mult * f
    temp_cons = primal_sage_poly_cone(f_mod, name='f_mod sage poly', log_AbK=X)
    constraints += temp_cons
    # noinspection PyTypeChecker
    prob = cl.Problem(cl.MAX, 0, constraints)
    if AUTO_CLEAR_INDICES:  # pragma:no cover
        cl.clear_variable_indices()
    return prob
Beispiel #7
0
 def test_simple_MILP(self):
     # Include continuous variables
     x = cl.Variable()
     y = cl.Variable((2,))
     obj_expr = y[0]  # minimize me
     cont_cons = [cl.sum(y) == x, -1.5 <= x, x <= 2.5, 0 <= y[1], y[1] <= 4.7]
     prob = cl.Problem(cl.MIN, obj_expr, cont_cons, integer_variables=[x])
     prob.solve(solver='MOSEK')
     # to push y[0] negative, we need to push x to its lower bounds
     # and y[1] to its upper bound.
     expect_y = np.array([-5.7, 4.7])
     expect_x = -1.0
     self.assertAlmostEqual(y[0].value, expect_y[0], places=5)
     self.assertAlmostEqual(y[1].value, expect_y[1], places=5)
     self.assertAlmostEqual(x.value, expect_x, places=5)
     pass
Beispiel #8
0
def sage_multiplier_search(f, level=1, X=None):
    """
    Constructs a coniclifts maximization Problem which is feasible if ``f`` can be certified as nonnegative
    over ``X``, by using an appropriate X-SAGE modulating function.

    Parameters
    ----------
    f : Signomial
        We want to test if ``f`` is nonnegative over ``X``.
    level : int
        Controls the complexity of the X-SAGE modulating function. Must be a positive integer.
    X : SigDomain
        If ``X`` is None, then we test nonnegativity of ``f`` over :math:`R^{\\texttt{f.n}}`.


    Returns
    -------
    prob : sageopt.coniclifts.Problem

    Notes
    -----
    This function provides an alternative to moving up the reference SAGE hierarchy, for the goal of certifying
    nonnegativity of a signomial ``f`` over some convex set ``X``.  In general, the approach is to introduce
    a signomial

        ``mult = Signomial(alpha_hat, c_tilde)``

    where the rows of ``alpha_hat`` are all ``level``-wise sums of rows from ``f.alpha``, and ``c_tilde``
    is a coniclifts Variable defining a nonzero X-SAGE function. Then we check if ``f_mod = f * mult``
    is X-SAGE for any choice of ``c_tilde``.
    """
    f = f.without_zeros()
    constraints = []
    mult_alpha = hierarchy_e_k([f, f.upcast_to_signomial(1)], k=level)
    c_tilde = cl.Variable(mult_alpha.shape[0], name='c_tilde')
    mult = Signomial(mult_alpha, c_tilde)
    constraints.append(cl.sum(c_tilde) >= 1)
    sig_under_test = mult * f
    con1 = primal_sage_cone(mult, name=str(mult), X=X)
    con2 = primal_sage_cone(sig_under_test, name=str(sig_under_test), X=X)
    constraints.append(con1)
    constraints.append(con2)
    prob = cl.Problem(cl.MAX, cl.Expression([0]), constraints)
    if AUTO_CLEAR_INDICES:  # pragma:no cover
        cl.clear_variable_indices()
    return prob