Exemplo n.º 1
0
def sage_dual(s, level=0, additional_cons=None):
    """
    :param s: a Signomial object.
    :param level: a nonnegative integer
    :param additional_cons: a list of CVXPY Constraint objects over the variables in s.c
    (unless you are working with SAGE polynomials, there likely won't be any of these).

    :return: a CVXPY Problem object representing the dual formulation for s_{SAGE}^{(level)}

    In the discussion that follows, let s satisfy s.alpha[0,:] == np.zeros((1,n)).

    When level == 0, the returned CVXPY problem has the following explicit form:
            min  (s.c).T * v
            s.t.    v[0] == 1
                    v[i] * ln(v[i] / v[j]) <= (s.alpha[i,:] - s.alpha[j,:]) * mu[i] for i \in N0, j \in Nc0, j != i.
                    mu[i] \in R^{s.n} for i \in N0
                    v \in R^{s.m}_{+}
            where N = { i : s.c[i] < 0}, N0 = union(N, {0}), Nc = { i : s.c[i] >= 0}, and Nc0 = union(Nc, {0}).

    When level > 0, the form of the optimization problem is harder to state explicitly. At a high level, the resultant
    CVXPY problem is the same as above, with the following modifications:
        (1) we introduce a multiplier signomial
                t_mul = Signomial(s.alpha, np.ones(s.m)) ** level,
        (2) as well as a constant signomial
                t_cst = Signomial(s.alpha, [1, 0, ..., 0]).
        (3) Then "s" is replaced by
                s_mod == s * t_mul,
        (4) and "v[0] == 1" is replaced by
                a * v == 1,
            where vector "a" is an appropriate permutation of (t_mul * t_cst).c, and finally
        (5) the index sets N0 and Nc0 are replaced by
                N_I = union(N, I) and Nc_I = union(Nc, I)
            for
                I = { i | a[i] != 0 }.
    """
    # Signomial definitions (for the objective).
    s_mod = Signomial(s.alpha_c)
    t_mul = Signomial(s.alpha, np.ones(s.m))**level
    lagrangian = (s_mod - cvxpy.Variable(name='gamma')) * t_mul
    s_mod = s_mod * t_mul
    # C_SAGE^STAR (v must belong to the set defined by these constraints).
    v = cvxpy.Variable(shape=(lagrangian.m, 1), name='v')
    constraints = relative_c_sage_star(lagrangian, v)
    # Equality constraint (for the Lagrangian to be bounded).
    a = relative_coeff_vector(t_mul, lagrangian.alpha)
    a = a.reshape(a.size, 1)
    constraints.append(a.T * v == 1)
    # Objective definition and problem creation.
    obj_vec = relative_coeff_vector(s_mod, lagrangian.alpha)
    obj = cvxpy.Minimize(obj_vec * v)
    if additional_cons is not None:
        constraints += additional_cons
    prob = cvxpy.Problem(obj, constraints)
    # Add fields that we can access later.
    prob.s_mod = s_mod
    prob.s = s
    prob.level = level
    return prob
Exemplo n.º 2
0
 def __init__(self, alpha_maybe_c, c=None):
     Signomial.__init__(self, alpha_maybe_c, c)
     if not np.all(self.alpha % 1 == 0):
         raise RuntimeError(
             'Exponents must belong the the integer lattice.')
     if not np.all(self.alpha >= 0):
         raise RuntimeError('Exponents must be nonnegative.')
     self._sig_rep = None
     self._sig_rep_constrs = []
Exemplo n.º 3
0
 def test_sage_feasibility(self):
     s = Signomial({(-1, ): 1, (1, ): -1})
     s = s**2
     s.remove_terms_with_zero_as_coefficient()
     status = sage.sage_feasibility(s).solve(solver='ECOS')
     assert status == 0
     s = s**2
     status = sage.sage_feasibility(s).solve(solver='ECOS')
     assert status == -np.inf
Exemplo n.º 4
0
 def test_standard_monomials(self):
     x = standard_monomials(2)
     y_actual = x[0] + 3 * x[1] ** 2
     y_expect = Signomial({(1,0): 1, (0,2): 3})
     assert TestSignomials.are_equal(y_actual, y_expect)
     x = standard_monomials(4)
     y_actual = np.sum(x)
     y_expect = Signomial(np.eye(4), np.ones(shape=(4,)))
     assert TestSignomials.are_equal(y_actual, y_expect)
Exemplo n.º 5
0
 def test_sage_multiplier_search(self):
     s = Signomial({(1, ): 1, (-1, ): -1})**4
     s.remove_terms_with_zero_as_coefficient()
     val0 = sage.sage_multiplier_search(s, level=1).solve(solver='ECOS')
     assert val0 == -np.inf
     s_star = sage.sage_primal(s, level=1).solve(solver='ECOS')
     s = s - 0.5 * s_star
     val1 = sage.sage_multiplier_search(s, level=1).solve(solver='ECOS')
     assert val1 == 0
Exemplo n.º 6
0
 def test_addition_and_subtraction(self):
     # data for tests
     s0 = Signomial({(0,): 1, (1,): 2, (2,): 3})
     t0 = Signomial({(-1,): 5})
     # tests
     s = s0 - s0
     s.remove_terms_with_zero_as_coefficient()
     assert s.m == 1 and set(s.c) == {0}
     s = -s0 + s0
     s.remove_terms_with_zero_as_coefficient()
     assert s.m == 1 and set(s.c) == {0}
     s = s0 + t0
     assert s.alpha_c == {(-1,): 5, (0,): 1, (1,): 2, (2,): 3}
Exemplo n.º 7
0
 def test_construction(self):
     # data for tests
     alpha = np.array([[0], [1], [2]])
     c = np.array([1, -1, -2])
     alpha_c = {(0,): 1, (1,): -1, (2,): -2}
     # Construction with two numpy arrays as arguments
     s = Signomial(alpha, c)
     assert s.n == 1 and s.m == 3 and s.alpha_c == alpha_c
     # Construction with a vector-to-coefficient dictionary
     s = Signomial(alpha_c)
     recovered_alpha_c = dict()
     for i in range(s.m):
         recovered_alpha_c[tuple(s.alpha[i, :])] = s.c[i]
     assert s.n == 1 and s.m == 3 and alpha_c == recovered_alpha_c
Exemplo n.º 8
0
 def test_signomial_multiplication(self):
     # data for tests
     s0 = Signomial({(0,): 1, (1,): 2, (2,): 3})
     t0 = Signomial({(-1,): 1})
     q0 = Signomial({(5,): 0})
     # tests
     s = s0 * t0
     s.remove_terms_with_zero_as_coefficient()
     assert s.alpha_c == {(-1,): 1, (0,): 2, (1,): 3}
     s = t0 * s0
     s.remove_terms_with_zero_as_coefficient()
     assert s.alpha_c == {(-1,): 1, (0,): 2, (1,): 3}
     s = s0 * q0
     s.remove_terms_with_zero_as_coefficient()
     assert s.alpha_c == {(0,): 0}
Exemplo n.º 9
0
def sage_multiplier_search(s, level=1):
    """
    Suppose we have a nonnegative signomial s, where s_mod := s * (Signomial(s.alpha, np.ones(s.m))) ** level
    is not SAGE. Do we have an alternative do proving that s is nonnegative other than moving up the SAGE
    hierarchy? Indeed we do. We can define a multiplier

        mult = Signomial(alpha_hat, c_tilde)

    where the rows of alpha_hat are all level-wise sums of rows from s.alpha, and c_tilde is a CVXPY Variable
    defining a nonzero SAGE function. Then we can check if s_mod := s * mult is SAGE for any choice of c_tilde.

    :param s: a Signomial object
    :param level: a nonnegative integer
    :return: a CVXPY Problem that is feasible iff s * mult is SAGE for some SAGE multiplier signomial "mult".
    """
    s.remove_terms_with_zero_as_coefficient()
    constraints = []
    mult_alpha = hierarchy_e_k([s], k=level)
    c_tilde = cvxpy.Variable(mult_alpha.shape[0], name='c_tilde')
    mult = Signomial(mult_alpha, c_tilde)
    constraints += relative_c_sage(mult)
    constraints.append(cvxpy.sum(c_tilde) >= 1)
    sig_under_test = mult * s
    sage_membership_constraints = relative_c_sage(sig_under_test)
    constraints += sage_membership_constraints
    # noinspection PyTypeChecker
    obj = cvxpy.Maximize(0)
    prob = cvxpy.Problem(obj, constraints)
    return prob
Exemplo n.º 10
0
def constrained_sage_dual(f, gs, p=0, q=1):
    """
    Compute the dual f_{SAGE}^{(p, q)} bound for

        inf f(x) : g(x) >= 0 for g \in gs.

    :param f: a Signomial.
    :param gs: a list of Signomials.
    :param p: a nonnegative integer,
    :param q: a positive integer.
    :return: a CVXPY Problem that defines the dual formulation for f_{SAGE}^{(p, q)}.
    """
    lagrangian, dualized_signomials = make_lagrangian(f, gs, p=p, q=q)
    v = cvxpy.Variable(shape=(lagrangian.m, 1))
    constraints = relative_c_sage_star(lagrangian, v)
    for s_h, h in dualized_signomials:
        v_h = cvxpy.Variable(name='v_h_' + str(s_h), shape=(s_h.m, 1))
        constraints += relative_c_sage_star(s_h, v_h)
        c_h = hierarchy_c_h_array(s_h, h, lagrangian)
        constraints.append(c_h * v == v_h)
    # Equality constraint (for the Lagrangian to be bounded).
    a = relative_coeff_vector(Signomial({(0, ) * f.n: 1}), lagrangian.alpha)
    a = a.reshape(a.size, 1)
    constraints.append(a.T * v == 1)
    obj_vec = relative_coeff_vector(f, lagrangian.alpha)
    obj = cvxpy.Minimize(obj_vec * v)
    prob = cvxpy.Problem(obj, constraints)
    return prob
Exemplo n.º 11
0
 def test_unconstrained_sage_4(self):
     s = Signomial({(3, ): 1, (2, ): -4, (1, ): 7, (-1, ): 1})
     expected = [3.464102, 4.60250026, 4.6217973]
     pds = [primal_dual_vals(s, ell) for ell in range(3)]
     for ell in range(3):
         assert abs(pds[ell][0] == expected[ell]) < 1e-5
         assert abs(pds[ell][1] == expected[ell]) < 1e-5
Exemplo n.º 12
0
 def test_unconstrained_sage_3(self):
     s = Signomial({(1, 0, 0): 1, (0, 1, 0): -1, (0, 0, 1): -1})
     s = s**2
     expected = -np.inf
     pd0 = primal_dual_vals(s, 0)
     assert pd0[0] == expected and pd0[1] == expected
     pd1 = primal_dual_vals(s, 1)
     assert pd1[0] == expected and pd1[1] == expected
Exemplo n.º 13
0
 def test_signomial_evaluation(self):
     s = Signomial({(1,): 1})
     assert s(0) == 1 and abs(s(1) - np.exp(1)) < 1e-10
     zero = np.array([0])
     one = np.array([1])
     assert s(zero) == 1 and abs(s(one) - np.exp(1)) < 1e-10
     zero_one = np.array([[0, 1]])
     assert np.allclose(s(zero_one), np.exp(zero_one), rtol=0, atol=1e-10)
Exemplo n.º 14
0
 def __sub__(self, other):
     if isinstance(other, Signomial) and not isinstance(other, Polynomial):
         raise RuntimeError(
             'Cannot subtract a signomial from a polynomial (or vice versa).'
         )
     temp = Signomial.__sub__(self, other)
     temp = Polynomial(temp.alpha, temp.c)
     return temp
Exemplo n.º 15
0
 def __pow__(self, power, modulo=None):
     if self.c.dtype not in __NUMERIC_TYPES__:
         raise RuntimeError(
             'Cannot exponentiate polynomials with symbolic coefficients.')
     temp = Signomial(self.alpha, self.c)
     temp = temp**power
     temp = Polynomial(temp.alpha, temp.c)
     return temp
Exemplo n.º 16
0
 def test_unconstrained_sage_2(self):
     alpha = np.array([[0, 0], [1, 0], [0, 1], [1, 1], [0.5, 1], [1, 0.5]])
     c = np.array([0, 1, 1, 1.9, -2, -2])
     s = Signomial(alpha, c)
     expected = [-np.inf, -0.122211863]
     pd0 = primal_dual_vals(s, 0)
     assert pd0[0] == expected[0] and pd0[1] == expected[0]
     pd1 = primal_dual_vals(s, 1)
     assert abs(pd1[0] - expected[1]) < 1e-5 and abs(pd1[1] -
                                                     expected[1]) < 1e-5
Exemplo n.º 17
0
 def test_unconstrained_sage_1(self):
     alpha = np.array([[0, 0], [1, 0], [0, 1], [1, 1], [0.5, 0], [0, 0.5]])
     c = np.array([0, 3, 2, 1, -4, -2])
     s = Signomial(alpha, c)
     expected = [-1.83333, -1.746505595]
     pd0 = primal_dual_vals(s, 0)
     assert abs(pd0[0] - expected[0]) < 1e-4 and abs(pd0[1] -
                                                     expected[0]) < 1e-4
     pd1 = primal_dual_vals(s, 1)
     assert abs(pd1[0] - expected[1]) < 1e-4 and abs(pd1[1] -
                                                     expected[1]) < 1e-4
Exemplo n.º 18
0
 def test_constrained_sage_1(self):
     s0 = Signomial({(10.2, 0, 0): 10, (0, 9.8, 0): 10, (0, 0, 8.2): 10})
     s1 = Signomial({(1.5089, 1.0981, 1.3419): -14.6794})
     s2 = Signomial({(1.0857, 1.9069, 1.6192): -7.8601})
     s3 = Signomial({(1.0459, 0.0492, 1.6245): 8.7838})
     f = s0 + s1 + s2 + s3
     g = Signomial({
         (10.2, 0, 0): -8,
         (0, 9.8, 0): -8,
         (0, 0, 8.2): -8,
         (1.0857, 1.9069, 1.6192): -6.4,
         (0, 0, 0): 1
     })
     gs = [g]
     expected = -0.6147
     actual = [
         sage.constrained_sage_primal(f, gs, p=0, q=1).solve(solver='ECOS'),
         sage.constrained_sage_dual(f, gs, p=0, q=1).solve(solver='ECOS')
     ]
     assert abs(actual[0] - expected) < 1e-4 and abs(actual[1] -
                                                     expected) < 1e-4
Exemplo n.º 19
0
 def test_unconstrained_sage_6(self):
     alpha = np.array([[0., 1.], [0., 0.], [0.52, 0.15], [1., 0.], [2., 2.],
                       [1.3, 1.38]])
     c = np.array([2.55, 0.31, -1.48, 0.85, 0.65, -1.73])
     s = Signomial(alpha, c)
     expected = [0.00354263, 0.13793126]
     pd0 = primal_dual_vals(s, 0)
     assert abs(pd0[0] - expected[0]) < 1e-6 and abs(pd0[1] -
                                                     expected[0]) < 1e-6
     pd1 = primal_dual_vals(s, 1)
     assert abs(pd1[0] - expected[1]) < 1e-6 and abs(pd1[1] -
                                                     expected[1]) < 1e-6
Exemplo n.º 20
0
 def test_unconstrained_sage_5(self):
     alpha = np.array([[0., 1.], [0.21, 0.08], [0.16, 0.54], [0., 0.],
                       [1., 0.], [0.3, 0.58]])
     c = np.array([1., -57.75, -40.37, 33.94, 67.29, 38.28])
     s = Signomial(alpha, c)
     expected = [-24.054866, -21.31651]
     pd0 = primal_dual_vals(s, 0)
     assert abs(pd0[0] - expected[0]) < 1e-4 and abs(pd0[1] -
                                                     expected[0]) < 1e-4
     pd1 = primal_dual_vals(s, 1)
     assert abs(pd1[0] - expected[1]) < 1e-4 and abs(pd1[1] -
                                                     expected[1]) < 1e-4
Exemplo n.º 21
0
def hierarchy_e_k(sig_list, k):
    """
    :param sig_list: a list of Signomial objects over a common domain R^n
    :param k: a nonnegative integer
    :return: If "alpha" denotes the union of exponent vectors over Signomials in
    sig_list, then this function returns "E_k(alpha)" from the original paper
    on the SAGE hierarchy.
    """
    alpha_tups = sum([list(s.alpha_c.keys()) for s in sig_list], [])
    alpha_tups = set(alpha_tups)
    s = Signomial(dict([(a, 1.0) for a in alpha_tups]))
    s = s**k
    return s.alpha
Exemplo n.º 22
0
def make_lagrangian(f, gs, p, q, add_constant_sig=True):
    """
    Given a problem \inf{ f(x) : g(x) >= 0 for g in gs}, construct the q-fold constraints H,
    and the lagrangian
        L = f - \gamma - \sum_{h \in H} s_h * h
    where \gamma and the coefficients on Signomials s_h are CVXPY Variables.

    :param f: a Signomial (or a constant numeric type).
    :param gs: a nonempty list of Signomials.
    :param p: a nonnegative integer. Defines the exponent set of the Signomials s_h.
    :param q: a positive integer. Defines "H" as all products of q elements from gs.
    :param add_constant_sig: a boolean. If True, makes sure that "gs" contains a
    Signomial that is identically equal to 1.

    :return: a Signomial object with coefficients as affine expressions of CVXPY Variables.
    The coefficients will either be optimized directly (in the case of constrained_sage_primal),
    or simply used to determine appropriate dual variables (in the case of constrained_sage_dual).
    """
    if not all([isinstance(g, Signomial) for g in gs]):
        raise RuntimeError('Constraints must be Signomial objects.')
    if add_constant_sig:
        gs.append(Signomial({(0, ) * gs[0].n:
                             1}))  # add the constant signomial
    if not isinstance(f, Signomial):
        f = Signomial({(0, ) * gs[0].n: f})
    gs = set(gs)  # remove duplicates
    hs = set([np.prod(comb) for comb in combinations_with_replacement(gs, q)])
    gamma = cvxpy.Variable(name='gamma')
    lagrangian = f - gamma
    alpha_E_p = hierarchy_e_k([f] + list(gs), k=p)
    dualized_signomials = []
    for h in hs:
        temp_shc = cvxpy.Variable(name='shc_' + str(h),
                                  shape=(alpha_E_p.shape[0], ))
        temp_sh = Signomial(alpha_E_p, temp_shc)
        lagrangian -= temp_sh * h
        dualized_signomials.append((temp_sh, h))
    return lagrangian, dualized_signomials
Exemplo n.º 23
0
def sage_primal(s, level=0, special_multiplier=None, additional_cons=None):
    """
    :param s: a Signomial object.
    :param level: a nonnegative integer
    :param special_multiplier: an optional parameter, applicable when level > 0. Must be a nonzero
    SAGE function.
    :param additional_cons: a list of CVXPY Constraint objects over the variables in s.c
    (unless you are working with SAGE polynomials, there likely won't be any of these).

    :return: a CVXPY Problem object representing the primal formulation for s_{SAGE}^{(level)}

    Unlike the sage_dual, this formulation can be stated in full generality without too much trouble.
    We define a multiplier signomial "t" as either the standard multiplier (Signomial(s.alpha, np.ones(s.n))),
    or a user-provided multiplier. We then return a CVXPY Problem representing

        max  gamma
        s.t.    s_mod.c \in C_{SAGE}(s_mod.alpha)
        where   s_mod := (t ** level) * (s - gamma).

    Our implementation of Signomial objects allows CVXPY variables in the coefficient vector c. As a result, the
    mapping "gamma \to s_mod.c" is an affine function that takes in a CVXPY Variable and returns a CVXPY Expression.
    This makes it very simple to represent "s_mod.c \in C_{SAGE}(s_mod.alpha)" via CVXPY Constraints. The work defining
    the necessary CVXPY variables and constructing the CVXPY constraints is handled by the function "c_sage."
    """
    if special_multiplier is None:
        t = Signomial(s.alpha, np.ones(s.m))
    else:
        # noinspection PyTypeChecker
        if np.all(special_multiplier.c == 0):
            raise RuntimeError('The multiplier must be a nonzero signomial.')
        # test if SAGE
        prob = sage_feasibility(special_multiplier)
        if prob.solve() < 0:
            raise RuntimeError('The multiplier must be a SAGE function.')
        t = special_multiplier
    gamma = cvxpy.Variable(name='gamma')
    s_mod = (s - gamma) * (t**level)
    s_mod.remove_terms_with_zero_as_coefficient()
    constraints = relative_c_sage(s_mod)
    obj = cvxpy.Maximize(gamma)
    if additional_cons is not None:
        constraints += additional_cons
    prob = cvxpy.Problem(obj, constraints)
    # Add fields that we can access later.
    prob.s_mod = s_mod
    prob.s = s
    prob.level = level
    return prob
Exemplo n.º 24
0
 def __mul__(self, other):
     if not isinstance(other, Polynomial):
         if isinstance(other, Signomial):
             raise RuntimeError(
                 'Cannot multiply signomials and polynomials.')
         # else, we assume that "other" is a scalar type
         other = Polynomial.promote_scalar_to_polynomial(other, self.n)
     self_var_coeffs = (self.c.dtype not in __NUMERIC_TYPES__)
     other_var_coeffs = (other.c.dtype not in __NUMERIC_TYPES__)
     if self_var_coeffs and other_var_coeffs:
         raise RuntimeError(
             'Cannot multiply two polynomials that posesses non-numeric coefficients.'
         )
     temp = Signomial.__mul__(self, other)
     temp = Polynomial(temp.alpha, temp.c)
     return temp
Exemplo n.º 25
0
 def test_scalar_multiplication(self):
     # data for tests
     alpha0 = np.array([[0], [1], [2]])
     c0 = np.array([1, 2, 3])
     s0 = Signomial(alpha0, c0)
     # Tests
     s = 2 * s0
     # noinspection PyTypeChecker
     assert set(s.c) == set(2 * s0.c)
     s = s0 * 2
     # noinspection PyTypeChecker
     assert set(s.c) == set(2 * s0.c)
     s = 1 * s0
     assert s.alpha_c == s0.alpha_c
     s = 0 * s0
     s.remove_terms_with_zero_as_coefficient()
     assert s.m == 1 and set(s.c) == {0}
Exemplo n.º 26
0
def hierarchy_c_h_array(s_h, h, lagrangian):
    """
    Assume (s_h * h).alpha is a subset of lagrangian.alpha.

    :param s_h: a SAGE multiplier Signomial for the constrained hierarchy
    :param h: the constraint Signomial
    :param lagrangian: the Signomial f - \gamma - \sum_{h \in H} s_h * h.

    :return: a matrix c_h so that if "v" is a dual variable to the constraint
    "lagrangian is SAGE", then the constraint "s_h is SAGE" is dualizes to
    "c_h * v \in C_{SAGE}^{\star}(s_h)".
    """
    c_h = np.zeros((s_h.alpha.shape[0], lagrangian.alpha.shape[0]))
    for i, row in enumerate(s_h.alpha):
        temp_sig = Signomial({tuple(row): 1}) * h
        c_h[i, :] = relative_coeff_vector(temp_sig, lagrangian.alpha)
    return c_h
Exemplo n.º 27
0
 def compute_sig_rep(self):
     self._sig_rep = None
     self._sig_rep_constrs = []
     d = defaultdict(lambda: 0)
     for i, row in enumerate(self.alpha):
         if np.any(row % 2 != 0):
             row = tuple(row)
             if isinstance(self.c[i], __NUMERIC_TYPES__):
                 d[row] = -abs(self.c[i])
             else:
                 d[row] = cvxpy.Variable(shape=(),
                                         name=('sig_rep_coeff[' + str(i) +
                                               ']'))
                 self._sig_rep_constrs.append(d[row] <= self.c[i])
                 self._sig_rep_constrs.append(d[row] <= -self.c[i])
         else:
             d[tuple(row)] = self.c[i]
     self._sig_rep = Signomial(d)
     pass
Exemplo n.º 28
0
 def test_exponentiation(self):
     # raise to a negative power
     s = Signomial({(0.25,): -1})
     t_actual = s ** -3
     t_expect = Signomial({(-0.75,): -1})
     assert TestSignomials.are_equal(t_actual, t_expect)
     # raise to a fractional power
     s = Signomial({(2,): 9})
     t_actual = s ** 0.5
     t_expect = Signomial({(1,): 3})
     assert TestSignomials.are_equal(t_actual, t_expect)
     # raise to a nonnegative integer power
     s = Signomial({(0,): 1, (1,): 2})
     t_actual = s ** 2
     t_expect = Signomial({(0,): 1, (1,): 4, (2,): 4})
     assert TestSignomials.are_equal(t_actual, t_expect)
Exemplo n.º 29
0
 def test_constrained_sage_2(self):
     # a Signomial Programming formulation of an example from page 16 of
     # http://homepages.laas.fr/henrion/papers/gloptipoly3.pdf
     # --- which is itself borrowed from somewhere else.
     f = Signomial({(1, 0, 0): -2, (0, 1, 0): 1, (0, 0, 1): -1})
     # Constraints over more than one variable
     g1 = Signomial({
         (0, 0, 0): 24,
         (1, 0, 0): -20,
         (0, 1, 0): 9,
         (0, 0, 1): -13,
         (2, 0, 0): 4,
         (1, 1, 0): -4,
         (1, 0, 1): 4,
         (0, 2, 0): 2,
         (0, 1, 1): -2,
         (0, 0, 2): 2
     })
     g2 = Signomial({
         (1, 0, 0): -1,
         (0, 1, 0): -1,
         (0, 0, 1): -1,
         (0, 0, 0): 4
     })
     g3 = Signomial({(0, 1, 0): -3, (0, 0, 1): -1, (0, 0, 0): 6})
     # Bound constraints on x_1
     g4 = Signomial({(1, 0, 0): -1, (0, 0, 0): 2})
     # Bound constraints on x_3
     g5 = Signomial({(0, 0, 1): -1, (0, 0, 0): 3})
     # Assemble!
     gs = [g1, g2, g3, g4, g5]
     res01 = [
         sage.constrained_sage_primal(f, gs, p=0,
                                      q=1).solve(solver='ECOS',
                                                 max_iters=1000),
         sage.constrained_sage_dual(f, gs, p=0, q=1).solve(solver='ECOS',
                                                           max_iters=1000)
     ]
     assert abs(res01[0] - res01[1]) < 1e-5
     if 'MOSEK' in cvxpy.installed_solvers():
         res11 = [
             sage.constrained_sage_primal(f, gs, p=1,
                                          q=1).solve(solver='MOSEK'),
             sage.constrained_sage_dual(f, gs, p=1,
                                        q=1).solve(solver='MOSEK')
         ]
         assert abs(res11[0] - res11[1]) < 1e-4
Exemplo n.º 30
0
 def __add__(self, other):
     if isinstance(other, Signomial) and not isinstance(other, Polynomial):
         raise RuntimeError('Cannot add signomials to polynomials.')
     temp = Signomial.__add__(self, other)
     temp = Polynomial(temp.alpha, temp.c)
     return temp