Beispiel #1
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 = temp.as_polynomial()
     return temp
Beispiel #2
0
 def grad(self):
     """
     A numpy ndarray of shape ``(n,)`` whose entries are Polynomials. For a numpy ndarray ``x``,
     ``grad[i](x)`` is the partial derivative of this Polynomial with respect to coordinate ``i``,
     evaluated at ``x``. This array is constructed only when necessary, and is cached upon construction.
     """
     Signomial._cache_grad(
         self)  # This ends up calling the Polynomial "_partial" function.
     return self._grad
Beispiel #3
0
 def hess(self):
     """
     A numpy ndarray of shape ``(n, n)``, whose entries are Polynomials. For a numpy ndarray ``x``,
     ``hess[i,j](x)`` is the (i,j)-th partial derivative of this Polynomial, evaluated at ``x``.
     This array is constructed only when necessary, and is cached upon construction.
     """
     Signomial._cache_hess(
         self)  # This ends up calling the Polynomial "_partial" function.
     return self._hess
Beispiel #4
0
 def __init__(self, alpha, c):
     Signomial.__init__(self, alpha, c)
     if not np.all(self.alpha % 1 == 0):  # pragma: no cover
         raise ValueError('Exponents must be integers.')
     if not np.all(self.alpha >= 0):  # pragma: no cover
         raise ValueError('Exponents must be nonnegative.')
     self._sig_rep = None
     self._sig_rep_constrs = []
     pass
Beispiel #5
0
 def test_addition_and_subtraction(self):
     # data for tests
     s0 = Signomial.from_dict({(0, ): 1, (1, ): 2, (2, ): 3})
     t0 = Signomial.from_dict({(-1, ): 5})
     # tests
     s = s0 - s0
     s = s.without_zeros()
     assert s.m == 1 and set(s.c) == {0}
     s = -s0 + s0
     s = s.without_zeros()
     assert s.m == 1 and set(s.c) == {0}
     s = s0 + t0
     assert s.alpha_c == {(-1, ): 5, (0, ): 1, (1, ): 2, (2, ): 3}
Beispiel #6
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.from_dict(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
Beispiel #7
0
 def test_signomial_multiplication(self):
     # data for tests
     s0 = Signomial.from_dict({(0, ): 1, (1, ): 2, (2, ): 3})
     t0 = Signomial.from_dict({(-1, ): 1})
     q0 = Signomial.from_dict({(5, ): 0})
     # tests
     s = s0 * t0
     s = s.without_zeros()
     assert s.alpha_c == {(-1, ): 1, (0, ): 2, (1, ): 3}
     s = t0 * s0
     s = s.without_zeros()
     assert s.alpha_c == {(-1, ): 1, (0, ): 2, (1, ): 3}
     s = s0 * q0
     s = s.without_zeros()
     assert s.alpha_c == {(0, ): 0}
Beispiel #8
0
 def __add__(self, other):
     if isinstance(other, Signomial) and not isinstance(
             other, Polynomial):  # pragma: no cover
         raise RuntimeError('Cannot add signomials to polynomials.')
     temp = Signomial.__add__(self, other)
     temp = temp.as_polynomial()
     return temp
Beispiel #9
0
def sig_dual(f, ell=0, X=None, modulator_support=None):
    f = f.without_zeros()
    # Signomial definitions (for the objective).
    lagrangian = f - cl.Variable(name='gamma')
    if modulator_support is None:
        modulator_support = lagrangian.alpha
    t_mul = Signomial(modulator_support,
                      np.ones(modulator_support.shape[0]))**ell
    metadata = {'f': f, 'lagrangian': lagrangian, 'modulator': t_mul, 'X': X}
    lagrangian = lagrangian * t_mul
    f_mod = f * t_mul
    # C_SAGE^STAR (v must belong to the set defined by these constraints).
    v = cl.Variable(shape=(lagrangian.m, 1), name='v')
    con = relative_dual_sage_cone(lagrangian,
                                  v,
                                  name='Lagrangian SAGE dual constraint',
                                  X=X)
    constraints = [con]
    # Equality constraint (for the Lagrangian to be bounded).
    a = sym_corr.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 = sym_corr.relative_coeff_vector(f_mod, lagrangian.alpha)
    obj = obj_vec.T @ v
    # Create coniclifts Problem
    prob = cl.Problem(cl.MIN, obj, constraints)
    prob.metadata = metadata
    cl.clear_variable_indices()
    return prob
Beispiel #10
0
 def test_signomial_shift_coordinates(self):
     f = Signomial.from_dict({(0,): 1, (1,): 2, (2,): 3})
     g = Signomial.from_dict({(-1,): 1})
     h = Signomial.from_dict({(2, 3): 1,
                              (1, -3): -2})
     x0 = -1.2345
     x_test = 3.21
     f_shift = f.shift_coordinates(x0)
     self.assertAlmostEqual(f(x_test + x0), f_shift(x_test), places=4)
     g_shift = g.shift_coordinates(x0)
     self.assertAlmostEqual(g(x_test + x0), g_shift(x_test), places=4)
     x0 = np.array([1.1, 2.2])
     x_test = np.array([-0.5, 3])
     h_shift = h.shift_coordinates(x0)
     self.assertAlmostEqual(h(x_test + x0), h_shift(x_test), places=4)
     self.assertRaises(ValueError, f.shift_coordinates, np.array([1, 1j]))
Beispiel #11
0
def poly_primal(f, poly_ell=0, sigrep_ell=0, X=None):
    if poly_ell == 0:
        sr, _ = f.sig_rep
        prob = sage_sigs.sig_primal(sr, sigrep_ell, X=X)
        if AUTO_CLEAR_INDICES:  # pragma:no cover
            cl.clear_variable_indices()
        return prob
    else:
        poly_modulator = f.standard_multiplier()**poly_ell
        gamma = cl.Variable(shape=(), name='gamma')
        lagrangian = (f - gamma) * poly_modulator
        if sigrep_ell > 0:
            sr, cons = lagrangian.sig_rep
            sig_modulator = Signomial(sr.alpha,
                                      np.ones(shape=(sr.m, )))**sigrep_ell
            sig_under_test = sr * sig_modulator
            con_name = 'Lagrangian modulated sigrep sage'
            con = sage_sigs.primal_sage_cone(sig_under_test, con_name, X=X)
            constraints = [con] + cons
        else:
            con_name = 'Lagrangian sage poly'
            constraints = primal_sage_poly_cone(lagrangian,
                                                con_name,
                                                log_AbK=X)
        obj = gamma
        prob = cl.Problem(cl.MAX, obj, constraints)
        if AUTO_CLEAR_INDICES:  # pragma:no cover
            cl.clear_variable_indices()
        return prob
Beispiel #12
0
def sig_constrained_primal(f, gts, eqs, p=0, q=1, ell=0, X=None):
    """
    Construct the SAGE-(p, q, ell) primal problem for the signomial program

        min{ f(x) : g(x) >= 0 for g in gts,
                    g(x) == 0 for g in eqs,
                    and x in X }

    where X = :math:`R^{\\texttt{f.n}}` by default.
    """
    lagrangian, ineq_lag_mults, _, gamma = make_sig_lagrangian(f, gts, eqs, p=p, q=q)
    metadata = {'lagrangian': lagrangian, 'X': X}
    if ell > 0:
        alpha_E_1 = hierarchy_e_k([f, f.upcast_to_signomial(1)] + gts + eqs, k=1)
        modulator = Signomial(alpha_E_1, np.ones(alpha_E_1.shape[0])) ** ell
        lagrangian = lagrangian * modulator
    else:
        modulator = f.upcast_to_signomial(1)
    metadata['modulator'] = modulator
    # The Lagrangian (after possible multiplication, as above) must be a SAGE signomial.
    con = primal_sage_cone(lagrangian, name='Lagrangian is SAGE', X=X)
    constrs = [con]
    #  Lagrange multipliers (for inequality constraints) must be SAGE signomials.
    expcovers = None
    for i, (s_h, _) in enumerate(ineq_lag_mults):
        con_name = 'SAGE multiplier for signomial inequality # ' + str(i)
        con = primal_sage_cone(s_h, name=con_name, X=X, expcovers=expcovers)
        expcovers = con.ech.expcovers  # only * really * needed in first iteration, but keeps code flat.
        constrs.append(con)
    # Construct the coniclifts Problem.
    prob = cl.Problem(cl.MAX, gamma, constrs)
    prob.metadata = metadata
    cl.clear_variable_indices()
    return prob
Beispiel #13
0
 def test_unconstrained_sage_3(self):
     # Background
     #
     #       This is Example 2.5 from the original SAGE paper by Chandrasekaran and Shah.
     #       The signomial s(x1,x2,x3) = (exp(x1) - exp(x2) - exp(x3))**2 is nonnegative
     #       over R^3, but it is not SAGE.
     #
     # Tests
     #
     #       (1) Show that the standard SAGE hierarchy produces no finite bound on "s",
     #           for ell \in {0, 1}.
     #
     # Notes
     #
     #       It is suspected that the standard SAGE hierarchy never produces a finite bound
     #       for this signomial.
     #
     s = Signomial.from_dict({(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
Beispiel #14
0
 def test_unconstrained_sage_2(self):
     # Background
     #
     #       This is Example 2 from a 2018 paper by Murray, Chandrasekaran, and Wierman
     #       (https://arxiv.org/pdf/1810.01614.pdf).
     #
     # Tests
     #
     #       (1) Check that primal / dual objective are -\infty for ell == 0.
     #
     #       (2) Check that primal / dual objectives are close to a reference value, for ell == 1.
     #
     #       (3) Recover a globally optimal solution at ell == 1.
     #
     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, dual = primal_dual_vals(s, 1)
     assert abs(pd1[0] - expected[1]) < 1e-5 and abs(pd1[1] - expected[1]) < 1e-5
     solns = sig_solrec(dual)
     assert s(solns[0]) < 1e-6 + dual.value
Beispiel #15
0
 def test_sage_multiplier_search(self):
     # Background
     #
     #       This example was constructed solely as a test case for sageopt.
     #
     #       The problem is to find a bound on the nonnegative signomial
     #       s(x) = (exp(x)  - exp(-x))**4, using the machinery of SAGE certificates.
     #
     # Tests
     #
     #       (1) Show that there is no SAGE signomial "f" (over the same exponents as "s")
     #           such that f * s is SAGE.
     #
     #       (2) Obtain a loose (but finite) bound on "s", via a SAGE relaxation with ell == 1.
     #
     #       (3) Improve the finite bound from Test 2 by verifying nonnegativity of an
     #           appropriate translate of "s".
     #
     s = Signomial.from_dict({(1,): 1, (-1,): -1}) ** 4
     prob0 = sage_multiplier_search(s, level=1)
     res0 = prob0.solve(solver='ECOS', verbose=False)
     val0 = res0[1]
     assert val0 == -np.inf
     prob1 = sig_relaxation(s, form='primal', ell=1)
     res1 = prob1.solve(solver='ECOS', verbose=False)
     s_bound = res1[1]
     assert -np.inf < s_bound < 0
     s_shifted = s - 0.5 * s_bound  # shifted_s is nonnegative, and not-SAGE by construction.
     prob2 = sage_multiplier_search(s_shifted, level=1)
     res2 = prob2.solve(solver='ECOS', verbose=False)
     val2 = res2[1]
     assert val2 == 0.
Beispiel #16
0
 def test_constrained_sage_2(self):
     # Background
     #
     #       This is a signomial formulation of a nonnegative polynomial optimization problem.
     #
     #       The problem can be found on page 16 of the gloptipoly3 manual
     #                   http://homepages.laas.fr/henrion/papers/gloptipoly3.pdf
     #       among other places. The optimal objective is -4.
     #
     # Tests - (p, q, ell) = (0, 1, 0)
     #
     #       (1) Check for similar primal / dual objectives.
     #
     x = standard_sig_monomials(3)
     f = -2 * x[0] + x[1] - x[2]
     g1 = Signomial.from_dict({(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 = 4 - x[0] - x[1] - x[2]
     g3 = 6 - 3*x[1] - x[2]
     g4 = 2 - x[0]
     g5 = 3 - x[2]
     gts = [g1, g2, g3, g4, g5]
     res01, _ = constrained_primal_dual_vals(f, gts, [], p=0, q=1, ell=0, X=None)
     expect = -6
     assert abs(res01[0] - expect) < 1e-4
     assert abs(res01[1] - expect) < 1e-4
     assert abs(res01[0] - res01[1]) < 1e-5
Beispiel #17
0
 def _compute_sig_rep(self):
     self._sig_rep = None
     self._sig_rep_constrs = []
     sigrep_c = np.zeros(shape=(self.m, ), dtype=object)
     need_vars = []
     for i, row in enumerate(self.alpha):
         if np.any(row % 2 != 0):
             if isinstance(self.c[i], __NUMERIC_TYPES__):
                 sigrep_c[i] = -abs(self.c[i])
             elif self.c[i].is_constant():
                 sigrep_c[i] = -abs(self.c[i].value)
             else:
                 need_vars.append(i)
         else:
             if isinstance(self.c[i], np.ndarray):
                 sigrep_c[i] = self.c[i][()]
             else:
                 sigrep_c[i] = self.c[i]
     if len(need_vars) > 0:
         var_name = str(self) + ' variable sigrep coefficients'
         c_hat = cl.Variable(shape=(len(need_vars), ), name=var_name)
         sigrep_c[need_vars] = c_hat
         self._sig_rep_constrs.append(c_hat <= self.c[need_vars])
         self._sig_rep_constrs.append(c_hat <= -self.c[need_vars])
     if sigrep_c.dtype == object:
         sigrep_c = cl.Expression(sigrep_c)
     self._sig_rep = Signomial(self.alpha, sigrep_c)
     pass
Beispiel #18
0
def sig_solrec(prob, ineq_tol=1e-8, eq_tol=1e-6, skip_ls=False):
    """
    Recover a list of candidate solutions from a dual SAGE relaxation. Solutions are
    guaranteed to be feasible up to specified tolerances, but not necessarily optimal.

    Parameters
    ----------
    prob : coniclifts.Problem
        A dual-form SAGE relaxation.
    ineq_tol : float
        The amount by which recovered solutions can violate inequality constraints.
    eq_tol : float
        The amount by which recovered solutions can violate equality constraints.
    skip_ls : bool
        Whether or not to skip constrained least-squares solution recovery.

    Returns
    -------
    sols : list of ndarrays
        A list of feasible solutions, sorted in increasing order of objective function value.
        It is possible that this list is empty, in which case no feasible solutions were recovered.

    """
    con = prob.constraints[0]
    if not con.name == 'Lagrangian SAGE dual constraint':  # pragma: no cover
        raise RuntimeError('Unexpected first constraint in dual SAGE relaxation.')
    metadata = prob.metadata
    f = metadata['f']
    # Recover any constraints present in "prob"
    lag_gts, lag_eqs = [], []
    if 'gts' in metadata:
        # only happens in "constrained_sage_dual".
        lag_gts = metadata['gts']
        lag_eqs = metadata['eqs']
    lagrangian = _make_dummy_lagrangian(f, lag_gts, lag_eqs)
    if con.X is None:
        X_gts, X_eqs = [], []
    else:
        X_gts, X_eqs = con.X.gts, con.X.eqs
    gts = lag_gts + X_gts
    eqs = lag_eqs + X_eqs
    # Search for solutions which meet the feasibility criteria
    v = con.v.value
    v[v < 0] = 0
    if np.any(np.isnan(v)):
        return None
    alpha = con.alpha
    dummy_modulated_lagrangian = Signomial(alpha, np.ones(shape=(alpha.shape[0],)))
    alpha_reduced = lagrangian.alpha
    modulator = metadata['modulator']
    M = moment_reduction_array(lagrangian, modulator, dummy_modulated_lagrangian)
    if skip_ls:
        sols0 = []
    else:
        sols0 = _least_squares_solution_recovery(alpha_reduced, con, v, M, gts, eqs, ineq_tol, eq_tol)
    sols1 = _dual_age_cone_solution_recovery(con, v, M, gts, eqs, ineq_tol, eq_tol)
    sols = sols0 + sols1
    sols.sort(key=lambda mu: f(mu))
    return sols
Beispiel #19
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 = temp.as_polynomial()
     return temp
Beispiel #20
0
def hierarchy_e_k(sigs, k):
    alphas = [s.alpha for s in sigs]
    alpha = np.vstack(alphas)
    alpha = np.unique(alpha, axis=0)
    c = np.ones(shape=(alpha.shape[0], ))
    s = Signomial(alpha, c)
    s = s**k
    return s.alpha
Beispiel #21
0
 def test_exponentiation(self):
     x = standard_sig_monomials(2)
     y0 = (x[0] - x[1])**2
     y1 = x[0]**2 - 2 * x[0] * x[1] + x[1]**2
     assert y0 == y1
     z0 = x[0]**0.5
     z1 = Signomial.from_dict({(0.5, 0): 1})
     assert z0 == z1
Beispiel #22
0
 def without_zeros(self):
     """
     Return a Polynomial which is symbolically equivalent to ``self``,
     but which doesn't track basis functions ``alpha[i,:]`` for which ``c[i] == 0``.
     """
     p = Signomial.without_zeros(self)
     p = p.as_polynomial()
     return p
Beispiel #23
0
 def test_signomial_evaluation(self):
     s = Signomial.from_dict({(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)
Beispiel #24
0
def sig_constrained_dual(f, gts, eqs, p=0, q=1, ell=0, X=None, slacks=False):
    """
    Construct the SAGE-(p, q, ell) dual problem for the signomial program

        min{ f(x) : g(x) >= 0 for g in gts,
                    g(x) == 0 for g in eqs,
                    and x in X }

    where X = :math:`R^{\\texttt{f.n}}` by default.
    """
    lagrangian, ineq_lag_mults, eq_lag_mults, _ = make_sig_lagrangian(f, gts, eqs, p=p, q=q)
    metadata = {'lagrangian': lagrangian, 'f': f, 'gts': gts, 'eqs': eqs, 'level': (p, q, ell), 'X': X}
    if ell > 0:
        alpha_E_1 = hierarchy_e_k([f, f.upcast_to_signomial(1)] + list(gts) + list(eqs), k=1)
        modulator = Signomial(alpha_E_1, np.ones(alpha_E_1.shape[0])) ** ell
        lagrangian = lagrangian * modulator
        f = f * modulator
    else:
        modulator = f.upcast_to_signomial(1)
    metadata['modulator'] = modulator
    # In primal form, the Lagrangian is constrained to be a SAGE signomial.
    # Introduce a dual variable "v" for this constraint.
    v = cl.Variable(shape=(lagrangian.m, 1), name='v')
    con = relative_dual_sage_cone(lagrangian, v, name='Lagrangian SAGE dual constraint', X=X)
    constraints = [con]
    expcovers = None
    for i, (s_h, h) in enumerate(ineq_lag_mults):
        # These generalized Lagrange multipliers "s_h" are SAGE signomials.
        # For each such multiplier, introduce an appropriate dual variable "v_h", along
        # with constraints over that dual variable.
        h_m = h * modulator
        c_h = sym_corr.moment_reduction_array(s_h, h_m, lagrangian)
        if slacks:
            v_h = cl.Variable(name='v_' + str(h), shape=(s_h.m, 1))
            constraints.append(c_h @ v == v_h)
        else:
            v_h = c_h @ v
        con_name = 'SAGE dual for signomial inequality # ' + str(i)
        con = relative_dual_sage_cone(s_h, v_h, name=con_name, X=X, expcovers=expcovers)
        expcovers = con.ech.expcovers  # only * really * needed in first iteration, but keeps code flat.
        constraints.append(con)
    for s_h, h in eq_lag_mults:
        # These generalized Lagrange multipliers "s_h" are arbitrary signomials.
        # They dualize to homogeneous equality constraints.
        h = h * modulator
        c_h = sym_corr.moment_reduction_array(s_h, h, lagrangian)
        constraints.append(c_h @ v == 0)
    # Equality constraint (for the Lagrangian to be bounded).
    a = sym_corr.relative_coeff_vector(modulator, lagrangian.alpha)
    constraints.append(a.T @ v == 1)
    # Define the dual objective function.
    obj_vec = sym_corr.relative_coeff_vector(f, lagrangian.alpha)
    obj = obj_vec.T @ v
    # Return the coniclifts Problem.
    prob = cl.Problem(cl.MIN, obj, constraints)
    prob.metadata = metadata
    cl.clear_variable_indices()
    return prob
Beispiel #25
0
def infer_domain(f, gts, eqs, check_feas=True):
    """
    Identify a subset of the constraints in ``gts`` and ``eqs`` which can be incorporated into
    conditional SAGE relaxations for polynomials. Construct a PolyDomain object from the inferred
    constraints.

    Parameters
    ----------
    f : Polynomial
        The objective in a desired optimization problem. This parameter is only used to determine
        the dimension of the set defined by constraints in ``gts`` and ``eqs``.
    gts : list of Polynomials
        For every ``g in gts``, there is a desired constraint that variables ``x`` satisfy ``g(x) >= 0``.
    eqs : list of Polynomials
        For every ``g in eqs``, there is a desired constraint that variables ``x`` satisfy ``g(x) == 0``.
    check_feas : bool
        Indicates whether or not to verify that the returned PolyDomain is nonempty.

    Returns
    -------
    X : PolyDomain or None

    """
    # GP-representable inequality constraints (recast as "Signomial >= 0")
    gp_gts = con_gen.valid_gp_representable_poly_inequalities(gts)
    gp_gts_sigreps = [Signomial(g.alpha, g.c) for g in gp_gts]
    gp_gts_sigreps = con_gen.valid_posynomial_inequalities(gp_gts_sigreps)
    #   ^ That second call is to convexify the signomials.
    # GP-representable equality constraints (recast as "Signomial == 0")
    gp_eqs = con_gen.valid_gp_representable_poly_eqs(eqs)
    gp_eqs_sigreps = [Signomial(g.alpha, g.c) for g in gp_eqs]
    gp_eqs_sigreps = con_gen.valid_monomial_equations(gp_eqs_sigreps)
    #  ^ That second call is to make sure the nonconstant term has
    #    a particular sign (specifically, a negative sign).
    clcons = con_gen.clcons_from_standard_gprep(f.n, gp_gts_sigreps,
                                                gp_eqs_sigreps)
    if len(clcons) > 0:
        polydom = PolyDomain(f.n,
                             logspace_cons=clcons,
                             gts=gp_gts,
                             eqs=gp_eqs,
                             check_feas=check_feas)
        return polydom
    else:
        return None
Beispiel #26
0
 def as_signomial(self):
     """
     Returns
     -------
     f : Signomial
         For every elementwise positive vector ``x``, we have ``self(x) == f(np.log(x))``.
     """
     f = Signomial(self.alpha, self.c)
     return f
Beispiel #27
0
def gpkit_hmap_to_sageopt_sig(curhmap, vkmap):
    n_vks = len(vkmap)
    temp_sig_dict = dict()
    for expinfo, coeff in curhmap.items():
        tup = n_vks * [0]
        for vk, expval in expinfo.items():
            tup[vkmap[vk]] = expval
        temp_sig_dict[tuple(tup)] = coeff
    s = Signomial.from_dict(temp_sig_dict)
    return s
Beispiel #28
0
 def _constrained_sage_1():
     # Background
     #
     #       This is Example 3.3 from Chandraskearan and Shah's original paper on SAGE relaxations.
     #       The problem is to minimize a nonconvex signomial, over a convex set defined by a single
     #       posynomial inequality.
     #
     s0 = Signomial.from_dict({(10.2, 0, 0): 10, (0, 9.8, 0): 10, (0, 0, 8.2): 10})
     s1 = Signomial.from_dict({(1.5089, 1.0981, 1.3419): -14.6794})
     s2 = Signomial.from_dict({(1.0857, 1.9069, 1.6192): -7.8601})
     s3 = Signomial.from_dict({(1.0459, 0.0492, 1.6245): 8.7838})
     f = s0 + s1 + s2 + s3
     g = Signomial.from_dict({(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]
     return f, gs
def valid_monomial_equations(eqs):
    conv_eqs = []
    for g in eqs:
        # g defines a constraint g(x) == 0.
        if np.count_nonzero(g.c) > 2:
            # cannot convexify
            continue
        pos_loc = np.where(g.c > 0)[0]
        if pos_loc.size == 1:
            pos_loc = pos_loc[0]
            inverse_term = Signomial.from_dict(
                {tuple(-g.alpha[pos_loc, :]): 1})
            conv_eqs.append(g * inverse_term)
    return conv_eqs
Beispiel #30
0
 def test_broadcasting(self):
     # any signomial will do.
     alpha_c = {(0, ): 1, (1, ): -1, (2, ): -2}
     s = Signomial.from_dict(alpha_c)
     other = np.array([1, 2])
     t1 = s + other
     self.assertIsInstance(t1, np.ndarray)
     t2 = other + s
     self.assertIsInstance(t2, np.ndarray)
     delta = t1 - t2
     d1 = delta[0].without_zeros()
     d2 = delta[1].without_zeros()
     self.assertEqual(d1.m, 1)
     self.assertEqual(d2.m, 1)