Exemplo n.º 1
0
def synth_h2_state_feedback_LMI(A, Binput, Bdist, C1, D12):
    #Dullerud p 217 (?)
    
    n = A.shape[0]  #num states
    m = Binput.shape[1]  #num control inputs
    q = C1.shape[0]  #num outputs to "be kept small"

    X = cvxpy.Variable(n,n)
    Y = cvxpy.Variable(m,n)
    Z = cvxpy.Variable(q,q)
    
    tmp1 = cvxpy.hstack(X, (C1*X+D12*Y).T)
    tmp2 = cvxpy.hstack((C1*X+D12*Y), Z)
    tmp  = cvxpy.vstack(tmp1, tmp2)

    constraints = [A*X + Binput*Y + X*A.T + Y.T*Binput.T + Bdist*Bdist.T == -cvxpy.Semidef(n),
                   tmp == cvxpy.Semidef(n+q),
                  ]

    obj = cvxpy.Minimize(cvxpy.trace(Z))

    prob = cvxpy.Problem(obj, constraints)
    
    prob.solve(solver='CVXOPT', kktsolver='robust')
    
    K = -Y.value*np.linalg.inv(X.value)
    return K
Exemplo n.º 2
0
def sys_norm_h2_LMI(Acl, Bdisturbance, C):
    #doesn't work very well, if problem poorly scaled Riccati works better.
    #Dullerud p 210
    n = Acl.shape[0]
    X = cvxpy.Semidef(n)
    Y = cvxpy.Semidef(n)

    constraints = [ Acl*X + X*Acl.T + Bdisturbance*Bdisturbance.T == -Y,
                  ]

    obj = cvxpy.Minimize(cvxpy.trace(Y))

    prob = cvxpy.Problem(obj, constraints)
    
    prob.solve()
    eps = 1e-16
    if np.max(np.linalg.eigvals((-Acl*X - X*Acl.T - Bdisturbance*Bdisturbance.T).value)) > -eps:
        print('Acl*X + X*Acl.T +Bdisturbance*Bdisturbance.T is not neg def.')
        return np.Inf

    if np.min(np.linalg.eigvals(X.value)) < eps:
        print('X is not pos def.')
        return np.Inf

    return np.sqrt(np.trace(C*X.value*C.T))
Exemplo n.º 3
0
def solve_sdp(G):
    """ Solves the SDP problem:
    
    maximize    1' * s
    subject to  0 <= s <= 1
                [G, G - diag(s); G - diag(s), G] >= 0
    """
    G = np.asarray(G)
    assert G.ndim == 2 and G.shape[0] == G.shape[1]
    p = G.shape[0]

    # Define the problem.
    s = cvx.Variable(p)
    objective = cvx.Maximize(cvx.sum_entries(s))
    constraints = [
        0 <= s,
        s <= 1,
        2 * G - cvx.diag(s) == cvx.Semidef(p),
    ]
    prob = cvx.Problem(objective, constraints)

    # Solve the problem.
    prob.solve()
    assert prob.status == cvx.OPTIMAL

    # Return as array, not as matrix.
    return np.asarray(s.value).flatten()
Exemplo n.º 4
0
def solve_spectral(prob, *args, **kwargs):
    """Solve the spectral relaxation with lambda = 1.
    """

    # TODO: do this efficiently without SDP lifting

    # lifted variables and semidefinite constraint
    X = cvx.Semidef(prob.n + 1)

    W = prob.f0.homogeneous_form()
    rel_obj = cvx.Minimize(cvx.sum_entries(cvx.mul_elemwise(W, X)))

    W1 = sum([f.homogeneous_form() for f in prob.fs if f.relop == '<='])
    W2 = sum([f.homogeneous_form() for f in prob.fs if f.relop == '=='])

    rel_prob = cvx.Problem(
        rel_obj,
        [
            cvx.sum_entries(cvx.mul_elemwise(W1, X)) <= 0,
            cvx.sum_entries(cvx.mul_elemwise(W2, X)) == 0,
            X[-1, -1] == 1
        ]
    )
    rel_prob.solve(*args, **kwargs)

    if rel_prob.status not in [cvx.OPTIMAL, cvx.OPTIMAL_INACCURATE]:
        raise Exception("Relaxation problem status: %s" % rel_prob.status)

    (w, v) = LA.eig(X.value)
    return np.sqrt(np.max(w))*np.asarray(v[:-1, np.argmax(w)]).flatten(), rel_prob.value
Exemplo n.º 5
0
def solve_sdr(prob, *args, **kwargs):
    """Solve the SDP relaxation.
    """

    # lifted variables and semidefinite constraint
    X = cvx.Semidef(prob.n + 1)

    W = prob.f0.homogeneous_form()
    rel_obj = cvx.Minimize(cvx.sum_entries(cvx.mul_elemwise(W, X)))
    rel_constr = [X[-1, -1] == 1]

    for f in prob.fs:
        W = f.homogeneous_form()
        lhs = cvx.sum_entries(cvx.mul_elemwise(W, X))
        if f.relop == '==':
            rel_constr.append(lhs == 0)
        else:
            rel_constr.append(lhs <= 0)

    rel_prob = cvx.Problem(rel_obj, rel_constr)
    rel_prob.solve(*args, **kwargs)

    if rel_prob.status not in [cvx.OPTIMAL, cvx.OPTIMAL_INACCURATE]:
        raise Exception("Relaxation problem status: %s" % rel_prob.status)

    return X.value, rel_prob.value
Exemplo n.º 6
0
def sdp_partition(graph, constraints, k):
    if k != 2: raise Exception('SDP only applicable for 2 partitions')
    adjmat = nx.to_numpy_matrix(graph, weight='weight')
    n = nx.number_of_nodes(graph)
    Y = cvx.Semidef(n)
    obj = cvx.Maximize(
        cvx.sum_entries(cvx.mul_elemwise(np.tril(adjmat), (1 - Y))))
    consts = [Y == Y.T]
    for i in range(n):
        consts.append(Y[i, i] == 1)
    for c1 in constraints.keys():
        for c2 in constraints.keys():
            if constraints[c1] != constraints[c2]:
                consts.append(Y[c1, c2] <= math.cos(2 * math.pi / k))
            else:
                consts.append(Y[c1, c2] == 1)
    prob = cvx.Problem(obj, consts)
    prob.solve(solver='SCS')
    vecs = Y.value
    random_cut = sample_spherical(1, ndim=n)
    partition = {}
    signs = []
    for i in range(n):
        signs.append(np.sign(np.dot(vecs[i, :], random_cut)))
    for con in constraints:
        for i in range(n):
            if signs[con] == signs[i]:
                partition[i] = constraints[con]
    return partition
Exemplo n.º 7
0
def test_synthesis(A, B):
    sf = 10.0
    # Problem data.

    N_u = B.shape[1]
    N_x = A.shape[0]
    Cv = np.eye(N_u)
    Avbar = cvxpy.Variable(rows=N_u, cols=N_u)
    Bvbar = cvxpy.Variable(rows=N_u, cols=N_x)

    P1 = cvxpy.Semidef(A.shape[0])
    #,cols=A.shape[0]); #
    P2 = cvxpy.Semidef(N_u)
    #,cols=N_u);

    Zeros = cvxpy.Variable(rows=N_x + N_u + N_x + N_u,
                           cols=N_x + N_u + N_x + N_u)

    # Construct the problem.

    objective = cvxpy.Minimize(cvxpy.norm1(Avbar) + cvxpy.norm1(Bvbar))
    #+cvxpy.norm2(Bv))
    #PMatrix = cvxpy.vstack([cvxpy.hstack([P1,np.zeros(N_x,N_u)]), cvxpy.hstack([np.zeros(( N_u,N_x )),P2]) ]);
    #QMatrix = cvxpy.vstack([cvxpy.hstack([A,np.matmul(B,Cv)]), cvxpy.hstack([Bv,Av]) ]);
    #SystemMatrix = cvxpy.vstack([cvxpy.hstack([PMatrix,QMatrix]),cvxpy.hstack([QMatrix,PMatrix])])
    SystemMatrix1 = cvxpy.hstack([P1,
                                  np.zeros((N_x, N_u)), A.T * P1, Bvbar.T])
    SystemMatrix2 = cvxpy.hstack(
        [np.zeros((N_u, N_x)), P2,
         np.matmul(Cv.T, B.T) * P1, Avbar])
    SystemMatrix3 = cvxpy.hstack(
        [P1 * A, P1 * np.matmul(B, Cv), P1,
         np.zeros((N_x, N_u))])
    SystemMatrix4 = cvxpy.hstack([Bvbar, Avbar,
                                  np.zeros((N_u, N_x)), P2])
    SystemMatrix = cvxpy.vstack(
        [SystemMatrix1, SystemMatrix2, SystemMatrix3, SystemMatrix4])
    constraints = [Zeros == 1e-10, Zeros << SystemMatrix, 0 < P1, 0 < P2]

    prob = cvxpy.Problem(objective, constraints)

    # The optimal objective is returned by prob.solve().
    result = prob.solve(verbose=True, solver='SCS')

    return result, Avbar.value, Bvbar.value, Cv, P1.value, P2.value, SystemMatrix.value
Exemplo n.º 8
0
    def learn_with_similarity_label(self, data, label, mode, lam):
        """
        Implement the metric learning algorithm in "Distance metric learning, with application to clustering with
        side-information" by Eric P. Xing, et al. The alg learns distance metrics from similarity labels of data pairs
        """
        n_feature = data[0][0].shape[0]
        index_s = [i for i, x in enumerate(label) if x == 1]
        index_ns = [i for i, x in enumerate(label) if x == 0]
        X_s = [list(data[i][0] - data[i][1]) for i in index_s]
        X_ns = [list(data[i][0] - data[i][1]) for i in index_ns]

        # mode tells if the learned Mahalanobis distance metrics are specified by a diagonal matrix or a
        # fully-parametrized matrix
        if mode == "diag":
            x = cvx.Variable(rows=n_feature, cols=1)
            obj = 0
            for i in range(len(X_s)):
                obj = obj + cvx.sum_entries(mul_elemwise(np.square(X_s[i]), x))
            obj_neg = 0
            for i in range(len(X_ns)):
                obj_neg = obj_neg + sqrt(
                    cvx.sum_entries(cvx.mul_elemwise(np.square(X_ns[i]), x)))
            obj = obj - cvx.log(obj_neg)
            obj = obj + lam * norm(x, 1)
            constraints = [x >= 0]
            obj_cvx = cvx.Minimize(obj)
            prob = cvx.Problem(obj_cvx, constraints)
            prob.solve(solver=SCS)
            x_mat = np.diag(x.value.transpose().tolist()[0])
            if prob.status == 'optimal' or prob.status == 'optimal_inaccurate':
                return prob.status, prob.value, x_mat
            else:
                return prob.status, np.nan, np.nan

        if mode == "full":
            lam = 1
            A = cvx.Semidef(n_feature)
            obj = 0
            for i in range(len(X_s)):
                obj = obj + cvx.quad_form(X_s[i], A)
            obj += lam * norm(A, 1)
            const = 0
            for i in range(len(X_ns)):
                const = const + cvx.sqrt(cvx.quad_form(X_ns[i], A))
            constraints = [const >= 1]
            obj_cvx = cvx.Minimize(obj)
            prob = cvx.Problem(obj_cvx, constraints)
            prob.solve(solver=MOSEK)
            if prob.status == 'optimal' or prob.status == 'optimal_inaccurate':
                return prob.status, prob.value, A.value
            else:
                return prob.status, np.nan, np.nan
Exemplo n.º 9
0
def dilat_lvggm_ccg_cvx_sub(S, alpha, beta, covariance_h, precision_h, max_iter_in=1000, threshold_in=1e-3, verbose=False):
    '''
         A cvx implementation of the Decayed-influence Latent variable Gaussian Graphial Model

        The subproblem in Convex-Concave Procedure

        
            min_{R} -log det(R) + trace(R*S_t) + alpha*||[1,0]*R*[1;0]||_1 + gamma*||[0, Theta]*R*[1;0]||_{1,2} 

                s.t.   [0,1]*R*[0;1] = Theta^{-1}

                       R >= 0 

            S_t = [Cov(X), -Cov*B*Theta; -Theta*B'*Cov, beta I]

    '''
    if np.linalg.norm(S-S.T) > 1e-3:
        raise ValueError("Covariance matrix should be symmetric.")

    n = S.shape[0]
    #n1 = covariance.shape[0]
    n2 = covariance_h.shape[0]
    n1 = n - n2
    #if n != (n1+n2):
    if n1 < 0:
        raise ValueError("dimension mismatch n=%d, n1=%d, n2=%d" % (n,n1,n2))
    
    mask = np.zeros((n,n))
    mask[np.ix_(np.arange(n1), np.arange(n1))]
    J1 = np.zeros((n, n1))
    J1[np.arange(n1),:] = np.eye(n1)
    J2 = np.zeros((n, n2))
    J2[np.arange(n1,n), :] = np.eye(n2)
    Q = np.zeros((n,n2))
    Q[np.arange(n1,n),:] = precision_h
    #Q  = np.zeros((n, n1))
    #Q[np.arange(n1),:] = -covariance

    J1 = np.asmatrix(J1)
    J2 = np.asmatrix(J2)
    Q = np.asmatrix(Q)
    S - np.asmatrix(S)
 
    R = cvx.Semidef(n)
    # define the SDP problem 
    objective = cvx.Minimize(-cvx.log_det(R) + cvx.trace(S*R) + alpha*(cvx.norm((J1.T*R*J1), 1) + beta*cvx.mixed_norm((J1.T*R*Q).T, 2, 1)  ))#beta*cvx.norm( (J1.T*R*Q), 1)) )
    constraints = [J2.T*R*J2 ==  covariance_h]
    # solve the problem
    problem = cvx.Problem(objective, constraints)
    problem.solve(verbose = verbose)

    return np.asarray(R.value)
Exemplo n.º 10
0
def _semidef_complex_as_real(dim):
    """Returns a cvxpy Semidefinite matrix and constraints for representing
    a complex hermitian non-neg. matrix represented as

                            Z = X + iY   <==> Z' = [X -Y; Y X]    (*)

    :param dim: Dimension of the complex matrix
    :returns: cvxpy.Semidef(2 * dim), List of constaints ensuring the structure
        in (*)

    """
    z = cvx.Semidef(2 * dim)
    return z, [z[:dim, :dim] == z[dim:, dim:], z[:dim, dim:] == -z[dim:, :dim]]
def sdp_mosek(omega, fmin):
    k_ = omega.shape[0]

    Y = []
    C = []

    C.append(np.zeros((k_, k_)))
    C[0][-1, -1] = 0
    Y.append(cvx.Semidef(k_))
    cost_sum = Y[0] * C[0]

    for i in range(1, k_):
        Y.append(cvx.Semidef(k_))
        C.append(np.zeros((k_, k_)))
        C[i][-1, i - 1] = 1 / 2
        C[i][i - 1, -1] = 1 / 2
        C[i][-1, -1] = -fmin
        cost_sum += Y[i] * C[i]

    constraints = [sum(Y) == omega]

    objective = cvx.Minimize(cvx.trace(cost_sum))

    prob = cvx.Problem(objective, constraints)
    opt_val = prob.solve(solver=cvx.MOSEK, verbose=0)

    # Assert a valid solution is returned
    assert (isinstance(opt_val, np.ndarray) or isinstance(opt_val, float))\
        and np.isfinite(opt_val)

    M = -constraints[0].dual_value
    M = np.asarray((M + M.T) / 2)  # From matrix to array

    Y_return = []
    for y in Y:
        Y_return.append(np.asarray(y.value))

    return opt_val, M, Y_return, C
Exemplo n.º 12
0
    def setUpClass(cls):
        cls.X = cvxpy.Semidef(3)
        cls.constraints = []

        for i in range(3):
            cls.constraints += [cls.X[i, i] == 1]

        cls.constraints += [
            cls.X[0, 1] >= -0.2, cls.X[0, 1] <= -0.1, cls.X[1, 2] >= 0.4,
            cls.X[1, 2] <= 0.5
        ]

        cls.temp_folder = os.path.abspath("./temp")
        if not os.path.exists(cls.temp_folder):
            os.makedirs(cls.temp_folder)
Exemplo n.º 13
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
Exemplo n.º 14
0
def sdp_km(D, n_clusters):
    ones = np.ones((D.shape[0], 1))
    Z = cp.Semidef(D.shape[0])
    objective = cp.Maximize(cp.trace(D * Z))
    constraints = [Z >= 0, Z * ones == ones, cp.trace(Z) == n_clusters]

    prob = cp.Problem(objective, constraints)
    prob.solve(solver=cp.SCS, verbose=False)

    Q = np.asarray(Z.value)
    rs = Q.sum(axis=1)
    print('Q', Q.min(), Q.max(), '|', rs.min(), rs.max(), '|', np.trace(Q),
          np.trace(D.dot(Q)))
    print('Final objective', np.trace(D.dot(Q)))

    return Q
Exemplo n.º 15
0
def _solve_soft_bias_correction_cvxpy(UE, EUT, I, N, B, tuning):
    X = cvx.Semidef(N.shape[0], name='T')
    objective = (cvx.Minimize(
        cvx.sum_squares(EUT * (X - I) * UE) +
        cvx.quad_over_lin(N.T * X * B.T, tuning)))
    constraints = [X >> 0]
    prob = cvx.Problem(objective, constraints)

    print("Large constants:")
    for c in prob.constants():
        try:
            print("\tConstant of size:", c.value.shape, type(c.value))
        except AttributeError:
            pass

    prob.solve(solver=cvx.SCS, verbose=True, gpu=True)
    return X.value, prob.value
Exemplo n.º 16
0
def getLargestInnerEllip(pt, maxChange=[None, None], Pold=None, optsIn={}):
    #Opts
    opts = {'conv': 1e-2}
    opts.update(optsIn)

    #There are faster ways to do this, but this is very convenient
    dim, Npt = pt.shape

    if Pold is None:
        Pval = np.identity(dim)
    else:
        Pval = Pold

    oldDet = 2 * det(Pval)

    #To avoid constant recreation of vars
    P = cvxpy.Semidef(pt.shape[0], "P")
    obj = cvxpy.Maximize(cvxpy.log_det(P))

    while ((np.abs(oldDet - det(Pval)) / oldDet) > opts['conv']):
        oldDet = det(Pval)

        CpreTrans = chol(Pval).T
        CpreTransI = inv(CpreTrans)

        ptPre = ndot(CpreTrans, pt)
        normPtsq = colWiseSquaredNorm(ptPre)
        ptI = np.divide(ptPre, np.tile(normPtsq, (dim, 1)))
        #Adapt old
        PoldInvA = inv(ndot(CpreTransI.T, Pold, CpreTransI))
        ptInM = np.max(colWiseSquaredKerNorm(PoldInvA, ptI))
        PoldInvA = PoldInvA / ptInM
        #Solve
        PpreInv = smallestCircumScribedEllip(ptI,
                                             P=P,
                                             obj=obj,
                                             maxChange=maxChange,
                                             Pold=PoldInvA)
        Ppre = inv(PpreInv)
        Pval = ndot(CpreTrans.T, Ppre, CpreTrans)

    thisAlpha = ((det(Pval))**(1. / float(dim)))
    thisP = Pval / thisAlpha

    return [thisP, thisAlpha]
def pick_bundle(A, tau, dim):

	# varaible
	t = cvx.Variable()
	lamda = cvx.Variable()
	#constraint_matrix = cvx.Variable(dim + 1, dim + 1)
	constraint_matrix = cvx.Semidef(dim+1)
	
	I = np.eye(dim)

	# objective
	obj = cvx.Maximize(-t-lamda)
	
	# constraints
	constraints = []
	for i in range(dim):
		for j in range(dim):
			constraints += [ constraint_matrix[i,j] ==  A[i,j] + lamda * I[i,j] ]

	for i in range(dim):
			constraints += [ constraint_matrix[i,dim] == 0]

	for j in range(dim):
			constraints += [ constraint_matrix[dim,j] == 0]

	constraints += [constraint_matrix[dim,dim] == t] 

	# solve
	prob = cvx.Problem(obj, constraints)
	prob.solve()
	#print prob.status
	#print constraint_matrix
	#print "t = ", t.value
	#print "lambda = ", lamda.value

	if (prob.status == 'optimal'):
		print prob.value
		#print "length = ", len(constraints)
		#print "dual = ", constraints[len(constraints)-1].dual_value
		print "lambda = ", lamda.value
		# print "smallest eigen vector = "
		#A_prime = A+lamda.value*np.eye(dim)
		A_prime = A-prob.value
		
		print A_prime
Exemplo n.º 18
0
def sos_to_sdp_min(syms, poly, z):
    deg = len(z)
    Q = cvx.Semidef(deg)
    q = cvx.vec(Q)
    gamma = cvx.Variable()

    A, b = construct_constraints_min(syms, poly, z)
    const_val = np.asscalar(b[-1]) - gamma
    A = A[:-1]
    b = b[:-1]
    constraints = [A * q == b, q[0] == const_val]
    obj = cvx.Maximize(gamma)

    prob = cvx.Problem(obj, constraints)
    opt_val = prob.solve(solver=cvx.SCS)

    Q = np.matrix(Q.value)
    return (prob.status, opt_val, Q)
Exemplo n.º 19
0
def MVU(Y, Omega, p):
    """This is an implementation of Maximum Variance Unfolding using CVXPY;

    Args:
       Y - A m by n matrix of n data points in m dimensional space.

       Omega - A 0-1 matrix that encodes the distances to obsere.
          1 for a distance to enforce and 0 for a free distance

       p -  The dimension of the low dimensional space.

    Returns:
       XHat - .A p by n matrix of n data points in p dimensional space.

    """
    assert isinstance(Y, np.matrix), 'Y must be a matrix'
    n = Y.shape[1]

    assert Omega.shape[0] == Omega.shape[0] == n, 'Omega wrong size'

    Sy = Y.T * Y

    K = cvxpy.Semidef(n)

    # We want to maximize the trace(K), and that is the same thing as
    # minimizing -trace(K).  Note, trace(K) is affine, so both trace(K)
    # and -trace(K) are convex.
    objective = cvxpy.Minimize(-cvxpy.trace(K))

    constraints = []
    # constraints.append(cvxpy.sum_entries(K) == 0)
    for i in range(n):
        for j in range(n):
            if Omega[i, j] == 1:
                constraints.append(K[i, j] == Sy[i, j])

    prob = cvxpy.Problem(objective, constraints)

    result = prob.solve(solver='SCS', eps=1e-6)
    U, E, UT = np.linalg.svd(np.matrix(K.value))
    return np.diag(np.sqrt(E[:p])) * UT[:p, :]
Exemplo n.º 20
0
def sdp_relaxation(Y, z, printing=False):
    """
    SDP solver of the observation Y and ground truth z.
    """

    if printing:
        print('Solving sdp relaxation problem...')
    n, _ = Y.shape
    X = cvx.Semidef(n)
    A = X * Y
    objective = cvx.Maximize(cvx.trace(A))
    constraints = [cvx.diag(X) == 1]
    problem = cvx.Problem(objective, constraints)
    problem.solve()
    if printing:
        print('Status: ' + problem.status)
        print('Optimal value: \n', problem.value)
        print('Verifying optimality (dual value): \n',
              np.sum(constraints[0].dual_value))
        print('Optimal X: \n', X.value)
        print('Optimal dual D (only diagonal entries): \n',
              constraints[0].dual_value)
    return problem.value, X, constraints[0].dual_value
Exemplo n.º 21
0
def sdp_prob():
    # {LP, SDP, SOCP}
    x = cp.Semidef(2)
    return cp.Problem(cp.Minimize(cp.norm(3 * x, 'fro')))
def ntf_fir_from_digested(order, osrs, H_inf, f0s, zf, **opts):
    """
    Synthesize FIR NTF with minmax approach from predigested specification

    Version for the cvxpy_tinoco modeler.
    """
    verbose = opts['show_progress']
    if opts['cvxpy_opts']['solver'] == 'cvxopt':
        opts['cvxpy_opts']['solver'] = cvxpy.CVXOPT
    elif opts['cvxpy_opts']['solver'] == 'scs':
        opts['cvxpy_opts']['solver'] = cvxpy.SCS

    # State space representation of NTF
    A = np.matrix(np.eye(order, order, 1))
    B = np.matrix(np.vstack((np.zeros((order-1, 1)), 1.)))
    # C contains the NTF coefficients
    D = np.matrix(1)

    # Set up the problem
    bands = len(f0s)
    c = cvxpy.Variable(1, order)
    F = []
    gg = cvxpy.Variable(bands, 1)

    for idx in range(bands):
        f0 = f0s[idx]
        osr = osrs[idx]
        omega0 = 2*f0*np.pi
        Omega = 1./osr*np.pi
        P = cvxpy.Symmetric(order)
        Q = cvxpy.Semidef(order)
        if f0 == 0:
            # Lowpass modulator
            M1 = A.T*P*A+Q*A+A.T*Q-P-2*Q*np.cos(Omega)
            M2 = A.T*P*B + Q*B
            M3 = B.T*P*B - gg[idx, 0]
            M = cvxpy.bmat([[M1, M2, c.T],
                            [M2.T, M3, D],
                            [c, D, -1]])
            F += [M << 0]
            if zf:
                # Force a zero at DC
                F += [cvxpy.sum_entries(c) == -1]
        else:
            # Bandpass modulator
            M1r = (A.T*P*A + Q*A*np.cos(omega0) + A.T*Q*np.cos(omega0) -
                   P - 2*Q*np.cos(Omega))
            M2r = A.T*P*B + Q*B*np.cos(omega0)
            M3r = B.T*P*B - gg[idx, 0]
            M1i = A.T*Q*np.sin(omega0) - Q*A*np.sin(omega0)
            M21i = -Q*B*np.sin(omega0)
            M22i = B.T*Q*np.sin(omega0)
            Mr = cvxpy.bmat([[M1r, M2r, c.T],
                             [M2r.T, M3r, D],
                             [c, D, -1]])
            Mi = cvxpy.bmat([[M1i, M21i, np.zeros((order, 1))],
                             [M22i, 0, 0],
                             [np.zeros((1, order)), 0, 0]])
            M = cvxpy.bmat([[Mr, Mi],
                            [-Mi, Mr]])
            F += [M << 0]
            if zf:
                # Force a zero at z=np.exp(1j*omega0)
                nn = np.arange(order).reshape((order, 1))
                vr = np.matrix(np.cos(omega0*nn))
                vi = np.matrix(np.sin(omega0*nn))
                vn = np.matrix(
                    [-np.cos(omega0*order), -np.sin(omega0*order)])
                F += [c*cvxpy.hstack(vr, vi) == vn]
    if H_inf < np.inf:
        # Enforce the Lee constraint
        R = cvxpy.Semidef(order)
        MM = cvxpy.bmat([[A.T*R*A-R, A.T*R*B, c.T],
                         [B.T*R*A, -H_inf**2+B.T*R*B, D],
                         [c, D, -1]])
        F += [MM << 0]
    target = cvxpy.Minimize(cvxpy.max_entries(gg))
    p = cvxpy.Problem(target, F)
    p.solve(verbose=verbose, **opts['cvxpy_opts'])
    return np.hstack((1, np.asarray(c.value)[0, ::-1]))
Exemplo n.º 23
0
def sls_common_lyapunov(A, B, Q, R, eps_A, eps_B, tau, logger=None):
    """
    Solves the common Lyapunov relaxation to the robust 
    synthesis problem.

    Taken from
    lstd-lqr/blob/master/code/policy_iteration.ipynb
    learning-lqr/experiments/matlab/sls_synth_yalmip/common_lyap_synth_var2_alpha.m

    """

    if logger is None:
        logger = logging.getLogger(__name__)

    d, p = B.shape
    X = cvx.Symmetric(d)  # inverse Lyapunov function
    Z = cvx.Variable(p, d)  # -K*X
    W_11 = cvx.Symmetric(d)
    W_12 = cvx.Variable(d, p)
    W_22 = cvx.Symmetric(p)
    alph = cvx.Variable()  # scalar for tuning the H_inf constraint

    constraints = []

    # H2 cost: trace(W)=H2 cost
    mat1 = cvx.bmat([[X, X, Z.T], [X, W_11, W_12], [Z, W_12.T, W_22]])
    constraints.append(mat1 == cvx.Semidef(2 * d + p))

    # H_infinity constraint
    mat2 = cvx.bmat(
        [[X - np.eye(d), (A * X + B * Z),
          np.zeros((d, d)),
          np.zeros((d, p))], [(X * A.T + Z.T * B.T), X, eps_A * X,
                              eps_B * Z.T],
         [
             np.zeros((d, d)), eps_A * X, alph * (tau**2) * np.eye(d),
             np.zeros((d, p))
         ],
         [
             np.zeros((p, d)), eps_B * Z,
             np.zeros((p, d)), (1 - alph) * (tau**2) * np.eye(p)
         ]])
    constraints.append(mat2 == cvx.Semidef(3 * d + p))

    # constrain alpha to be in [0,1]:
    constraints.append(alph >= 0)
    constraints.append(alph <= 1)

    # Solve!
    objective = cvx.Minimize(cvx.trace(Q * W_11) + cvx.trace(R * W_22))
    prob = cvx.Problem(objective, constraints)
    try:
        obj = prob.solve(solver=cvx.MOSEK)
    except cvx.SolverError:
        logger.warn("SolverError encountered")
        return (False, None, None, None)

    if prob.status == cvx.OPTIMAL:
        logging.debug("common_lyapunov: found optimal solution")

        X_value = np.array(X.value)
        P_value = scipy.linalg.solve(X_value, np.eye(d), sym_pos=True)

        # NOTE: the K returned here is meant to be used
        # as A + BK **NOT** A - BK
        K_value = np.array(Z.value).dot(P_value)

        return (True, obj, P_value, K_value)

    else:
        logging.debug("common_lyapunov: could not solve (status={})".format(
            prob.status))

        return (False, None, None, None)
Exemplo n.º 24
0
    # compute log loss
    loss = 0.
    for q in S:
        i, j, k = q
        # should this be Mt^T * K??
        Mt = (2. * np.outer(X[i], X[j]) - 2. * np.outer(X[i], X[k]) -
              np.outer(X[j], X[j]) + np.outer(X[k], X[k]))
        score = cvx.trace(Mt.T * K)
        loss = loss + cvx.logistic(-score)
    # regularize with the 1,2 norm
    loss = loss / len(S) + lam * cvx.mixed_norm(K, 2, 1)
    return loss


# create L1 problem
K = cvx.Semidef(p)
objectiveL1 = cvx.Minimize(costL1(K, X, S, lam1))
probL1 = cvx.Problem(objectiveL1)

# solve the L1 problemLasso method:
print("Beginning test with L_1")
ts = time()
probL1.solve(verbose=True)
tot_time = time() - ts
Khat_L1 = np.array(K.value)
emp_loss, log_loss = lossK(Khat_L1, X, S)
print("L_1 regularization: Time=%f, emp_loss=%f, log_loss=%f" %
      (tot_time, emp_loss, log_loss))

# create L_{1,2} problem
K = cvx.Semidef(p)
Exemplo n.º 25
0
    def calculateEmbeddingMatrix(
        D, verbose=False, target_dist=1.1, jlt_tries=30
    ):
        assert isMetricSpaceMatrix(D)
        n = D.shape[0]
        if int(cvx.__version__.split(".")[0]) == 0:
            Q = cvx.Semidef(n)
            d = cvx.NonNegative()
        else:
            Q = cvx.Variable(shape=(n, n), PSD=True)
            d = cvx.Variable(shape=(1, 1), nonneg=True)
        # print(D)

        # c = matrix(([1]*n))
        log.debug("Generating constraints for embedding:")
        log.debug(f"Distance matrix: {D}")
        constraints = []
        for i in range(n):
            for j in range(i, n):
                constraints += [D[i, j] ** 2 <= Q[i, i] + Q[j, j] - 2 * Q[i, j]]
                constraints += [
                    Q[i, i] + Q[j, j] - 2 * Q[i, j] <= d * D[i, j] ** 2
                ]
                log.debug(
                    f"adding constraint: {D[i,j]}**2 <= Q{[i,i]} + Q{[j,j]} - 2*Q{[i,j]}"
                )
                log.debug(
                    f"adding constraint: Q{[i,i]} + Q{[j,j]} - 2*Q{[i,j]} <= d * {D[i,j]}**2 "
                )

        obj = cvx.Minimize(d)
        prob = cvx.Problem(obj, constraints)
        solvers = cvx.installed_solvers()
        if "MOSEK" in solvers:
            log.info("Solving problem with MOSEK solver")
            prob.solve(solver=cvx.MOSEK, verbose=verbose)
        elif "CVXOPT" in solvers:
            prob.solve(
                solver=cvx.CVXOPT,
                kktsolver=cvx.ROBUST_KKTSOLVER,
                verbose=verbose,
            )
            log.info("Solving problem with CVXOPT solver")
        else:
            prob.solve(verbose=verbose)
            log.warning(
                "CVXOPT not installed. Solving problem with default solver."
            )
        if prob.status != cvx.OPTIMAL:
            log.warning(
                "embedding optimization status non-optimal: " + str(prob.status)
            )
            return None, None
        # print(Q.value)
        # print(np.linalg.eigvals(np.matrix(Q.value)))
        # print(np.linalg.eigh(np.matrix(Q.value)))
        # print(type(np.matrix(Q.value)))
        # print(np.matrix(Q.value))
        try:
            L = np.linalg.cholesky(np.array(Q.value))
        except np.linalg.LinAlgError:
            eigenvals, eigenvecs = np.linalg.eigh(np.array(Q.value))
            min_eigenv = min(eigenvals)
            if min_eigenv < 0:
                log.warning(
                    "Warning, matrix not positive semidefinite."
                    + "Trying to correct for numerical errors with minimal eigenvalue: "
                    + str(min_eigenv)
                    + " (max. eigenvalue:"
                    + str(max(eigenvals))
                    + ")."
                )

                Q_new_t = (
                    np.transpose(eigenvecs) @ np.array(Q.value) @ eigenvecs
                )
                # print(eigenvals)
                # print(Q_new_t) # should be = diagonal(eigenvalues)
                # print(np.transpose(eigenvecs) * eigenvecs) # should be = Identity matrix
                Q_new_t += np.diag([-min_eigenv] * len(eigenvals))
                Q_new = eigenvecs @ Q_new_t @ np.transpose(eigenvecs)
                L = np.linalg.cholesky(Q_new)

        log.debug(f"Shape of lower-triangular matrix L: {L.shape}")
        lowerdim, d = jlt_search(D, L, target_dist, num_tries=jlt_tries)
        # print(lowerdim)
        # return L,d.value
        return lowerdim, d
def forward_single_d_cvx_Filter(Q, q, G, h, A, b, d, epsilon, xi, delta, T, p=None,
                                sol_opt=cp.CVXOPT, verbose=False):
    """
    This function processes the SDP
    :param Q:
    :param q:
    :param G:
    :param h:
    :param A:
    :param b:
    :param xi:
    :param d:
    :param epsilon:
    :param delta:
    :param T:
    :param p:
    :param sol_opt:
    :param verbose:
    :return:
    """
    nz, neq, nineq = q.shape[0], A.shape[0] if A is not None else 0, G.shape[0]

    if p.shape == (T,):
        p = np.expand_dims(p, 1) # convert the price into a column vector

    if d.shape == (T,):
        d = np.expand_dims(d, 1)

    if verbose:
        print("\n inside the cvx np filter :", T, nz )
        print([part.shape for part in [Q, q, G, h, A, b]])

    x_ = cp.Variable(nz)
    GAMMA = cp.Semidef(T)
    # assert T == nz / 3
    # print("x size {}, num of ineq {}".format(x_.size, nineq))
    term1 = GAMMA * epsilon + d

    obj = cp.Minimize(0.5 * cp.quad_form(x_, Q) + q.T * x_ + p.T * cp.pos(term1) + cp.pos(cp.norm(GAMMA, "nuc") - xi ) )
    eqCon = A * x_ == b if neq > 0 else None
    soc_ineqCon = [cp.norm(GAMMA[:, i], 2) <= (d[i, 0] / abs(ut.function_normal_cdf_inv(delta))) for i in range(T)] # ut.function_normal_cdf_inv(delta)

    # eqCon_sdp = None  # convert the SDP constraint in the objective, # eqCon_sdp = cp.norm(GAMMA, "nuc") == xi
    if nineq > 0:
        slacks = cp.Variable(nineq)  # define slack variables
        ineqCon = G * x_ + slacks == h
        slacksCon = slacks >= 0
    else:
        ineqCon = slacks = slacksCon = None
    cons_collected = [eqCon, ineqCon] + soc_ineqCon + [slacksCon]

    cons = [constraint for constraint in cons_collected if constraint is not None]
    prob = cp.Problem(obj, cons)
    # ------------------------------
    # calculate time
    # ------------------------------
    # start = time.perf_counter()
    if sol_opt == cp.MOSEK:
        # mosek params: https://docs.mosek.com/9.0/javafusion/parameters.html
        mosek_param_setting = {"MSK_DPAR_BASIS_TOL_X": 1e-4,
                               "MSK_DPAR_BASIS_TOL_S": 1e-5,
                               "MSK_DPAR_INTPNT_CO_TOL_DFEAS": 1e-5,
                               "MSK_DPAR_INTPNT_CO_TOL_MU_RED": 1e-5,
                               "MSK_DPAR_INTPNT_TOL_INFEAS": 1e-5,
                               "MSK_DPAR_INTPNT_CO_TOL_PFEAS": 1e-5,
                               "MSK_DPAR_INTPNT_CO_TOL_REL_GAP": 1e-5}
        # The first 5 items might be not important, we discovered that
        # most relavent metrics is 'MSK_DPAR_INTPNT_CO_TOL_PFEAS' and 'MSK_DPAR_INTPNT_CO_TOL_REL_GAP'
        prob.solve(solver=sol_opt, verbose=verbose, mosek_params=mosek_param_setting)  # solver=cp.SCS, max_iters=5000, verbose=False)
    else:
        prob.solve(solver=sol_opt, verbose=verbose) # e.g. prob.solve(solver=cp.SCS, max_iters=10000, verbose=True)

    assert ('optimal' in prob.status)
    # end = time.perf_counter()
    # print("[CVX - %s] Compute solution : %.4f s." % (sol_opt, end - start))

    xhat = np.array(x_.value).ravel()
    GAMMA_hat = np.array(GAMMA.value)
    lam = np.array(eqCon.dual_value).ravel() if eqCon is not None else None
    # lam_socp = np.array(soc_ineqCon.dual_value).ravel() if soc_ineqCon is not None else None
    if ineqCon is not None:
        mu = np.array(ineqCon.dual_value).ravel()
        slacks = np.array(slacks.value).ravel()
    else:
        mu = slacks = None

    # return prob.value, xhat, GAMMA_hat, lam, lam_socp, mu, slacks
    return prob.value, xhat, GAMMA_hat, lam, mu, slacks
Exemplo n.º 27
0
def N4SID(u, y, NumRows, NumCols, NSig, require_stable=False):
    """
    A,B,C,D,Cov,Sigma = N4SID(u,y,NumRows,NumCols,n,require_stable=False)

    Let NumVals be the number of input and output values available
    In this case:

    u - NumInputs x NumVals array of inputs
    y - NumOutputs x NumVals array of outputs

    NumRows - Number of block rows in the past and future block Hankel matrices
    NumCols - Number of columns in the past and future block Hankel matrices

    n - desired state dimension.

    For the algorithm to work, you must have:

    NumVals >= 2*NumRows + NumCols - 1

    Returns

    A,B,C,D - the state space realization from inputs to outputs
    
    Cov - the joint covariance of the process and measurement noise

    Sigma - the singular values of the oblique projection of 
            row space of future outputs along row space of 
            future inputs on the row space of past inputs and outputs.
            
            Examining Sigma can be used to determine the required state 
            dimension

    require_stable - An optional boolean parameter. Default is False
                     If False, the standard N4SID algorithm is used
                     If True, the state matrix, A, 
                     will have spectral radius < 1.
                     In order to run with require_stable=True, cvxpy 
                     must be installed. 
           

    """
    NumInputs = u.shape[0]
    NumOutputs = y.shape[0]

    NumDict = {
        'Inputs': NumInputs,
        'Outputs': NumOutputs,
        'Dimension': NSig,
        'Rows': NumRows,
        'Columns': NumCols
    }

    GammaDict, S = preProcess(u, y, NumDict)

    GamData = GammaDict['Data']
    GamYData = GammaDict['DataY']

    if not require_stable:
        K = la.lstsq(GamData.T, GamYData.T)[0].T
    else:

        Kvar = cvx.Variable(NSig + NumOutputs, NSig + NumInputs * NumRows)

        Avar = Kvar[:NSig, :NSig]

        Pvar = cvx.Semidef(NSig)

        LyapCheck = cvx.vstack(cvx.hstack(Pvar, Avar),
                               cvx.hstack(Avar.T, np.eye(NSig)))

        Constraints = [LyapCheck >> 0, Pvar << np.eye(NSig)]

        diffVar = GamYData - Kvar * GamData
        objFun = cvx.norm(diffVar, 'fro')
        Objective = cvx.Minimize(objFun)

        Prob = cvx.Problem(Objective, Constraints)

        result = Prob.solve()

        K = Kvar.value

    AID, BID, CID, DID, CovID = postProcess(K, GammaDict, NumDict)

    return AID, BID, CID, DID, CovID, S
Exemplo n.º 28
0
def latent_variable_gmm_cvx(X_o,
                            alpha=1,
                            lambda_s=1,
                            S_init=None,
                            verbose=False):
    '''
          A cvx implementation of  the Latent Variable Gaussian Graphical Model 
      
       see review of  "Venkat Chandrasekaran, Pablo A Parrilo, and Alan S Willsky. Latent variable graphical model selection via convex optimization. The Annals of Statistics, 40(4):1935–1967, 2012."
    
        
           min_{S, L} -log det (S-L) + trace(emp_Cov*(S-L)) + alpha*lambda_s*\|S\|_{1} + alpha*\|L\|_{*}
                  s.t.  S-L \succeq 0
                        L \succeq 0

         return S, L

    '''
    n, m = X_o.shape
    emp_cov = np.cov(X_o)
    if alpha == 0:
        if return_costs:
            precision = np.linalg.pinv(emp_cov)
            cost = -2. * log_likelihood(emp_cov, precision)
            cost += n_features * np.log(2 * np.pi)
            d_gap = np.sum(emp_cov * precision) - n
            return emp_cov, precision, (cost, d_gap)
        else:
            return emp_cov, np.linalg.pinv(emp_cov)

    costs = list()
    if S_init is None:
        covariance_o = emp_cov.copy()
    else:
        covariance_o = S_init.copy()
    # As a trivial regularization (Tikhonov like), we scale down the
    # off-diagonal coefficients of our starting point: This is needed, as
    # in the cross-validation the cov_init can easily be
    # ill-conditioned, and the CV loop blows. Beside, this takes
    # conservative stand-point on the initial conditions, and it tends to
    # make the convergence go faster.

    covariance_o *= 0.95
    diagonal_o = emp_cov.flat[::n + 1]
    covariance_o.flat[::n + 1] = diagonal_o

    # define the low-rank term L and sparse term S
    L = cvx.Semidef(n)
    S = cvx.Symmetric(n)
    # define the SDP problem
    objective = cvx.Minimize(-cvx.log_det(S - L) + cvx.trace(covariance_o *
                                                             (S - L)) +
                             alpha * lambda_s * cvx.norm(S, 1) +
                             alpha * cvx.norm(L, "nuc"))
    constraints = [S - L >> 0]

    # solve the problem
    problem = cvx.Problem(objective, constraints)
    problem.solve(verbose=verbose)

    return (S.value, L.value)
Exemplo n.º 29
0
# Set the values of the relevant matrices in the LMI
A_hat.value = np.array([[1, alpha.value - 1], [0, 0]])
B_hat.value = np.array([[alpha.value, -1], [0, -1]])
C1_hat.value = np.array([[-1, -1], [0, 0]])
C2_hat.value = np.array([[1, alpha.value - 1], [0, 0]])
D1_hat.value = np.array([[-1, 0], [1, 0]])
D2_hat.value = np.array([[alpha.value, -1], [0, 1]])
M1.value = np.array([[
    -2 * rho0.value**-2,
    1.0 / rho0.value * (kappa.value**-0.5 + kappa.value**0.5)
], [1. / rho0.value * (kappa.value**-0.5 + kappa.value**0.5), -2]])
M2.value = np.array([[0, 1], [1, 0]])
zeros.value = np.zeros((2, 2))

# Variables
P = cvx.Semidef(2)
lam1 = cvx.Variable()
lam2 = cvx.Variable()

# Create the (constant) objective function
obj = cvx.Minimize(c)

# Create the matrices for the LMI
mat1 = cvx.bmat([[A_hat.T * P * A_hat - tau**2 * P, A_hat.T * P * B_hat],
                 [B_hat.T * P * A_hat, B_hat.T * P * B_hat]])
mat2 = cvx.bmat([[C1_hat, D1_hat], [C2_hat, D2_hat]])
mat3 = cvx.bmat([[lam1 * M1, zeros], [zeros, lam2 * M2]])

# Create the constraints: LMI, lambda1 and lambda 2 non-negative, P positive definite
constraints = [mat1 + mat2 * mat3 * mat2 << 0, lam1 >= 0, lam2 >= 0, P >> 1e-9]
Exemplo n.º 30
0
# print('\ntime elapsed=', time.time()-tt)
# exec(open('file.py').read())
# newArray = np.array([[0,1,2], [3,4,5], [6,7,8]])
# sliceArray = PTl[np.asmatrix([1,3,5]).T, [1,3,5]]
# pl.figure(figsize=(6, 6))
# fig = pl.figure()
# ax = fig.gca(projection='3d')
# ax.plot(xs=p.value[0,:].A1,ys=p.value[1,:].A1,zs=p.value[2,:].A1)
# legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), prop={'size': 18})
# print(dir(ct))
# raise Exception('exit')
# print(cv.installed_solvers())

import quad_metric_data as ct

P = cv.Semidef(ct.n)  # cv.Variable(ct.n, ct.n)  # slower


def OBJ(X, Y, n_, N, d_, P):
    U = cv.Parameter(n_, N)  # *X.shape
    UUT = cv.Parameter(n_, n_)
    dd = cv.Parameter(N, sign="positive")
    # THIS AFFECTS CONVEXITY!!!!!!
    # DIDN'T KNOW UNTIL ACCIDENTALLY MADE dd A PARAMETER

    U.value = X - Y
    UUT.value = np.dot(X - Y, (X - Y).T)
    dd.value = d_

    term1 = sum(d_**2)
    # term2 = sum([dd[i]*cv.sqrt(cv.quad_form(U[:, i], P)) for i in range(N)])