Exemple #1
0
def get_constr_error(constr):
    if isinstance(constr, cp.constraints.Equality):
        error = cp.abs(constr.args[0] - constr.args[1])
    elif isinstance(constr, cp.constraints.Inequality):
        error = cp.pos(constr.args[0] - constr.args[1])
    elif isinstance(constr, cp.constraints.PSD):
        mat = constr.args[0] - constr.args[1]
        error = cp.neg(cp.lambda_min(mat + mat.T) / 2)
    return cp.sum(error)
Exemple #2
0
def get_constr_error(constr):
    if isinstance(constr, cvx.constraints.EqConstraint):
        error = cvx.abs(constr.args[0] - constr.args[1])
    elif isinstance(constr, cvx.constraints.LeqConstraint):
        error = cvx.pos(constr.args[0] - constr.args[1])
    elif isinstance(constr, cvx.constraints.PSDConstraint):
        mat = constr.args[0] - constr.args[1]
        error = cvx.neg(cvx.lambda_min(mat + mat.T)/2)
    return cvx.sum_entries(error)
Exemple #3
0
def gen_data_ndim(nb_datapoints, dim, savefile, rand_seed=7):
    """Sampling according to Table 1 in manuscript:
    - uniform point positioning (x) in [0,1] for each dimension
    - uniform eigenvalues in [-1,1]
    - ortho-normal basis/matrix (eigvecs) of eigenvectors
    :param nb_datapoints: how many data points to sample
    :param dim: dimensionality of SDP sub-problem to sample
    :param savefile: file to save sampled data in
    :param rand_seed: random seed, pre-set to 7
    :return: None
    """
    np.random.seed(rand_seed)
    X = cvx.Variable(dim, dim)
    data_points = []
    t_init = timer()
    t0 = timer()
    for data_pt_nb in range(1, nb_datapoints + 1):
        # ortho-normal basis/matrix (eigvecs) of eigenvectors
        eigvecs = ortho_group.rvs(dim)
        # uniform eigenvalues in [-1,1]
        eigvals = np.random.uniform(-1, 1, dim).tolist()
        # construct sampled Q from eigen-decomposition
        Q = np.matmul(np.matmul(eigvecs, np.diag(eigvals)),
                      np.transpose(eigvecs))
        # uniform point positioning (x) in [0,1] for each dimension
        x = np.random.uniform(0, 1, dim).tolist()
        # construct cvx SDP sub-problem
        obj_sdp = cvx.Minimize(cvx.sum_entries(cvx.mul_elemwise(Q, X)))
        constraints = [
            cvx.lambda_min(
                cvx.hstack(cvx.vstack(1, np.array(x)),
                           cvx.vstack(cvx.vec(x).T, X))) >= 0,
            *[X[ids, ids] <= x[ids] for ids in range(0, dim)]
        ]
        prob = cvx.Problem(obj_sdp, constraints)
        # solve it using Mosek SDP solver
        prob.solve(verbose=False, solver=cvx.MOSEK)
        # store upper triangular matrix in array (row major) since it is symmetric
        Q = np.triu(Q, 1) + np.triu(Q, 0)
        # save eigendecomposition, point positioning, matrix Q and solution of SDP sub-problem
        data_points.append([
            *eigvecs.T.flatten(), *eigvals, *x, *list(Q[np.triu_indices(dim)]),
            obj_sdp.value
        ])
        # save to file and empty data_points buffer every 1000 entries
        if not data_pt_nb % 1000:
            t1 = timer()
            with open(savefile, "a") as f:
                for line in data_points:
                    f.write(",".join(str(x) for x in line) + "\n")
                data_points = []
                print(
                    str(data_pt_nb) + " " + str(dim) + "D points, time = " +
                    str(t1 - t0) + "s" + ", total = " + str(t1 - t_init) + "s")
                t0 = t1
Exemple #4
0
def e_optimal(A, N):

    # Initializing Variables, Objective, and Constraints
    W = cp.Variable(N)
    obj = cp.Maximize(cp.lambda_min(cp.sum([W[i] * A[i] for i in range(N)])))
    const = [0 <= W, cp.sum(W) == 1]

    # Creating Problem & Solving
    prob = cp.Problem(obj, const)
    prob.solve()

    return prob
Exemple #5
0
def smallestCircumScribedEllip(ptS,
                               P=None,
                               obj=None,
                               maxChange=[None, None],
                               Pold=None,
                               **kwargs):
    #ptS holds the points columnwise
    #mindCondition < lambda_max/lambda_min
    opts = {'minCondition': 1.e3}
    opts.update(kwargs)

    Pold = (Pold.T + Pold) / 2.

    dim = ptS.shape[0]

    if P is None:
        P = cvxpy.Semidef(dim, "P")

    cstr = [cvxpy.quad_form(aPt, P) <= 1. for aPt in ptS.T]

    eigMax = np.max(np.linalg.eigh(Pold)[0])

    #restrict changement
    zeta = cvxpy.Variable(1)
    if not (Pold is None) and not (maxChange[0] is None):
        cstr.append(eigMax * maxChange[0] * np.identity(dim) < P - zeta * Pold)
    if not (Pold is None) and not (maxChange[1] is None):
        cstr.append(P - zeta * Pold < eigMax * maxChange[1] * np.identity(dim))

    if not (opts['minCondition'] is None):
        cstr.append(
            cvxpy.lambda_max(P) < opts['minCondition'] * cvxpy.lambda_min(P))

    if obj is None:
        obj = cvxpy.Maximize(cvxpy.log_det(P))

    prob = cvxpy.Problem(obj, cstr)

    #prob.solve();
    prob.solve(solver='CVXOPT',
               verbose=False,
               kktsolver=cvxpy.ROBUST_KKTSOLVER)

    assert prob.status == 'optimal', "Failed to solve circumscribed ellip prob"

    Pval = np.array(P.value)

    return Pval
Exemple #6
0
# Z = cvx.Variable(3,3)

# objective = cvx.Minimize( sum(cvx.square(P - Z)) )
# constr = [cvx.constraints.semi_definite.SDP(P)]
# prob = cvx.Problem(objective, constr)
# prob.solve()

import cvxpy as cp
import numpy as np
import cvxopt

# create data P
P = cp.Parameter(3,3)
Z = cp.semidefinite(3)

objective = cp.Minimize( cp.lambda_max(P) - cp.lambda_min(P - Z) )
prob = cp.Problem(objective, [Z >= 0])
P.value = cvxopt.matrix(np.matrix('4 1 3; 1 3.5 0.8; 3 0.8 1'))
prob.solve()
print "optimal value =", prob.value


# [ 4,     1+2*j,     3-j       ; ...
#       1-2*j, 3.5,       0.8+2.3*j ; ...
#       3+j,   0.8-2.3*j, 4         ];
#
# % Construct and solve the model
# n = size( P, 1 );
# cvx_begin sdp
#     variable Z(n,n) hermitian toeplitz
#     dual variable Q
Exemple #7
0
   minimize   || Z - P ||_F
   subject to Z >= 0

Adapted from an example provided in the SeDuMi documentation and CVX examples.
Unlike those examples, the data is real (not complex) and the result is only
required to be PSD (instead of also Toeplitz)
"""
import cvxpy as cp
import numpy as np
import cvxopt

# create data P
P = cp.Parameter(3,3)
Z = cp.SDPVar(3,3)

objective = cp.Minimize( cp.lambda_max(P) - cp.lambda_min(P - Z) )
prob = cp.Problem(objective)
P.value = cvxopt.matrix(np.matrix('4 1 3; 1 3.5 0.8; 3 0.8 1'))
prob.solve()


# [ 4,     1+2*j,     3-j       ; ...
#       1-2*j, 3.5,       0.8+2.3*j ; ...
#       3+j,   0.8-2.3*j, 4         ];
# 
# % Construct and solve the model
# n = size( P, 1 );
# cvx_begin sdp
#     variable Z(n,n) hermitian toeplitz
#     dual variable Q
#     minimize( norm( Z - P, 'fro' ) )
Exemple #8
0
def main(args):

    system = System(args)
    control = Cmrac(system)

    x = system.reset()
    control.reset()

    data = Data()
    for i in range(args.ts.size):
        t = args.ts[i]
        u = control.get_inputs(t, x)

        # step
        next_x = system.step(t, x, u)

        # controller update
        current_data = control.update(t, x)

        data.append('time', t)
        data.append('state', x)
        data.append('input', u)

        [data.append(*item) for item in current_data.items()]

        x = next_x

    data.system = system
    data.control = control

    # Plot
    # plot_basis(data)

    #     # SDP
    #     N = cvx.Parameter(nonneg=True)
    #     mineig = []
    #     for n in range(10, 21):
    #         N.value = n
    #         a = cvx.Variable(N.value, nonneg=True)
    #         s = cvx.Variable(1, nonneg=True)
    #         constr = [sum(a) == 5]

    #         basis = np.array([system.unc.basis(state).tolist()
    #                           for state in data.state])
    #         expr = 0
    #         for ai, phi in zip(a, basis[:N.value]):
    #             expr += phi[:, np.newaxis] * phi * ai

    #         constr += [expr - s * np.eye(5) >> 0]

    #         obj = cvx.Maximize(s)
    #         prob = cvx.Problem(obj, constr)
    #         prob.solve(solver=cvx.CVXOPT, verbose=True)

    #         mineig.append(s.value)

    # SDP
    N = cvx.Parameter(nonneg=True)
    mineig = []
    for n in range(10, 22):
        N.value = n
        a = cvx.Variable(N.value, nonneg=True)
        # s = cvx.Variable(1, nonneg=True)
        constr = [sum(a) == 5]

        basis = np.array(
            [system.unc.basis(state).tolist() for state in data.state])
        expr = 0
        for ai, phi in zip(a, basis[:N.value]):
            expr += phi[:, np.newaxis] * phi * ai

        # constr += [expr - s * np.eye(5) >> 0]

        obj = cvx.Maximize(cvx.lambda_min(expr))
        prob = cvx.Problem(obj, constr)
        result = prob.solve(solver=cvx.CVXOPT, verbose=True)

        mineig.append(result)

    plt.figure()
    plt.plot(mineig)

    plt.show()

    return data
Exemple #9
0
def solve_original_sdp(adj, qs):
    """
    Original gain design formulation. Solved as SDP with CVXPY.

    See K. Fathian et al., "Robust 3D Distributed Formation Control with 
    Collision Avoidance and Application to Multirotor Aerial Vehicles," ICRA'18

    Parameters
    ----------
    adj: nxn numpy array
        adjacency matrix encoding the sensing topology of swarm

    qs: nx3 numpy array
        desired positions (in R^3) of all the agents w.r.t the current
        agent's coordinate frame.

    Returns
    -------

    A: 3nx3n numpy array
        symmetric nsd matrix with the last 5 or 6 (based on nullity) eigenvalues
        constrained to be zero. This gain matrix contains subblocks for each agent.
    """
    n = np.shape(adj)[0]  # Number of agents

    oneX = np.kron(np.ones(n), [1, 0, 0])
    oneY = np.kron(np.ones(n), [0, 1, 0])
    oneZ = np.kron(np.ones(n), [0, 0, 1])

    # 90 deg rotation about z
    R = np.array([[0, -1, 0], [+1, 0, 0], [0, 0, +1]], dtype=np.float32)

    # Rotate 90 degrees about z-axis
    qsBar = np.zeros_like(qs)
    for i, vec in enumerate(qs):
        qsBar[i] = np.matmul(R, vec.T)

    # Project onto x-y plane
    qsp = np.copy(qs)
    qsp[:, 2] = 0

    # formations that have the same z coordinate are "flat", which causes
    # a rank deficiency in N. We use 'nullity' to choose the appropriate
    # number of linearly independent columns of U (from svd of N).
    flat = (np.std(qs[:, 2]) <= 1e-2)
    nullity = 5 if flat else 6

    # Kernel space
    N = np.vstack(
        (qs.flatten(), qsBar.flatten(), qsp.flatten(), oneX, oneY, oneZ)).T

    # Get orthogonal complement of kernel of A
    U, diag, Vh = np.linalg.svd(N)
    Q = U[:, nullity:3 * n]

    # Subspace constraints for given sensing topology
    S = 1 - np.kron(adj + np.eye(n), np.ones((3, 3)))

    # Solve via CVX
    A = cp.Variable((3 * n, 3 * n), symmetric=True)
    obj = cp.Maximize(cp.lambda_min(cp.matmul(Q.T, cp.matmul(A, Q))))
    constraints = [
        cp.matmul(A, N) == 0,  # Kernel of A
        cp.multiply(A, S) == 0,  # For agents that are not neighbors
        cp.norm(A) <= 10
    ]

    for i in range(n):
        for j in range(n):
            if adj[i, j]:  # If agents are neighbors
                constraints.append(A[3 * i, 3 * j] == A[3 * i + 1, 3 * j + 1])
                constraints.append(A[3 * i, 3 * j + 1] == -A[3 * i + 1, 3 * j])
                constraints.append(A[3 * i:3 * i + 2, 3 * j + 2] == 0)
                constraints.append(A[3 * i + 2, 3 * j:3 * j + 2] == 0)

    prob = cp.Problem(obj, constraints)
    prob.solve(eps=1e-6)

    if prob.status not in ["infeasible", "unbounded"]:
        Ar = -np.copy(A.value)  # Make matrix negative semi-definite
        Ar /= np.max(np.abs(Ar))  # Scale matrix

        # Since we aren't very confident in our solver right now
        # (cvxpy seems to be choosing SCS to solve the SDP),
        # we will manually enforce symmetry of the gain matrix.
        Ar = 0.5 * (np.array(Ar) + np.array(Ar).T)

    else:
        Ar = None

    return Ar
Exemple #10
0
    def __sel_eigcut_by_ordering_on_measure(self, strat, vars_values, cut_round, sel_size=0):
        """Apply selection strategy to rank sub-problems (feasibility/ optimality/ combined/ exact/ random/ figure 8)
        """
        nb_lifted, agg_list, Q, get_eigendecomp = self._nb_lifted, self._agg_list, self._Q, self._get_eigendecomp
        X_vals, x_vals = list(vars_values[0:nb_lifted]), list(vars_values[nb_lifted:])
        rank_list = [0] * len(agg_list)
        feas_sel, opt_sel, exact_sel, comb_sel, rand_sel, figure_8 = \
            (strat == 1), (strat == 2), (strat == 3), (strat == 4), (strat == 5), (strat == -1)
        # If optimality selection involved
        if opt_sel or comb_sel or exact_sel:
            nns = self._nns
            for agg_idx, (set_inds, Xarr_inds, Q_slice, max_elem) in enumerate(agg_list):
                dim_act = len(set_inds)
                curr_pt = itemgetter(*set_inds)(x_vals)
                X_slice = itemgetter(*Xarr_inds)(X_vals)
                obj_improve = - sum(map(mul, Q_slice, X_slice)) * max_elem
                # Optimality selection via neural networks (alone or combined with feasibility)
                if opt_sel or comb_sel:
                    # Estimate objective improvement using neural network (after casting input to right ctype)
                    obj_improve += nns[dim_act - 2][0](nns[dim_act - 2][1](*curr_pt, *Q_slice)) * max_elem
                    # Combining opt + feas selection
                    if comb_sel:
                        # Check smallest eigenvalue for valid cuts
                        eigval = get_eigendecomp(dim_act, curr_pt, X_slice, False)[0]
                        if obj_improve > CutSolver._THRES_MIN_OPT:      # strong cut
                            if eigval < CutSolver._THRES_NEG_EIGVAL:    # valid strong cut
                                obj_improve += CutSolver._BIG_M
                            else:                                       # invalid cut
                                obj_improve -= CutSolver._BIG_M
                        else:                                           # not strong but potentially valid cut
                            obj_improve = -eigval
                # Optimality selection via exact SDP solution
                elif exact_sel:
                    X_sdp = cvx.Variable(dim_act, dim_act)
                    constr_sdp = [X_sdp[ids, ids] <= curr_pt[ids] for ids in range(dim_act)] + \
                                 [cvx.lambda_min(cvx.hstack(cvx.vstack(1, np.array(curr_pt)),
                                                            cvx.vstack(cvx.vec(np.array(curr_pt)).T, X_sdp))) >= 0]
                    obj_sdp_coeffs = Q[np.array(set_inds), np.array([[Ind] for Ind in set_inds])]
                    obj_sdp = cvx.Minimize(cvx.sum_entries(cvx.mul_elemwise(obj_sdp_coeffs, X_sdp)))
                    prob = cvx.Problem(obj_sdp, constr_sdp)
                    prob.solve(verbose=False, solver=cvx.MOSEK)
                    if prob.status == 'optimal':
                        obj_improve += obj_sdp.value
                    else:
                        print('Mosek error when solving a sub-problem!')
                        obj_improve = - CutSolver._BIG_M
                rank_list[agg_idx] = (agg_idx, obj_improve, curr_pt, X_slice, Xarr_inds, Q_slice)
            # Order by expected objective improvement
            rank_list.sort(key=lambda tup: tup[1], reverse=True)
        # Random selection
        elif rand_sel:
            # random ordering shuffle with seed
            np.random.shuffle(agg_list)
            rank_list = agg_list
        # Feasibility (-only) selection
        elif feas_sel:
            rank_list = []
            # Rank by eigenvalues (when negative)
            for agg_idx, (set_inds, Xarr_inds, _, _) in enumerate(agg_list):
                dim_act = len(set_inds)
                curr_pt = itemgetter(*set_inds)(x_vals)
                X_slice = itemgetter(*Xarr_inds)(X_vals)
                eigvals, evecs = get_eigendecomp(dim_act, curr_pt, X_slice, True)
                if eigvals[0] < CutSolver._THRES_NEG_EIGVAL:
                    rank_list.append((-eigvals[0], evecs.T[0], set_inds, Xarr_inds, dim_act,agg_idx))
            rank_list.sort(key=lambda tup: tup[0], reverse=True)

        ####################
        # Special separate case for Figure 8
        # Comparison of exact vs estimated (neural net) measures for optimality cut selection
        ####################
        elif figure_8:
            exact_list, this_round_cuts, nb_cuts_sel_by_both = [], [], 0
            nns = self._nns
            for agg_idx, (set_inds, Xarr_inds, Q_slice, max_elem) in enumerate(agg_list):
                dim_act = len(set_inds)
                curr_pt = itemgetter(*set_inds)(x_vals)
                X_slice = itemgetter(*Xarr_inds)(X_vals)
                curr_obj = sum(map(mul, Q_slice, X_slice)) * max_elem
                # optimality selection via estimated (neural network) ordering
                obj_improve = nns[dim_act - 2][0](nns[dim_act - 2][1](*(curr_pt + Q_slice))) * max_elem - curr_obj
                rank_list[agg_idx] = (agg_idx, obj_improve, curr_pt, X_slice, Xarr_inds, Q_slice)
                # optimality based exact ordering (for comparison)
                X_sdp = cvx.Variable(dim_act, dim_act)
                constr_sdp = [X_sdp[ids, ids] <= curr_pt[ids] for ids in range(dim_act)] + \
                             [cvx.lambda_min(cvx.hstack(cvx.vstack(1, np.array(curr_pt)),
                                                        cvx.vstack(cvx.vec(np.array(curr_pt)).T, X_sdp))) >= 0]
                obj_sdp_coeffs = Q[np.array(set_inds), np.array([[Ind] for Ind in set_inds])]
                obj_sdp = cvx.Minimize(cvx.sum_entries(cvx.mul_elemwise(obj_sdp_coeffs, X_sdp)))
                prob = cvx.Problem(obj_sdp, constr_sdp)
                prob.solve(verbose=False, solver=cvx.MOSEK)
                if prob.status == 'optimal':
                    obj_improve_exact = obj_sdp.value - curr_obj
                else:
                    print('Mosek error when solving a sub-problem!')
                    obj_improve_exact = - CutSolver._BIG_M
                exact_list.append((agg_idx, obj_improve_exact))
            # Sort by estimated optimality measure
            rank_list.sort(key=lambda tup: tup[1], reverse=True)
            # Sort by exact optimality measure
            exact_list.sort(key=lambda tup: tup[1], reverse=True)
            for estim_idx, cut in enumerate(rank_list):
                cut_idx = cut[0]
                exact_idx = [elem[0] for elem in exact_list].index(cut_idx)
                sel_by_estim = 1 if estim_idx < sel_size else 0  # if cut is selected by estimated measure
                sel_by_exact = 1 if exact_idx < sel_size else 0  # if cut is selected by exact measure
                this_round_cuts.append([cut_round, cut_idx, sel_by_estim, sel_by_exact, cut[1], exact_list[exact_idx][1]])
                if sel_by_estim and sel_by_exact:
                    nb_cuts_sel_by_both += 1
            return rank_list, nb_cuts_sel_by_both / sel_size, this_round_cuts
        return rank_list
Exemple #11
0
def gen_sdp_surface_2d(Q, iters, pt_tan, savefile):
    """Generate the semidefinite surface/underestimator for semidefinite 2D sub-problems with given Q on a mesh
    with distance between points 1/(iters-1) and finds hyoperplane tangent to the SDP surface at tangent point pt_tan
    """
    dim = 2
    # 2x2 variable X holding the relaxed bilinear/quadratic terms.
    X = cvx.Variable(2, 2)
    x = cvx.Variable(2)
    # Create objective
    obj_expr = 0
    for i in range(dim):
        for j in range(dim):
            obj_expr += Q[i, j] * X[i, j]
    obj = cvx.Minimize(obj_expr)
    # deviation from point pt_tan
    dev = 0.01
    # Create 3 additional points around pt_tan to determine a hyperplane tangent to
    # the SDP surface at approximately pt_tan
    pts = [
        pt_tan, [pt_tan[0] - dev, pt_tan[1] - dev],
        [pt_tan[0] - dev, pt_tan[1] + dev],
        [pt_tan[0] + math.sqrt(2 * pow(dev, 2)), pt_tan[1]]
    ]
    res_points = []
    # Calculate for point of SDP surface for pt_tan and the 3 points around it determining hyperplane
    for i in range(0, dim + 2):
        pt = np.array(pts[i])
        constraints = [
            cvx.lambda_min(
                cvx.bmat([[1, *pt], [pt[0], X[0, :]], [pt[1], X[1, :]]])) >= 0,
            X[0, 0] <= pt[0], X[1, 1] <= pts[i][1]
        ]
        prob = cvx.Problem(obj, constraints)
        prob.solve(verbose=False, solver=cvx.MOSEK)
        res_points.append([*pts[i], obj_expr.value])

    # Hyperplane equation calculations
    vectors = [[1, *([0] * dim)]]
    for i in range(2, dim + 2):
        vectors.append(
            [x - y for x, y in zip(res_points[i], res_points[i - 1])])
    hp_sols = np.linalg.solve(np.array(vectors), vectors[0])
    coeffs = [*np.ndarray.tolist(hp_sols), -np.dot(hp_sols, res_points[1])]
    # Separating the hyperplane
    obj_hp = obj_expr - (coeffs[0] * x[0] + coeffs[1] * x[1] +
                         coeffs[dim + 1]) / (-coeffs[dim])
    obj_sdp_hp = cvx.Minimize(obj_hp)
    constraints_hp = [
        cvx.lambda_min(cvx.hstack(cvx.vstack(1, x), cvx.vstack(x.T, X))) >= 0,
        *[X[ids, ids] <= x[ids] for ids in range(0, dim)], x[0] >= 0,
        x[1] >= 0, x[0] <= 1, x[1] <= 1
    ]
    prob = cvx.Problem(obj_sdp_hp, constraints_hp)
    prob.solve(verbose=False, solver=cvx.MOSEK)
    # Constant coordinate minus distance to hyperplane (bring out hyperplane till tangent)
    coeffs[dim + 1] += obj_hp.value * (-coeffs[dim])

    # Determine points on SDP surface and on hyperplane tangent to it at pt_tan
    # on a mesh grid, with spaces in between them of 1/(iters-1)
    data_points = []
    for i in range(1, iters + 1):
        for j in range(1, iters + 1):
            pt = [(i - 1) / float(iters - 1), (j - 1) / float(iters - 1)]
            obj_value = 0
            for r in range(0, dim):
                for c in range(0, dim):
                    obj_value += Q[r, c] * pt[r] * pt[c]
            # Mosek fails due to numerical error at pt=[0,0], but solution is obviously 0
            if i == 1 and j == 1:
                hp_value = (np.dot(coeffs[0:dim], pt[0:dim]) +
                            coeffs[dim + 1]) / (-coeffs[dim])
                data_points.append([pt[0], pt[1], obj_value, hp_value, 0])
                continue
            constraints = [
                cvx.lambda_min(
                    cvx.bmat([[1, *pt], [pt[0], X[0, :]], [pt[1], X[1, :]]]))
                >= 0, X[0, 0] <= pt[0], X[1, 1] <= pt[1]
            ]
            prob = cvx.Problem(obj, constraints)
            prob.solve(verbose=False, solver=cvx.MOSEK)
            # hyperplane value at pt
            hp_value = (np.dot(coeffs[0:dim], pt[0:dim]) +
                        coeffs[dim + 1]) / (-coeffs[dim])
            data_points.append(
                [pt[0], pt[1], obj_value, hp_value, obj_expr.value])
    # save all data point in .csv file
    with open(savefile, "w") as f:
        for line in data_points:
            f.write(",".join(str(x) for x in line) + "\n")
Exemple #12
0
def solve_random_inst_3d(nb_vars, nb_instances, savefile):
    """Calculates percent gap between M and S+M  closed by M+S_3 for randomly generated (dense BoxQP) instances
    :param nb_vars: size of instances (number of unlifted variables x)
    :param nb_instances: number of problem instances to sample
    :param savefile: file to save results
    :return: None
    """
    # variables for problems of dimension nb_vars
    X = cvx.Variable(nb_vars, nb_vars)
    x = cvx.Variable(nb_vars)
    # (M) McCormick constraints
    constraints_rlt = []
    for i in range(nb_vars):
        constraints_rlt.extend([
            X[i, i] <= x[i], X[i, i] >= 0, X[i, i] >= 2 * x[i] - 1, x[i] <= 1
        ])
        for j in range(i + 1, nb_vars):
            constraints_rlt.extend([
                X[i, j] >= 0, X[i, j] >= x[i] + x[j] - 1, X[i, j] <= x[i],
                X[i, j] <= x[j], X[i, j] == X[j, i]
            ])
    # (M+S) McCormick + full SDP constraint
    constraints_sdp = deepcopy(constraints_rlt)
    constraints_sdp.append(
        cvx.lambda_min(cvx.hstack(cvx.vstack(1, x), cvx.vstack(x.T, X))) >= 0)
    # (M+S_3) McCormick + 3D SDP constraints
    constraints_3d = deepcopy(constraints_rlt)
    for i in range(nb_vars):
        for j in range(i + 1, nb_vars):
            for k in range(j + 1, nb_vars):
                set_inds = [i, j, k]
                constraints_3d += \
                    [cvx.lambda_min(cvx.hstack(
                        cvx.vstack(1, x[i], x[j], x[k]),
                        cvx.vstack(cvx.hstack(x[i], x[j], x[k]),
                                   X[np.array(set_inds), np.array([[Ind] for Ind in set_inds])]))) >= 0]
    # generate random Q and therefore objectives for nb_instances problem instances and solve them
    for sample_nb in range(nb_instances):
        # generate random Q according to Table 1 in manuscript
        eigvecs = ortho_group.rvs(nb_vars)
        eigvals = np.random.uniform(-1, 1, nb_vars).tolist()
        Q = np.matmul(np.matmul(eigvecs, np.diag(eigvals)),
                      np.transpose(eigvecs))
        # Create objective
        obj_expr = 0
        for i in range(0, nb_vars):
            for j in range(0, nb_vars):
                obj_expr += Q[i, j] * X[i, j]
        obj = cvx.Minimize(obj_expr)
        solution = []
        for constraints in [constraints_sdp, constraints_3d, constraints_rlt]:
            prob = cvx.Problem(obj, constraints)
            prob.solve(verbose=False, solver=cvx.MOSEK)
            solution.append(obj.value)
        # Calculate the percent gap between M+S and M closed by M+S_3
        if solution[0] - solution[2] <= 10e-5:
            percent_gap = 1  # if there is no gap, the percent closed is 1
        else:
            percent_gap = (solution[1] - solution[2]) / (solution[0] -
                                                         solution[2])
        solution.append(min(1, percent_gap))
        print("nb_vars=" + str(nb_vars) + ", sample_nb=" + str(sample_nb) +
              ", percent=" + str(solution[-1]))
        with open(savefile, "a") as f:
            f.write((str(nb_vars) + "," + str(sample_nb) + ",") +
                    ",".join(str(x) for x in solution) + "\n")
Exemple #13
0
n = 20
N = 1000

C = np.random.random_sample((n, n))
C = - C.dot(C.T) + 1000 * np.eye(n)
# print(np.linalg.eigvals(C))

import cvxpy as cp

mX = cp.Symmetric(n, n)
constraints = [cp.lambda_min(mX) >= 0, cp.diag(mX) == 1]

obj = cp.Maximize(cp.trace(C * mX))
maxcut = cp.Problem(obj, constraints).solve()

print(maxcut)
# print(mX.value)

data = np.zeros(N)
for i in range(N):
    X = np.matrix(np.random.randint(0, 2, n) * 2 - 1).T
    data[i] = X.T.dot(C).dot(X)[0][0]

fig = plt.figure(figsize=[10, 5])

plt.plot(data, 'bo', markersize=1)
plt.plot([maxcut], 'ro')
plt.plot([maxcut for i in range(N)], 'ro', markersize=0.2)


plt.show()