Beispiel #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
Beispiel #2
0
    def create_opt_vars(self, large_gamma=False, large_t=False):
        # init gamma from abs(N(0,1))
        if large_gamma:
            gamma = cp.Variable((self.in_numel, self.in_numel), name='gamma')
        else:
            gamma = cp.Variable((self.in_numel,), name='gamma')
        self.constraints.append((gamma >= 0.))

        s = cp.Variable(name='s')

        if large_t:
            lbda_n = sum(self.shapes[1:-1])
            lbda_vec = cp.Variable((lbda_n,), name='lbda_vec')
            lbda_mat = cp.Variable((lbda_n, lbda_n), name='lbda_mat', symmetric=True)
            self.constraints.append((lbda_mat >= 0.))
            lbda_mat_masked = cp.multiply((- np.ones((lbda_n, lbda_n)) + np.eye(lbda_n)), lbda_mat)
            lbda_mat_diag = cp.hstack([- cp.sum(lbda_mat_masked[i, i+1:]) for i in range(lbda_n)])
            lbdas = cp.diag(lbda_vec) + lbda_mat_masked + cp.diag(lbda_mat_diag)
        else:
            lbdas = list()

        nus = list()
        etas = list()

        for i in range(1, len(self.shapes) - 1):
            if not large_t:
                now_lbda = cp.Variable((self.shapes[i],), name=f'lbda_{i}')
            now_nu = cp.Variable((self.shapes[i],), name=f'nu_{i}')
            now_eta = cp.Variable((self.shapes[i],), name=f'eta_{i}')

            if not large_t:
                self.constraints.append((now_lbda >= 0.))
            self.constraints.append((now_nu >= 0.))
            self.constraints.append((now_eta >= 0.))

            if not large_t:
                lbdas.append(now_lbda)
            nus.append(now_nu)
            etas.append(now_eta)

        self.gamma = gamma
        self.lbdas = lbdas
        self.nus = nus
        self.etas = etas
        self.s = s
def solve_g_dual_cp(C, a, b, eta, tau):
    u = cp.Variable(shape=a.shape)
    v = cp.Variable(shape=b.shape)

    u_stack = cp.vstack([u.T for _ in range(nr)])
    v_stack = cp.hstack([v for _ in range(nc)])
    print(u_stack.shape, v_stack.shape)

    # obj = eta * cp.sum(cp.multiply(cp.exp(u + v.T) * cp.exp(v).T, 1 / cp.exp(C)))
    # obj = eta * cp.sum(cp.multiply(cp.exp(u_stack + v_stack), 1 / cp.exp(C)))
    obj = eta * cp.sum(cp.exp((u_stack + v_stack - C) / eta))
    obj += tau * cp.sum(cp.multiply(cp.exp(-u / tau), a))
    obj += tau * cp.sum(cp.multiply(cp.exp(-v / tau), b))

    prob = cp.Problem(cp.Minimize(obj))
    prob.solve()

    return prob.value, u.value, v.value
Beispiel #4
0
    def _obtain_r_tilde(self, r_cs_param):
        '''
        This function handles the smoothness and periodicity constraints when
        the data set is less than a year long. It operates by filling out the
        rest of the year with blank variables, which are subsequently dropped
        after the problem is solved.

        :param r_cs_param: the right matrix CVX variable
        :return: A cvx variable with second dimension at least 367
        '''
        if r_cs_param.shape[1] < 365 + 2:
            n_tilde = 365 + 2 - r_cs_param.shape[1]
            r_tilde = cvx.hstack(
                [r_cs_param,
                 cvx.Variable(shape=(self._rank_k, n_tilde))])
        else:
            r_tilde = r_cs_param
        return r_tilde
Beispiel #5
0
def solve(Q, C, D):
    q1 = cp.Variable(1)
    c = cp.Variable(T)
    q = cp.hstack([q1, cp.cumsum(c)[:-1]])

    constraints = [
        q <= Q,
        q >= 0,
        c <= C,
        c >= -D,
        q[-1] + c[-1] == q[0],
        u + c >= 0,
    ]

    obj = cp.Minimize(p @ (u + c))
    problem = cp.Problem(obj, constraints)
    problem.solve()
    return q.value, c.value, problem.value
Beispiel #6
0
def sdp(D):
    lam = 1
    n = D.shape[0]
    G = cp.Variable((n, n), symmetric=True)
    eta = cp.Variable((n, n))
    constraints = [G >> 0] 
    constraints += [eta[i, j] >= 0 for i in range(n) for j in range(n)]
    reg = lam * cp.norm(eta, p=1)
    Gii = cp.diag(G)
    hstacked = cp.hstack([cp.reshape(Gii, (n, 1)) for i in range(n)])
    vstacked = cp.vstack([cp.reshape(Gii, (1, n)) for i in range(n)])
    obj = reg + 0.5 * cp.sum((hstacked + vstacked - 2 * G + eta - D**2)**2)
    prob = cp.Problem(cp.Minimize(obj), constraints)
    prob.solve(verbose=False)
    U, S, V = np.linalg.svd(G.value)
    u, s = np.real(U), np.real(S)
    dim = 3
    Xtag = np.dot(u, np.diag(np.sqrt(s)))[:,0:dim]
    return Xtag
Beispiel #7
0
 def test_paper_example_logreg_is_dpp(self):
     N, n = 3, 2
     beta = cp.Variable((n, 1))
     b = cp.Variable((1, 1))
     X = cp.Parameter((N, n))
     Y = np.ones((N, 1))
     lambd1 = cp.Parameter(nonneg=True)
     lambd2 = cp.Parameter(nonneg=True)
     log_likelihood = (1. / N) * cp.sum(
         cp.multiply(Y, X @ beta + b) -
         cp.log_sum_exp(cp.hstack([np.zeros((N, 1)), X @ beta + b]).T,
                        axis=0,
                        keepdims=True).T)
     regularization = -lambd1 * cp.norm(beta,
                                        1) - lambd2 * cp.sum_squares(beta)
     problem = cp.Problem(cp.Maximize(log_likelihood + regularization))
     self.assertTrue(log_likelihood.is_dpp())
     self.assertTrue(problem.is_dcp())
     self.assertTrue(problem.is_dpp())
Beispiel #8
0
    def _optimize(self, A, disk, M):
        n = A.shape[0]
        print(n)
        constraints = []
        X = cp.Variable(shape=(n, n), boolean=True)
        Y = cp.Variable(shape=(n, n), boolean=True)
        Z = cp.Variable(shape=n, boolean=True)
        W = cp.Variable(shape=(n, n), boolean=True)

        zero_v = np.zeros((n, 1))
        one_v = np.ones((n, 1))
        I = np.identity(n)
        Z_vec = cp.reshape(Z, (n, 1))

        # W constraints
        Y_prev = cp.hstack([zero_v, Y[:, :n - 1]])
        Y_prev_not = np.ones((n, n)) - Y_prev
        constraints.append(np.zeros((n, n)) <= Y + Y_prev_not - 2 * W)
        constraints.append(np.ones((n, n)) >= Y + Y_prev_not - 2 * W)

        # permutation constraints
        constraints.append(cp.sum(X, axis=1) == np.ones(n))
        constraints.append(cp.sum(X, axis=0) == np.ones(n))

        # cache limit constraints
        for i in range(n):
            constraints.append(cp.sum(Y[:, i]) <= M)  # cache limit
            constraints.append(cp.sum(X[:, :(i + 1)], axis=1) >=
                               Y[:, i])  # previous cache comparison
            constraints.append(
                W[:, i] <= X[:, i] +
                Z)  # new cache elements must be less than disk + new elements
            constraints.append(W[:, i] >= X[:, i])
            constraints.append(Y[:, i:i + 1] >=
                               (A + I) @ X[:, i:i + 1])  # adjacency constraint
            constraints.append(cp.sum(Y[:, i] - Y_prev[:, i]) >=
                               0)  # can only maintain or increase cache size

        obj = cp.Minimize(cp.sum(Z) + cp.sum(W) - cp.sum(X))
        prob = cp.Problem(obj, constraints)
        prob.solve(solver=cp.GUROBI, verbose=True, Threads=state.NUM_THREADS)
        assert (prob.status in [cp.OPTIMAL, cp.OPTIMAL_INACCURATE])
        return X.value, prob.value
Beispiel #9
0
def calc_Koopman(Yf, Yp, flag=1):
    solver_instance = cvxpy.CVXOPT
    #solver_instance = cvxpy.ECOS;
    if flag == 1:  # moore penrose inverse, plain ol' least squares Koopman
        #Yp_inv = np.dot(np.transpose(Yp_final), np.linalg.inv( np.dot(Yp_final,np.transpose(Yp_final)) )   );
        Yp_inv = np.linalg.pinv(Yp)
        K = np.dot(Yf, Yp_inv)

    if flag == 2:  # cvx optimization approach - L2 + L1 lasso
        norm1_term = 0.0
        all_col_handles = [None] * Yf.shape[0]
        for i in range(0, Yf.shape[0]):
            all_col_handles[i] = Variable(Yf.shape[0], 1)
            norm1_term = norm1_term + norm2(all_col_handles[i])

        operator = all_col_handles[0]
        for i in range(1, Yf.shape[0]):
            operator = cvxpy.hstack(operator, all_col_handles[i])

        print "[INFO]: CVXPY Koopman operator variable: " + repr(operator)
        print "[INFO]: Yf.shape in calc_Koopman: " + repr(Yf.shape)
        norm2_fit_term = norm2(norm2(Yf - operator * Yp, axis=0))
        objective = Minimize(norm2_fit_term + norm1_term)
        constraints = []
        prob = Problem(objective, constraints)
        result = prob.solve(verbose=True, solver=solver_instance)
        print "[INFO]: Finished executing cvx solver, printing CVXPY problem status"
        print(prob.status)
        K = operator.value

    if flag == 3:
        operator = Variable(Yf.shape[0], Yf.shape[0])
        objective = Minimize(cvxpynorm(operator, 2))
        constraints = [
            cvxpynorm(Yf - operator * Yp, 'fro') / cvxpynorm(Yf, 'fro') < 0.01
        ]
        prob = Problem(objective, constraints)
        result = prob.solve(verbose=True)  #(solver=solver_instance);
        print(prob.status)
        K = operator.value

    return K
    def test_problem_penalty(self):
        """
        Compare cvxpy solutions to cvxopt ground truth
        """

        from cvxpy import (matrix,variable,program,minimize,
                           sum,abs,norm2,log,square,zeros,max,
                           hstack,vstack)

        m, n = self.m, self.n
        A = matrix(self.A)
        b = matrix(self.b)

        # set tolerance to 5 significant digits
        tol_exp = 5

        # l1 approximation
        x = variable(n)
        p = program(minimize(sum(abs(A*x + b))))
        p.solve(True)
        np.testing.assert_array_almost_equal(x.value,self.x1,tol_exp)

        # l2 approximation
        x = variable(n)
        p = program(minimize(norm2(A*x + b)))
        p.solve(True)
        np.testing.assert_array_almost_equal(x.value,self.x2,tol_exp)

        # Deadzone approximation - implementation is currently ugly (need max along axis)
        x = variable(n)
        Axbm = abs(A*x+b)-0.5
        Axbm_deadzone = vstack([max(hstack((Axbm[i,0],0.0))) for i in range(m)])
        p = program(minimize(sum(Axbm_deadzone)))
        p.solve(True)
        obj_dz_cvxpy = np.sum(np.max([np.abs(A*x.value+b)-0.5,np.zeros((m,1))],axis=0))
        np.testing.assert_array_almost_equal(obj_dz_cvxpy,self.obj_dz,tol_exp)

        # Log barrier
        x = variable(n)
        p = program(minimize(-sum(log(1.0-square(A*x + b)))))
        p.solve(True)
        np.testing.assert_array_almost_equal(x.value,self.cxlb,tol_exp)
Beispiel #11
0
def DR_W2_conditional_mean_variance_long_only_opt_cvx_kernel_new(
    X_mat, Y_mat, X0, reg_params, epsilon, rho_div_rho_min
):
    """
    CVXPY solver kernel for conditional distributionally robust optimization problem:
    
    See problem formulation in DR_Conditional_EstimationW2.ipynb
    """
    def compute_rho_min(X_mat, X0, epsilon):
        X_dist = np.linalg.norm(X_mat - X0, axis = 1)
        X_dist[np.isnan(X_dist)] = 1e8
        X_cut = np.quantile(X_dist, q=epsilon, interpolation = 'higher')
        return X_dist[X_dist <= X_cut].mean() * epsilon
    
    rho = rho_div_rho_min * compute_rho_min(X_mat, X0, epsilon)
    X_dist = np.linalg.norm(X_mat - X0, axis = 1)
    X_dist[np.isnan(X_dist)] = 1e8
    
    eta = reg_params
    epsilon_inv = 1/epsilon;

    N, sample_stock_num = Y_mat.shape

    m = cp.Variable(N, nonneg = True)
    beta = cp.Variable(sample_stock_num)
    alpha = cp.Variable(1)
    lambda1 = cp.Variable(1, nonneg = True)
    denom = cp.Variable(1, nonneg = True)
    lambda2 = cp.Variable(1)
    linear_expr = [email protected]*eta
    obj = lambda1*rho+lambda2*epsilon + cp.sum(cp.pos(epsilon_inv*m
                                                    - 0.25*epsilon_inv*eta**2 
                                                    - epsilon_inv*eta*alpha 
                                                    - lambda1*X_dist - lambda2))/N
    constraints = [m >= cp.hstack([cp.quad_over_lin(linear_expr[i], denom) for i in range(N)]),
                  epsilon_inv*cp.quad_over_lin(beta, lambda1) + denom <= 1,
                  beta >= 0,
                  cp.sum(beta) == 1]
    prob = cp.Problem(cp.Minimize(obj), constraints)
    prob.solve()
    assert prob.status == 'optimal'
    return beta.value
Beispiel #12
0
def and_constraint(xs, y):
    """ y is true if all elements in xs is True

    xs: Variable(boolean=True)
    y : Variable(boolean=True)

    if dimenison of xs is 2 then:
        dimension 0 -> number of ands


    returns: list of Constraints
    """
    N = len(xs)
    if isinstance(xs, list):
        xs = cvx.hstack(xs)
    C = [
         0     <= cvx.sum(xs) - N * y,
         N - 1 >= cvx.sum(xs) - N * y
    ]
    return C
Beispiel #13
0
def partB():
    c0 = np.loadtxt("../Data/data/quiz4_class0.txt")
    c1 = np.loadtxt("../Data/data/quiz4_class1.txt")
    row0, col0 = c0.shape
    row1, col1 = c1.shape
    x = np.column_stack((np.vstack(
        (c0, c1)), np.ones(row0 + row1).reshape(-1, 1)))
    y = np.vstack((np.zeros(row0).reshape(-1, 1), np.ones(row1).reshape(-1,
                                                                        1)))
    lambd = 0.01
    theta = cvx.Variable((3, 1))
    loss = -cvx.sum(cvx.multiply(y, x @ theta)) + cvx.sum(
        cvx.log_sum_exp(cvx.hstack([np.zeros((row1 + row0, 1)), x @ theta]),
                        axis=1))
    reg = cvx.sum_squares(theta)
    prob = cvx.Problem(cvx.Minimize(loss / (row1 + row0) + lambd * reg))
    prob.solve()
    w = theta.value
    print(w)
    return w
    def test_logistic_regression(self):
        np.random.seed(243)
        N, n = 10, 2

        def sigmoid(z):
            return 1 / (1 + np.exp(-z))

        X_np = np.random.randn(N, n)
        a_true = np.random.randn(n, 1)
        y_np = np.round(sigmoid(X_np @ a_true + np.random.randn(N, 1) * 0.5))

        X_tf = tf.Variable(X_np)
        lam_tf = tf.Variable(1.0 * tf.ones(1))

        a = cp.Variable((n, 1))
        X = cp.Parameter((N, n))
        lam = cp.Parameter(1, nonneg=True)
        y = y_np

        log_likelihood = cp.sum(
            cp.multiply(y, X @ a) - cp.log_sum_exp(
                cp.hstack([np.zeros((N,
                                     1)), X @ a]).T, axis=0, keepdims=True).T)
        prob = cp.Problem(
            cp.Minimize(-log_likelihood + lam * cp.sum_squares(a)))
        fit_logreg = CvxpyLayer(prob, [X, lam], [a])

        with tf.GradientTape(persistent=True) as tape:
            weights = fit_logreg(X_tf, lam_tf, solver_args={'eps': 1e-8})[0]
            summed = tf.math.reduce_sum(weights)
        grad_X_tf, grad_lam_tf = tape.gradient(summed, [X_tf, lam_tf])

        def f_train():
            prob.solve(solver=cp.SCS, eps=1e-8)
            return np.sum(a.value)

        numgrad_X_tf, numgrad_lam_tf = numerical_grad(f_train, [X, lam],
                                                      [X_tf, lam_tf],
                                                      delta=1e-6)
        np.testing.assert_allclose(grad_X_tf, numgrad_X_tf, atol=1e-2)
        np.testing.assert_allclose(grad_lam_tf, numgrad_lam_tf, atol=1e-2)
Beispiel #15
0
 def min_R(self, calc_deg=True, max_deg=0., min_deg=-0.25):
     if self.R_cs.shape[1] < 365 + 2:
         n_tilde = 365 + 2 - self.R_cs.shape[1]
         R_tilde = cvx.hstack(
             [self.R_cs, cvx.Variable(shape=(self.k, n_tilde))])
     else:
         R_tilde = self.R_cs
     W1 = np.diag(self.weights)
     f1 = cvx.sum(
         (0.5 * cvx.abs(self.D - self.L_cs.value * self.R_cs) +
          (self.tau - 0.5) * (self.D - self.L_cs.value * self.R_cs)) * W1)
     f2 = self.mu_R * cvx.norm(
         R_tilde[:, :-2] - 2 * R_tilde[:, 1:-1] + R_tilde[:, 2:], 'fro')
     constraints = [self.L_cs.value * self.R_cs >= 0, self.R_cs[0] >= 0]
     if self.D.shape[1] > 365:
         r = self.R_cs[0, :].T
         if calc_deg:
             constraints.extend([
                 cvx.multiply(1. / self.r0[:-365],
                              r[365:] - r[:-365]) == self.beta,
                 self.beta >= -.25
             ])
             if max_deg is not None:
                 constraints.append(self.beta <= max_deg)
             if min_deg is not None:
                 constraints.append(self.beta >= min_deg)
         else:
             constraints.append(
                 cvx.multiply(1. / self.r0[:-365], r[365:] - r[:-365]) == 0)
         f3 = self.mu_R * cvx.norm(R_tilde[1:, :-365] - R_tilde[1:, 365:],
                                   'fro')
     else:
         f3 = self.mu_R * cvx.norm(R_tilde[:, :-365] - R_tilde[:, 365:],
                                   'fro')
     objective = cvx.Minimize(f1 + f2 + f3)
     problem = cvx.Problem(objective, constraints)
     problem.solve(solver='MOSEK')
     #problem.solve(solver=SOLVER_OBJ)
     if problem.status != 'optimal':
         raise ProblemStatusError('Minimize R status: ' + problem.status)
     self.r0 = self.R_cs.value[0, :]
Beispiel #16
0
def max_minimum_allocation_for_families(instance, families) -> AllocationToFamilies:
    """
    Find the max-minimum (aka Egalitarian) allocation.
    :param agents: a matrix v in which each row represents an agent, each column represents an object, and v[i][j] is the value of agent i to object j.
    :param families: a list of lists. Each list represents a family and contains the indices of the agents in the family.

    :return allocation_matrix:  a matrix alloc of a similar shape in which alloc[i][j] is the fraction allocated to agent i from object j.
    The allocation should maximize the leximin vector of utilities.
    >>> families = [ [0], [1] ]  # two singleton families
    >>> max_minimum_allocation_for_families([ [3] , [5] ],families).round(3).matrix
    [[0.625]
     [0.375]]
    >>> max_minimum_allocation_for_families([ [4,2] , [1,4] ], families).round(3).matrix   # two different items
    [[1. 0.]
     [0. 1.]]
    >>> alloc = max_minimum_allocation_for_families([ [3,3] , [1,1] ], families).round(3).matrix   # two identical items
    >>> [sum(alloc[i]) for i in alloc.agents()]
    [0.5, 1.5]
    >>> v = [ [4,2] , [1,3] ]   # two different items
    >>> a = max_minimum_allocation_for_families(v, families).round(3)
    >>> a
    Family #0 with members [0] gets { 80.0% of 0} with values [3.2].
    Family #1 with members [1] gets { 20.0% of 0, 100.0% of 1} with values [3.2].
    <BLANKLINE>
    >>> a.matrix
    [[0.8 0. ]
     [0.2 1. ]]
    >>> print(a.utility_profile())
    [3.2 3.2]
    >>> families = [ [0, 1] ]  # One couple
    >>> max_minimum_allocation_for_families([ [4,2] , [1,4] ], families).round(3).matrix
    [[1. 1.]]
    >>> families = [ [0, 1], [2, 3] ]  # Two couples
    >>> a = max_minimum_allocation_for_families([ [4,2] , [1,4], [3,3], [5,5] ], families).round(3).matrix
    >>> a
    [[0.414 0.621]
     [0.586 0.379]]
    """
    return max_welfare_allocation_for_families(instance, families,
        welfare_function=lambda utilities: cvxpy.min(cvxpy.hstack(utilities)),
        welfare_constraint_function=lambda utility: utility >= 0)
Beispiel #17
0
def partC(kernel):
    c0 = np.loadtxt("../Data/data/quiz4_class0.txt")
    c1 = np.loadtxt("../Data/data/quiz4_class1.txt")
    x = np.vstack((c0, c1))
    row0, col0 = c0.shape
    row1, col1 = c1.shape
    y = np.vstack(
        (np.zeros(row0).reshape(-1,
                                1), np.ones(row1).reshape(-1,
                                                          1))).reshape(-1, 1)
    lambd = 0.01
    alpha = cvx.Variable((row0 + row1, 1))
    loss = -y.T @ kernel @ alpha + cvx.sum(
        cvx.log_sum_exp(
            cvx.hstack([np.zeros((row1 + row0, 1)), kernel @ alpha]), axis=1))
    reg = cvx.quad_form(alpha, kernel)
    prob = cvx.Problem(cvx.Minimize(loss / (row1 + row0) + lambd * reg))
    prob.solve()
    w = alpha.value
    print(w[:2])
    return w
Beispiel #18
0
    def test_max(self):
        x = cvxpy.Variable(pos=True)
        y = cvxpy.Variable(pos=True)

        prod1 = x * y**0.5
        prod2 = 3.0 * x * y**0.5
        obj = cvxpy.Minimize(cvxpy.max(cvxpy.hstack([prod1, prod2])))
        constr = [x == 1.0, y == 4.0]

        dgp = cvxpy.Problem(obj, constr)
        dgp2dcp = cvxpy.reductions.Dgp2Dcp(dgp)
        dcp = dgp2dcp.reduce()
        dcp.solve(SOLVER)
        dgp.unpack(dgp2dcp.retrieve(dcp.solution))
        self.assertAlmostEqual(dgp.value, 6.0)
        self.assertAlmostEqual(x.value, 1.0)
        self.assertAlmostEqual(y.value, 4.0)
        dgp._clear_solution()
        dgp.solve(SOLVER, gp=True)
        self.assertAlmostEqual(dgp.value, 6.0, places=4)
        self.assertAlmostEqual(x.value, 1.0)
Beispiel #19
0
def _direct_deconvolution(w, y, Nx, gamma_L2=0, gamma_L1=0):
    w = np.asarray(w)
    y = np.asarray(y)
    cplx = np.issubdtype(w.dtype, complex) or np.issubdtype(y.dtype, complex)

    if cplx:
        wr, wi = w.real, w.imag
        yr, yi = y.real, y.imag

        xr = cvx.Variable(Nx)
        xi = cvx.Variable(Nx)

        error = (cvx.sum_squares(cvx.conv(wr, xr) - cvx.conv(wi, xi) - yr) +
                 cvx.sum_squares(cvx.conv(wi, xr) + cvx.conv(wr, xi) - yi))
        u = cvx.norm(cvx.hstack(xr, xi), 2, axis=1)
    else:
        x = cvx.Variable(Nx)
        error = cvx.sum_squares(cvx.conv(w, x) - y)
        u = x

    cost = error

    if gamma_L1 != 0:
        gamma_L1 = cvx.Parameter(value=gamma_L1, sign="positive")
        cost = cost + gamma_L1 * cvx.norm(x, 1)
    if gamma_L2 != 0:
        gamma_L2 = cvx.Parameter(value=gamma_L2, sign="positive")
        cost = cost + gamma_L2 * cvx.sum_squares(x)

    objective = cvx.Minimize(cost)
    prob = cvx.Problem(objective)
    prob.solve()
    print("Problem Status: {0}".format(prob.status))

    if cplx:
        result = np.array(xr.value).ravel() + 1j * np.array(xi.value).ravel()
    else:
        result = np.asarray(x.value).ravel()

    return result
Beispiel #20
0
def calc_Input_Koopman(Kol,Yf,Yp,Up,flag=1,lambda_val=0.0):
    solver_instance = cvxpy.SCS;
    Ki = None;
    if flag==1: # moore penrose inverse, plain ol' least squares input-Koopman
        #Yp_inv = np.dot(np.transpose(Yp_final), np.linalg.inv( np.dot(Yp_final,np.transpose(Yp_final)) )   );
        Yfprime = Yf-np.dot(Kol,Yp)
        Up_inv = np.linalg.pinv(Up);
        Ki = np.dot(Yfprime,Up_inv);
        

    if flag ==2: # cvx optimization approach - L2 + L1 lasso 
        norm1_term = 0.0;
        all_col_handles = [None]*Up.shape[0]
        for i in range(0,Up.shape[0]):
            #print(Yf.shape[0])
            all_col_handles[i] = Variable(shape=(Yf.shape[0],1)) ;#Variable(shape=(Yf.shape[0],1) );
        #    if norm1_term < cvxpy.norm(all_col_handles[i],p=1):
        #        norm1_term = cvxpy.norm(all_col_handles[i],p=1);
            #norm1_term =  cvxpy.max(cvxpy.hstack( [norm1_term,cvxpy.norm(all_col_handles[i],p=1) ])  );
        operator = cvxpy.hstack(all_col_handles);
        norm1_term =cvxpy.norm( operator,p=1);
        #operator = all_col_handles[0];
        #for i in range(1,Yf.shape[0]):
        #    operator = cvxpy.hstack([operator,all_col_handles[i]]);
        #operator.
        #print("[INFO]: CVXPY Koopman operator variable: " +repr(operator.shape));
        #print(repr(operator));
        #print("[INFO]: Yf.shape in calc_Koopman: " + repr(Yf.shape));
        #print("[INFO]: Yp.shape in calc_Koopman: " + repr(Yp.shape));
        Yfprime = Yf-np.dot(Kol,Yp)
        norm2_fit_term = cvxpy.norm(cvxpy.norm(Yfprime-operator*Up,p=2,axis=0),p=2);
        objective = Minimize(norm2_fit_term + lambda_val*norm1_term)
        constraints = [];
        prob = Problem(objective,constraints);
        result = prob.solve(verbose=True,solver=solver_instance,max_iters=np.int(1e7))#,reltol=1e-10,abstol=1e-10);
        print("[INFO]: Finished executing cvx solver, printing CVXPY problem status")
        print(prob.status);
        Ki = operator.value;
    return Ki;
Beispiel #21
0
 def make_cvx_problem():
     depth = cvx.Variable(len(juncdepth))
     scale = cvx.Variable()
     objective = 0
     constraints = [depth >= 1, scale >= 0]
     for iw, (iline, u) in T.items():
         iu, iv = lines[iline]
         constraints.append(
             depth[iw] >= (1 - u) * depth[iu] + u * depth[iv])
     for w, c in vp:
         w = invK @ w
         w /= LA.norm(w)
         for l in c:
             i, j = lines[l]
             uv = depth[i] * vertices[i] - depth[j] * vertices[j]
             objective += cvx.norm(cvx.hstack(cross(uv, w)))
     for i in range(len(juncdepth)):
         if juncdepth[i] is None or juncdepth[i] == 0:
             continue
         objective += lambda_ * cvx.square(depth[i] - scale * juncdepth[i])
     problem = cvx.Problem(cvx.Minimize(objective), constraints)
     return problem, depth, scale
Beispiel #22
0
def cvx_kron(expr_1: Union[np.ndarray, Expression],
             expr_2: Union[np.ndarray, Expression]) -> Expression:
    """
    Compute Kronecker product between CVXPY objects.

    By default, CVXPY does not support taking the Kronecker product when the
    argument on the left is equal to a CVXPY object and the object on the right
    is equal to a numpy object.

    At most one of :code:`expr_1` and :code:`b` may be CVXPY Variable objects.

    Kudos to Riley J. Murray for this function:
    https://github.com/cvxgrp/cvxpy/issues/457

    :param expr_1: 2D numpy ndarray, or a CVXPY Variable with expr_1.ndim == 2
    :param expr_2: 2D numpy ndarray, or a CVXPY Variable with expr_2.ndim == 2
    """
    expr = np.kron(expr_1, expr_2)
    num_rows = expr.shape[0]
    rows = [cvxpy.hstack(expr[i, :]) for i in range(num_rows)]
    full_expr = cvxpy.vstack(rows)
    return full_expr
Beispiel #23
0
def recover_coords_sdp(D):
    n = D.shape[0]
    G = cp.Variable((n, n), symmetric=True)
    eta = cp.Variable((n, n))
    lam = 1

    constraints = [G >> 0]
    constraints += [eta[i, j] >= 0 for i in range(n) for j in range(n)]
    reg = lam * cp.norm(eta, p=1)
    Gii = cp.diag(G)
    hstacked = cp.hstack([cp.reshape(Gii, (n, 1)) for i in range(n)])
    vstacked = cp.vstack([cp.reshape(Gii, (1, n)) for i in range(n)])
    obj = reg + 0.5 * cp.sum((hstacked + vstacked - 2 * G + eta - D**2)**2)
    #obj = 0.5 * cp.sum((hstacked + vstacked - 2 * G - D**2))
    prob = cp.Problem(cp.Minimize(obj), constraints)
    prob.solve(verbose=True)
    #print("The optimal value is", prob.value)
    #print("A solution G is: {}".format(G.value))
    u, s, v = np.linalg.svd(G.value)
    u, s = np.real(u), np.real(s)
    X = np.dot(u, np.diag(np.sqrt(s)))[:, :3]
    return X
    def solve_problem(self, x_k, penalizer, p, delta, constraints=None, lower_limit=None, upper_limit=None):
        model_objective, actual_objective = self.get_model_objective(x_k, penalizer, p)
        if constraints is not None:
            if constraints.shape[1] == 2 * p.shape[0]:
                p1 = cvxpy.hstack([p, p])
            else:
                p1 = p
            if lower_limit is not None and upper_limit is not None:
                constraints = [cvxpy.norm(p, self.trust_region_norm) <= delta,
                               lower_limit <= cvxpy.matmul(constraints, p1),
                               cvxpy.matmul(constraints, p1) <= upper_limit]
            elif lower_limit is None:
                constraints = [cvxpy.norm(p, self.trust_region_norm) <= delta,
                               cvxpy.matmul(constraints, p1) >= upper_limit]
            elif upper_limit is None:

                constraints = [
                    cvxpy.norm(p, self.trust_region_norm) <= delta,
                    lower_limit <= cvxpy.matmul(constraints, p1)
                ]
        else:
            constraints = [cvxpy.norm(p, self.trust_region_norm) <= delta]
        problem = cvxpy.Problem(cvxpy.Minimize(model_objective), constraints)
        # print problem.get_problem_data(self.solver)[0]
        if self.solver == "CVXOPT":
            start = time.time()
            result = problem.solve(solver=self.solver, warm_start=True, kktsolver=cvxpy.ROBUST_KKTSOLVER, verbose=False)
            end = time.time()
        else:
            # result = problem.solve(solver=self.solver, warm_start=True, verbose=False, max_iters=5000)
            start = time.time()
            result = problem.solve(solver=self.solver, warm_start=True, verbose=False, max_iters=100)
            # result = problem.solve(solver=self.solver, warm_start=True, verbose=False)
            end = time.time()
        self.solving_time += end - start

        return p.value, model_objective, actual_objective, problem.status, problem.value
Beispiel #25
0
    def get_allocation_using_job_type_throughputs(
            self, unflattened_throughputs, job_id_to_job_type_key,
            scale_factors, unflattened_priority_weights, cluster_spec):
        job_ids = sorted(job_id_to_job_type_key.keys())
        if len(job_ids) == 0:
            return None
        job_type_keys = sorted(unflattened_throughputs.keys())
        worker_types = sorted(cluster_spec.keys())
        num_workers = \
            [cluster_spec[worker_type] for worker_type in worker_types]

        # Create a map from job type to list of job indexes.
        job_type_key_to_job_idx = {}
        for i, job_id in enumerate(job_ids):
            job_type_key = job_id_to_job_type_key[job_id]
            if job_type_key not in job_type_key_to_job_idx:
                job_type_key_to_job_idx[job_type_key] = []
            job_type_key_to_job_idx[job_type_key].append(i)

        # Num jobs.
        n = len(job_ids)
        # Num job_types.
        a = len(unflattened_throughputs.keys())
        # Num worker_types.
        m = len(worker_types)
        # Num varibles per job.
        num_vars_per_job = 1 + a

        # Set up scale factors.
        flattened_scale_factors = \
            np.reshape([scale_factors[job_id] for job_id in job_ids], (n, 1))
        scale_factors_array = np.tile(flattened_scale_factors,
                                      (1, num_vars_per_job * m))

        # Set up flattened job type throughputs.
        flattened_throughputs = np.zeros(shape=(a, (1 + a) * m),
                                         dtype=np.float32)
        for i, job_type_key in enumerate(job_type_keys):
            for k, worker_type in enumerate(worker_types):
                for j, other_job_type_key in enumerate([None] + job_type_keys):
                    if j > 0 and other_job_type_key[1] != job_type_key[1]:
                        flattened_throughputs[i, k * (1 + a) + j] = 0.0
                    else:
                        flattened_throughputs[i,k*(1+a)+j] = \
                            unflattened_throughputs[job_type_key][worker_type][other_job_type_key]

        # Set up masks to avoid double-counting allocation values when
        # computing constraint that the sum of allocation values of each
        # worker type must be <= the number of workers of that worker type.
        # TODO: Change this if we ever consider combinations larger than pairs.
        masks = np.full(shape=(n, num_vars_per_job), fill_value=0.5)
        masks[:, 0] = 1.0

        # Allocation matrix.
        x = cp.Variable((n, num_vars_per_job * m))

        constraints = [
            # All allocation values must be >= 0.
            x >= 0,
            # The sum of allocation values for each job must be <= 1.
            cp.sum(x, axis=1) <= 1
        ]

        # The sum of allocation values for each worker type must be <=
        # the number of workers of that type.
        per_worker_type_allocations = []
        for i in range(m):
            relevant_vars = \
                x[:,i*num_vars_per_job:(i+1)*num_vars_per_job]
            relevant_scale_factors = \
                scale_factors_array[:,i*num_vars_per_job:(i+1)*num_vars_per_job]
            per_worker_type_allocations.append(
                cp.sum(
                    cp.multiply(relevant_vars,
                                cp.multiply(relevant_scale_factors, masks))))
        constraints.append(
            cp.hstack(per_worker_type_allocations) <= num_workers)

        # Set the following constraints:
        # for all job type pairs a, b:
        #   sum of allocation of all jobs of type a paired with type b ==
        #   sum of allocation of all jobs of type b paired with type a
        lhs = []
        rhs = []
        for i, job_type_key_0 in enumerate(job_type_keys):
            for j, job_type_key_1 in enumerate(job_type_keys):
                if j <= i:
                    continue
                elif job_type_key_0[1] != job_type_key_1[1]:
                    continue

                # Retrieve the list of jobs of each type.
                job_type_0_jobs = job_type_key_to_job_idx[job_type_key_0]
                job_type_1_jobs = job_type_key_to_job_idx[job_type_key_1]

                for k in range(m):
                    job_type_0_mask = np.zeros(x.shape)
                    job_type_1_mask = np.zeros(x.shape)

                    # Allocation of job_type_0 jobs when paired with job_type_1
                    for job_idx in job_type_0_jobs:
                        offset = k * num_vars_per_job + 1 + j
                        job_type_0_mask[job_idx, offset] = 1

                    # Allocation of job_type_1 jobs when paired with job_type_0
                    for job_idx in job_type_1_jobs:
                        offset = k * num_vars_per_job + 1 + i
                        job_type_1_mask[job_idx, offset] = 1

                    lhs.append(cp.sum(x[job_type_0_mask == 1]))
                    rhs.append(cp.sum(x[job_type_1_mask == 1]))

        assert (len(lhs) == len(rhs))
        if len(lhs) > 0:
            constraints.append(cp.hstack(lhs) == cp.hstack(rhs))

        # Add constraints to make all variables of the form i-A where job i
        # is of job type A equal.
        for i, job_type_key in enumerate(job_type_keys):
            for k in range(m):
                same_job_type_vars = []
                job_type_jobs = job_type_key_to_job_idx[job_type_key]

                # Find all variables for job-job_type pairs where the job
                # types match.
                offset = k * num_vars_per_job + 1 + i
                for job_idx in job_type_jobs:
                    same_job_type_vars.append(x[job_idx, offset])

                # Constrain the variables to all be equal.
                c = cp.Variable()
                constraints.append(cp.hstack(same_job_type_vars) == c)

        throughputs_no_packed_jobs = np.zeros(
            (len(job_ids), len(worker_types)))
        for i, job_id in enumerate(job_ids):
            job_type_key = job_id_to_job_type_key[job_id]
            for j, worker_type in enumerate(worker_types):
                throughputs_no_packed_jobs[i, j] = \
                    unflattened_throughputs[job_type_key][worker_type][None]
        proportional_throughputs = self._proportional_policy.get_throughputs(
            throughputs_no_packed_jobs, (job_ids, worker_types), cluster_spec)

        # Allocation coefficients.
        all_coefficients = np.zeros((n, num_vars_per_job * m))
        for i, job_id in enumerate(job_ids):
            job_type_key = job_id_to_job_type_key[job_id]
            job_type_idx = job_type_keys.index(job_type_key)
            if len(job_type_key_to_job_idx[job_type_key]) == 1:
                for k, worker_type in enumerate(worker_types):
                    offset = k * num_vars_per_job + 1 + job_type_idx
                    constraints.append(x[i, offset] == 0.0)
            proportional_throughput = proportional_throughputs[i]
            all_coefficients[i] = \
                np.multiply(flattened_throughputs[job_type_idx],
                            scale_factors_array[i]) /\
                    (unflattened_priority_weights[job_id] * proportional_throughput)
        objective = \
            cp.Maximize(cp.min(cp.sum(cp.multiply(all_coefficients, x),
                                      axis=1)))

        cvxprob = cp.Problem(objective, constraints)
        result = cvxprob.solve(solver=self._solver)

        if cvxprob.status != "optimal":
            print('WARNING: Allocation returned by policy not optimal!')

        allocation = x.value.clip(min=0.0).clip(max=1.0)

        # Unflatten allocation.
        unflattened_allocation = {}
        for i, job_id in enumerate(job_ids):
            unflattened_allocation[job_id] = {}
            for j, worker_type in enumerate(worker_types):
                unflattened_allocation[job_id][worker_type] = {}
                for k, job_type_key in enumerate([None] + job_type_keys):
                    unflattened_allocation[job_id][worker_type][job_type_key] = \
                        allocation[i, j * num_vars_per_job + k]

        return self.convert_job_type_allocation(unflattened_allocation,
                                                job_id_to_job_type_key)
Beispiel #26
0
    def test_sum_largest(self):
        self.skipTest("Enable test once sum_largest is implemented.")
        x = cvxpy.Variable((4, ), pos=True)
        obj = cvxpy.Minimize(cvxpy.sum_largest(x, 3))
        constr = [x[0] * x[1] * x[2] * x[3] >= 16]
        dgp = cvxpy.Problem(obj, constr)
        dgp2dcp = cvxpy.reductions.Dgp2Dcp(dgp)
        dcp = dgp2dcp.reduce()
        dcp.solve(SOLVER)
        dgp.unpack(dgp2dcp.retrieve(dcp.solution))
        opt = 6.0
        self.assertAlmostEqual(dgp.value, opt)
        self.assertAlmostEqual((x[0] * x[1] * x[2] * x[3]).value, 16, places=2)
        dgp._clear_solution()
        dgp.solve(SOLVER, gp=True)
        self.assertAlmostEqual(dgp.value, opt)
        self.assertAlmostEqual((x[0] * x[1] * x[2] * x[3]).value, 16, places=2)

        # An unbounded problem.
        x = cvxpy.Variable((4, ), pos=True)
        y = cvxpy.Variable(pos=True)
        obj = cvxpy.Minimize(cvxpy.sum_largest(x, 3) * y)
        constr = [x[0] * x[1] * x[2] * x[3] >= 16]
        dgp = cvxpy.Problem(obj, constr)
        dgp2dcp = cvxpy.reductions.Dgp2Dcp(dgp)
        dcp = dgp2dcp.reduce()
        opt = dcp.solve(SOLVER)
        self.assertEqual(dcp.value, -float("inf"))
        dgp.unpack(dgp2dcp.retrieve(dcp.solution))
        self.assertAlmostEqual(dgp.value, 0.0)
        self.assertAlmostEqual(dgp.status, "unbounded")
        dgp._clear_solution()
        dgp.solve(SOLVER, gp=True)
        self.assertAlmostEqual(dgp.value, 0.0)
        self.assertAlmostEqual(dgp.status, "unbounded")

        # Another unbounded problem.
        x = cvxpy.Variable(2, pos=True)
        obj = cvxpy.Minimize(cvxpy.sum_largest(x, 1))
        dgp = cvxpy.Problem(obj, [])
        dgp2dcp = cvxpy.reductions.Dgp2Dcp(dgp)
        dcp = dgp2dcp.reduce()
        opt = dcp.solve(SOLVER)
        self.assertEqual(dcp.value, -float("inf"))
        dgp.unpack(dgp2dcp.retrieve(dcp.solution))
        self.assertAlmostEqual(dgp.value, 0.0)
        self.assertAlmostEqual(dgp.status, "unbounded")
        dgp._clear_solution()
        dgp.solve(SOLVER, gp=True)
        self.assertAlmostEqual(dgp.value, 0.0)
        self.assertAlmostEqual(dgp.status, "unbounded")

        # Composition with posynomials.
        x = cvxpy.Variable((4, ), pos=True)
        obj = cvxpy.Minimize(
            cvxpy.sum_largest(
                cvxpy.hstack([
                    3 * x[0]**0.5 * x[1]**0.5,
                    x[0] * x[1] + 0.5 * x[1] * x[3]**3, x[2]
                ]), 2))
        constr = [x[0] * x[1] >= 16]
        dgp = cvxpy.Problem(obj, constr)
        dgp2dcp = cvxpy.reductions.Dgp2Dcp(dgp)
        dcp = dgp2dcp.reduce()
        dcp.solve(SOLVER)
        dgp.unpack(dgp2dcp.retrieve(dcp.solution))
        # opt = 3 * sqrt(4) * sqrt(4) + (4 * 4 + 0.5 * 4 * epsilon) = 28
        opt = 28.0
        self.assertAlmostEqual(dgp.value, opt, places=2)
        self.assertAlmostEqual((x[0] * x[1]).value, 16.0, places=2)
        self.assertAlmostEqual(x[3].value, 0.0, places=2)
        dgp._clear_solution()
        dgp.solve(SOLVER, gp=True)
        self.assertAlmostEqual(dgp.value, opt, places=2)
        self.assertAlmostEqual((x[0] * x[1]).value, 16.0, places=2)
        self.assertAlmostEqual(x[3].value, 0.0, places=2)
Beispiel #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
Beispiel #28
0
def solve_group_SDP(
    Sigma,
    groups=None,
    verbose=False,
    objective="abs",
    norm_type=2,
    num_iter=10,
    tol=1e-2,
    **kwargs,
):
    """ Solves the group SDP problem: extends the
    formulation from Barber and Candes 2015/
    Candes et al 2018 (MX Knockoffs). Note this will be 
    much faster with equal-sized groups and objective="abs."
    :param Sigma: true covariance (correlation) matrix, 
    p by p numpy array.
    :param groups: numpy array of length p with
    integer values between 1 and m. 
    :param verbose: if True, print progress of solver
    :param objective: How to optimize the S matrix for 
    group knockoffs. (For ungrouped knockoffs, using the 
    objective = 'abs' is strongly recommended.)
    There are several options:
        - 'abs': minimize sum(abs(Sigma - S))
        between groups and the group knockoffs.
        - 'pnorm': minimize Lp-th matrix norm.
        Equivalent to abs when p = 1.
        - 'norm': minimize different type of matrix norm
        (see norm_type below).
    :param norm_type: Means different things depending on objective.
        - When objective == 'pnorm', i.e. objective is Lp-th matrix norm, 
          which p to use. Can be any float >= 1. 
        - When objective == 'norm', can be 'fro', 'nuc', np.inf, or 1
          (i.e. which other norm to use).
    Defaults to 2.
    :param num_iter: We do a line search and scale S at the end to make 
    absolutely sure there are no numerical errors. Defaults to 10.
    :param tol: Minimum eigenvalue of S must be greater than this.
    """

    # By default we lower the convergence epsilon a bit for drastic speedup.
    if "eps" not in kwargs:
        kwargs["eps"] = 5e-3

    # Default groups
    p = Sigma.shape[0]
    if groups is None:
        groups = np.arange(1, p + 1, 1)

    # Test corr matrix
    TestIfCorrMatrix(Sigma)

    # Check to make sure the objective is valid
    objective = str(objective).lower()
    if objective not in OBJECTIVE_OPTIONS:
        raise ValueError(
            f"Objective ({objective}) must be one of {OBJECTIVE_OPTIONS}")
    # Warn user if they're using a weird norm...
    if objective == "norm" and norm_type == 2:
        warnings.warn(
            "Using norm objective and norm_type = 2 can lead to strange behavior: consider using Frobenius norm"
        )
    # Find minimum tolerance, possibly warn user if lower than they specified
    maxtol = np.linalg.eigh(Sigma)[0].min() / 1.1
    if tol > maxtol and verbose:
        warnings.warn(
            f"Reducing SDP tol from {tol} to {maxtol}, otherwise SDP would be infeasible"
        )
    tol = min(maxtol, tol)

    # Figure out sizes of groups
    m = groups.max()
    group_sizes = utilities.calc_group_sizes(groups)

    # Possibly solve non-grouped SDP
    if m == p:
        return solve_SDP(
            Sigma=Sigma,
            verbose=verbose,
            num_iter=num_iter,
            tol=tol,
        )

    # Sort the covariance matrix according to the groups
    inds, inv_inds = utilities.permute_matrix_by_groups(groups)
    sortedSigma = Sigma[inds][:, inds]

    # Create blocks of semidefinite matrix S,
    # as well as the whole matrix S
    variables = []
    constraints = []
    S_rows = []
    shift = 0
    for j in range(m):

        # Create block variable
        gj = int(group_sizes[j])
        Sj = cp.Variable((gj, gj), symmetric=True)
        constraints += [Sj >> 0]
        variables.append(Sj)

        # Create row of S
        if shift == 0 and shift + gj < p:
            rowj = cp.hstack([Sj, cp.Constant(np.zeros((gj, p - gj)))])
        elif shift + gj < p:
            rowj = cp.hstack([
                cp.Constant(np.zeros((gj, shift))),
                Sj,
                cp.Constant(np.zeros((gj, p - gj - shift))),
            ])
        elif shift + gj == p and shift > 0:
            rowj = cp.hstack([cp.Constant(np.zeros((gj, shift))), Sj])
        elif gj == p and shift == 0:
            rowj = cp.hstack([Sj])

        else:
            raise ValueError(
                f"shift ({shift}) and gj ({gj}) add up to more than p ({p})")
        S_rows.append(rowj)

        # Incremenet shift
        shift += gj

    # Construct S and Grahm Matrix
    S = cp.vstack(S_rows)
    sortedSigma = cp.Constant(sortedSigma)
    constraints += [2 * sortedSigma - S >> 0]

    # Construct optimization objective
    if objective == "abs":
        objective = cp.Minimize(cp.sum(cp.abs(sortedSigma - S)))
    elif objective == "pnorm":
        objective = cp.Minimize(cp.pnorm(sortedSigma - S, norm_type))
    elif objective == "norm":
        objective = cp.Minimize(cp.norm(sortedSigma - S, norm_type))
    # Note we already checked objective is one of these values earlier

    # Construct, solve the problem.
    problem = cp.Problem(objective, constraints)
    problem.solve(verbose=verbose, **kwargs)
    if verbose:
        print("Finished solving SDP!")

    # Unsort and get numpy
    S = S.value
    if S is None:
        raise ValueError(
            "SDP formulation is infeasible. Try decreasing the tol parameter.")
    S = S[inv_inds][:, inv_inds]

    # Clip 0 and 1 values
    for i in range(p):
        S[i, i] = max(tol, min(1 - tol, S[i, i]))

    # Scale to make this PSD using binary search
    S, gamma = scale_until_PSD(Sigma, S, tol, num_iter)
    if verbose:
        mineig = np.linalg.eigh(2 * Sigma - S)[0].min()
        print(
            f"After SDP, mineig is {mineig} after {num_iter} line search iters. Gamma is {gamma}"
        )

    # Return unsorted S value
    return S
import numpy as np
import cvxpy as cp
from data.correlation_bounds_data import m, n, A, sigma
np.set_printoptions(precision=4, suppress=True)

Sigma = cp.Variable((n, n), PSD=True)
constraints = []
for i in range(m):
    a = A[:,i]
    constraints.append(cp.quad_form(a, Sigma) == sigma[i] ** 2)

rhos = []
for i in range(n):
    for j in range(i):
        denom = cp.geo_mean(cp.hstack([Sigma[i, i], Sigma[j, j]]))
        rho_ij = cp.quad_over_lin(Sigma[i, j], denom)
        rhos.append(rho_ij)

rho_max = cp.max(cp.hstack(rhos))
obj = cp.Minimize(rho_max)
problem = cp.Problem(obj, constraints)
problem.solve()
print(problem.status)
print(Sigma.value)
print(rho_max.value)
Beispiel #30
0
 def link_tt_heuristic(link):
   ff = link.l / link.fd.v
   q_max = (link.l / link.fd.q_max) * link.v_dens
   rho_hat = link.fd.rho_max - link.v_dens
   cong = link.l / link.fd.w * (quad_over_lin(link.fd.rho_max ** .5, rho_hat) - 1)
   return cvx_max(hstack([ff, q_max, cong]))
Beispiel #31
0
    def NPA1_constraint(self, proj=True):

        # Introduce the normalization factor
        renorm = lambda x, y: self.dimT**2 / (self.probQ1[x] * self.probQ2[y])

        # The P matrix containing the information about the variables rho_variable is give by
        P = []

        for a1, q1 in self.indices_A1Q1:
            P_row = [
                renorm(q1, q2) *
                cp.trace(self.Phi_TTSS @ self.rho_TTSS(a1, q1, a2, q2))
                for a2, q2 in self.indices_A2Q2
            ]
            P.append(P_row)

        P = cp.bmat(P)

        # The Q matrix containing the information about the variables rho_variable and also some new variables
        Q = []

        for a1, q1 in self.indices_A1Q1:
            Q_row = []
            for a1p, q1p in self.indices_A1Q1:
                if q1 == q1p:
                    if a1 == a1p:
                        val = sum([
                            renorm(q1, q2) * cp.trace(
                                self.Phi_TTSS @ self.rho_TTSS(a1, q1, a2, q2))
                            for a2, q2 in self.indices_A2Q2
                        ]) / self.dimQ2
                    else:
                        if proj:
                            val = cp.Constant(
                                0)  # Assume projective measurements.
                        else:
                            val = cp.Variable()  # Otherwise, just new variable
                else:
                    val = cp.Variable()
                Q_row.append(val)
            Q.append(Q_row)

        Q = cp.bmat(Q)

        # The R matrix containing the information about the variables rho_variable and also some new variables
        R = []

        for a2, q2 in self.indices_A2Q2:
            R_row = []
            for a2p, q2p in self.indices_A2Q2:
                if q2 == q2p:
                    if a2 == a2p:
                        val = sum([
                            renorm(q1, q2) * cp.trace(
                                self.Phi_TTSS @ self.rho_TTSS(a1, q1, a2, q2))
                            for a1, q1 in self.indices_A1Q1
                        ]) / self.dimQ1
                    else:
                        if proj:
                            val = cp.Constant(
                                0)  # Assume projective measurements.
                        else:
                            val = cp.Variable()  # Otherwise, just new variable
                else:
                    val = cp.Variable()
                R_row.append(val)
            R.append(R_row)

        R = cp.bmat(R)

        # Constructing vector v of dimension dimA1*dimQ1+dimA2*dimQ2
        v = []

        for a1, q1 in self.indices_A1Q1:
            v.append(
                sum([
                    renorm(q1, q2) *
                    cp.trace(self.Phi_TTSS @ self.rho_TTSS(a1, q1, a2, q2))
                    for a2, q2 in self.indices_A2Q2
                ]) / self.dimQ2)

        for a2, q2 in self.indices_A2Q2:
            v.append(
                sum([
                    renorm(q1, q2) *
                    cp.trace(self.Phi_TTSS @ self.rho_TTSS(a1, q1, a2, q2))
                    for a1, q1 in self.indices_A1Q1
                ]) / self.dimQ1)

        v = cp.bmat([v])
        w = cp.vstack([cp.Constant([[1]]), v.T])

        # Builiding the matrix M that should be positive semi-definite (NPA constraint)
        M = cp.vstack([cp.hstack([Q, P]), cp.hstack([P.T, R])])
        M = cp.vstack([v, M])
        M = cp.hstack([w, M])

        self.constraints.append(M >> 0)
        self.constraints.append(M - M.T == 0)
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]))
Beispiel #33
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
    def compute_decision_for_current_state(self, verbose=False):
        """
        1. Get the decision for the current state
            a. Get the SINDYc coefficients for the dynamics
            b. Do the computation
        2. Use scipy.optimize to compute the best control action
        3. Return the decision
        """

        if verbose:
            print('Current state: {:s}'.format(np.array_str(
                self.current_state, precision=2)))

        # Compute the decision
        query_timer_start = time.time()

        # Compute the SINDYc coefficients for the dynamics
        coeff_state, coeff_input = self.compute_sindyc_coeff()

        # Compute the sublibrary for dynamics
        L_x = self.evaluate_sub_library_at_state(self.current_state)

        # One-step optimal control: Solve
        # minimize       objective(delta_state, current_action)
        # subject to     delta_state = Model(current_action)
        #                lb <= u <= ub
        # for delta_state and current_action
        #
        # Here, the estimated next state is given by current_state + delta_state
        # under the influence of current_action
        current_action = cp.Variable((self.input_seq.shape[1],))
        delta_state = cp.Variable((self.trajectory.shape[1],))
        L_input = cp.hstack((current_action[input_indx] * L_x for input_indx
                             in range(self.input_seq.shape[1])))
        const = [current_action <= self.input_ub,
                 current_action >= self.input_lb,
                 delta_state == coeff_state.T@L_x + coeff_input.T@L_input]
        obj = self.cvxpy_objective(self.current_state, delta_state,
                                   current_action)
        
        prob = cp.Problem(cp.Minimize(obj), const)

        try:
            prob.solve(**self.cvxpy_args)
        except cp.SolverError:
            raise RuntimeError('CVXPY solver error')

        if prob.status in ['optimal', 'optimal_inaccurate']:
            current_decision = np.array([current_action.value])
        else:
            raise RuntimeError('compute_decision_for_current_state failed'
                    ' with CVXPY status: {:s}'.format(prob.status))

        query_timer_end = time.time()
        query_time = query_timer_end - query_timer_start

        if verbose:
            # Update user
            print('Best action = {:s} | Estimated cost = {:1.4f} | Time = '
                  '{:1.4f} s '.format(np.array_str(current_decision,
                                                   precision=2),
                      prob.value, query_time))

        # Get the next state
        self.current_state = self.one_step_dyn(self.current_state, 
                                               current_decision)

        # Update the data matrices
        self.trajectory = np.vstack((self.trajectory, self.current_state))
        self.input_seq = np.vstack((self.input_seq, current_decision))
        self.cost_val_vec = np.hstack((self.cost_val_vec, prob.value))

        # Return decision
        solution_dict = {'next_query': current_decision,
                         'lb_opt_val': prob.value,
                         'query_time': query_time}
        return solution_dict
Beispiel #35
0
def sys_norm_hinf_LMI(A, Bdisturbance, C, D = None):
    '''Compute a system's Hinfinity norm, using an LMI approach.
    
    Acl, Bdisturbance are system matrices, describing the systems dynamics:
     dx/dt = Acl*x  + Bdisturbance*v
    where x is the system state and v is the disturbance.
    
    The system output is:
     z = C*x + D*v
    
    The matrix Acl must be Hurwitz for the Hinf norm to be finite. 
    
    Parameters
    ----------
    A  : (n, n) Matrix
         Input
    Bdisturbance : (n, m) Matrix
         Input
    C : (q, n) Matrix
         Input
    D : (q,m) Matrix
         Input (optional)

    Returns
    -------
    Jinf : Systems Hinf norm.
    
    See: Robust Controller Design By Convex Optimization, Alireza Karimi Laboratoire d'Automatique, EPFL
    '''
    
    if not controlpy.analysis.is_hurwitz(A):
        return np.Inf

    n = A.shape[0]
    ndist = Bdisturbance.shape[1]
    nout  = C.shape[0]

    X = cvxpy.Semidef(n)
    g = cvxpy.Variable()
    
    if D is None:
        D = np.matrix(np.zeros([nout, ndist]))
        
    r1 = cvxpy.hstack(cvxpy.hstack(A.T*X+X*A, X*Bdisturbance), C.T)
    r2 = cvxpy.hstack(cvxpy.hstack(Bdisturbance.T*X, -g*np.matrix(np.identity(ndist))), D.T)
    r3 = cvxpy.hstack(cvxpy.hstack(C, D), -g*np.matrix(np.identity(nout)))
    tmp = cvxpy.vstack(cvxpy.vstack(r1,r2),r3)
                        
    constraints = [tmp == -cvxpy.Semidef(n + ndist + nout)]

    obj = cvxpy.Minimize(g)

    prob = cvxpy.Problem(obj, constraints)
    
    try:
        prob.solve()#solver='CVXOPT', kktsolver='robust')
    except cvxpy.error.SolverError:
        print('Solution not found!')
        return None
    
    if not prob.status == cvxpy.OPTIMAL:
        return None
    
    return g.value
Beispiel #36
0
np.random.seed(1)
(m, n) = (70, 500)
k = 10
z_true = np.zeros(n, dtype=complex)
z_true[0:k] = np.random.randn(k) + 1j * np.random.randn(k)
np.random.shuffle(z_true); z_true = np.asmatrix(z_true).T
A = np.random.randn(m, n) + 1j * np.random.randn(m, n)
A = np.asmatrix(A)
b = A*z_true; b = np.asmatrix(b)

zr = cvx.Variable(n)
zi = cvx.Variable(n)
t = cvx.Variable(m)
obj = cvx.Minimize(cvx.sum_entries(t))
#AA = cvx.norm2(cvx.hstack(cvx.vstack(A.real,A.imag),cvx.vstack(-A.imag,A.real)))
z = cvx.vstack(zr,zi)
constraints = [ cvx.norm2(cvx.hstack(cvx.vstack(A[i,:].real,A[i,:].imag),
                cvx.vstack(-A[i,:].imag,A[i,:].real))*z
                -cvx.vstack(b[i].real,b[i].imag))
                <= t[i] for i in range(m)]
'''
constraints = [ cvx.norm2(cvx.hstack(cvx.vstack(A.real,A.imag),cvx.vstack(-A.imag,A.real))*z
             - cvx.vstack(b.real,b.imag)) <= t]
'''
prob = cvx.Problem(obj, constraints)
sol = prob.solve(solver=cvx.ECOS)
print 'status: {}'.format(prob.status)
print 'norm z: {}'.format(cvx.norm2(z).value)
print 'norm z_true: {}'.format((cvx.norm2(z_true.real)+cvx.norm2(z_true.imag)).value)
for i in range(n):
    print '{} + {}j' .format(zr[i].value,zi[i].value)
Beispiel #37
0
"""
@author: cyrusl
EE 364A Convex Optimization Homework 5 A5.2 Minimax rational fit
Due 7/25/2014
"""
import numpy as np
import cvxpy as cvx
import matplotlib.pyplot as plt

k = 201
t = np.asmatrix(np.linspace(-3,3,k)).T
y = np.exp(t)
one = np.asmatrix(np.ones((k,1)))
Tpow = cvx.hstack(one, t, cvx.square(t))
u = np.exp(3)
l = 0
tol = 1e-3

while u-l >= tol:
    mid = (l+u)/2
    a = cvx.Variable(3)
    b = cvx.Variable(2)
    obj = cvx.Minimize(0)
    constraints = [cvx.abs(Tpow*a - cvx.mul_elemwise(y, Tpow*cvx.vstack(1, b)))
                    <= mid * Tpow*cvx.vstack(1, b)]          
    prob = cvx.Problem(obj, constraints)
    sol = prob.solve(solver=cvx.CVXOPT)
    if prob.status == cvx.OPTIMAL:
        print('gamma = {}', format(mid))
        u = mid
        a_opt = a