コード例 #1
0
ファイル: enzpl.py プロジェクト: jacopoantonello/enzpy
    def solve_full(self, bi, lmbd, show_progress=True):
        solvers.options['show_progress'] = show_progress

        # load problem data
        self.bi = bi
        self.lmbd = lmbd
        self.c[1 + self.Nm:1 + self.Nm + self.Nb] = lmbd
        self.h[1:1 + self.Nm] = -bi

        t1 = time()
        self.sol = solvers.conelp(
            self.c, self.G, self.h, self.dims, self.A, self.b)
        t2 = time()

        t3 = time()
        if self.sol['status'] in ('optimal'):
            S = self.sol['s'][1 + self.Nm:]
            self.sA[:] = S[self.I11] + 1j*S[self.I21]
            lapack.heevr(
                self.sA, self.sW, jobz='V', range='I', uplo='L',
                vl=0.0, vu=0.0, il=self.Nb, iu=self.Nb, Z=self.sZ)
            self.beta_hat[:] = math.sqrt(self.sW[0])*self.sZ[:, 0]
        else:
            raise RuntimeError('numerical problems')
        t4 = time()

        self.solver_time = t2 - t1
        self.eig_time = t4 - t3
コード例 #2
0
def solve(opts):
    c = matrix([-6., -4., -5.])

    G = matrix([[
        16., 7., 24., -8., 8., -1., 0., -1., 0., 0., 7., -5., 1., -5., 1., -7.,
        1., -7., -4.
    ],
                [
                    -14., 2., 7., -13., -18., 3., 0., 0., -1., 0., 3., 13.,
                    -6., 13., 12., -10., -6., -10., -28.
                ],
                [
                    5., 0., -15., 12., -6., 17., 0., 0., 0., -1., 9., 6., -6.,
                    6., -7., -7., -6., -7., -11.
                ]])
    h = matrix([
        -3., 5., 12., -2., -14., -13., 10., 0., 0., 0., 68., -30., -19., -30.,
        99., 23., -19., 23., 10.
    ])

    A = matrix(0.0, (0, c.size[0]))
    b = matrix(0.0, (0, 1))

    dims = {'l': 2, 'q': [4, 4], 's': [3]}

    #localcones.options.update(opts)
    #sol = localcones.conelp(c, G, h, dims, kktsolver='qr')
    solvers.options.update(opts)
    sol = solvers.conelp(c, G, h, dims)
    print("\nStatus: " + sol['status'])
    if sol['status'] == 'optimal':
        print "x=\n", helpers.strSpe(sol['x'], "%.5f")
        print "s=\n", helpers.strSpe(sol['s'], "%.5f")
        print "z=\n", helpers.strSpe(sol['z'], "%.5f")
        rungotest(sol)
コード例 #3
0
    def solve_full(self, bi, lmbd, show_progress=True):
        solvers.options['show_progress'] = show_progress

        # load problem data
        self.bi = bi
        self.lmbd = lmbd
        self.c[1 + self.Nm:1 + self.Nm + self.Nb] = lmbd
        self.h[1:1 + self.Nm] = -bi

        t1 = time()
        self.sol = solvers.conelp(self.c, self.G, self.h, self.dims, self.A,
                                  self.b)
        t2 = time()

        t3 = time()
        if self.sol['status'] in ('optimal'):
            S = self.sol['s'][1 + self.Nm:]
            self.sA[:] = S[self.I11] + 1j * S[self.I21]
            lapack.heevr(self.sA,
                         self.sW,
                         jobz='V',
                         range='I',
                         uplo='L',
                         vl=0.0,
                         vu=0.0,
                         il=self.Nb,
                         iu=self.Nb,
                         Z=self.sZ)
            self.beta_hat[:] = math.sqrt(self.sW[0]) * self.sZ[:, 0]
        else:
            raise RuntimeError('numerical problems')
        t4 = time()

        self.solver_time = t2 - t1
        self.eig_time = t4 - t3
コード例 #4
0
ファイル: call_solver.py プロジェクト: SteveDiamond/PyDSM
def call_solver(p,quiet):
    """
    Calls solver. 

    :param p: Convex cvxpy_program. 
              Assumed to be expanded.
    :param quiet: Boolean.
    """

    # Set printing format for cvxopt sparse matrices
    opt.spmatrix_str = opt.printing.spmatrix_str_triplet 	
    
    # Expand objects defined via partial minimization
    constr_list = cvxpy_list(pm_expand(p.constraints))
    
    # Get variables
    variables = constr_list.variables
    variables.sort()

    # Count variables
    n = len(variables)

    # Create variable-index map
    var_to_index = {}
    for i in range(0,n,1):
        var_to_index[variables[i]] = i

    # Construct objective vector
    c = construct_c(p.objective,var_to_index,n,p.action)

    # Construct Ax == b
    A,b = construct_Ab(constr_list._get_eq(),var_to_index,n)

    # Construct  Gx <= h
    G,h,dim_l,dim_q,dim_s = construct_Gh(constr_list._get_ineq_in(),
                                         var_to_index,n)
    
    # Construct F
    F = construct_F(constr_list._get_ineq_in(),var_to_index,n)

    # Call cvxopt
    solvers.options['maxiters'] = p.options['maxiters']
    solvers.options['abstol'] = p.options['abstol']
    solvers.options['reltol'] = p.options['reltol']
    solvers.options['feastol'] = p.options['feastol']
    solvers.options['show_progress'] = not quiet
    dims = {'l':dim_l, 'q':dim_q, 's':dim_s}
    if F is None:
        r =  solvers.conelp(c,G,h,dims,A,b)
    else:
        r =  solvers.cpl(c,F,G,h,dims,A,b)

    # Store numerical values
    if r['status'] != PRIMAL_INFEASIBLE:
        for v in variables:
            v.value =  r['x'][var_to_index[v]]

    # Return result
    return r
コード例 #5
0
ファイル: call_solver.py プロジェクト: Python3pkg/PyDSM
def call_solver(p, quiet):
    """
    Calls solver. 

    :param p: Convex cvxpy_program. 
              Assumed to be expanded.
    :param quiet: Boolean.
    """

    # Set printing format for cvxopt sparse matrices
    opt.spmatrix_str = opt.printing.spmatrix_str_triplet

    # Expand objects defined via partial minimization
    constr_list = cvxpy_list(pm_expand(p.constraints))

    # Get variables
    variables = constr_list.variables
    variables.sort()

    # Count variables
    n = len(variables)

    # Create variable-index map
    var_to_index = {}
    for i in range(0, n, 1):
        var_to_index[variables[i]] = i

    # Construct objective vector
    c = construct_c(p.objective, var_to_index, n, p.action)

    # Construct Ax == b
    A, b = construct_Ab(constr_list._get_eq(), var_to_index, n)

    # Construct  Gx <= h
    G, h, dim_l, dim_q, dim_s = construct_Gh(constr_list._get_ineq_in(),
                                             var_to_index, n)

    # Construct F
    F = construct_F(constr_list._get_ineq_in(), var_to_index, n)

    # Call cvxopt
    solvers.options['maxiters'] = p.options['maxiters']
    solvers.options['abstol'] = p.options['abstol']
    solvers.options['reltol'] = p.options['reltol']
    solvers.options['feastol'] = p.options['feastol']
    solvers.options['show_progress'] = not quiet
    dims = {'l': dim_l, 'q': dim_q, 's': dim_s}
    if F is None:
        r = solvers.conelp(c, G, h, dims, A, b)
    else:
        r = solvers.cpl(c, F, G, h, dims, A, b)

    # Store numerical values
    if r['status'] != PRIMAL_INFEASIBLE:
        for v in variables:
            v.value = r['x'][var_to_index[v]]

    # Return result
    return r
コード例 #6
0
ファイル: test_mosek.py プロジェクト: cvxopt/cvxopt
 def test_conelp(self):
     from cvxopt import matrix, msk, solvers
     c = matrix([-6., -4., -5.])
     G = matrix([[ 16., 7.,  24.,  -8.,   8.,  -1.,  0., -1.,  0.,  0.,   7.,  -5.,   1.,  -5.,   1.,  -7.,   1.,   -7.,  -4.],
                 [-14., 2.,   7., -13., -18.,   3.,  0.,  0., -1.,  0.,   3.,   13.,  -6.,  13.,  12., -10.,  -6.,  -10., -28.],
                 [  5., 0., -15.,  12.,  -6.,  17.,  0.,  0.,  0., -1.,   9.,    6.,  -6.,   6.,  -7.,  -7.,  -6.,   -7., -11.]])
     h = matrix( [ -3., 5.,  12.,  -2., -14., -13., 10.,  0.,  0.,  0.,  68.,  -30., -19., -30.,  99.,  23., -19.,   23.,  10.] )
     dims = {'l': 2, 'q': [4, 4], 's': [3]}
     self.assertAlmostEqualLists(list(solvers.conelp(c, G, h, dims)['x']),list(msk.conelp(c, G, h, dims)[1]))
コード例 #7
0
    def run(self, lam=10.0, mu=0.0, eps=0.0, s0_val=0.001):
        G_tmp, h_tmp = get_G_h(self.var_No)
        h_eps = matrix(0.0, (self.G_No, 1))
        G_x = []
        G_i = []
        G_j = []
        for G_name in self.SFG:
            G = self.SFG.node[G_name]
            if G['type'] == 'G':
                g_cnt = G['cnt']
                h_eps[g_cnt] = G['intensity'] + eps
                for I_name in self.SFG[G_name]:
                    i_cnt = self.SFG.node[I_name]['cnt']
                    G_x.append(1.0)
                    G_i.append(g_cnt)
                    G_j.append(i_cnt)
                G_x.append(-1.0)
                G_i.append(g_cnt)
                G_j.append(self.GI_No + self.M_No + g_cnt)
        G_tmp2 = spmatrix(G_x, G_i, G_j, size=(self.G_No, self.var_No))
        G = sparse([G_tmp, G_tmp2])
        h = matrix([h_tmp, h_eps])

        A_tmp, b = get_A_b(self.SFG, self.M_No, self.I_No, self.GI_No)
        A_eps = spmatrix([], [], [], (self.I_No, self.G_No))
        A = sparse([[A_tmp], [A_eps]])

        x0 = get_initvals(self.var_No)
        x0['s'] = matrix(s0_val, size=h.size)

        c = matrix([
            matrix(-1.0, size=(self.GI_No, 1)),
            matrix(mu, size=(self.M_No, 1)),
            matrix((1.0 + lam), size=(self.G_No, 1))
        ])

        self.sol = solvers.conelp(c=c, G=G, h=h, A=A, b=b, primalstart=x0)
        Xopt = self.sol['x']

        alphas = []  # reporting results
        for N_name in self.SFG:
            N = self.SFG.node[N_name]
            if N['type'] == 'M':
                N['estimate'] = Xopt[self.GI_No + N['cnt']]
                alphas.append(N.copy())
            if N['type'] == 'G':
                for I_name in self.SFG[N_name]:
                    NI = self.SFG.edge[N_name][I_name]
                    NI['estimate'] = Xopt[NI['cnt']]
                    g_cnt = self.GI_No + self.M_No + N['cnt']
                    N['relaxation'] = Xopt[g_cnt]

        # fit error: evaluation of the cost function at the minimizer
        error = self.get_mean_square_error()

        return alphas, error, self.sol['status']
コード例 #8
0
def find_naive_one_time_best_team(Q, A, B, G, H):
    # Tracer()()
    Q = matrix(Q)
    best_team = conelp(Q, G, H, A=A, b=B)
    team = [int(round(s)) for s in best_team['x']]
    players_np = np.array(players)
    scores_np = np.array(scores)
    team_players = players_np[np.nonzero(team)].tolist()
    team_player_scores = scores_np[np.nonzero(team)].tolist()
    print team_player_scores
    print team_players
コード例 #9
0
def find_naive_one_time_best_team(Q,A,B,G,H):
  # Tracer()()
  Q = matrix(Q)
  best_team = conelp(Q,G,H,A=A,b=B)
  team = [int(round(s)) for s in best_team['x']]
  players_np = np.array(players)
  scores_np = np.array(scores)
  team_players = players_np[np.nonzero(team)].tolist()
  team_player_scores = scores_np[np.nonzero(team)].tolist()
  print team_player_scores
  print team_players
コード例 #10
0
ファイル: solvers.py プロジェクト: artuntun/convexThesis
def balanced_cut(A, delta=1.0, cut='min', solver="conelp_custom"):
    """
    Solves semidefinite relaxation of the following 
    balance-constrained min/max cut problem
    """
    N = A.shape[0]
    prob = balanced_cut_conelp(A, N, delta, cut)
    if solver == "mosek":
        sol = msk.conelp(*prob)
        Z = matrix(sol[2][1:], (N, N), tc='d')
    elif solver == "conelp":
        sol = solvers.conelp(*prob)
        Z = matrix(sol['z'][1:], (N, N), tc='d')
    elif solver == "conelp_custom":
        sol = solvers.conelp(*prob,
                             kktsolver=custom_kkt,
                             options={'refinement': 3})
        Z = matrix(sol['z'][1:], (N, N), tc='d')
    else:
        raise ValueError("Unknown solver")
    return Z
コード例 #11
0
 def Optimise(self, obj, n, order=None):
     c, G, h, A, b, dims = self.ConstructSDP(obj, n, order, self.ineqcons,
                                             self.eqcons)
     solvers.options['show_progress'] = False
     sol = solvers.conelp(c, G, h, dims, A, b)
     solution = {'status': None, 'obj': None, 'iterations': None, 'x': None}
     xopt = np.array(sol['x'][:n])
     solution['iterations'] = sol['iterations']
     if sol['status'] == 'optimal':
         solution['status'] = sol['status']
         solution['x'] = np.array(xopt)
         solution['obj'] = sol['primal objective'] + obj[0][0, 0]
     return solution
コード例 #12
0
ファイル: cone.py プロジェクト: smhjn/cvxFin
    def solve(self):
        if len(self.aux.G) == 0:
            raise ArithmeticError('No constraints')

        A = solvers.conelp(c=matrix(self.__c),
                           G=matrix(numpy.array(self.aux.G)),
                           h=matrix(numpy.array(self.aux.h)),
                           dims=self.aux.dims)

        if A["status"] == "optimal":
            return numpy.array(A['x']).transpose()[0], A
        else:
            raise ArithmeticError("Solution not optimal: " + A["status"])
コード例 #13
0
ファイル: RobustSTL.py プロジェクト: jfr311/RobustSTL
def l1(P, q):
    m, n = P.size
    c = matrix(n*[0.0] + m*[1.0])
    h = matrix([q, -q])

    def Fi(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):    
        if trans == 'N':
            u = P*x[:n]
            y[:m] = alpha * ( u - x[n:]) + beta*y[:m]
            y[m:] = alpha * (-u - x[n:]) + beta*y[m:]
        else:
            y[:n] =  alpha * P.T * (x[:m] - x[m:]) + beta*y[:n]
            y[n:] = -alpha * (x[:m] + x[m:]) + beta*y[n:]

    def Fkkt(W): 
        d1, d2 = W['d'][:m], W['d'][m:]
        D = 4*(d1**2 + d2**2)**-1
        A = P.T * spdiag(D) * P
        lapack.potrf(A)

        def f(x, y, z):
            x[:n] += P.T * ( mul( div(d2**2 - d1**2, d1**2 + d2**2), x[n:]) 
                + mul( .5*D, z[:m]-z[m:] ) )
            lapack.potrs(A, x)

            u = P*x[:n]
            x[n:] =  div( x[n:] - div(z[:m], d1**2) - div(z[m:], d2**2) + 
                mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2 )

            z[:m] = div(u-x[n:]-z[:m], d1)
            z[m:] = div(-u-x[n:]-z[m:], d2)
        return f

    uls =  +q
    lapack.gels(+P, uls)
    rls = P*uls[:n] - q 

    x0 = matrix( [uls[:n],  1.1*abs(rls)] ) 
    s0 = +h
    Fi(x0, s0, alpha=-1, beta=1) 

    if max(abs(rls)) > 1e-10:  
        w = .9/max(abs(rls)) * rls
    else: 
        w = matrix(0.0, (m,1))
    z0 = matrix([.5*(1+w), .5*(1-w)])

    dims = {'l': 2*m, 'q': [], 's': []}
    sol = solvers.conelp(c, Fi, h, dims, kktsolver = Fkkt,  
        primalstart={'x': x0, 's': s0}, dualstart={'z': z0})
    return sol['x'][:n]
コード例 #14
0
 def optimise(self,obj,n,order=None,ineqcons=[],eqcons=[]):
     c,G,h,A,b,dims = self.constructsdp(obj,n,ineqcons,eqcons,order)
     
     sol = solvers.conelp(c, G, h, dims, A, b)
     
     solution = {'status': None, 'objective': None, 'iterations': None, 'xopt': None}
     solution['status'] = sol['status']
     solution['iterations'] = sol['iterations']
     if solution['status'] is 'optimal':
         solution['objective'] = sol['primal objective'] + obj[0][0,0]
         solution['xopt'] = np.array(sol['x'][:n])
         return solution
     else:
         return solution
コード例 #15
0
  def check_point(self, p, A1, B_s, u_s):
    dims = {
        'l': self.size_tb() + 2*self.size_x(),  # Pure inequality constraints
            # No com cone
        'q': [4]*len(self.contacts)*len(self.gravity_envelope),
        's': []  # No sd cones
            }

    size_cones = self.size_x()*4 // 3

    #Min x ~ who cares, we just want to know if there is a solution
    c = matrix(np.ones((self.size_x(), 1)))

    A1_diag = block_diag(*([A1]*len(self.gravity_envelope)))
    A2 = np.vstack([self.computeA2(self.gravity+e)
                    for e in self.gravity_envelope])

    T = np.vstack([self.computeT(self.gravity+e, height=self.height)
                   for e in self.gravity_envelope]) - A2.dot(p)

    A = matrix(A1_diag)

    g_s = []
    h_s = []

    if self.L_s:
      g_s.append(np.vstack(self.L_s))
      h_s.append(np.vstack(self.tb_s))

    g_force = np.vstack([np.eye(self.size_x()), -np.eye(self.size_x())])
    g_s.append(g_force)

    h_s.append(self.force_lim*self.mass*9.81*np.ones((2*self.size_x(), 1)))

    #B = diag{[u_i b_i.T].T}
    blocks = [-np.vstack([u.T, B]) for u, B in zip(u_s, B_s)]*len(self.gravity_envelope)
    block = block_diag(*blocks)

    g_s.append(block)
    h_cones = np.zeros((size_cones, 1))
    h_s.append(h_cones)

    g = np.vstack(g_s)
    h = np.vstack(h_s)

    sol = solvers.conelp(c, G=matrix(g), h=matrix(h),
                         A=A, b=matrix(T), dims=dims)
    return sol
コード例 #16
0
ファイル: apirl.py プロジェクト: zwc662/LMDP
    def QP(self, expert, features, epsilon=None):
        if epsilon is None:
            epsilon = self.M.epsilon

        assert expert.shape[-1] == np.array(features).shape[-1]
        c = matrix(np.eye(len(expert) + 1)[-1] * -1)
        G_i = []
        h_i = []

        for k in range(len(expert)):
            G_i.append([0])
        G_i.append([-1])
        h_i.append(0)

        for j in range(len(features)):
            for k in range(len(expert)):
                G_i[k].append(-expert[k] + features[j][k])
            G_i[len(expert)].append(1)
            h_i.append(0)

        for k in range(len(expert)):
            G_i[k] = G_i[k] + [0.0] * (k + 1) + [
                -1.0
            ] + [0.0] * (len(expert) + 1 - k - 1)
        G_i[len(expert)] = G_i[len(expert)] + [0.0] * (1 + len(expert)) + [0.0]
        h_i = h_i + [1] + (1 + len(expert)) * [0.0]

        G = matrix(G_i)
        h = matrix(h_i)

        dims = {'l': 1 + len(features), 'q': [len(expert) + 1, 1], 's': []}
        start = time.time()
        sol = solvers.conelp(c, G, h, dims)
        end = time.time()
        print("QP operation time = " + str(end - start))
        solution = np.array(sol['x'])
        if solution is not None:
            solution = solution.reshape([len(expert) + 1]).tolist()
            w = solution[0:-1]
            t = solution[-1]
        else:
            w = None
            t = None
        return w, t
コード例 #17
0
    def l2_bound_layer1(self, weight, bias, x):
        """ Given input weights and biases will compute if each neuron can be
            on or off

        We do this using cvxopt conelp, but it's a messy formulation
        the G matrix looks like
        [ -I | I | 0row | -I]^T
        and the h matrix looks like
        [-lo_bounds, u_bounds, radius, -x]
        """

        G_list = [
            -1 * np.eye(self.dimension),
            np.eye(self.dimension),
            np.zeros((1, self.dimension)), -1 * np.eye(self.dimension)
        ]
        G = matrix(np.vstack(G_list).astype(np.float))

        h_list = [
            -1 * self.box_low, self.box_high,
            np.array([self.l2_radius]), -x
        ]
        h = matrix(np.hstack(h_list).astype(np.float))

        dims = {'l': self.dimension * 2, 'q': [self.dimension + 1], 's': [0]}

        m = weight.shape[0]

        # Do lowers first
        new_lows, new_highs = [], []
        for scale, working_list in [(1, new_lows), (-1, new_highs)]:
            for i in range(m):
                if (i % 10) == 0:
                    print(scale, i)
                c = matrix(weight[i].astype(np.float) * scale)
                import time
                start = time.time()
                solve_out = solvers.conelp(c, G, h, dims, solver='mosek')
                print(i, time.time() - start)
                working_list.append(scale * solve_out['primal objective'] +
                                    bias[i])

        return new_lows, new_highs
コード例 #18
0
 def s_SDP(self, Sigma):
     p = Sigma.shape[0]
     c = -np.ones(p)
     c = matrix(c)
     G = np.zeros((2 * p + p**2, p))
     G[:p, :] = np.eye(p)
     G[p:2 * p, :] = -np.eye(p)
     for i in range(p):
         G[2 * p + p * i, i] = 1
     G = matrix(G)
     h = np.ones(2 * p + p**2)
     h[p:2 * p] *= 0
     h[2 * p:] *= 2 * (Sigma).reshape(-1)
     h = matrix(h)
     dims = {'l': 2 * p, 'q': [], 's': [p]}
     solvers.options['show_progress'] = False
     sol = conelp(c, G, h, dims)
     s = np.array(sol['x']).reshape(-1)
     return s
コード例 #19
0
 def test_conelp(self):
     from cvxopt import matrix, msk, solvers
     c = matrix([-6., -4., -5.])
     G = matrix([[
         16., 7., 24., -8., 8., -1., 0., -1., 0., 0., 7., -5., 1., -5., 1.,
         -7., 1., -7., -4.
     ],
                 [
                     -14., 2., 7., -13., -18., 3., 0., 0., -1., 0., 3., 13.,
                     -6., 13., 12., -10., -6., -10., -28.
                 ],
                 [
                     5., 0., -15., 12., -6., 17., 0., 0., 0., -1., 9., 6.,
                     -6., 6., -7., -7., -6., -7., -11.
                 ]])
     h = matrix([
         -3., 5., 12., -2., -14., -13., 10., 0., 0., 0., 68., -30., -19.,
         -30., 99., 23., -19., 23., 10.
     ])
     dims = {'l': 2, 'q': [4, 4], 's': [3]}
     self.assertAlmostEqualLists(list(solvers.conelp(c, G, h, dims)['x']),
                                 list(msk.conelp(c, G, h, dims)[1]))
コード例 #20
0
  def block_socp(self, a, A1, A2, t, B_s, u_s):
    dims = {
        'l': 0,  # No pure inequality constraints
        'q': [4]*len(self.contacts),  # Size of the 2nd order cones : x,y,z+1
        's': []  # No sd cones
        }
    #Max a^T z ~ min -a^T z
    c = matrix(np.vstack([np.zeros((self.size_x(), 1)), -a]))

    A = matrix(np.hstack([A1, A2]))

    #B = diag{[u_i b_i.T].T}
    blocks = [-np.vstack([u.T, B]) for u, B in zip(u_s, B_s)]
    block = block_diag(*blocks)

    g = np.hstack([block, np.zeros((self.size_x()*4 // 3, self.size_z()))])

    h = np.zeros((self.size_x()*4 // 3, 1))

    sol = solvers.conelp(c, G=matrix(g), h=matrix(h),
                         A=A, b=matrix(t), dims=dims)
    return sol
コード例 #21
0
def _intersection_point(T, radii, alpha, values):
    lines = list()
    for i in range(0, len(T)):
        lines.append([(1 - values[i]) * T[i][alpha[i] - 1][k] +
                      values[i] * T[i][alpha[i]][k]
                      for k in range(0, T[i].dimensions)])

    c = matrix([0.] * T[0].dimensions)
    G = []
    for i in range(0, T[0].dimensions):
        m = len(T) * ([0.] + i * [0.] + [-1] +
                      (T[0].dimensions - i - 1) * [0.])
        G.append(m)

    G = matrix(G)
    h = []
    for i in range(0, len(T)):
        h += [radii[i]] + [-lines[i][j] for j in range(0, T[i].dimensions)]
    h = matrix(h)
    dims = {'l': 0, 'q': [1 + T[0].dimensions] * len(T), 's': [0]}
    sol = solvers.conelp(c, G, h, dims)
    return sol['status'] == 'optimal', np.array(
        [s for s in sol['x']]) if sol['x'] is not None else None
コード例 #22
0
ファイル: testconelp.py プロジェクト: hrautila/go.opt.old
def solve(opts):
    c = matrix([-6., -4., -5.])

    G = matrix([[ 16., 7.,  24.,  -8.,   8.,  -1.,  0., -1.,  0.,  0.,   7.,  
                  -5.,   1.,  -5.,   1.,  -7.,   1.,   -7.,  -4.],
                [-14., 2.,   7., -13., -18.,   3.,  0.,  0., -1.,  0.,   3.,  
                  13.,  -6.,  13.,  12., -10.,  -6.,  -10., -28.],
                [  5., 0., -15.,  12.,  -6.,  17.,  0.,  0.,  0., -1.,   9.,   
                   6.,  -6.,   6.,  -7.,  -7.,  -6.,   -7., -11.]])
    h = matrix([-3., 5.,  12.,  -2., -14., -13., 10.,  0.,  0.,  0.,  68., 
                 -30., -19., -30.,  99.,  23., -19.,   23.,  10.] )

    A = matrix(0.0, (0, c.size[0]))
    b = matrix(0.0, (0, 1))

    dims = {'l': 2, 'q': [4, 4], 's': [3]}
    solvers.options.update(opts)
    sol = solvers.conelp(c, G, h, dims, kktsolver='ldl')
    print("\nStatus: " + sol['status'])
    if sol['status'] == 'optimal':
        print "x=\n", helpers.str2(sol['x'])
        print "s=\n", helpers.str2(sol['s'])
        print "z=\n", helpers.str2(sol['z'])
        helpers.run_go_test("../testconelp", {'x': sol['x'], 's': sol['s'], 'z': sol['z']})
コード例 #23
0
def solve_convex(p,mode):
    """
    Description
    -----------
    Solves the convex program p. It assumes p is the convex part 
    of an expanded and transformed program.

    Arguments
    ---------
    p: convex cvxpy_program.    
    mode: 'rel' (relaxation) or 'scp' (sequential convex programming).
    """

    # Select options
    if(mode == 'scp'):
        options = p.options['SCP_SOL']
    else:
        options = p.options['REL_SOL']
    quiet = p.options['quiet']

    # Printing format for cvxopt sparse matrices
    opt.spmatrix_str = opt.printing.spmatrix_str_triplet 	
    
    # Partial minimization expansion
    constr_list = pm_expand(p.constr)
    
    # Get variables
    variables = constr_list.get_vars()

    # Count variables
    n = len(variables)

    # Create a map (var - pos)
    if(options['show steps'] and not quiet):
        print '\nCreating variable - index map'
    var_to_index = {}
    for i in range(0,n,1):
        if(options['show steps'] and not quiet):
            print variables[i],'<-->',i
        var_to_index[variables[i]] = i

    # Construct objective vector
    c = construct_c(p.obj,var_to_index,n,p.action)
    if(options['show steps'] and not quiet):
        print '\nConstructing c vector'
        print 'c = '
        print c

    # Construct Ax == b
    A,b = construct_Ab(constr_list._get_eq(),var_to_index,n,options)
    if(options['show steps'] and not quiet):
        print '\nConstructing Ax == b'
        print 'A ='
        print A
        print 'b ='
        print b

    # Construct  Gx <= h
    G,h,dim_l,dim_q,dim_s = construct_Gh(constr_list._get_ineq_in(),
                                         var_to_index,n)
    if(options['show steps'] and not quiet):
        print '\nConstructing Gx <= h'
        print 'G ='
        print G
        print 'h ='
        print h
    
    # Construct F
    F = construct_F(constr_list._get_ineq_in(),var_to_index,n)
    if(options['show steps'] and not quiet):
        print '\nConstructing F'

    # Call cvxopt
    solvers.options['show_progress'] = options['solver progress'] and not quiet
    solvers.options['maxiters'] = options['maxiters']
    solvers.options['abstol'] = options['abstol']
    solvers.options['reltol'] = options['reltol']
    solvers.options['feastol'] = options['feastol']
    dims = {'l':dim_l, 'q':dim_q, 's':dim_s}
    if(F is None):
        if(options['show steps'] and not quiet):
            print '\nCalling cvxopt conelp solver'
        r =  solvers.conelp(c,G,h,dims,A,b)
    else:
        if(options['show steps'] and not quiet):
            print '\nCalling cvxopt cpl solver'
        r =  solvers.cpl(c,F,G,h,dims,A,b)

    # Store numerical values
    if(r['status'] != 'primal infeasible'):
        if(options['show steps'] and not quiet):
            print '\nStoring numerical values:'
        for v in variables:
            value = r['x'][var_to_index[v]]
            v.data =  value
            if(options['show steps']and not quiet):
                print v,' <- ', v.data

    # Return result
    return r
コード例 #24
0
ファイル: ubsdp.py プロジェクト: a85531506/research_project
def ubsdp(c, A, B, pstart = None, dstart = None):
    """

        minimize  c'*x  + tr(X) 
        s.t.      sum_{i=1}^n xi * Ai - X <= B 
                  X >= 0

        maximize  -tr(B * Z0)
        s.t.      tr(Ai * Z0) + ci = 0,  i = 1, ..., n
                  -Z0 - Z1 + I = 0
                  Z0 >= 0,  Z1 >= 0.

    c is an n-vector.

    A is an m^2 x n-matrix.

    B is an m x m-matrix.
    """

    msq, n = A.size
    m = int(math.sqrt(msq))
    mpckd = int(m * (m+1) / 2)
    dims = {'l': 0, 'q': [], 's': [m, m]}

    # The primal variable is stored as a tuple (x, X).
    cc = (c, matrix(0.0, (m, m)))
    cc[1][::m+1] = 1.0

        
    def xnewcopy(u):

        return (+u[0], +u[1])


    def xdot(u, v):

        return blas.dot(u[0], v[0]) + misc.sdot2(u[1], v[1])


    def xscal(alpha, u):

        blas.scal(alpha, u[0]) 
        blas.scal(alpha, u[1]) 


    def xaxpy(u, v, alpha = 1.0):

        blas.axpy(u[0], v[0], alpha)
        blas.axpy(u[1], v[1], alpha)

    
    def G(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
        """
        If trans is 'N':

            v[:msq] := alpha * (A*u[0] - u[1][:]) + beta * v[:msq]
            v[msq:] := -alpha * u[1][:] + beta * v[msq:].


        If trans is 'T':

            v[0] := alpha *  A' * u[:msq] + beta * v[0]
            v[1][:] := alpha * (-u[:msq] - u[msq:]) + beta * v[1][:].

        """
 
        if trans == 'N': 

            blas.gemv(A, u[0], v, alpha = alpha, beta = beta) 
            blas.axpy(u[1], v, alpha = -alpha)
            blas.scal(beta, v, offset = msq)
            blas.axpy(u[1], v, alpha = -alpha, offsety = msq)
            
        else:

            misc.sgemv(A, u, v[0], dims = {'l': 0, 'q': [], 's': [m]},
                alpha = alpha, beta = beta, trans = 'T')   
            blas.scal(beta, v[1])
            blas.axpy(u, v[1], alpha = -alpha, n = msq)
            blas.axpy(u, v[1], alpha = -alpha, n = msq, offsetx = msq)


    h = matrix(0.0, (2*msq, 1))
    blas.copy(B, h)
    
    L = matrix(0.0, (m, m))
    U = matrix(0.0, (m, m))
    Us = matrix(0.0, (m, m))
    Uti = matrix(0.0, (m, m))
    s = matrix(0.0, (m, 1))
    Asc = matrix(0.0, (msq, n))
    S = matrix(0.0, (m, m))
    tmp = matrix(0.0, (m, m))
    x1 = matrix(0.0, (m**2, 1))
    H = matrix(0.0, (n, n))

    def F(W):
        """
        Generate a solver for

                                             A'(uz0) = bx[0]
                                          -uz0 - uz1 = bx[1] 
            A(ux[0]) - ux[1] - r0*r0' * uz0 * r0*r0' = bz0 
                     - ux[1] - r1*r1' * uz1 * r1*r1' = bz1.

        uz0, uz1, bz0, bz1 are symmetric m x m-matrices.
        ux[0], bx[0] are n-vectors.
        ux[1], bx[1] are symmetric m x m-matrices.

        We first calculate a congruence that diagonalizes r0*r0' and r1*r1':
 
            U' * r0 * r0' * U = I,  U' * r1 * r1' * U = S.

        We then make a change of variables

            usx[0] = ux[0],  
            usx[1] = U' * ux[1] * U  
              usz0 = U^-1 * uz0 * U^-T  
              usz1 = U^-1 * uz1 * U^-T 

        and define 

              As() = U' * A() * U'  
            bsx[1] = U^-1 * bx[1] * U^-T
              bsz0 = U' * bz0 * U  
              bsz1 = U' * bz1 * U.  

        This gives

                             As'(usz0) = bx[0]
                          -usz0 - usz1 = bsx[1] 
            As(usx[0]) - usx[1] - usz0 = bsz0 
                -usx[1] - S * usz1 * S = bsz1.


        1. Eliminate usz0, usz1 using equations 3 and 4,

               usz0 = As(usx[0]) - usx[1] - bsz0
               usz1 = -S^-1 * (usx[1] + bsz1) * S^-1.

           This gives two equations in usx[0] an usx[1].

               As'(As(usx[0]) - usx[1]) = bx[0] + As'(bsz0)

               -As(usx[0]) + usx[1] + S^-1 * usx[1] * S^-1
                   = bsx[1] - bsz0 - S^-1 * bsz1 * S^-1.


        2. Eliminate usx[1] using equation 2:

               usx[1] + S * usx[1] * S 
                   = S * ( As(usx[0]) + bsx[1] - bsz0 ) * S - bsz1

           i.e., with Gamma[i,j] = 1.0 + S[i,i] * S[j,j],
 
               usx[1] = ( S * As(usx[0]) * S ) ./ Gamma 
                        + ( S * ( bsx[1] - bsz0 ) * S - bsz1 ) ./ Gamma.

           This gives an equation in usx[0].

               As'( As(usx[0]) ./ Gamma ) 
                   = bx0 + As'(bsz0) + 
                     As'( (S * ( bsx[1] - bsz0 ) * S - bsz1) ./ Gamma )
                   = bx0 + As'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ Gamma ).

        """

        # Calculate U s.t. 
        # 
        #     U' * r0*r0' * U = I,   U' * r1*r1' * U = diag(s).
 
        # Cholesky factorization r0 * r0' = L * L'
        blas.syrk(W['r'][0], L)
        lapack.potrf(L)

        # SVD L^-1 * r1 = U * diag(s) * V'  
        blas.copy(W['r'][1], U)
        blas.trsm(L, U) 
        lapack.gesvd(U, s, jobu = 'O')

        # s := s**2
        s[:] = s**2

        # Uti := U
        blas.copy(U, Uti)

        # U := L^-T * U
        blas.trsm(L, U, transA = 'T')

        # Uti := L * Uti = U^-T 
        blas.trmm(L, Uti)

        # Us := U * diag(s)^-1
        blas.copy(U, Us)
        for i in range(m):
            blas.tbsv(s, Us, n = m, k = 0, ldA = 1, incx = m, offsetx = i)

        # S is m x m with lower triangular entries s[i] * s[j] 
        # sqrtG is m x m with lower triangular entries sqrt(1.0 + s[i]*s[j])
        # Upper triangular entries are undefined but nonzero.

        blas.scal(0.0, S)
        blas.syrk(s, S)
        Gamma = 1.0 + S
        sqrtG = sqrt(Gamma)


        # Asc[i] = (U' * Ai * * U ) ./  sqrtG,  for i = 1, ..., n
        #        = Asi ./ sqrt(Gamma)
        blas.copy(A, Asc)
        misc.scale(Asc,   # only 'r' part of the dictionary is used   
            {'dnl': matrix(0.0, (0, 1)), 'dnli': matrix(0.0, (0, 1)),
             'd': matrix(0.0, (0, 1)), 'di': matrix(0.0, (0, 1)),
             'v': [], 'beta': [], 'r': [ U ], 'rti': [ U ]}) 
        for i in range(n):
            blas.tbsv(sqrtG, Asc, n = msq, k = 0, ldA = 1, offsetx = i*msq)

        # Convert columns of Asc to packed storage
        misc.pack2(Asc, {'l': 0, 'q': [], 's': [ m ]})

        # Cholesky factorization of Asc' * Asc.
        H = matrix(0.0, (n, n))
        blas.syrk(Asc, H, trans = 'T', k = mpckd)
        lapack.potrf(H)


        def solve(x, y, z):
            """

            1. Solve for usx[0]:

               Asc'(Asc(usx[0]))
                   = bx0 + Asc'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ sqrtG)
                   = bx0 + Asc'( ( bsz0 + S * ( bsx[1] - bssz1) S ) 
                     ./ sqrtG)

               where bsx[1] = U^-1 * bx[1] * U^-T, bsz0 = U' * bz0 * U, 
               bsz1 = U' * bz1 * U, bssz1 = S^-1 * bsz1 * S^-1 

            2. Solve for usx[1]:

               usx[1] + S * usx[1] * S 
                   = S * ( As(usx[0]) + bsx[1] - bsz0 ) * S - bsz1 

               usx[1] 
                   = ( S * (As(usx[0]) + bsx[1] - bsz0) * S - bsz1) ./ Gamma
                   = -bsz0 + (S * As(usx[0]) * S) ./ Gamma
                     + (bsz0 - bsz1 + S * bsx[1] * S ) . / Gamma
                   = -bsz0 + (S * As(usx[0]) * S) ./ Gamma
                     + (bsz0 + S * ( bsx[1] - bssz1 ) * S ) . / Gamma

               Unscale ux[1] = Uti * usx[1] * Uti'

            3. Compute usz0, usz1

               r0' * uz0 * r0 = r0^-1 * ( A(ux[0]) - ux[1] - bz0 ) * r0^-T
               r1' * uz1 * r1 = r1^-1 * ( -ux[1] - bz1 ) * r1^-T

            """

            # z0 := U' * z0 * U 
            #     = bsz0
            __cngrnc(U, z, trans = 'T')

            # z1 := Us' * bz1 * Us 
            #     = S^-1 * U' * bz1 * U * S^-1
            #     = S^-1 * bsz1 * S^-1
            __cngrnc(Us, z, trans = 'T', offsetx = msq)

            # x[1] := Uti' * x[1] * Uti 
            #       = bsx[1]
            __cngrnc(Uti, x[1], trans = 'T')
        
            # x[1] := x[1] - z[msq:] 
            #       = bsx[1] - S^-1 * bsz1 * S^-1
            blas.axpy(z, x[1], alpha = -1.0, offsetx = msq)


            # x1 = (S * x[1] * S + z[:msq] ) ./ sqrtG
            #    = (S * ( bsx[1] - S^-1 * bsz1 * S^-1) * S + bsz0 ) ./ sqrtG
            #    = (S * bsx[1] * S - bsz1 + bsz0 ) ./ sqrtG
            # in packed storage
            blas.copy(x[1], x1)
            blas.tbmv(S, x1, n = msq, k = 0, ldA = 1)
            blas.axpy(z, x1, n = msq)
            blas.tbsv(sqrtG, x1, n = msq, k = 0, ldA = 1)
            misc.pack2(x1, {'l': 0, 'q': [], 's': [m]})

            # x[0] := x[0] + Asc'*x1 
            #       = bx0 + Asc'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ sqrtG)
            #       = bx0 + As'( ( bz0 - bz1 + S * bx[1] * S ) ./ Gamma )
            blas.gemv(Asc, x1, x[0], m = mpckd, trans = 'T', beta = 1.0)

            # x[0] := H^-1 * x[0]
            #       = ux[0]
            lapack.potrs(H, x[0])


            # x1 = Asc(x[0]) .* sqrtG  (unpacked)
            #    = As(x[0])  
            blas.gemv(Asc, x[0], tmp, m = mpckd)
            misc.unpack(tmp, x1, {'l': 0, 'q': [], 's': [m]})
            blas.tbmv(sqrtG, x1, n = msq, k = 0, ldA = 1)


            # usx[1] = (x1 + (x[1] - z[:msq])) ./ sqrtG**2 
            #        = (As(ux[0]) + bsx[1] - bsz0 - S^-1 * bsz1 * S^-1) 
            #           ./ Gamma

            # x[1] := x[1] - z[:msq] 
            #       = bsx[1] - bsz0 - S^-1 * bsz1 * S^-1
            blas.axpy(z, x[1], -1.0, n = msq)

            # x[1] := x[1] + x1
            #       = As(ux) + bsx[1] - bsz0 - S^-1 * bsz1 * S^-1 
            blas.axpy(x1, x[1])

            # x[1] := x[1] / Gammma
            #       = (As(ux) + bsx[1] - bsz0 + S^-1 * bsz1 * S^-1 ) / Gamma
            #       = S^-1 * usx[1] * S^-1
            blas.tbsv(Gamma, x[1], n = msq, k = 0, ldA = 1)
            

            # z[msq:] := r1' * U * (-z[msq:] - x[1]) * U * r1
            #         := -r1' * U * S^-1 * (bsz1 + ux[1]) * S^-1 *  U * r1
            #         := -r1' * uz1 * r1
            blas.axpy(x[1], z, n = msq, offsety = msq)
            blas.scal(-1.0, z, offset = msq)
            __cngrnc(U, z, offsetx = msq)
            __cngrnc(W['r'][1], z, trans = 'T', offsetx = msq)

            # x[1] :=  S * x[1] * S
            #       =  usx1 
            blas.tbmv(S, x[1], n = msq, k = 0, ldA = 1)

            # z[:msq] = r0' * U' * ( x1 - x[1] - z[:msq] ) * U * r0
            #         = r0' * U' * ( As(ux) - usx1 - bsz0 ) * U * r0
            #         = r0' * U' *  usz0 * U * r0
            #         = r0' * uz0 * r0
            blas.axpy(x1, z, -1.0, n = msq)
            blas.scal(-1.0, z, n = msq)
            blas.axpy(x[1], z, -1.0, n = msq)
            __cngrnc(U, z)
            __cngrnc(W['r'][0], z, trans = 'T')

            # x[1] := Uti * x[1] * Uti'
            #       = ux[1]
            __cngrnc(Uti, x[1])


        return solve
    
    solvers.options['show_progress'] = 0
    sol = solvers.conelp(cc, G, h, dims = {'l': 0, 's': [m, m], 'q': []},
        kktsolver = F, xnewcopy = xnewcopy, xdot = xdot, xaxpy = xaxpy, 
        xscal = xscal, primalstart = pstart, dualstart = dstart) 

    return matrix(sol['x'][1], (n,n))
コード例 #25
0
ファイル: testCVXQP.py プロジェクト: edwintye/pygotools
c = matrix([-2., 1., 5.])
G = [ matrix( [[12., 13., 12.], [6., -3., -12.], [-5., -5., 6.]] ) ]
G += [ matrix( [[3., 3., -1., 1.], [-6., -6., -9., 19.], [10., -2., -2., -3.]] ) ]
h = [ matrix( [-12., -3., -2.] ),  matrix( [27., 0., 3., -42.] ) ]
sol = solvers.socp(c, Gq = G, hq = h)
sol['status']


c = matrix([-2., 1., 5.])
G = matrix( [[12., 13., 12., 3., 3., -1., 1.],
             [6., -3., -12., -6., -6., -9., 19.],
             [-5., -5., 6., 10., -2., -2., -3.]])
h = matrix( [-12., -3., -2., 27., 0., 3., -42.] )
dims = {'l': 0, 'q': [3,4], 's': []}
sol2 = solvers.conelp(c, G, h, dims)



## least sqaures problem, as a QP

A = matrix([ [ .3, -.4,  -.2,  -.4,  1.3 ],
                 [ .6, 1.2, -1.7,   .3,  -.3 ],
                 [-.3,  .0,   .6, -1.2, -2.0 ] ])
b = matrix([ 1.5, .0, -1.2, -.7, .0])
m, n = A.size
I = matrix(0.0, (n,n))
I[::n+1] = 1.0
G = matrix([-I, matrix(0.0, (1,n)), I])
h = matrix(n*[0.0] + [1.0] + n*[0.0])
dimsQP = {'l': n, 'q': [n+1], 's': []}
コード例 #26
0
ファイル: qpUpdate.py プロジェクト: edwintye/pygotools
def _updateTrustRegionSOCP(x, fx, oldFx, oldDeltaX, p, radius, g, oldGrad, H, func, grad, z, G, h, y, A, b):

    if A is not None:
        bTemp = b - A.dot(x)
    else:
        bTemp = None

    GTemp = numpy.append(numpy.zeros((1,p)), numpy.eye(p), axis=0)
    hTemp = numpy.zeros(p+1)
    hTemp[0] += radius

    if G is not None:
        GTemp = numpy.append(G, GTemp, axis=0)
        hTemp = numpy.append(h - G.dot(x), hTemp)
        dims1 = {'l': G.shape[0], 'q': [p+1,p+1], 's': []}
    else:
        dims1 = {'l': 0, 'q': [p+1,p+1], 's': []}

    # now we have finished the setup process, we reformulate
    # the problem as a SOCP

    m,n = GTemp.shape
    c = matrix([1.0] + [0.0]*n)

    hTemp1 = matrix([0.0]+(-g.flatten()).tolist())
    GTemp1 = matrix(numpy.array(scipy.sparse.bmat([
        [[-1.0],None],
        [None,H]
    ]).todense()))

    GTemp1 = matrix(numpy.append(numpy.append(numpy.array([0]*m).reshape(m,1),numpy.array(GTemp),axis=1),
                                 numpy.array(GTemp1),
                                 axis=0))

    hTemp1 = matrix(numpy.append(hTemp,hTemp1))
    if A is not None:
        out = solvers.conelp(c, GTemp1, hTemp1, dims1, matrix(A), matrix(bTemp))
    else:
        out = solvers.conelp(c, GTemp1, hTemp1, dims1)

    # exact the descent diretion and do a line search
    deltaX = numpy.array(out['x'][1::])

    M = _diffM(g.flatten(), H)
    
    newFx = func(x + deltaX)
    predRatio = (fx - newFx) / M(deltaX)
        
    if predRatio>=0.75:
        radius = min(2.0*radius, maxRadius)
    elif predRatio<=0.25:
        radius *= 0.25

    if predRatio>=0.25:
        oldGrad = g.copy()
        x += deltaX
        oldFx = fx
        fx = newFx
        update = True
    else:
        update = False

    if G is not None:
        # only want the information for the inequalities
        # and not the two cones - trust region, objective functionn
        z[:] = numpy.array(out['z'])[G.shape[0]]
    if A is not None:
        y[:] = numpy.array(out['y'])

    # print numpy.append(numpy.array(out['s']),numpy.array(s),axis=1)

    return x, update, radius, deltaX, z, y, fx, oldFx, oldGrad, out['iterations']
コード例 #27
0
ファイル: l1.py プロジェクト: cuihantao/cvxopt
def l1blas (P, q):

    """
    Returns the solution u of the ell-1 approximation problem

        (primal) minimize ||P*u - q||_1       
    
        (dual)   maximize    q'*w
                 subject to  P'*w = 0
                             ||w||_infty <= 1.
    """

    m, n = P.size

    # Solve equivalent LP 
    #
    #     minimize    [0; 1]' * [u; v]
    #     subject to  [P, -I; -P, -I] * [u; v] <= [q; -q]
    #
    #     maximize    -[q; -q]' * z 
    #     subject to  [P', -P']*z  = 0
    #                 [-I, -I]*z + 1 = 0 
    #                 z >= 0 
    
    c = matrix(n*[0.0] + m*[1.0])
    h = matrix([q, -q])

    u = matrix(0.0, (m,1)) 
    Ps = matrix(0.0, (m,n))
    A = matrix(0.0, (n,n))

    def Fi(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):    
        if trans == 'N':
            # y := alpha * [P, -I; -P, -I] * x + beta*y
            blas.gemv(P, x, u) 
            y[:m] = alpha * ( u - x[n:]) + beta*y[:m]
            y[m:] = alpha * (-u - x[n:]) + beta*y[m:]

        else:
            # y := alpha * [P', -P'; -I, -I] * x + beta*y
            blas.copy(x[:m] - x[m:], u)
            blas.gemv(P, u, y, alpha = alpha, beta = beta, trans = 'T')
            y[n:] = -alpha * (x[:m] + x[m:]) + beta*y[n:]


    def Fkkt(W): 

        # Returns a function f(x, y, z) that solves
        #
        # [ 0  0  P'      -P'      ] [ x[:n] ]   [ bx[:n] ]
        # [ 0  0 -I       -I       ] [ x[n:] ]   [ bx[n:] ]
        # [ P -I -D1^{-1}  0       ] [ z[:m] ] = [ bz[:m] ]
        # [-P -I  0       -D2^{-1} ] [ z[m:] ]   [ bz[m:] ]
        #
        # where D1 = diag(di[:m])^2, D2 = diag(di[m:])^2 and di = W['di'].
        #
        # On entry bx, bz are stored in x, z.
        # On exit x, z contain the solution, with z scaled (di .* z is
        # returned instead of z). 

        # Factor A = 4*P'*D*P where D = d1.*d2 ./(d1+d2) and
        # d1 = d[:m].^2, d2 = d[m:].^2.

        di = W['di']
        d1, d2 = di[:m]**2, di[m:]**2
        D = div( mul(d1,d2), d1+d2 )  
        Ds = spdiag(2 * sqrt(D))
        base.gemm(Ds, P, Ps)
        blas.syrk(Ps, A, trans = 'T')
        lapack.potrf(A)

        def f(x, y, z):

            # Solve for x[:n]:
            #
            #    A*x[:n] = bx[:n] + P' * ( ((D1-D2)*(D1+D2)^{-1})*bx[n:]
            #        + (2*D1*D2*(D1+D2)^{-1}) * (bz[:m] - bz[m:]) ).

            blas.copy(( mul( div(d1-d2, d1+d2), x[n:]) + 
                mul( 2*D, z[:m]-z[m:] ) ), u)
            blas.gemv(P, u, x, beta = 1.0, trans = 'T')
            lapack.potrs(A, x)

            # x[n:] := (D1+D2)^{-1} * (bx[n:] - D1*bz[:m] - D2*bz[m:]
            #     + (D1-D2)*P*x[:n])

            base.gemv(P, x, u)
            x[n:] =  div( x[n:] - mul(d1, z[:m]) - mul(d2, z[m:]) + 
                mul(d1-d2, u), d1+d2 )

            # z[:m] := d1[:m] .* ( P*x[:n] - x[n:] - bz[:m])
            # z[m:] := d2[m:] .* (-P*x[:n] - x[n:] - bz[m:]) 

            z[:m] = mul(di[:m],  u-x[n:]-z[:m])
            z[m:] = mul(di[m:], -u-x[n:]-z[m:])

        return f


    # Initial primal and dual points from least-squares solution.

    # uls minimizes ||P*u-q||_2; rls is the LS residual.
    uls =  +q
    lapack.gels(+P, uls)
    rls = P*uls[:n] - q 

    # x0 = [ uls;  1.1*abs(rls) ];   s0 = [q;-q] - [P,-I; -P,-I] * x0
    x0 = matrix( [uls[:n],  1.1*abs(rls)] ) 
    s0 = +h
    Fi(x0, s0, alpha=-1, beta=1) 

    # z0 = [ (1+w)/2; (1-w)/2 ] where w = (.9/||rls||_inf) * rls  
    # if rls is nonzero and w = 0 otherwise.
    if max(abs(rls)) > 1e-10:  
        w = .9/max(abs(rls)) * rls
    else: 
        w = matrix(0.0, (m,1))
    z0 = matrix([.5*(1+w), .5*(1-w)])

    dims = {'l': 2*m, 'q': [], 's': []}
    sol = solvers.conelp(c, Fi, h, dims, kktsolver = Fkkt,  
        primalstart={'x': x0, 's': s0}, dualstart={'z': z0})
    return sol['x'][:n]
コード例 #28
0
ファイル: testconelp.py プロジェクト: hrautila/go.opt
def solve(opts):
    c = matrix([-6.0, -4.0, -5.0])

    G = matrix(
        [
            [16.0, 7.0, 24.0, -8.0, 8.0, -1.0, 0.0, -1.0, 0.0, 0.0, 7.0, -5.0, 1.0, -5.0, 1.0, -7.0, 1.0, -7.0, -4.0],
            [
                -14.0,
                2.0,
                7.0,
                -13.0,
                -18.0,
                3.0,
                0.0,
                0.0,
                -1.0,
                0.0,
                3.0,
                13.0,
                -6.0,
                13.0,
                12.0,
                -10.0,
                -6.0,
                -10.0,
                -28.0,
            ],
            [
                5.0,
                0.0,
                -15.0,
                12.0,
                -6.0,
                17.0,
                0.0,
                0.0,
                0.0,
                -1.0,
                9.0,
                6.0,
                -6.0,
                6.0,
                -7.0,
                -7.0,
                -6.0,
                -7.0,
                -11.0,
            ],
        ]
    )
    h = matrix(
        [
            -3.0,
            5.0,
            12.0,
            -2.0,
            -14.0,
            -13.0,
            10.0,
            0.0,
            0.0,
            0.0,
            68.0,
            -30.0,
            -19.0,
            -30.0,
            99.0,
            23.0,
            -19.0,
            23.0,
            10.0,
        ]
    )

    A = matrix(0.0, (0, c.size[0]))
    b = matrix(0.0, (0, 1))

    dims = {"l": 2, "q": [4, 4], "s": [3]}

    # localcones.options.update(opts)
    # sol = localcones.conelp(c, G, h, dims, kktsolver='qr')
    solvers.options.update(opts)
    sol = solvers.conelp(c, G, h, dims)
    print ("\nStatus: " + sol["status"])
    if sol["status"] == "optimal":
        print "x=\n", helpers.strSpe(sol["x"], "%.5f")
        print "s=\n", helpers.strSpe(sol["s"], "%.5f")
        print "z=\n", helpers.strSpe(sol["z"], "%.5f")
        rungotest(sol)
コード例 #29
0
ファイル: l1.py プロジェクト: Ovec8hkin/PySAR
def l1(P, q):
    """
    Returns the solution u of the ell-1 approximation problem

        (primal) minimize ||P*u - q||_1       
    
        (dual)   maximize    q'*w
                 subject to  P'*w = 0
                             ||w||_infty <= 1.
    """

    m, n = P.size

    # Solve equivalent LP
    #
    #     minimize    [0; 1]' * [u; v]
    #     subject to  [P, -I; -P, -I] * [u; v] <= [q; -q]
    #
    #     maximize    -[q; -q]' * z
    #     subject to  [P', -P']*z  = 0
    #                 [-I, -I]*z + 1 = 0
    #                 z >= 0

    c = matrix(n * [0.0] + m * [1.0])
    h = matrix([q, -q])

    def Fi(x, y, alpha=1.0, beta=0.0, trans='N'):
        if trans == 'N':
            # y := alpha * [P, -I; -P, -I] * x + beta*y
            u = P * x[:n]
            y[:m] = alpha * (u - x[n:]) + beta * y[:m]
            y[m:] = alpha * (-u - x[n:]) + beta * y[m:]

        else:
            # y := alpha * [P', -P'; -I, -I] * x + beta*y
            y[:n] = alpha * P.T * (x[:m] - x[m:]) + beta * y[:n]
            y[n:] = -alpha * (x[:m] + x[m:]) + beta * y[n:]

    def Fkkt(W):

        # Returns a function f(x, y, z) that solves
        #
        # [ 0  0  P'      -P'      ] [ x[:n] ]   [ bx[:n] ]
        # [ 0  0 -I       -I       ] [ x[n:] ]   [ bx[n:] ]
        # [ P -I -W1^2     0       ] [ z[:m] ] = [ bz[:m] ]
        # [-P -I  0       -W2      ] [ z[m:] ]   [ bz[m:] ]
        #
        # On entry bx, bz are stored in x, z.
        # On exit x, z contain the solution, with z scaled (W['di'] .* z is
        # returned instead of z).

        d1, d2 = W['d'][:m], W['d'][m:]
        D = 4 * (d1**2 + d2**2)**-1
        A = P.T * spdiag(D) * P
        lapack.potrf(A)

        def f(x, y, z):

            x[:n] += P.T * (mul(div(d2**2 - d1**2, d1**2 + d2**2), x[n:]) +
                            mul(.5 * D, z[:m] - z[m:]))
            lapack.potrs(A, x)

            u = P * x[:n]
            x[n:] = div(
                x[n:] - div(z[:m], d1**2) - div(z[m:], d2**2) +
                mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2)

            z[:m] = div(u - x[n:] - z[:m], d1)
            z[m:] = div(-u - x[n:] - z[m:], d2)

        return f

    # Initial primal and dual points from least-squares solution.

    # uls minimizes ||P*u-q||_2; rls is the LS residual.
    uls = +q
    lapack.gels(+P, uls)
    rls = P * uls[:n] - q

    # x0 = [ uls;  1.1*abs(rls) ];   s0 = [q;-q] - [P,-I; -P,-I] * x0
    x0 = matrix([uls[:n], 1.1 * abs(rls)])
    s0 = +h
    Fi(x0, s0, alpha=-1, beta=1)

    # z0 = [ (1+w)/2; (1-w)/2 ] where w = (.9/||rls||_inf) * rls
    # if rls is nonzero and w = 0 otherwise.
    if max(abs(rls)) > 1e-10:
        w = .9 / max(abs(rls)) * rls
    else:
        w = matrix(0.0, (m, 1))
    z0 = matrix([.5 * (1 + w), .5 * (1 - w)])

    dims = {'l': 2 * m, 'q': [], 's': []}
    sol = solvers.conelp(c,
                         Fi,
                         h,
                         dims,
                         kktsolver=Fkkt,
                         primalstart={
                             'x': x0,
                             's': s0
                         },
                         dualstart={'z': z0})
    return sol['x'][:n]
コード例 #30
0
ファイル: testmcsdp.py プロジェクト: hrautila/go.opt
def mcsdp(w):
    """
    Returns solution x, z to 

        (primal)  minimize    sum(x)
                  subject to  w + diag(x) >= 0

        (dual)    maximize    -tr(w*z)
                  subject to  diag(z) = 1
                              z >= 0.
    """

    n = w.size[0]

    def Fs(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):
        """
            y := alpha*(-diag(x)) + beta*y.   
        """
        if trans=='N':
            # x is a vector; y is a matrix.
            blas.scal(beta, y)
            blas.axpy(x, y, alpha = -alpha, incy = n+1)
        else:   
            # x is a matrix; y is a vector.
            blas.scal(beta, y)
            blas.axpy(x, y, alpha = -alpha, incx = n+1)
	 

    def cngrnc(r, x, alpha = 1.0):
        """
        Congruence transformation

            x := alpha * r'*x*r.

        r and x are square matrices.  
        """

        # Scale diagonal of x by 1/2.  
        x[::n+1] *= 0.5 
    
        # a := tril(x)*r 
        a = +r
        tx = matrix(x, (n,n))
        blas.trmm(tx, a, side='L')

        # x := alpha*(a*r' + r*a') 
        blas.syr2k(r, a, tx, trans = 'T', alpha = alpha)

        x[:] = tx[:]
       

    def Fkkt(W):
       
        rti = W['rti'][0]

        # t = rti*rti' as a nonsymmetric matrix.
        t = matrix(0.0, (n,n))
        blas.gemm(rti, rti, t, transB = 'T') 

        # Cholesky factorization of tsq = t.*t.
        tsq = t**2
        lapack.potrf(tsq)
        
        def f(x, y, z):
            """
            Solve
                          -diag(z)                           = bx
                -diag(x) - inv(rti*rti') * z * inv(rti*rti') = bs

            On entry, x and z contain bx and bs.  
            On exit, they contain the solution, with z scaled
            (inv(rti)'*z*inv(rti) is returned instead of z).

            We first solve 

                ((rti*rti') .* (rti*rti')) * x = bx - diag(t*bs*t) 

            and take z  = -rti' * (diag(x) + bs) * rti.
            """
            # tbst := t * zs * t = t * bs * t
            tbst = matrix(z, (n,n))
            cngrnc(t, tbst) 

            # x := x - diag(tbst) = bx - diag(rti*rti' * bs * rti*rti')
            x -= tbst[::n+1]

            # x := (t.*t)^{-1} * x = (t.*t)^{-1} * (bx - diag(t*bs*t))
            lapack.potrs(tsq, x)

            # z := z + diag(x) = bs + diag(x)
            z[::n+1] += x

            # z := -rti' * z * rti = -rti' * (diag(x) + bs) * rti 
            cngrnc(rti, z, alpha = -1.0)

        return f

    c = matrix(1.0, (n,1))

    # Initial feasible x:  x = 1.0 - min(lambda(w)).
    lmbda = matrix(0.0, (n,1))
    lapack.syevx(+w, lmbda, range='I', il=1, iu=1)

    x0 = matrix(-lmbda[0]+1.0, (n,1)) 
    s0 = +w
    s0[::n+1] += x0
    # Initial feasible z is identity.
    z0 = matrix(0.0, (n,n))
    z0[::n+1] = 1.0

    dims = {'l': 0, 'q': [], 's': [n]}
    sol = solvers.conelp(c, Fs, w[:], dims, kktsolver = Fkkt,
        primalstart = {'x': x0, 's': s0[:]}, dualstart = {'z': z0[:]})
    return sol['x'], matrix(sol['z'], (n,n))
コード例 #31
0
def solve_convex(p, mode):
    """
    Description
    -----------
    Solves the convex program p. It assumes p is the convex part 
    of an expanded and transformed program.

    Arguments
    ---------
    p: convex cvxpy_program.    
    mode: 'rel' (relaxation) or 'scp' (sequential convex programming).
    """

    # Select options
    if (mode == 'scp'):
        options = p.options['SCP_SOL']
    else:
        options = p.options['REL_SOL']
    quiet = p.options['quiet']

    # Printing format for cvxopt sparse matrices
    opt.spmatrix_str = opt.printing.spmatrix_str_triplet

    # Partial minimization expansion
    constr_list = pm_expand(p.constr)

    # Get variables
    variables = constr_list.get_vars()

    # Count variables
    n = len(variables)

    # Create a map (var - pos)
    if (options['show steps'] and not quiet):
        print '\nCreating variable - index map'
    var_to_index = {}
    for i in range(0, n, 1):
        if (options['show steps'] and not quiet):
            print variables[i], '<-->', i
        var_to_index[variables[i]] = i

    # Construct objective vector
    c = construct_c(p.obj, var_to_index, n, p.action)
    if (options['show steps'] and not quiet):
        print '\nConstructing c vector'
        print 'c = '
        print c

    # Construct Ax == b
    A, b = construct_Ab(constr_list._get_eq(), var_to_index, n, options)
    if (options['show steps'] and not quiet):
        print '\nConstructing Ax == b'
        print 'A ='
        print A
        print 'b ='
        print b

    # Construct  Gx <= h
    G, h, dim_l, dim_q, dim_s = construct_Gh(constr_list._get_ineq_in(),
                                             var_to_index, n)
    if (options['show steps'] and not quiet):
        print '\nConstructing Gx <= h'
        print 'G ='
        print G
        print 'h ='
        print h

    # Construct F
    F = construct_F(constr_list._get_ineq_in(), var_to_index, n)
    if (options['show steps'] and not quiet):
        print '\nConstructing F'

    # Call cvxopt
    solvers.options['show_progress'] = options['solver progress'] and not quiet
    solvers.options['maxiters'] = options['maxiters']
    solvers.options['abstol'] = options['abstol']
    solvers.options['reltol'] = options['reltol']
    solvers.options['feastol'] = options['feastol']
    dims = {'l': dim_l, 'q': dim_q, 's': dim_s}
    if (F is None):
        if (options['show steps'] and not quiet):
            print '\nCalling cvxopt conelp solver'
        r = solvers.conelp(c, G, h, dims, A, b)
    else:
        if (options['show steps'] and not quiet):
            print '\nCalling cvxopt cpl solver'
        r = solvers.cpl(c, F, G, h, dims, A, b)

    # Store numerical values
    if (r['status'] != 'primal infeasible'):
        if (options['show steps'] and not quiet):
            print '\nStoring numerical values:'
        for v in variables:
            value = r['x'][var_to_index[v]]
            v.data = value
            if (options['show steps'] and not quiet):
                print v, ' <- ', v.data

    # Return result
    return r
コード例 #32
0
ファイル: conversion.py プロジェクト: xinist/chompack
A = sp_rand(n,n,0.015) + spmatrix(1.0,range(n),range(n))
I = cp.tril(A)[:].I
N = len(I)/50 # each data matrix has 1/50 of total nonzeros in pattern
Ig = []; Jg = []
for j in range(m):
    Ig += sorted(random.sample(I,N))   
    Jg += N*[j]
G = spmatrix(normal(len(Ig),1),Ig,Jg,(n**2,m))
h = G*normal(m,1) + spmatrix(1.0,range(n),range(n))[:]
c = normal(m,1)
dims =  {'l':0, 'q':[], 's': [n]};

# solve SDP with CVXOPT 
print("Solving SDP with CVXOPT..")
prob = (c, G, matrix(h), dims)
sol = solvers.conelp(*prob)
Z1 = matrix(sol['z'], (n,n))

# convert SDP and solve
prob2, blocks_to_sparse, symbs = cp.convert_conelp(*prob)
print("Solving converted SDP (no merging)..")
sol2 = solvers.conelp(*prob2) 

# convert block-diagonal solution to spmatrix
blki,I,J,bn = blocks_to_sparse[0]
Z2 = spmatrix(sol2['z'][blki],I,J)

# compute completion
symb = cp.symbolic(Z2, p=cp.maxcardsearch)
Z2c = cp.psdcompletion(cp.cspmatrix(symb)+Z2, reordered=False)
コード例 #33
0
ファイル: new_cegal.py プロジェクト: zwc662/CAV2018
    def MOQP(self, expert, features, K, epsilon = None):
        if epsilon is None:
            epsilon = self.M.epsilon

	cexs = features['cexs']
	
	cands = features['cands']

	safes = features['safes']
	
	if True:
		#G_i_j=[[], [], [], []]
		G_i_j_k = []
		for e in range(len(expert) + 2):
			G_i_j_k.append([])
		h_i_j_k = []
		c = matrix(- ((K) * np.eye(len(expert) + 2)[-2] + (1 - K) * np.eye(len(expert) + 2)[-1]))

		for m in range(len(cands)):
			for e in range(len(expert)):
				G_i_j_k[e].append(K * (- expert[e] + cands[m][e]))
			G_i_j_k[len(expert)].append(1)
			G_i_j_k[len(expert) + 1].append(0)
			h_i_j_k.append(0)
					#G_i_j[0].append(- (expert[0] - cands[m][0]))
					#G_i_j[1].append(- (expert[1] - cands[m][1]))
					#G_i_j[2].append(- (expert[2] - cands[m][2]))
					#G_i_j[3].append(- (expert[3] - cands[m][3]))
		for j in range(len(cexs)):
			for k in range(len(safes)):
				for e in range(len(expert)):
					G_i_j_k[e].append((1.0 - K) * (- safes[k][e] + cexs[j][e]))
				G_i_j_k[len(expert)].append(0)
				G_i_j_k[len(expert) + 1].append(1)
				h_i_j_k.append(0)
						#G_i_j[0].append(cands[k][0] - mu_Bs[j][0] - (cands[l][0] - mu_Bs[n][0]))
						#G_i_j[1].append(cands[k][1] - mu_Bs[j][1] - (cands[l][1] - mu_Bs[n][1]))
						#G_i_j[2].append(cands[k][2] - mu_Bs[j][2] - (cands[l][2] - mu_Bs[n][2]))
						#G_i_j[3].append(cands[k][3] - mu_Bs[j][3] - (cands[l][3] - mu_Bs[n][3]))
						#h_i_j.append(0)
				
		for e in range(len(expert)):
			G_i_j_k[e] = G_i_j_k[e] + [0.0] * (e + 1) + [-1.0] + [0.0] * (len(expert) + 2 - e - 1)
		G_i_j_k[len(expert)] = G_i_j_k[len(expert)] + [0.0] * (len(expert) + 3)
		G_i_j_k[len(expert) + 1] = G_i_j_k[len(expert) + 1] + [0.0] * (len(expert) + 3)
		h_i_j_k = h_i_j_k + [10] + (2 + len(expert)) * [0.0]
				#G_i_j[0]= G_i_j[0] + [0., -1., 0., 0., 0.]
				#G_i_j[1]= G_i_j[1] + [0., 0., -1., 0., 0.]
				#G_i_j[2]= G_i_j[2] + [0., 0., 0., -1., 0.]
				#G_i_j[3]= G_i_j[3] + [0., 0., 0., 0., -1.]
				#h_i_j = h_i_j + [1., 0., 0., 0., 0.]
		G = matrix(G_i_j_k)
		h = matrix(h_i_j_k)
				#G = matrix(G_i_j)
			#	h = matrix([-1 * penalty, 1., 0., 0., 0.])
				#h = matrix(h_i_j)
		dims = {'l':  len(cands) + len(cexs) * len(safes), 'q': [2 + len(expert), 1], 's': []}
		sol = solvers.conelp(c, G, h, dims)
		sol['status']
		solution = np.array(sol['x'])
		if solution is not None:
			solution=solution.reshape(len(expert) + 2)
			t=(1 - K) * solution[-1] + K * solution[-2]
			w=solution[:-2]
		else:
			solution = None
			t = None
			w = None
	return w, t
コード例 #34
0
ファイル: enzpl.py プロジェクト: jacopoantonello/enzpy
    def solve_linmap(self, bi, lmbd, linmap, show_progress=True):
        solvers.options['show_progress'] = show_progress

        # save all problem data
        self.bi, self.lmbd = bi, lmbd
        # count alive in map
        Nm2 = int(sum(linmap))
        self.Nm2 = Nm2
        self.linmap = linmap
        n_x1 = self.Nb*(self.Nb + 1)//2
        n_x2 = self.Nb*(self.Nb - 1)//2
        n_x = 1 + Nm2 + n_x1 + n_x2

        c = matrix(0.0, (1 + Nm2 + n_x1 + n_x2, 1))
        c[0] = 1.0
        c[1 + Nm2:1 + Nm2 + self.Nb] = lmbd

        G = matrix(0.0, (1 + Nm2 + (2*self.Nb)**2, n_x))
        G[:1 + Nm2, :1 + Nm2] = -eye(1 + Nm2)
        G[1 + Nm2:, 1 + Nm2:] = self.G[1 + self.Nm:, 1 + self.Nm:]

        h = matrix(0.0, (1 + Nm2 + (2*self.Nb)**2, 1))

        A = matrix(0.0, (Nm2, n_x))
        lbi = matrix(0.0, (Nm2, 1))
        A[:, 1:1 + Nm2] = eye(Nm2)
        pos = 0
        for i in range(self.Nm):
            if linmap[i] != 0.0:
                A[pos, 1 + Nm2:] = self.A[i, 1 + self.Nm:]
                lbi[pos] = bi[i]
                h[1 + pos] = -bi[i]
                pos += 1
        assert(pos == Nm2)

        b = matrix(0.0, (Nm2, 1))

        dims = {'l': 0, 'q': [1 + Nm2], 's': [2*self.Nb]}

        t1 = time()
        self.sol = solvers.conelp(c, G, h, dims, A, b)
        t2 = time()

        self.lc = c
        self.lG = G
        self.lh = h
        self.ldims = dims
        self.lA = A
        self.lb = b
        self.lNm = Nm2
        self.lbi = lbi

        t3 = time()
        if self.sol['status'] in ('optimal', 'unknown'):
            S = self.sol['s'][1 + Nm2:]
            self.sA[:] = S[self.I11] + 1j*S[self.I21]
            lapack.heevr(
                self.sA, self.sW, jobz='V', range='I', uplo='L',
                vl=0.0, vu=0.0, il=self.Nb, iu=self.Nb, Z=self.sZ)
            self.beta_hat[:] = math.sqrt(self.sW[0])*self.sZ[:, 0]
        else:
            raise RuntimeError('numerical problems')
        t4 = time()

        self.solver_time = t2 - t1
        self.eig_time = t4 - t3
コード例 #35
0
    def solve_linmap(self, bi, lmbd, linmap, show_progress=True):
        solvers.options['show_progress'] = show_progress

        # save all problem data
        self.bi, self.lmbd = bi, lmbd
        # count alive in map
        Nm2 = int(sum(linmap))
        self.Nm2 = Nm2
        self.linmap = linmap
        n_x1 = self.Nb * (self.Nb + 1) // 2
        n_x2 = self.Nb * (self.Nb - 1) // 2
        n_x = 1 + Nm2 + n_x1 + n_x2

        c = matrix(0.0, (1 + Nm2 + n_x1 + n_x2, 1))
        c[0] = 1.0
        c[1 + Nm2:1 + Nm2 + self.Nb] = lmbd

        G = matrix(0.0, (1 + Nm2 + (2 * self.Nb)**2, n_x))
        G[:1 + Nm2, :1 + Nm2] = -eye(1 + Nm2)
        G[1 + Nm2:, 1 + Nm2:] = self.G[1 + self.Nm:, 1 + self.Nm:]

        h = matrix(0.0, (1 + Nm2 + (2 * self.Nb)**2, 1))

        A = matrix(0.0, (Nm2, n_x))
        lbi = matrix(0.0, (Nm2, 1))
        A[:, 1:1 + Nm2] = eye(Nm2)
        pos = 0
        for i in range(self.Nm):
            if linmap[i] != 0.0:
                A[pos, 1 + Nm2:] = self.A[i, 1 + self.Nm:]
                lbi[pos] = bi[i]
                h[1 + pos] = -bi[i]
                pos += 1
        assert (pos == Nm2)

        b = matrix(0.0, (Nm2, 1))

        dims = {'l': 0, 'q': [1 + Nm2], 's': [2 * self.Nb]}

        t1 = time()
        self.sol = solvers.conelp(c, G, h, dims, A, b)
        t2 = time()

        self.lc = c
        self.lG = G
        self.lh = h
        self.ldims = dims
        self.lA = A
        self.lb = b
        self.lNm = Nm2
        self.lbi = lbi

        t3 = time()
        if self.sol['status'] in ('optimal', 'unknown'):
            S = self.sol['s'][1 + Nm2:]
            self.sA[:] = S[self.I11] + 1j * S[self.I21]
            lapack.heevr(self.sA,
                         self.sW,
                         jobz='V',
                         range='I',
                         uplo='L',
                         vl=0.0,
                         vu=0.0,
                         il=self.Nb,
                         iu=self.Nb,
                         Z=self.sZ)
            self.beta_hat[:] = math.sqrt(self.sW[0]) * self.sZ[:, 0]
        else:
            raise RuntimeError('numerical problems')
        t4 = time()

        self.solver_time = t2 - t1
        self.eig_time = t4 - t3
コード例 #36
0
ファイル: negSDP.py プロジェクト: TCBNutz/SDP
 def SDP():
         return solvers.conelp(c, G, h, dims)
コード例 #37
0
figure(2)
clf()
spy(matrix(Cun))
title('Sparsity of C')

figure(3)
clf()
spy(matrix(Aun[:, 10], Cun.size))
title('Sparsity of A_10')
print "(Close figure plots to continue)\n"
show()

#Solve unconverted problem using CVXOPT
print "Solve unconverted problem using CVXOPT"
solvers.options['show_progress'] = True
usol = solvers.conelp(-matrix(bun), Aun, matrix(Cun[:]), dims=dims_un)
print "Primal objective: %f" % -usol['primal objective']
print '(Press any key to continue)\n'
raw_input()

#Converted problem
print "Converted problem"
Acon, bcon, Ccon, Lcon, dims_con = convert(Aun,
                                           bun,
                                           Cun,
                                           Spun,
                                           dims_un,
                                           Atype=matrix)

#Plot sparsity pattern for converted pattern.
print "Plot sparsity pattern for converted pattern."
コード例 #38
0
ファイル: nucnrm.py プロジェクト: ab39826/IndexCoding
def nrmapp(A, B, C = None, d = None, G = None, h = None): 
    """

    Solves the regularized nuclear norm approximation problem 
    
        minimize    || A(x) + B ||_* + 1/2 x'*C*x + d'*x
        subject to  G*x <= h

    and its dual

        maximize    -h'*z + tr(B'*Z) - 1/2 v'*C*v 
        subject to  d + G'*z + A'(Z) = C*v 
                    z >= 0
                    || Z || <= 1.

    A(x) is a linear mapping that maps n-vectors x to (p x q)-matrices A(x).

    ||.||_* is the nuclear norm (sum of singular values).  

    A'(Z) is the adjoint mapping of A(x).

    ||.|| is the maximum singular value norm.


    INPUT 

    A       real dense or sparse matrix of size (p*q, n).  Its columns are
            the coefficients A_i of the mapping 

                A: reals^n --> reals^pxq,   A(x) = sum_i=1^n x_i * A_i, 
                     
            stored in column-major order, as p*q-vectors.
        
    B       real dense or sparse matrix of size (p, q), with p >= q.
    
    C       real symmetric positive semidefinite dense or sparse matrix of 
            order n.  Only the lower triangular part of C is accessed.
            The default value is a zero matrix.

    d       real dense matrix of size (n, 1).  The default value is a zero
            vector.
    
    G       real dense or sparse matrix of size (m, n), with m >= 0.  
            The default value is a matrix of size (0, n).
    
    h       real dense matrix of size (m, 1).  The default value is a 
            matrix of size (0, 1).


    OUTPUT

    status  'optimal', 'primal infeasible', or 'unknown'. 

    x       'd' matrix of size (n, 1) if status is 'optimal'; 
            None otherwise.

    z       'd' matrix of size (m, 1) if status is 'optimal' or 'primal 
            infeasible'; None otherwise.

    Z       'd' matrix of size (p, q) if status is 'optimal' or 'primal
            infeasible'; None otherwise.


    If status is 'optimal', then x, z, Z are approximate solutions of the
    optimality conditions

        C * x  + G' * z + A'(Z) + d = 0  
        G * x <= h 
        z >= 0,  || Z || < = 1
        z' * (h - G*x) = 0
        tr (Z' * (A(x) + B)) = || A(x) + B ||_*.

    The last (complementary slackness) condition can be replaced by the
    following.  If the singular value decomposition of A(x) + B is

        A(x) + B = [ U1  U2 ] * diag(s, 0) * [ V1  V2 ]',

    with s > 0, then

        Z = U1 * V1' + U2 * W * V2',  || W || <= 1. 


    If status is 'primal infeasible', then Z = 0 and z is a certificate of
    infeasibility for the inequalities G * x <= h, i.e., a vector that
    satisfies

        h' * z = 1,  G' * z = 0,  z >= 0.

    """

    if type(B) not in (matrix, spmatrix) or B.typecode is not 'd':
        raise TypeError, "B must be a real dense or sparse matrix"
    p, q = B.size
    if p < q:
        raise ValueError, "row dimension of B must be greater than or "\
            "equal to column dimension"
    
    if type(A) not in (matrix, spmatrix) or A.typecode is not 'd' or \
        A.size[0] != p*q:
        raise TypeError, "A must be a real dense or sparse matrix with "\
            "p*q rows if B has size (p, q)"
    n = A.size[1]
    
    if G is None:  G = spmatrix([], [], [], (0, n))
    if h is None:  h = matrix(0.0, (0, 1))
    if type(h) is not matrix or h.typecode is not 'd' or h.size[1] != 1:
        raise TypeError, "h must be a real dense matrix with one column"
    m = h.size[0]
    if type(G) not in (matrix, spmatrix) or G.typecode is not 'd' or \
        G.size != (m, n):
        raise TypeError, "G must be a real dense matrix or sparse matrix "\
            "of size (m, n) if h has length m and A has n columns"
       
    if C is None: C = spmatrix(0.0, [], [], (n,n))
    if d is None: d = matrix(0.0, (n, 1))
    if type(C) not in (matrix, spmatrix) or C.typecode is not 'd' or \
        C.size != (n,n):
        raise TypeError, "C must be real dense or sparse matrix of size "\
            "(n, n) if A has n columns"
    if type(d) is not matrix or d.typecode is not 'd' or d.size != (n,1):
        raise TypeError, "d must be a real matrix of size (n, 1) if A has "\
            "n columns"


    # The problem is solved as a cone program
    #
    #     minimize    (1/2) * x'*C*x + d'*x  + (1/2) * (tr X1 + tr X2)
    #     subject to  G*x <= h
    #                 [ X1         (A(x) + B)' ]
    #                 [ A(x) + B   X2          ]  >= 0.
    #
    # The primal variable is stored as a list [ x, X1, X2 ].

    def xnewcopy(u): 
        return [ matrix(u[0]), matrix(u[1]), matrix(u[2]) ]
    def xdot(u,v):
        return blas.dot(u[0], v[0]) + misc.sdot2(u[1], v[1]) + \
            misc.sdot2(u[2], v[2])
    def xscal(alpha, u):
        blas.scal(alpha, u[0])
        blas.scal(alpha, u[1])
        blas.scal(alpha, u[2])
    def xaxpy(u, v, alpha = 1.0):
        blas.axpy(u[0], v[0], alpha)
        blas.axpy(u[1], v[1], alpha)
        blas.axpy(u[2], v[2], alpha)

    def Pf(u, v, alpha = 1.0, beta = 0.0):  
        base.symv(C, u[0], v[0], alpha = alpha, beta = beta)
        blas.scal(beta, v[1])
        blas.scal(beta, v[2])

    c = [ d, matrix(0.0, (q,q)), matrix(0.0, (p,p)) ]
    c[1][::q+1] = 0.5
    c[2][::p+1] = 0.5


    # If V is a p+q x p+q matrix 
    #
    #         [ V11  V12 ]
    #     V = [          ]
    #         [ V21  V22 ] 
    #
    # with V11 q x q,  V21 p x q, V12 q x p, and V22 p x p, then I11, I21,
    # I22 are the index sets defined by
    #
    #     V[I11] = V11[:],  V[I21] = V21[:],  V[I22] = V22[:].
    #

    I11 = matrix([ i + j*(p+q) for j in xrange(q) for i in xrange(q) ])
    I21 = matrix([ q + i + j*(p+q) for j in xrange(q) for i in xrange(p) ])
    I22 = matrix([ (p+q)*q + q + i + j*(p+q) for j in xrange(p) for 
       i in xrange(p) ])

    dims = {'l': m, 'q': [], 's': [p+q]}
    hh = matrix(0.0, (m + (p+q)**2, 1))
    hh[:m] = h
    hh[m + I21] = B[:]

    def Gf(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):

        if trans == 'N':
 
            # v[:m] := alpha * G * u[0] + beta * v[:m]
            base.gemv(G, u[0], v, alpha = alpha, beta = beta)

            # v[m:] := alpha * [-u[1],  -A(u[0])';  -A(u[0]), -u[2]]
            #          + beta * v[m:]
            blas.scal(beta, v, offset = m)
            v[m + I11] -= alpha * u[1][:]
            v[m + I21] -= alpha * A * u[0]
            v[m + I22] -= alpha * u[2][:]

        else:   
           
            # v[0] := alpha * ( G.T * u[:m] - 2.0 * A.T * u[m + I21] )
            #         + beta v[1]
            base.gemv(G, u, v[0], trans = 'T', alpha = alpha, beta = beta)  
            base.gemv(A, u[m + I21], v[0], trans = 'T', alpha = -2.0*alpha,
                beta = 1.0)

            # v[1] := -alpha * u[m + I11] + beta * v[1]
            blas.scal(beta, v[1])
            blas.axpy(u[m + I11], v[1], alpha = -alpha)

            # v[2] := -alpha * u[m + I22] + beta * v[2]
            blas.scal(beta, v[2])
            blas.axpy(u[m + I22], v[2], alpha = -alpha)


    def Af(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
        if trans == 'N':
            pass
        else:
            blas.scal(beta, v[0])
            blas.scal(beta, v[1])
            blas.scal(beta, v[2])


    L1 = matrix(0.0, (q, q))
    L2 = matrix(0.0, (p, p))
    T21 = matrix(0.0, (p, q))
    s = matrix(0.0, (q, 1))
    SS = matrix(0.0, (q, q))
    V1 = matrix(0.0, (q, q))
    V2 = matrix(0.0, (p, p))
    As = matrix(0.0, (p*q, n))
    As2 = matrix(0.0, (p*q, n))
    tmp = matrix(0.0, (p, q))
    a = matrix(0.0, (p+q, p+q))
    H = matrix(0.0, (n,n))
    Gs = matrix(0.0, (m, n))
    Q1 = matrix(0.0, (q, p+q))
    Q2 = matrix(0.0, (p, p+q))
    tau1 = matrix(0.0, (q,1))
    tau2 = matrix(0.0, (p,1))
    bz11 = matrix(0.0, (q,q))
    bz22 = matrix(0.0, (p,p))
    bz21 = matrix(0.0, (p,q))

    # Suppose V = [V1; V2] is p x q with V1 q x q.  If v = V[:] then
    # v[Itriu] are the strict upper triangular entries of V1 stored
    # columnwise.
    Itriu = [ i + j*p for j in xrange(1,q) for i in xrange(j) ]

    # v[Itril] are the strict lower triangular entries of V1 stored rowwise.
    Itril = [ j + i*p for j in xrange(1,q) for i in xrange(j) ]

    # v[Idiag] are the diagonal entries of V1.
    Idiag = [ i*(p+1) for i in xrange(q) ]

    # v[Itriu2] are the upper triangular entries of V1, with the diagonal
    # entries stored first, followed by the strict upper triangular entries
    # stored columnwise.
    Itriu2 = Idiag + Itriu

    # If V is a q x q matrix and v = V[:], then v[Itril2] are the strict
    # lower triangular entries of V stored columnwise and v[Itril3] are
    # the strict lower triangular entries stored rowwise.
    Itril2 = [ i + j*q for j in xrange(q) for i in xrange(j+1,q) ]
    Itril3 = [ i + j*q for i in xrange(q) for j in xrange(i) ]

    P = spmatrix(0.0, Itriu, Itril, (p*q, p*q))
    D = spmatrix(1.0, range(p*q), range(p*q))
    DV = matrix(1.0, (p*q, 1))


    def F(W):
        """
        Create a solver for the linear equations

                                C * ux + G' * uzl - 2*A'(uzs21) = bx
                                                         -uzs11 = bX1
                                                         -uzs22 = bX2
                                            G * ux - Dl^2 * uzl = bzl
            [ -uX1   -A(ux)' ]          [ uzs11 uzs21' ]     
            [                ] - r*r' * [              ] * r*r' = bzs
            [ -A(ux) -uX2    ]          [ uzs21 uzs22  ]

        where Dl = diag(W['l']), r = W['r'][0].  

        On entry, x = (bx, bX1, bX2) and z = [ bzl; bzs[:] ].
        On exit, x = (ux, uX1, uX2) and z = [ Dl*uzl; (r'*uzs*r)[:] ].


        1. Compute matrices V1, V2 such that (with T = r*r')
        
               [ V1   0   ] [ T11  T21' ] [ V1'  0  ]   [ I  S' ]
               [          ] [           ] [         ] = [       ]
               [ 0    V2' ] [ T21  T22  ] [ 0    V2 ]   [ S  I  ]
        
           and S = [ diag(s); 0 ], s a positive q-vector.

        2. Factor the mapping X -> X + S * X' * S:

               X + S * X' * S = L( L'( X )). 

        3. Compute scaled mappings: a matrix As with as its columns the 
           coefficients of the scaled mapping 

               L^-1( V2' * A() * V1' ) 

           and the matrix Gs = Dl^-1 * G.

        4. Cholesky factorization of H = C + Gs'*Gs + 2*As'*As.

        """


        # 1. Compute V1, V2, s.  

        r = W['r'][0]

        # LQ factorization R[:q, :] = L1 * Q1.
        lapack.lacpy(r, Q1, m = q)
        lapack.gelqf(Q1, tau1)
        lapack.lacpy(Q1, L1, n = q, uplo = 'L')
        lapack.orglq(Q1, tau1)

        # LQ factorization R[q:, :] = L2 * Q2.
        lapack.lacpy(r, Q2, m = p, offsetA = q)
	lapack.gelqf(Q2, tau2)
        lapack.lacpy(Q2, L2, n = p, uplo = 'L')
        lapack.orglq(Q2, tau2)


        # V2, V1, s are computed from an SVD: if
        # 
        #     Q2 * Q1' = U * diag(s) * V',
        #
        # then V1 = V' * L1^-1 and V2 = L2^-T * U.
    
        # T21 = Q2 * Q1.T  
        blas.gemm(Q2, Q1, T21, transB = 'T')

        # SVD T21 = U * diag(s) * V'.  Store U in V2 and V' in V1.
        lapack.gesvd(T21, s, jobu = 'A', jobvt = 'A', U = V2, Vt = V1) 

#        # Q2 := Q2 * Q1' without extracting Q1; store T21 in Q2
#        this will requires lapack.ormlq or lapack.unmlq

        # V2 = L2^-T * U   
        blas.trsm(L2, V2, transA = 'T') 

        # V1 = V' * L1^-1 
        blas.trsm(L1, V1, side = 'R') 


        # 2. Factorization X + S * X' * S = L( L'( X )).  
        #
        # The factor L is stored as a diagonal matrix D and a sparse lower 
        # triangular matrix P, such that  
        #
        #     L(X)[:] = D**-1 * (I + P) * X[:] 
        #     L^-1(X)[:] = D * (I - P) * X[:].

        # SS is q x q with SS[i,j] = si*sj.
        blas.scal(0.0, SS)
        blas.syr(s, SS)    
        
        # For a p x q matrix X, P*X[:] is Y[:] where 
        #
        #     Yij = si * sj * Xji  if i < j
        #         = 0              otherwise.
        # 
        P.V = SS[Itril2]

        # For a p x q matrix X, D*X[:] is Y[:] where 
        #
        #     Yij = Xij / sqrt( 1 - si^2 * sj^2 )  if i < j
        #         = Xii / sqrt( 1 + si^2 )         if i = j
        #         = Xij                            otherwise.
        # 
        DV[Idiag] = sqrt(1.0 + SS[::q+1])
        DV[Itriu] = sqrt(1.0 - SS[Itril3]**2)
        D.V = DV**-1


        # 3. Scaled linear mappings 
         
        # Ask :=  V2' * Ask * V1' 
        blas.scal(0.0, As)
        base.axpy(A, As)
        for i in xrange(n):
            # tmp := V2' * As[i, :]
            blas.gemm(V2, As, tmp, transA = 'T', m = p, n = q, k = p,
                ldB = p, offsetB = i*p*q)
            # As[:,i] := tmp * V1'
            blas.gemm(tmp, V1, As, transB = 'T', m = p, n = q, k = q,
                ldC = p, offsetC = i*p*q)

        # As := D * (I - P) * As 
        #     = L^-1 * As.
        blas.copy(As, As2)
        base.gemm(P, As, As2, alpha = -1.0, beta = 1.0)
        base.gemm(D, As2, As)

        # Gs := Dl^-1 * G 
        blas.scal(0.0, Gs)
        base.axpy(G, Gs)
        for k in xrange(n):
            blas.tbmv(W['di'], Gs, n = m, k = 0, ldA = 1, offsetx = k*m)


        # 4. Cholesky factorization of H = C + Gs' * Gs + 2 * As' * As.

        blas.syrk(As, H, trans = 'T', alpha = 2.0)
        blas.syrk(Gs, H, trans = 'T', beta = 1.0)
        base.axpy(C, H)   
        lapack.potrf(H)


        def f(x, y, z):
            """

            Solve 

                              C * ux + G' * uzl - 2*A'(uzs21) = bx
                                                       -uzs11 = bX1
                                                       -uzs22 = bX2
                                           G * ux - D^2 * uzl = bzl
                [ -uX1   -A(ux)' ]       [ uzs11 uzs21' ]     
                [                ] - T * [              ] * T = bzs.
                [ -A(ux) -uX2    ]       [ uzs21 uzs22  ]

            On entry, x = (bx, bX1, bX2) and z = [ bzl; bzs[:] ].
            On exit, x = (ux, uX1, uX2) and z = [ D*uzl; (r'*uzs*r)[:] ].

            Define X = uzs21, Z = T * uzs * T:   
 
                      C * ux + G' * uzl - 2*A'(X) = bx
                                [ 0  X' ]               [ bX1 0   ]
                            T * [       ] * T - Z = T * [         ] * T
                                [ X  0  ]               [ 0   bX2 ]
                               G * ux - D^2 * uzl = bzl
                [ -uX1   -A(ux)' ]   [ Z11 Z21' ]     
                [                ] - [          ] = bzs
                [ -A(ux) -uX2    ]   [ Z21 Z22  ]

            Return x = (ux, uX1, uX2), z = [ D*uzl; (rti'*Z*rti)[:] ].

            We use the congruence transformation 

                [ V1   0   ] [ T11  T21' ] [ V1'  0  ]   [ I  S' ]
                [          ] [           ] [         ] = [       ]
                [ 0    V2' ] [ T21  T22  ] [ 0    V2 ]   [ S  I  ]

            and the factorization 

                X + S * X' * S = L( L'(X) ) 

            to write this as

                                  C * ux + G' * uzl - 2*A'(X) = bx
                L'(V2^-1 * X * V1^-1) - L^-1(V2' * Z21 * V1') = bX
                                           G * ux - D^2 * uzl = bzl
                            [ -uX1   -A(ux)' ]   [ Z11 Z21' ]     
                            [                ] - [          ] = bzs,
                            [ -A(ux) -uX2    ]   [ Z21 Z22  ]

            or

                C * ux + Gs' * uuzl - 2*As'(XX) = bx
                                      XX - ZZ21 = bX
                                 Gs * ux - uuzl = D^-1 * bzl
                                 -As(ux) - ZZ21 = bbzs_21
                                     -uX1 - Z11 = bzs_11
                                     -uX2 - Z22 = bzs_22

            if we introduce scaled variables

                uuzl = D * uzl
                  XX = L'(V2^-1 * X * V1^-1) 
                     = L'(V2^-1 * uzs21 * V1^-1)
                ZZ21 = L^-1(V2' * Z21 * V1') 

            and define

                bbzs_21 = L^-1(V2' * bzs_21 * V1')
                                           [ bX1  0   ]
                     bX = L^-1( V2' * (T * [          ] * T)_21 * V1').
                                           [ 0    bX2 ]           
 
            Eliminating Z21 gives 

                C * ux + Gs' * uuzl - 2*As'(XX) = bx
                                 Gs * ux - uuzl = D^-1 * bzl
                                   -As(ux) - XX = bbzs_21 - bX
                                     -uX1 - Z11 = bzs_11
                                     -uX2 - Z22 = bzs_22 

            and eliminating uuzl and XX gives

                        H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bX - bbzs_21)
                Gs * ux - uuzl = D^-1 * bzl
                  -As(ux) - XX = bbzs_21 - bX
                    -uX1 - Z11 = bzs_11
                    -uX2 - Z22 = bzs_22.


            In summary, we can use the following algorithm: 

            1. bXX := bX - bbzs21
                                        [ bX1 0   ]
                    = L^-1( V2' * ((T * [         ] * T)_21 - bzs_21) * V1')
                                        [ 0   bX2 ]

            2. Solve H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bXX).

            3. From ux, compute 

                   uuzl = Gs*ux - D^-1 * bzl and 
                      X = V2 * L^-T(-As(ux) + bXX) * V1.

            4. Return ux, uuzl, 

                   rti' * Z * rti = r' * [ -bX1, X'; X, -bX2 ] * r
 
               and uX1 = -Z11 - bzs_11,  uX2 = -Z22 - bzs_22.

            """

            # Save bzs_11, bzs_22, bzs_21.
            lapack.lacpy(z, bz11, uplo = 'L', m = q, n = q, ldA = p+q,
                offsetA = m)
            lapack.lacpy(z, bz21, m = p, n = q, ldA = p+q, offsetA = m+q)
            lapack.lacpy(z, bz22, uplo = 'L', m = p, n = p, ldA = p+q,
                offsetA = m + (p+q+1)*q)


            # zl := D^-1 * zl
            #     = D^-1 * bzl
            blas.tbmv(W['di'], z, n = m, k = 0, ldA = 1)


            # zs := r' * [ bX1, 0; 0, bX2 ] * r.

            # zs := [ bX1, 0; 0, bX2 ]
            blas.scal(0.0, z, offset = m)
            lapack.lacpy(x[1], z, uplo = 'L', m = q, n = q, ldB = p+q,
                offsetB = m)
            lapack.lacpy(x[2], z, uplo = 'L', m = p, n = p, ldB = p+q,
                offsetB = m + (p+q+1)*q)

            # scale diagonal of zs by 1/2
            blas.scal(0.5, z, inc = p+q+1, offset = m)

            # a := tril(zs)*r  
            blas.copy(r, a)
            blas.trmm(z, a, side = 'L', m = p+q, n = p+q, ldA = p+q, ldB = 
                p+q, offsetA = m)

            # zs := a'*r + r'*a 
            blas.syr2k(r, a, z, trans = 'T', n = p+q, k = p+q, ldB = p+q,
                ldC = p+q, offsetC = m)



            # bz21 := L^-1( V2' * ((r * zs * r')_21 - bz21) * V1')
            #
            #                           [ bX1 0   ]
            #       = L^-1( V2' * ((T * [         ] * T)_21 - bz21) * V1').
            #                           [ 0   bX2 ]

            # a = [ r21 r22 ] * z
            #   = [ r21 r22 ] * r' * [ bX1, 0; 0, bX2 ] * r
            #   = [ T21  T22 ] * [ bX1, 0; 0, bX2 ] * r
            blas.symm(z, r, a, side = 'R', m = p, n = p+q, ldA = p+q, 
                ldC = p+q, offsetB = q)
    
            # bz21 := -bz21 + a * [ r11, r12 ]'
            #       = -bz21 + (T * [ bX1, 0; 0, bX2 ] * T)_21
            blas.gemm(a, r, bz21, transB = 'T', m = p, n = q, k = p+q, 
                beta = -1.0, ldA = p+q, ldC = p)

            # bz21 := V2' * bz21 * V1'
            #       = V2' * (-bz21 + (T*[bX1, 0; 0, bX2]*T)_21) * V1'
            blas.gemm(V2, bz21, tmp, transA = 'T', m = p, n = q, k = p, 
                ldB = p)
            blas.gemm(tmp, V1, bz21, transB = 'T', m = p, n = q, k = q, 
                ldC = p)

            # bz21[:] := D * (I-P) * bz21[:] 
            #       = L^-1 * bz21[:]
            #       = bXX[:]
            blas.copy(bz21, tmp)
            base.gemv(P, bz21, tmp, alpha = -1.0, beta = 1.0)
            base.gemv(D, tmp, bz21)


            # Solve H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bXX).

            # x[0] := x[0] + Gs'*zl + 2*As'(bz21) 
            #       = bx + G' * D^-1 * bzl + 2 * As'(bXX)
            blas.gemv(Gs, z, x[0], trans = 'T', alpha = 1.0, beta = 1.0)
            blas.gemv(As, bz21, x[0], trans = 'T', alpha = 2.0, beta = 1.0) 

            # x[0] := H \ x[0] 
            #      = ux
            lapack.potrs(H, x[0])


            # uuzl = Gs*ux - D^-1 * bzl
            blas.gemv(Gs, x[0], z, alpha = 1.0, beta = -1.0)

            
            # bz21 := V2 * L^-T(-As(ux) + bz21) * V1
            #       = X
            blas.gemv(As, x[0], bz21, alpha = -1.0, beta = 1.0)
            blas.tbsv(DV, bz21, n = p*q, k = 0, ldA = 1)
            blas.copy(bz21, tmp)
            base.gemv(P, tmp, bz21, alpha = -1.0, beta = 1.0, trans = 'T')
            blas.gemm(V2, bz21, tmp)
            blas.gemm(tmp, V1, bz21)


            # zs := -zs + r' * [ 0, X'; X, 0 ] * r
            #     = r' * [ -bX1, X'; X, -bX2 ] * r.

            # a := bz21 * [ r11, r12 ]
            #   =  X * [ r11, r12 ]
            blas.gemm(bz21, r, a, m = p, n = p+q, k = q, ldA = p, ldC = p+q)
            
            # z := -z + [ r21, r22 ]' * a + a' * [ r21, r22 ]
            #    = rti' * uzs * rti
            blas.syr2k(r, a, z, trans = 'T', beta = -1.0, n = p+q, k = p,
                offsetA = q, offsetC = m, ldB = p+q, ldC = p+q)  



            # uX1 = -Z11 - bzs_11 
            #     = -(r*zs*r')_11 - bzs_11
            # uX2 = -Z22 - bzs_22 
            #     = -(r*zs*r')_22 - bzs_22


            blas.copy(bz11, x[1])
            blas.copy(bz22, x[2])

            # scale diagonal of zs by 1/2
            blas.scal(0.5, z, inc = p+q+1, offset = m)

            # a := r*tril(zs)  
            blas.copy(r, a)
            blas.trmm(z, a, side = 'R', m = p+q, n = p+q, ldA = p+q, ldB = 
                p+q, offsetA = m)

            # x[1] := -x[1] - a[:q,:] * r[:q, :]' - r[:q,:] * a[:q,:]'
            #       = -bzs_11 - (r*zs*r')_11
            blas.syr2k(a, r, x[1], n = q, alpha = -1.0, beta = -1.0) 

            # x[2] := -x[2] - a[q:,:] * r[q:, :]' - r[q:,:] * a[q:,:]'
            #       = -bzs_22 - (r*zs*r')_22
            blas.syr2k(a, r, x[2], n = p, alpha = -1.0, beta = -1.0, 
                offsetA = q, offsetB = q)

            # scale diagonal of zs by 1/2
            blas.scal(2.0, z, inc = p+q+1, offset = m)


        return f


    if C:
        sol = solvers.coneqp(Pf, c, Gf, hh, dims, Af, kktsolver = F, 
            xnewcopy = xnewcopy, xdot = xdot, xaxpy = xaxpy, xscal = xscal) 
    else: 
        sol = solvers.conelp(c, Gf, hh, dims, Af, kktsolver = F, 
            xnewcopy = xnewcopy, xdot = xdot, xaxpy = xaxpy, xscal = xscal) 

    if sol['status'] is 'optimal':
        x = sol['x'][0]
        z = sol['z'][:m]
        Z = sol['z'][m:]
        Z.size = (p + q, p + q)
        Z = -2.0 * Z[-p:, :q]

    elif sol['status'] is 'primal infeasible':
        x = None
        z = sol['z'][:m]
        Z = sol['z'][m:]
        Z.size = (p + q, p + q)
        Z = -2.0 * Z[-p:, :q]

    else:
        x, z, Z = None, None, None

    return {'status': sol['status'], 'x': x, 'z': z, 'Z': Z }
コード例 #39
0
def A_optimize_fast(sij,
                    N=1.,
                    nsofar=None,
                    delta=None,
                    only_include_measurements=None,
                    maxiters=100,
                    feastol=1e-6):
    '''
    Find the A-optimal of the difference network that minimizes the trace of
    the covariance matrix.  This corresponds to minimizing the average error.

    In an iterative optimization of the difference network, the
    optimal allocation is updated with the estimate of s_{ij}, and we
    need to allocate the next iteration of sampling based on what has
    already been sampled for each pair.

    This implementation uses a customized KKT solver.  The time complexity is
    O(K^5), memory complexity is O(K^4).

    Args:

    sij: KxK symmetric matrix, where the measurement variance of the
    difference between i and j is proportional to s[i][j]^2 =
    s[j][i]^2, and the measurement variance of i is proportional to
    s[i][i]^2.

    nadd: float, Nadd gives the additional number of samples to be collected in
    the next iteration.

    nsofar: KxK symmetric matrix, where nsofar[i,j] is the number of samples
    that has already been collected for (i,j) pair.

    delta: a length K vector.  delta[i] is the measurement uncertainty on the
    quantity x[i] from an independent experiment; if no independent experiment
    provides a value for x[i], delta[i] is set to numpy.infty.

    only_include_measurements: set of pairs, if not None, indicate which 
    pairs should be considered in the optimal network.  Any pair (i,j) not in 
    the set will be excluded in the allocation (i.e. dn[i,j] = 0).  The pair
    (i,j) in the set must be ordered so that i<=j. 

    Return:

    KxK symmetric matrix of float, the (i,j) element of which gives the
    number of samples to be allocated to the measurement of (i,j) difference
    in the next iteration.
    '''
    si2 = cvxopt.div(1., sij**2)
    K = si2.size[0]

    if delta is not None:
        di2 = np.array([
            1. / delta[i]**2 if delta[i] is not None else 0. for i in xrange(K)
        ])
    else:
        di2 = None

    if only_include_measurements is not None:
        for i in xrange(K):
            for j in xrange(i, K):
                if not (i, j) in only_include_measurements:
                    # Set the s[i,j] to infinity, thus excluding the pair.
                    si2[i, j] = si2[j, i] = 0.

    Gm, hv, Am = Aopt_GhA(si2, nsofar, di2=di2, G_as_function=True)
    dims = dict(l=K * (K + 1) / 2, q=[], s=[K + 1] * K)

    cv = matrix(np.concatenate([np.zeros(K * (K + 1) / 2),
                                np.ones(K)]), (K * (K + 1) / 2 + K, 1))
    bv = matrix(float(N), (1, 1))

    def default_kkt_solver(W):
        return misc.kkt_ldl(Gm, dims, Am)(W)

    sol = solvers.conelp(cv,
                         Gm,
                         hv,
                         dims,
                         Am,
                         bv,
                         options=dict(maxiters=maxiters, feastol=feastol),
                         kktsolver=lambda W: Aopt_KKT_solver(si2, W))

    return conelp_solution_to_nij(sol['x'], K)
コード例 #40
0
ファイル: testIP.py プロジェクト: edwintye/pygotools
c = matrix([1.0] + [0.0]*n)

hTemp1 = matrix([0.0]+(-g).tolist())
GTemp1 = matrix(numpy.array(scipy.sparse.bmat([
    [[-1.0],None],
    [None,H]
    ]).todense()))

GTemp1 = matrix(numpy.append(numpy.append(numpy.array([0]*m).reshape(m,1),numpy.array(GTemp),axis=1),
                             numpy.array(GTemp1),
                             axis=0))

hTemp1 = matrix(numpy.append(hTemp,hTemp1))
dims1 = {'l': G.shape[0], 'q': [n+1,n+1], 's': []}

solSOCP = solvers.conelp(c, GTemp1, hTemp1, dims1)

print solSOCP['x'][1::]

## testing the change in objective function

print F(matrix(theta))[0]
print F(matrix(theta) + solSOCP['x'][1::])[0]
print F(matrix(theta) + sol1['x'])[0]

blas.nrm2(solSOCP['x'][1::])
blas.nrm2(sol1['x'])
blas.nrm2(qpOut['x'])

blas.nrm2(hTemp1[-n::] - matrix(GTemp)[-n::,:] * solSOCP['x'][1::] )
コード例 #41
0
# The small linear cone program of section 8.1 (Linear cone programs).

from cvxopt import matrix, solvers

c = matrix([-6., -4., -5.])
G = matrix([[ 16., 7.,  24.,  -8.,   8.,  -1.,  0., -1.,  0.,  0.,   7.,  
    -5.,   1.,  -5.,   1.,  -7.,   1.,   -7.,  -4.],
            [-14., 2.,   7., -13., -18.,   3.,  0.,  0., -1.,  0.,   3.,  
    13.,  -6.,  13.,  12., -10.,  -6.,  -10., -28.],
            [  5., 0., -15.,  12.,  -6.,  17.,  0.,  0.,  0., -1.,   9.,   
     6.,  -6.,   6.,  -7.,  -7.,  -6.,   -7., -11.]])
h = matrix( [ -3., 5.,  12.,  -2., -14., -13., 10.,  0.,  0.,  0.,  68., 
    -30., -19., -30.,  99.,  23., -19.,   23.,  10.] )
dims = {'l': 2, 'q': [4, 4], 's': [3]}
sol = solvers.conelp(c, G, h, dims)
print("\nStatus: " + sol['status'])
print("\nx = \n") 
print(sol['x'])
print("\nz = \n")
print(sol['z'])
コード例 #42
0
ファイル: ubsdp.py プロジェクト: wsgan001/itce2011
def ubsdp(c, A, B, pstart=None, dstart=None):
    """

        minimize  c'*x  + tr(X) 
        s.t.      sum_{i=1}^n xi * Ai - X <= B 
                  X >= 0

        maximize  -tr(B * Z0)
        s.t.      tr(Ai * Z0) + ci = 0,  i = 1, ..., n
                  -Z0 - Z1 + I = 0
                  Z0 >= 0,  Z1 >= 0.

    c is an n-vector.

    A is an m^2 x n-matrix.

    B is an m x m-matrix.
    """

    msq, n = A.size
    m = int(math.sqrt(msq))
    mpckd = int(m * (m + 1) / 2)
    dims = {'l': 0, 'q': [], 's': [m, m]}

    # The primal variable is stored as a tuple (x, X).
    cc = (c, matrix(0.0, (m, m)))
    cc[1][::m + 1] = 1.0

    def xnewcopy(u):

        return (+u[0], +u[1])

    def xdot(u, v):

        return blas.dot(u[0], v[0]) + misc.sdot2(u[1], v[1])

    def xscal(alpha, u):

        blas.scal(alpha, u[0])
        blas.scal(alpha, u[1])

    def xaxpy(u, v, alpha=1.0):

        blas.axpy(u[0], v[0], alpha)
        blas.axpy(u[1], v[1], alpha)

    def G(u, v, alpha=1.0, beta=0.0, trans='N'):
        """
        If trans is 'N':

            v[:msq] := alpha * (A*u[0] - u[1][:]) + beta * v[:msq]
            v[msq:] := -alpha * u[1][:] + beta * v[msq:].


        If trans is 'T':

            v[0] := alpha *  A' * u[:msq] + beta * v[0]
            v[1][:] := alpha * (-u[:msq] - u[msq:]) + beta * v[1][:].

        """

        if trans == 'N':

            blas.gemv(A, u[0], v, alpha=alpha, beta=beta)
            blas.axpy(u[1], v, alpha=-alpha)
            blas.scal(beta, v, offset=msq)
            blas.axpy(u[1], v, alpha=-alpha, offsety=msq)

        else:

            misc.sgemv(A,
                       u,
                       v[0],
                       dims={
                           'l': 0,
                           'q': [],
                           's': [m]
                       },
                       alpha=alpha,
                       beta=beta,
                       trans='T')
            blas.scal(beta, v[1])
            blas.axpy(u, v[1], alpha=-alpha, n=msq)
            blas.axpy(u, v[1], alpha=-alpha, n=msq, offsetx=msq)

    h = matrix(0.0, (2 * msq, 1))
    blas.copy(B, h)

    L = matrix(0.0, (m, m))
    U = matrix(0.0, (m, m))
    Us = matrix(0.0, (m, m))
    Uti = matrix(0.0, (m, m))
    s = matrix(0.0, (m, 1))
    Asc = matrix(0.0, (msq, n))
    S = matrix(0.0, (m, m))
    tmp = matrix(0.0, (m, m))
    x1 = matrix(0.0, (m**2, 1))
    H = matrix(0.0, (n, n))

    def F(W):
        """
        Generate a solver for

                                             A'(uz0) = bx[0]
                                          -uz0 - uz1 = bx[1] 
            A(ux[0]) - ux[1] - r0*r0' * uz0 * r0*r0' = bz0 
                     - ux[1] - r1*r1' * uz1 * r1*r1' = bz1.

        uz0, uz1, bz0, bz1 are symmetric m x m-matrices.
        ux[0], bx[0] are n-vectors.
        ux[1], bx[1] are symmetric m x m-matrices.

        We first calculate a congruence that diagonalizes r0*r0' and r1*r1':
 
            U' * r0 * r0' * U = I,  U' * r1 * r1' * U = S.

        We then make a change of variables

            usx[0] = ux[0],  
            usx[1] = U' * ux[1] * U  
              usz0 = U^-1 * uz0 * U^-T  
              usz1 = U^-1 * uz1 * U^-T 

        and define 

              As() = U' * A() * U'  
            bsx[1] = U^-1 * bx[1] * U^-T
              bsz0 = U' * bz0 * U  
              bsz1 = U' * bz1 * U.  

        This gives

                             As'(usz0) = bx[0]
                          -usz0 - usz1 = bsx[1] 
            As(usx[0]) - usx[1] - usz0 = bsz0 
                -usx[1] - S * usz1 * S = bsz1.


        1. Eliminate usz0, usz1 using equations 3 and 4,

               usz0 = As(usx[0]) - usx[1] - bsz0
               usz1 = -S^-1 * (usx[1] + bsz1) * S^-1.

           This gives two equations in usx[0] an usx[1].

               As'(As(usx[0]) - usx[1]) = bx[0] + As'(bsz0)

               -As(usx[0]) + usx[1] + S^-1 * usx[1] * S^-1
                   = bsx[1] - bsz0 - S^-1 * bsz1 * S^-1.


        2. Eliminate usx[1] using equation 2:

               usx[1] + S * usx[1] * S 
                   = S * ( As(usx[0]) + bsx[1] - bsz0 ) * S - bsz1

           i.e., with Gamma[i,j] = 1.0 + S[i,i] * S[j,j],
 
               usx[1] = ( S * As(usx[0]) * S ) ./ Gamma 
                        + ( S * ( bsx[1] - bsz0 ) * S - bsz1 ) ./ Gamma.

           This gives an equation in usx[0].

               As'( As(usx[0]) ./ Gamma ) 
                   = bx0 + As'(bsz0) + 
                     As'( (S * ( bsx[1] - bsz0 ) * S - bsz1) ./ Gamma )
                   = bx0 + As'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ Gamma ).

        """

        # Calculate U s.t.
        #
        #     U' * r0*r0' * U = I,   U' * r1*r1' * U = diag(s).

        # Cholesky factorization r0 * r0' = L * L'
        blas.syrk(W['r'][0], L)
        lapack.potrf(L)

        # SVD L^-1 * r1 = U * diag(s) * V'
        blas.copy(W['r'][1], U)
        blas.trsm(L, U)
        lapack.gesvd(U, s, jobu='O')

        # s := s**2
        s[:] = s**2

        # Uti := U
        blas.copy(U, Uti)

        # U := L^-T * U
        blas.trsm(L, U, transA='T')

        # Uti := L * Uti = U^-T
        blas.trmm(L, Uti)

        # Us := U * diag(s)^-1
        blas.copy(U, Us)
        for i in range(m):
            blas.tbsv(s, Us, n=m, k=0, ldA=1, incx=m, offsetx=i)

        # S is m x m with lower triangular entries s[i] * s[j]
        # sqrtG is m x m with lower triangular entries sqrt(1.0 + s[i]*s[j])
        # Upper triangular entries are undefined but nonzero.

        blas.scal(0.0, S)
        blas.syrk(s, S)
        Gamma = 1.0 + S
        sqrtG = sqrt(Gamma)

        # Asc[i] = (U' * Ai * * U ) ./  sqrtG,  for i = 1, ..., n
        #        = Asi ./ sqrt(Gamma)
        blas.copy(A, Asc)
        misc.scale(
            Asc,  # only 'r' part of the dictionary is used   
            {
                'dnl': matrix(0.0, (0, 1)),
                'dnli': matrix(0.0, (0, 1)),
                'd': matrix(0.0, (0, 1)),
                'di': matrix(0.0, (0, 1)),
                'v': [],
                'beta': [],
                'r': [U],
                'rti': [U]
            })
        for i in range(n):
            blas.tbsv(sqrtG, Asc, n=msq, k=0, ldA=1, offsetx=i * msq)

        # Convert columns of Asc to packed storage
        misc.pack2(Asc, {'l': 0, 'q': [], 's': [m]})

        # Cholesky factorization of Asc' * Asc.
        H = matrix(0.0, (n, n))
        blas.syrk(Asc, H, trans='T', k=mpckd)
        lapack.potrf(H)

        def solve(x, y, z):
            """

            1. Solve for usx[0]:

               Asc'(Asc(usx[0]))
                   = bx0 + Asc'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ sqrtG)
                   = bx0 + Asc'( ( bsz0 + S * ( bsx[1] - bssz1) S ) 
                     ./ sqrtG)

               where bsx[1] = U^-1 * bx[1] * U^-T, bsz0 = U' * bz0 * U, 
               bsz1 = U' * bz1 * U, bssz1 = S^-1 * bsz1 * S^-1 

            2. Solve for usx[1]:

               usx[1] + S * usx[1] * S 
                   = S * ( As(usx[0]) + bsx[1] - bsz0 ) * S - bsz1 

               usx[1] 
                   = ( S * (As(usx[0]) + bsx[1] - bsz0) * S - bsz1) ./ Gamma
                   = -bsz0 + (S * As(usx[0]) * S) ./ Gamma
                     + (bsz0 - bsz1 + S * bsx[1] * S ) . / Gamma
                   = -bsz0 + (S * As(usx[0]) * S) ./ Gamma
                     + (bsz0 + S * ( bsx[1] - bssz1 ) * S ) . / Gamma

               Unscale ux[1] = Uti * usx[1] * Uti'

            3. Compute usz0, usz1

               r0' * uz0 * r0 = r0^-1 * ( A(ux[0]) - ux[1] - bz0 ) * r0^-T
               r1' * uz1 * r1 = r1^-1 * ( -ux[1] - bz1 ) * r1^-T

            """

            # z0 := U' * z0 * U
            #     = bsz0
            __cngrnc(U, z, trans='T')

            # z1 := Us' * bz1 * Us
            #     = S^-1 * U' * bz1 * U * S^-1
            #     = S^-1 * bsz1 * S^-1
            __cngrnc(Us, z, trans='T', offsetx=msq)

            # x[1] := Uti' * x[1] * Uti
            #       = bsx[1]
            __cngrnc(Uti, x[1], trans='T')

            # x[1] := x[1] - z[msq:]
            #       = bsx[1] - S^-1 * bsz1 * S^-1
            blas.axpy(z, x[1], alpha=-1.0, offsetx=msq)

            # x1 = (S * x[1] * S + z[:msq] ) ./ sqrtG
            #    = (S * ( bsx[1] - S^-1 * bsz1 * S^-1) * S + bsz0 ) ./ sqrtG
            #    = (S * bsx[1] * S - bsz1 + bsz0 ) ./ sqrtG
            # in packed storage
            blas.copy(x[1], x1)
            blas.tbmv(S, x1, n=msq, k=0, ldA=1)
            blas.axpy(z, x1, n=msq)
            blas.tbsv(sqrtG, x1, n=msq, k=0, ldA=1)
            misc.pack2(x1, {'l': 0, 'q': [], 's': [m]})

            # x[0] := x[0] + Asc'*x1
            #       = bx0 + Asc'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ sqrtG)
            #       = bx0 + As'( ( bz0 - bz1 + S * bx[1] * S ) ./ Gamma )
            blas.gemv(Asc, x1, x[0], m=mpckd, trans='T', beta=1.0)

            # x[0] := H^-1 * x[0]
            #       = ux[0]
            lapack.potrs(H, x[0])

            # x1 = Asc(x[0]) .* sqrtG  (unpacked)
            #    = As(x[0])
            blas.gemv(Asc, x[0], tmp, m=mpckd)
            misc.unpack(tmp, x1, {'l': 0, 'q': [], 's': [m]})
            blas.tbmv(sqrtG, x1, n=msq, k=0, ldA=1)

            # usx[1] = (x1 + (x[1] - z[:msq])) ./ sqrtG**2
            #        = (As(ux[0]) + bsx[1] - bsz0 - S^-1 * bsz1 * S^-1)
            #           ./ Gamma

            # x[1] := x[1] - z[:msq]
            #       = bsx[1] - bsz0 - S^-1 * bsz1 * S^-1
            blas.axpy(z, x[1], -1.0, n=msq)

            # x[1] := x[1] + x1
            #       = As(ux) + bsx[1] - bsz0 - S^-1 * bsz1 * S^-1
            blas.axpy(x1, x[1])

            # x[1] := x[1] / Gammma
            #       = (As(ux) + bsx[1] - bsz0 + S^-1 * bsz1 * S^-1 ) / Gamma
            #       = S^-1 * usx[1] * S^-1
            blas.tbsv(Gamma, x[1], n=msq, k=0, ldA=1)

            # z[msq:] := r1' * U * (-z[msq:] - x[1]) * U * r1
            #         := -r1' * U * S^-1 * (bsz1 + ux[1]) * S^-1 *  U * r1
            #         := -r1' * uz1 * r1
            blas.axpy(x[1], z, n=msq, offsety=msq)
            blas.scal(-1.0, z, offset=msq)
            __cngrnc(U, z, offsetx=msq)
            __cngrnc(W['r'][1], z, trans='T', offsetx=msq)

            # x[1] :=  S * x[1] * S
            #       =  usx1
            blas.tbmv(S, x[1], n=msq, k=0, ldA=1)

            # z[:msq] = r0' * U' * ( x1 - x[1] - z[:msq] ) * U * r0
            #         = r0' * U' * ( As(ux) - usx1 - bsz0 ) * U * r0
            #         = r0' * U' *  usz0 * U * r0
            #         = r0' * uz0 * r0
            blas.axpy(x1, z, -1.0, n=msq)
            blas.scal(-1.0, z, n=msq)
            blas.axpy(x[1], z, -1.0, n=msq)
            __cngrnc(U, z)
            __cngrnc(W['r'][0], z, trans='T')

            # x[1] := Uti * x[1] * Uti'
            #       = ux[1]
            __cngrnc(Uti, x[1])

        return solve

    sol = solvers.conelp(cc,
                         G,
                         h,
                         dims={
                             'l': 0,
                             's': [m, m],
                             'q': []
                         },
                         kktsolver=F,
                         xnewcopy=xnewcopy,
                         xdot=xdot,
                         xaxpy=xaxpy,
                         xscal=xscal,
                         primalstart=pstart,
                         dualstart=dstart)

    return matrix(sol['x'][1], (n, n))
コード例 #43
0
def nrmapp(A, B, C=None, d=None, G=None, h=None):
    """

    Solves the regularized nuclear norm approximation problem 
    
        minimize    || A(x) + B ||_* + 1/2 x'*C*x + d'*x
        subject to  G*x <= h

    and its dual

        maximize    -h'*z + tr(B'*Z) - 1/2 v'*C*v 
        subject to  d + G'*z + A'(Z) = C*v 
                    z >= 0
                    || Z || <= 1.

    A(x) is a linear mapping that maps n-vectors x to (p x q)-matrices A(x).

    ||.||_* is the nuclear norm (sum of singular values).  

    A'(Z) is the adjoint mapping of A(x).

    ||.|| is the maximum singular value norm.


    INPUT 

    A       real dense or sparse matrix of size (p*q, n).  Its columns are
            the coefficients A_i of the mapping 

                A: reals^n --> reals^pxq,   A(x) = sum_i=1^n x_i * A_i, 
                     
            stored in column-major order, as p*q-vectors.
        
    B       real dense or sparse matrix of size (p, q), with p >= q.
    
    C       real symmetric positive semidefinite dense or sparse matrix of 
            order n.  Only the lower triangular part of C is accessed.
            The default value is a zero matrix.

    d       real dense matrix of size (n, 1).  The default value is a zero
            vector.
    
    G       real dense or sparse matrix of size (m, n), with m >= 0.  
            The default value is a matrix of size (0, n).
    
    h       real dense matrix of size (m, 1).  The default value is a 
            matrix of size (0, 1).


    OUTPUT

    status  'optimal', 'primal infeasible', or 'unknown'. 

    x       'd' matrix of size (n, 1) if status is 'optimal'; 
            None otherwise.

    z       'd' matrix of size (m, 1) if status is 'optimal' or 'primal 
            infeasible'; None otherwise.

    Z       'd' matrix of size (p, q) if status is 'optimal' or 'primal
            infeasible'; None otherwise.


    If status is 'optimal', then x, z, Z are approximate solutions of the
    optimality conditions

        C * x  + G' * z + A'(Z) + d = 0  
        G * x <= h 
        z >= 0,  || Z || < = 1
        z' * (h - G*x) = 0
        tr (Z' * (A(x) + B)) = || A(x) + B ||_*.

    The last (complementary slackness) condition can be replaced by the
    following.  If the singular value decomposition of A(x) + B is

        A(x) + B = [ U1  U2 ] * diag(s, 0) * [ V1  V2 ]',

    with s > 0, then

        Z = U1 * V1' + U2 * W * V2',  || W || <= 1. 


    If status is 'primal infeasible', then Z = 0 and z is a certificate of
    infeasibility for the inequalities G * x <= h, i.e., a vector that
    satisfies

        h' * z = 1,  G' * z = 0,  z >= 0.

    """

    if type(B) not in (matrix, spmatrix) or B.typecode is not 'd':
        raise TypeError, "B must be a real dense or sparse matrix"
    p, q = B.size
    if p < q:
        raise ValueError, "row dimension of B must be greater than or "\
            "equal to column dimension"

    if type(A) not in (matrix, spmatrix) or A.typecode is not 'd' or \
        A.size[0] != p*q:
        raise TypeError, "A must be a real dense or sparse matrix with "\
            "p*q rows if B has size (p, q)"
    n = A.size[1]

    if G is None: G = spmatrix([], [], [], (0, n))
    if h is None: h = matrix(0.0, (0, 1))
    if type(h) is not matrix or h.typecode is not 'd' or h.size[1] != 1:
        raise TypeError, "h must be a real dense matrix with one column"
    m = h.size[0]
    if type(G) not in (matrix, spmatrix) or G.typecode is not 'd' or \
        G.size != (m, n):
        raise TypeError, "G must be a real dense matrix or sparse matrix "\
            "of size (m, n) if h has length m and A has n columns"

    if C is None: C = spmatrix(0.0, [], [], (n, n))
    if d is None: d = matrix(0.0, (n, 1))
    if type(C) not in (matrix, spmatrix) or C.typecode is not 'd' or \
        C.size != (n,n):
        raise TypeError, "C must be real dense or sparse matrix of size "\
            "(n, n) if A has n columns"
    if type(d) is not matrix or d.typecode is not 'd' or d.size != (n, 1):
        raise TypeError, "d must be a real matrix of size (n, 1) if A has "\
            "n columns"

    # The problem is solved as a cone program
    #
    #     minimize    (1/2) * x'*C*x + d'*x  + (1/2) * (tr X1 + tr X2)
    #     subject to  G*x <= h
    #                 [ X1         (A(x) + B)' ]
    #                 [ A(x) + B   X2          ]  >= 0.
    #
    # The primal variable is stored as a list [ x, X1, X2 ].

    def xnewcopy(u):
        return [matrix(u[0]), matrix(u[1]), matrix(u[2])]

    def xdot(u, v):
        return blas.dot(u[0], v[0]) + misc.sdot2(u[1], v[1]) + \
            misc.sdot2(u[2], v[2])

    def xscal(alpha, u):
        blas.scal(alpha, u[0])
        blas.scal(alpha, u[1])
        blas.scal(alpha, u[2])

    def xaxpy(u, v, alpha=1.0):
        blas.axpy(u[0], v[0], alpha)
        blas.axpy(u[1], v[1], alpha)
        blas.axpy(u[2], v[2], alpha)

    def Pf(u, v, alpha=1.0, beta=0.0):
        base.symv(C, u[0], v[0], alpha=alpha, beta=beta)
        blas.scal(beta, v[1])
        blas.scal(beta, v[2])

    c = [d, matrix(0.0, (q, q)), matrix(0.0, (p, p))]
    c[1][::q + 1] = 0.5
    c[2][::p + 1] = 0.5

    # If V is a p+q x p+q matrix
    #
    #         [ V11  V12 ]
    #     V = [          ]
    #         [ V21  V22 ]
    #
    # with V11 q x q,  V21 p x q, V12 q x p, and V22 p x p, then I11, I21,
    # I22 are the index sets defined by
    #
    #     V[I11] = V11[:],  V[I21] = V21[:],  V[I22] = V22[:].
    #

    I11 = matrix([i + j * (p + q) for j in xrange(q) for i in xrange(q)])
    I21 = matrix([q + i + j * (p + q) for j in xrange(q) for i in xrange(p)])
    I22 = matrix([(p + q) * q + q + i + j * (p + q) for j in xrange(p)
                  for i in xrange(p)])

    dims = {'l': m, 'q': [], 's': [p + q]}
    hh = matrix(0.0, (m + (p + q)**2, 1))
    hh[:m] = h
    hh[m + I21] = B[:]

    def Gf(u, v, alpha=1.0, beta=0.0, trans='N'):

        if trans == 'N':

            # v[:m] := alpha * G * u[0] + beta * v[:m]
            base.gemv(G, u[0], v, alpha=alpha, beta=beta)

            # v[m:] := alpha * [-u[1],  -A(u[0])';  -A(u[0]), -u[2]]
            #          + beta * v[m:]
            blas.scal(beta, v, offset=m)
            v[m + I11] -= alpha * u[1][:]
            v[m + I21] -= alpha * A * u[0]
            v[m + I22] -= alpha * u[2][:]

        else:

            # v[0] := alpha * ( G.T * u[:m] - 2.0 * A.T * u[m + I21] )
            #         + beta v[1]
            base.gemv(G, u, v[0], trans='T', alpha=alpha, beta=beta)
            base.gemv(A,
                      u[m + I21],
                      v[0],
                      trans='T',
                      alpha=-2.0 * alpha,
                      beta=1.0)

            # v[1] := -alpha * u[m + I11] + beta * v[1]
            blas.scal(beta, v[1])
            blas.axpy(u[m + I11], v[1], alpha=-alpha)

            # v[2] := -alpha * u[m + I22] + beta * v[2]
            blas.scal(beta, v[2])
            blas.axpy(u[m + I22], v[2], alpha=-alpha)

    def Af(u, v, alpha=1.0, beta=0.0, trans='N'):
        if trans == 'N':
            pass
        else:
            blas.scal(beta, v[0])
            blas.scal(beta, v[1])
            blas.scal(beta, v[2])

    L1 = matrix(0.0, (q, q))
    L2 = matrix(0.0, (p, p))
    T21 = matrix(0.0, (p, q))
    s = matrix(0.0, (q, 1))
    SS = matrix(0.0, (q, q))
    V1 = matrix(0.0, (q, q))
    V2 = matrix(0.0, (p, p))
    As = matrix(0.0, (p * q, n))
    As2 = matrix(0.0, (p * q, n))
    tmp = matrix(0.0, (p, q))
    a = matrix(0.0, (p + q, p + q))
    H = matrix(0.0, (n, n))
    Gs = matrix(0.0, (m, n))
    Q1 = matrix(0.0, (q, p + q))
    Q2 = matrix(0.0, (p, p + q))
    tau1 = matrix(0.0, (q, 1))
    tau2 = matrix(0.0, (p, 1))
    bz11 = matrix(0.0, (q, q))
    bz22 = matrix(0.0, (p, p))
    bz21 = matrix(0.0, (p, q))

    # Suppose V = [V1; V2] is p x q with V1 q x q.  If v = V[:] then
    # v[Itriu] are the strict upper triangular entries of V1 stored
    # columnwise.
    Itriu = [i + j * p for j in xrange(1, q) for i in xrange(j)]

    # v[Itril] are the strict lower triangular entries of V1 stored rowwise.
    Itril = [j + i * p for j in xrange(1, q) for i in xrange(j)]

    # v[Idiag] are the diagonal entries of V1.
    Idiag = [i * (p + 1) for i in xrange(q)]

    # v[Itriu2] are the upper triangular entries of V1, with the diagonal
    # entries stored first, followed by the strict upper triangular entries
    # stored columnwise.
    Itriu2 = Idiag + Itriu

    # If V is a q x q matrix and v = V[:], then v[Itril2] are the strict
    # lower triangular entries of V stored columnwise and v[Itril3] are
    # the strict lower triangular entries stored rowwise.
    Itril2 = [i + j * q for j in xrange(q) for i in xrange(j + 1, q)]
    Itril3 = [i + j * q for i in xrange(q) for j in xrange(i)]

    P = spmatrix(0.0, Itriu, Itril, (p * q, p * q))
    D = spmatrix(1.0, range(p * q), range(p * q))
    DV = matrix(1.0, (p * q, 1))

    def F(W):
        """
        Create a solver for the linear equations

                                C * ux + G' * uzl - 2*A'(uzs21) = bx
                                                         -uzs11 = bX1
                                                         -uzs22 = bX2
                                            G * ux - Dl^2 * uzl = bzl
            [ -uX1   -A(ux)' ]          [ uzs11 uzs21' ]     
            [                ] - r*r' * [              ] * r*r' = bzs
            [ -A(ux) -uX2    ]          [ uzs21 uzs22  ]

        where Dl = diag(W['l']), r = W['r'][0].  

        On entry, x = (bx, bX1, bX2) and z = [ bzl; bzs[:] ].
        On exit, x = (ux, uX1, uX2) and z = [ Dl*uzl; (r'*uzs*r)[:] ].


        1. Compute matrices V1, V2 such that (with T = r*r')
        
               [ V1   0   ] [ T11  T21' ] [ V1'  0  ]   [ I  S' ]
               [          ] [           ] [         ] = [       ]
               [ 0    V2' ] [ T21  T22  ] [ 0    V2 ]   [ S  I  ]
        
           and S = [ diag(s); 0 ], s a positive q-vector.

        2. Factor the mapping X -> X + S * X' * S:

               X + S * X' * S = L( L'( X )). 

        3. Compute scaled mappings: a matrix As with as its columns the 
           coefficients of the scaled mapping 

               L^-1( V2' * A() * V1' ) 

           and the matrix Gs = Dl^-1 * G.

        4. Cholesky factorization of H = C + Gs'*Gs + 2*As'*As.

        """

        # 1. Compute V1, V2, s.

        r = W['r'][0]

        # LQ factorization R[:q, :] = L1 * Q1.
        lapack.lacpy(r, Q1, m=q)
        lapack.gelqf(Q1, tau1)
        lapack.lacpy(Q1, L1, n=q, uplo='L')
        lapack.orglq(Q1, tau1)

        # LQ factorization R[q:, :] = L2 * Q2.
        lapack.lacpy(r, Q2, m=p, offsetA=q)
        lapack.gelqf(Q2, tau2)
        lapack.lacpy(Q2, L2, n=p, uplo='L')
        lapack.orglq(Q2, tau2)

        # V2, V1, s are computed from an SVD: if
        #
        #     Q2 * Q1' = U * diag(s) * V',
        #
        # then V1 = V' * L1^-1 and V2 = L2^-T * U.

        # T21 = Q2 * Q1.T
        blas.gemm(Q2, Q1, T21, transB='T')

        # SVD T21 = U * diag(s) * V'.  Store U in V2 and V' in V1.
        lapack.gesvd(T21, s, jobu='A', jobvt='A', U=V2, Vt=V1)

        #        # Q2 := Q2 * Q1' without extracting Q1; store T21 in Q2
        #        this will requires lapack.ormlq or lapack.unmlq

        # V2 = L2^-T * U
        blas.trsm(L2, V2, transA='T')

        # V1 = V' * L1^-1
        blas.trsm(L1, V1, side='R')

        # 2. Factorization X + S * X' * S = L( L'( X )).
        #
        # The factor L is stored as a diagonal matrix D and a sparse lower
        # triangular matrix P, such that
        #
        #     L(X)[:] = D**-1 * (I + P) * X[:]
        #     L^-1(X)[:] = D * (I - P) * X[:].

        # SS is q x q with SS[i,j] = si*sj.
        blas.scal(0.0, SS)
        blas.syr(s, SS)

        # For a p x q matrix X, P*X[:] is Y[:] where
        #
        #     Yij = si * sj * Xji  if i < j
        #         = 0              otherwise.
        #
        P.V = SS[Itril2]

        # For a p x q matrix X, D*X[:] is Y[:] where
        #
        #     Yij = Xij / sqrt( 1 - si^2 * sj^2 )  if i < j
        #         = Xii / sqrt( 1 + si^2 )         if i = j
        #         = Xij                            otherwise.
        #
        DV[Idiag] = sqrt(1.0 + SS[::q + 1])
        DV[Itriu] = sqrt(1.0 - SS[Itril3]**2)
        D.V = DV**-1

        # 3. Scaled linear mappings

        # Ask :=  V2' * Ask * V1'
        blas.scal(0.0, As)
        base.axpy(A, As)
        for i in xrange(n):
            # tmp := V2' * As[i, :]
            blas.gemm(V2,
                      As,
                      tmp,
                      transA='T',
                      m=p,
                      n=q,
                      k=p,
                      ldB=p,
                      offsetB=i * p * q)
            # As[:,i] := tmp * V1'
            blas.gemm(tmp,
                      V1,
                      As,
                      transB='T',
                      m=p,
                      n=q,
                      k=q,
                      ldC=p,
                      offsetC=i * p * q)

        # As := D * (I - P) * As
        #     = L^-1 * As.
        blas.copy(As, As2)
        base.gemm(P, As, As2, alpha=-1.0, beta=1.0)
        base.gemm(D, As2, As)

        # Gs := Dl^-1 * G
        blas.scal(0.0, Gs)
        base.axpy(G, Gs)
        for k in xrange(n):
            blas.tbmv(W['di'], Gs, n=m, k=0, ldA=1, offsetx=k * m)

        # 4. Cholesky factorization of H = C + Gs' * Gs + 2 * As' * As.

        blas.syrk(As, H, trans='T', alpha=2.0)
        blas.syrk(Gs, H, trans='T', beta=1.0)
        base.axpy(C, H)
        lapack.potrf(H)

        def f(x, y, z):
            """

            Solve 

                              C * ux + G' * uzl - 2*A'(uzs21) = bx
                                                       -uzs11 = bX1
                                                       -uzs22 = bX2
                                           G * ux - D^2 * uzl = bzl
                [ -uX1   -A(ux)' ]       [ uzs11 uzs21' ]     
                [                ] - T * [              ] * T = bzs.
                [ -A(ux) -uX2    ]       [ uzs21 uzs22  ]

            On entry, x = (bx, bX1, bX2) and z = [ bzl; bzs[:] ].
            On exit, x = (ux, uX1, uX2) and z = [ D*uzl; (r'*uzs*r)[:] ].

            Define X = uzs21, Z = T * uzs * T:   
 
                      C * ux + G' * uzl - 2*A'(X) = bx
                                [ 0  X' ]               [ bX1 0   ]
                            T * [       ] * T - Z = T * [         ] * T
                                [ X  0  ]               [ 0   bX2 ]
                               G * ux - D^2 * uzl = bzl
                [ -uX1   -A(ux)' ]   [ Z11 Z21' ]     
                [                ] - [          ] = bzs
                [ -A(ux) -uX2    ]   [ Z21 Z22  ]

            Return x = (ux, uX1, uX2), z = [ D*uzl; (rti'*Z*rti)[:] ].

            We use the congruence transformation 

                [ V1   0   ] [ T11  T21' ] [ V1'  0  ]   [ I  S' ]
                [          ] [           ] [         ] = [       ]
                [ 0    V2' ] [ T21  T22  ] [ 0    V2 ]   [ S  I  ]

            and the factorization 

                X + S * X' * S = L( L'(X) ) 

            to write this as

                                  C * ux + G' * uzl - 2*A'(X) = bx
                L'(V2^-1 * X * V1^-1) - L^-1(V2' * Z21 * V1') = bX
                                           G * ux - D^2 * uzl = bzl
                            [ -uX1   -A(ux)' ]   [ Z11 Z21' ]     
                            [                ] - [          ] = bzs,
                            [ -A(ux) -uX2    ]   [ Z21 Z22  ]

            or

                C * ux + Gs' * uuzl - 2*As'(XX) = bx
                                      XX - ZZ21 = bX
                                 Gs * ux - uuzl = D^-1 * bzl
                                 -As(ux) - ZZ21 = bbzs_21
                                     -uX1 - Z11 = bzs_11
                                     -uX2 - Z22 = bzs_22

            if we introduce scaled variables

                uuzl = D * uzl
                  XX = L'(V2^-1 * X * V1^-1) 
                     = L'(V2^-1 * uzs21 * V1^-1)
                ZZ21 = L^-1(V2' * Z21 * V1') 

            and define

                bbzs_21 = L^-1(V2' * bzs_21 * V1')
                                           [ bX1  0   ]
                     bX = L^-1( V2' * (T * [          ] * T)_21 * V1').
                                           [ 0    bX2 ]           
 
            Eliminating Z21 gives 

                C * ux + Gs' * uuzl - 2*As'(XX) = bx
                                 Gs * ux - uuzl = D^-1 * bzl
                                   -As(ux) - XX = bbzs_21 - bX
                                     -uX1 - Z11 = bzs_11
                                     -uX2 - Z22 = bzs_22 

            and eliminating uuzl and XX gives

                        H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bX - bbzs_21)
                Gs * ux - uuzl = D^-1 * bzl
                  -As(ux) - XX = bbzs_21 - bX
                    -uX1 - Z11 = bzs_11
                    -uX2 - Z22 = bzs_22.


            In summary, we can use the following algorithm: 

            1. bXX := bX - bbzs21
                                        [ bX1 0   ]
                    = L^-1( V2' * ((T * [         ] * T)_21 - bzs_21) * V1')
                                        [ 0   bX2 ]

            2. Solve H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bXX).

            3. From ux, compute 

                   uuzl = Gs*ux - D^-1 * bzl and 
                      X = V2 * L^-T(-As(ux) + bXX) * V1.

            4. Return ux, uuzl, 

                   rti' * Z * rti = r' * [ -bX1, X'; X, -bX2 ] * r
 
               and uX1 = -Z11 - bzs_11,  uX2 = -Z22 - bzs_22.

            """

            # Save bzs_11, bzs_22, bzs_21.
            lapack.lacpy(z, bz11, uplo='L', m=q, n=q, ldA=p + q, offsetA=m)
            lapack.lacpy(z, bz21, m=p, n=q, ldA=p + q, offsetA=m + q)
            lapack.lacpy(z,
                         bz22,
                         uplo='L',
                         m=p,
                         n=p,
                         ldA=p + q,
                         offsetA=m + (p + q + 1) * q)

            # zl := D^-1 * zl
            #     = D^-1 * bzl
            blas.tbmv(W['di'], z, n=m, k=0, ldA=1)

            # zs := r' * [ bX1, 0; 0, bX2 ] * r.

            # zs := [ bX1, 0; 0, bX2 ]
            blas.scal(0.0, z, offset=m)
            lapack.lacpy(x[1], z, uplo='L', m=q, n=q, ldB=p + q, offsetB=m)
            lapack.lacpy(x[2],
                         z,
                         uplo='L',
                         m=p,
                         n=p,
                         ldB=p + q,
                         offsetB=m + (p + q + 1) * q)

            # scale diagonal of zs by 1/2
            blas.scal(0.5, z, inc=p + q + 1, offset=m)

            # a := tril(zs)*r
            blas.copy(r, a)
            blas.trmm(z,
                      a,
                      side='L',
                      m=p + q,
                      n=p + q,
                      ldA=p + q,
                      ldB=p + q,
                      offsetA=m)

            # zs := a'*r + r'*a
            blas.syr2k(r,
                       a,
                       z,
                       trans='T',
                       n=p + q,
                       k=p + q,
                       ldB=p + q,
                       ldC=p + q,
                       offsetC=m)

            # bz21 := L^-1( V2' * ((r * zs * r')_21 - bz21) * V1')
            #
            #                           [ bX1 0   ]
            #       = L^-1( V2' * ((T * [         ] * T)_21 - bz21) * V1').
            #                           [ 0   bX2 ]

            # a = [ r21 r22 ] * z
            #   = [ r21 r22 ] * r' * [ bX1, 0; 0, bX2 ] * r
            #   = [ T21  T22 ] * [ bX1, 0; 0, bX2 ] * r
            blas.symm(z,
                      r,
                      a,
                      side='R',
                      m=p,
                      n=p + q,
                      ldA=p + q,
                      ldC=p + q,
                      offsetB=q)

            # bz21 := -bz21 + a * [ r11, r12 ]'
            #       = -bz21 + (T * [ bX1, 0; 0, bX2 ] * T)_21
            blas.gemm(a,
                      r,
                      bz21,
                      transB='T',
                      m=p,
                      n=q,
                      k=p + q,
                      beta=-1.0,
                      ldA=p + q,
                      ldC=p)

            # bz21 := V2' * bz21 * V1'
            #       = V2' * (-bz21 + (T*[bX1, 0; 0, bX2]*T)_21) * V1'
            blas.gemm(V2, bz21, tmp, transA='T', m=p, n=q, k=p, ldB=p)
            blas.gemm(tmp, V1, bz21, transB='T', m=p, n=q, k=q, ldC=p)

            # bz21[:] := D * (I-P) * bz21[:]
            #       = L^-1 * bz21[:]
            #       = bXX[:]
            blas.copy(bz21, tmp)
            base.gemv(P, bz21, tmp, alpha=-1.0, beta=1.0)
            base.gemv(D, tmp, bz21)

            # Solve H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bXX).

            # x[0] := x[0] + Gs'*zl + 2*As'(bz21)
            #       = bx + G' * D^-1 * bzl + 2 * As'(bXX)
            blas.gemv(Gs, z, x[0], trans='T', alpha=1.0, beta=1.0)
            blas.gemv(As, bz21, x[0], trans='T', alpha=2.0, beta=1.0)

            # x[0] := H \ x[0]
            #      = ux
            lapack.potrs(H, x[0])

            # uuzl = Gs*ux - D^-1 * bzl
            blas.gemv(Gs, x[0], z, alpha=1.0, beta=-1.0)

            # bz21 := V2 * L^-T(-As(ux) + bz21) * V1
            #       = X
            blas.gemv(As, x[0], bz21, alpha=-1.0, beta=1.0)
            blas.tbsv(DV, bz21, n=p * q, k=0, ldA=1)
            blas.copy(bz21, tmp)
            base.gemv(P, tmp, bz21, alpha=-1.0, beta=1.0, trans='T')
            blas.gemm(V2, bz21, tmp)
            blas.gemm(tmp, V1, bz21)

            # zs := -zs + r' * [ 0, X'; X, 0 ] * r
            #     = r' * [ -bX1, X'; X, -bX2 ] * r.

            # a := bz21 * [ r11, r12 ]
            #   =  X * [ r11, r12 ]
            blas.gemm(bz21, r, a, m=p, n=p + q, k=q, ldA=p, ldC=p + q)

            # z := -z + [ r21, r22 ]' * a + a' * [ r21, r22 ]
            #    = rti' * uzs * rti
            blas.syr2k(r,
                       a,
                       z,
                       trans='T',
                       beta=-1.0,
                       n=p + q,
                       k=p,
                       offsetA=q,
                       offsetC=m,
                       ldB=p + q,
                       ldC=p + q)

            # uX1 = -Z11 - bzs_11
            #     = -(r*zs*r')_11 - bzs_11
            # uX2 = -Z22 - bzs_22
            #     = -(r*zs*r')_22 - bzs_22

            blas.copy(bz11, x[1])
            blas.copy(bz22, x[2])

            # scale diagonal of zs by 1/2
            blas.scal(0.5, z, inc=p + q + 1, offset=m)

            # a := r*tril(zs)
            blas.copy(r, a)
            blas.trmm(z,
                      a,
                      side='R',
                      m=p + q,
                      n=p + q,
                      ldA=p + q,
                      ldB=p + q,
                      offsetA=m)

            # x[1] := -x[1] - a[:q,:] * r[:q, :]' - r[:q,:] * a[:q,:]'
            #       = -bzs_11 - (r*zs*r')_11
            blas.syr2k(a, r, x[1], n=q, alpha=-1.0, beta=-1.0)

            # x[2] := -x[2] - a[q:,:] * r[q:, :]' - r[q:,:] * a[q:,:]'
            #       = -bzs_22 - (r*zs*r')_22
            blas.syr2k(a,
                       r,
                       x[2],
                       n=p,
                       alpha=-1.0,
                       beta=-1.0,
                       offsetA=q,
                       offsetB=q)

            # scale diagonal of zs by 1/2
            blas.scal(2.0, z, inc=p + q + 1, offset=m)

        return f

    if C:
        sol = solvers.coneqp(Pf,
                             c,
                             Gf,
                             hh,
                             dims,
                             Af,
                             kktsolver=F,
                             xnewcopy=xnewcopy,
                             xdot=xdot,
                             xaxpy=xaxpy,
                             xscal=xscal)
    else:
        sol = solvers.conelp(c,
                             Gf,
                             hh,
                             dims,
                             Af,
                             kktsolver=F,
                             xnewcopy=xnewcopy,
                             xdot=xdot,
                             xaxpy=xaxpy,
                             xscal=xscal)

    if sol['status'] is 'optimal':
        x = sol['x'][0]
        z = sol['z'][:m]
        Z = sol['z'][m:]
        Z.size = (p + q, p + q)
        Z = -2.0 * Z[-p:, :q]

    elif sol['status'] is 'primal infeasible':
        x = None
        z = sol['z'][:m]
        Z = sol['z'][m:]
        Z.size = (p + q, p + q)
        Z = -2.0 * Z[-p:, :q]

    else:
        x, z, Z = None, None, None

    return {'status': sol['status'], 'x': x, 'z': z, 'Z': Z}
コード例 #44
0
ファイル: l1.py プロジェクト: cuihantao/cvxopt
def l1(P, q):

    """
    Returns the solution u of the ell-1 approximation problem

        (primal) minimize ||P*u - q||_1       
    
        (dual)   maximize    q'*w
                 subject to  P'*w = 0
                             ||w||_infty <= 1.
    """

    m, n = P.size

    # Solve equivalent LP 
    #
    #     minimize    [0; 1]' * [u; v]
    #     subject to  [P, -I; -P, -I] * [u; v] <= [q; -q]
    #
    #     maximize    -[q; -q]' * z 
    #     subject to  [P', -P']*z  = 0
    #                 [-I, -I]*z + 1 = 0 
    #                 z >= 0 
    
    c = matrix(n*[0.0] + m*[1.0])
    h = matrix([q, -q])

    def Fi(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):    
        if trans == 'N':
            # y := alpha * [P, -I; -P, -I] * x + beta*y
            u = P*x[:n]
            y[:m] = alpha * ( u - x[n:]) + beta*y[:m]
            y[m:] = alpha * (-u - x[n:]) + beta*y[m:]

        else:
            # y := alpha * [P', -P'; -I, -I] * x + beta*y
            y[:n] =  alpha * P.T * (x[:m] - x[m:]) + beta*y[:n]
            y[n:] = -alpha * (x[:m] + x[m:]) + beta*y[n:]


    def Fkkt(W): 

        # Returns a function f(x, y, z) that solves
        #
        # [ 0  0  P'      -P'      ] [ x[:n] ]   [ bx[:n] ]
        # [ 0  0 -I       -I       ] [ x[n:] ]   [ bx[n:] ]
        # [ P -I -W1^2     0       ] [ z[:m] ] = [ bz[:m] ]
        # [-P -I  0       -W2      ] [ z[m:] ]   [ bz[m:] ]
        #
        # On entry bx, bz are stored in x, z.
        # On exit x, z contain the solution, with z scaled (W['di'] .* z is
        # returned instead of z). 

        d1, d2 = W['d'][:m], W['d'][m:]
        D = 4*(d1**2 + d2**2)**-1
        A = P.T * spdiag(D) * P
        lapack.potrf(A)

        def f(x, y, z):

            x[:n] += P.T * ( mul( div(d2**2 - d1**2, d1**2 + d2**2), x[n:]) 
                + mul( .5*D, z[:m]-z[m:] ) )
            lapack.potrs(A, x)

            u = P*x[:n]
            x[n:] =  div( x[n:] - div(z[:m], d1**2) - div(z[m:], d2**2) + 
                mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2 )

            z[:m] = div(u-x[n:]-z[:m], d1)
            z[m:] = div(-u-x[n:]-z[m:], d2)

        return f


    # Initial primal and dual points from least-squares solution.

    # uls minimizes ||P*u-q||_2; rls is the LS residual.
    uls =  +q
    lapack.gels(+P, uls)
    rls = P*uls[:n] - q 

    # x0 = [ uls;  1.1*abs(rls) ];   s0 = [q;-q] - [P,-I; -P,-I] * x0
    x0 = matrix( [uls[:n],  1.1*abs(rls)] ) 
    s0 = +h
    Fi(x0, s0, alpha=-1, beta=1) 

    # z0 = [ (1+w)/2; (1-w)/2 ] where w = (.9/||rls||_inf) * rls  
    # if rls is nonzero and w = 0 otherwise.
    if max(abs(rls)) > 1e-10:  
        w = .9/max(abs(rls)) * rls
    else: 
        w = matrix(0.0, (m,1))
    z0 = matrix([.5*(1+w), .5*(1-w)])

    dims = {'l': 2*m, 'q': [], 's': []}
    sol = solvers.conelp(c, Fi, h, dims, kktsolver = Fkkt,  
        primalstart={'x': x0, 's': s0}, dualstart={'z': z0})
    return sol['x'][:n]
コード例 #45
0
  def block_socp(self, a, A1, A2, t, B_s, u_s):
    dims = {
        'l': self.size_tb() + 2*self.size_x() + sum([cc.size for cc in self.cube_constraints]),  # Pure inequality constraints
            # Com cone is now 3d, Size of the cones: x,y,z+1
        'q': [dc.size for dc in self.dist_constraints]+[4]*len(self.contacts)*len(self.gravity_envelope)+[self.size_z()+1]*self.size_s()+[fc.size for fc in self.force_constraints],
        's': []  # No sd cones
            }
    size_cones = self.size_x()*4 // 3

    #Optimization vector [ f1 ... fn CoM s1 ... sn]

    #Max a^T z ~ min -a^T z
    #Final cost : min -a^T z + s
    c = np.vstack([np.zeros((self.size_x(), 1)), -a, np.zeros((self.size_s(), 1))])
    A1_diag = block_diag(*([A1]*len(self.gravity_envelope)))
    A2 = np.vstack([self.computeA2(self.gravity+e)
                    for e in self.gravity_envelope])

    T = np.vstack([self.computeT(self.gravity+e, height=self.height)
                   for e in self.gravity_envelope])

    A = np.hstack([A1_diag, A2, np.zeros((A2.shape[0], self.size_s()))])

    g_s = []
    h_s = []

    #Torque constraint
    if self.L_s:
      g_s.extend(self.L_s)
      h_s.extend(self.tb_s)

    #Linear force constraint
    #       <x> <z>                      <1>
    # <x> [[ I  0] <= <x> lim*mg  2*<x> [ 1]
    # <x> [[ -I 0]
    g_force = np.vstack([np.eye(self.size_x()), -np.eye(self.size_x())])
    g_s.append(np.hstack([g_force, np.zeros((2*self.size_x(), self.size_z()+self.size_s()))]))

    h_s.append(self.force_lim*self.mass*9.81*np.ones((2*self.size_x(), 1)))

    #Cube constraints
    if self.C_s:
      g_s.append(np.vstack(self.C_s))
      h_s.append(np.vstack(self.d_s))

    #These are additional dist constraints
    g_s.extend(self.S_s)
    h_s.extend(self.r_s)

    #B = diag{[u_i b_i.T].T}
    blocks = [-np.vstack([u.T, B]) for u, B in zip(u_s, B_s)]*len(self.gravity_envelope)
    block = block_diag(*blocks)

    g_contacts = np.hstack([block, np.zeros((size_cones, self.size_z()+self.size_s()))])
    h_cones = np.zeros((size_cones, 1))

    g_slacks, h_slacks = None, None
    if self.robust_sphere > 0:
      g_slacks = np.zeros((4*self.size_s(), self.nrVars()))
      h_slacks = np.zeros((4*self.size_s(), 1))
      for i, contact in enumerate(self.contacts):
        robusticity = -self.robust_sphere*self.mass*(self.theta_bar+self.sigma_bar*contact.mu)
        g_contacts[4*i, self.size_x()+self.size_z()+i] = -robusticity
        h_cones[4*i, 0] = robusticity

        #Add slack variables cones
        # || z || < s
        g_slacks[4*i, self.size_x()+self.size_z()+i] = -1
        g_slacks[4*i+1:4*i+1+self.size_z(), self.size_x():self.size_x()+self.size_z()] = -np.eye(self.size_z())

    g_s.append(g_contacts)
    h_s.append(h_cones)

    if g_slacks is not None:
      g_s.append(g_slacks)
      h_s.append(h_slacks)

    #Force Constraints
    g_s.extend(self.F_s)
    h_s.extend(self.f_s)

    #Concat everything
    g = np.vstack(g_s)
    h = np.vstack(h_s)

    sol = solvers.conelp(matrix(c), G=matrix(g), h=matrix(h),
                         A=matrix(A), b=matrix(T), dims=dims)
    return sol
コード例 #46
0
ファイル: negSDP.py プロジェクト: peteshadbolt/SDP
 def SDP():
     return solvers.conelp(c, G, h, dims)
コード例 #47
0
def qcl1(A, b):
    """
    Returns the solution u, z of

        (primal)  minimize    || u ||_1       
                  subject to  || A * u - b ||_2  <= 1

        (dual)    maximize    b^T z - ||z||_2
                  subject to  || A'*z ||_inf <= 1.

    Exploits structure, assuming A is m by n with m >= n. 
    """

    m, n = A.size

    # Solve equivalent cone LP with variables x = [u; v]:
    #
    #     minimize    [0; 1]' * x
    #     subject to  [ I  -I ] * x <=  [  0 ]   (componentwise)
    #                 [-I  -I ] * x <=  [  0 ]   (componentwise)
    #                 [ 0   0 ] * x <=  [  1 ]   (SOC)
    #                 [-A   0 ]         [ -b ].
    #
    #     maximize    -t + b' * w
    #     subject to  z1 - z2 = A'*w
    #                 z1 + z2 = 1
    #                 z1 >= 0,  z2 >=0,  ||w||_2 <= t.

    c = matrix(n * [0.0] + n * [1.0])
    h = matrix(0.0, (2 * n + m + 1, 1))
    h[2 * n] = 1.0
    h[2 * n + 1:] = -b

    def G(x, y, alpha=1.0, beta=0.0, trans='N'):
        y *= beta
        if trans == 'N':
            # y += alpha * G * x
            y[:n] += alpha * (x[:n] - x[n:2 * n])
            y[n:2 * n] += alpha * (-x[:n] - x[n:2 * n])
            y[2 * n + 1:] -= alpha * A * x[:n]

        else:
            # y += alpha * G'*x
            y[:n] += alpha * (x[:n] - x[n:2 * n] - A.T * x[-m:])
            y[n:] -= alpha * (x[:n] + x[n:2 * n])

    def Fkkt(W):

        # Returns a function f(x, y, z) that solves
        #
        #     [ 0   G'   ] [ x ] = [ bx ]
        #     [ G  -W'*W ] [ z ]   [ bz ].

        # First factor
        #
        #     S = G' * W**-1 * W**-T * G
        #       = [0; -A]' * W3^-2 * [0; -A] + 4 * (W1**2 + W2**2)**-1
        #
        # where
        #
        #     W1 = diag(d1) with d1 = W['d'][:n] = 1 ./ W['di'][:n]
        #     W2 = diag(d2) with d2 = W['d'][n:] = 1 ./ W['di'][n:]
        #     W3 = beta * (2*v*v' - J),  W3^-1 = 1/beta * (2*J*v*v'*J - J)
        #        with beta = W['beta'][0], v = W['v'][0], J = [1, 0; 0, -I].

        # As = W3^-1 * [ 0 ; -A ] = 1/beta * ( 2*J*v * v' - I ) * [0; A]
        beta, v = W['beta'][0], W['v'][0]
        As = 2 * v * (v[1:].T * A)
        As[1:, :] *= -1.0
        As[1:, :] -= A
        As /= beta

        # S = As'*As + 4 * (W1**2 + W2**2)**-1
        S = As.T * As
        d1, d2 = W['d'][:n], W['d'][n:]
        d = 4.0 * (d1**2 + d2**2)**-1
        S[::n + 1] += d
        lapack.potrf(S)

        def f(x, y, z):

            # z := - W**-T * z
            z[:n] = -div(z[:n], d1)
            z[n:2 * n] = -div(z[n:2 * n], d2)
            z[2 * n:] -= 2.0 * v * (v[0] * z[2 * n] -
                                    blas.dot(v[1:], z[2 * n + 1:]))
            z[2 * n + 1:] *= -1.0
            z[2 * n:] /= beta

            # x := x - G' * W**-1 * z
            x[:n] -= div(z[:n], d1) - div(z[n:2 * n], d2) + As.T * z[-(m + 1):]
            x[n:] += div(z[:n], d1) + div(z[n:2 * n], d2)

            # Solve for x[:n]:
            #
            #    S*x[:n] = x[:n] - (W1**2 - W2**2)(W1**2 + W2**2)^-1 * x[n:]

            x[:n] -= mul(div(d1**2 - d2**2, d1**2 + d2**2), x[n:])
            lapack.potrs(S, x)

            # Solve for x[n:]:
            #
            #    (d1**-2 + d2**-2) * x[n:] = x[n:] + (d1**-2 - d2**-2)*x[:n]

            x[n:] += mul(d1**-2 - d2**-2, x[:n])
            x[n:] = div(x[n:], d1**-2 + d2**-2)

            # z := z + W^-T * G*x
            z[:n] += div(x[:n] - x[n:2 * n], d1)
            z[n:2 * n] += div(-x[:n] - x[n:2 * n], d2)
            z[2 * n:] += As * x[:n]

        return f

    dims = {'l': 2 * n, 'q': [m + 1], 's': []}
    sol = solvers.conelp(c, G, h, dims, kktsolver=Fkkt)
    if sol['status'] == 'optimal':
        return sol['x'][:n], sol['z'][-m:]
    else:
        return None, None
コード例 #48
0
def l1(P, q):
    """
    Returns the solution u, w of the ell-1 approximation problem

        (primal) minimize ||P*u - q||_1       
    
        (dual)   maximize    q'*w
                 subject to  P'*w = 0
                             ||w||_infty <= 1.
    """

    m, n = P.size

    # Solve equivalent LP
    #
    #     minimize    [0; 1]' * [u; v]
    #     subject to  [P, -I; -P, -I] * [u; v] <= [q; -q]
    #
    #     maximize    -[q; -q]' * z
    #     subject to  [P', -P']*z  = 0
    #                 [-I, -I]*z + 1 = 0
    #                 z >= 0

    c = matrix(n * [0.0] + m * [1.0])
    h = matrix([q, -q])

    def Fi(x, y, alpha=1.0, beta=0.0, trans='N'):
        if trans == 'N':
            # y := alpha * [P, -I; -P, -I] * x + beta*y
            u = P * x[:n]
            y[:m] = alpha * (u - x[n:]) + beta * y[:m]
            y[m:] = alpha * (-u - x[n:]) + beta * y[m:]

        else:
            # y := alpha * [P', -P'; -I, -I] * x + beta*y
            y[:n] = alpha * P.T * (x[:m] - x[m:]) + beta * y[:n]
            y[n:] = -alpha * (x[:m] + x[m:]) + beta * y[n:]

    def Fkkt(W):

        # Returns a function f(x, y, z) that solves
        #
        # [ 0  0  P'      -P'      ] [ x[:n] ]   [ bx[:n] ]
        # [ 0  0 -I       -I       ] [ x[n:] ]   [ bx[n:] ]
        # [ P -I -D1^{-1}  0       ] [ z[:m] ] = [ bz[:m] ]
        # [-P -I  0       -D2^{-1} ] [ z[m:] ]   [ bz[m:] ]
        #
        # where D1 = diag(di[:m])^2, D2 = diag(di[m:])^2 and di = W['di'].
        #
        # On entry bx, bz are stored in x, z.
        # On exit x, z contain the solution, with z scaled (di .* z is
        # returned instead of z).

        # Factor A = 4*P'*D*P where D = d1.*d2 ./(d1+d2) and
        # d1 = d[:m].^2, d2 = d[m:].^2.

        di = W['di']
        d1, d2 = di[:m]**2, di[m:]**2
        D = div(mul(d1, d2), d1 + d2)
        A = P.T * spdiag(4 * D) * P
        lapack.potrf(A)

        def f(x, y, z):

            # Solve for x[:n]:
            #
            #    A*x[:n] = bx[:n] + P' * ( ((D1-D2)*(D1+D2)^{-1})*bx[n:]
            #        + (2*D1*D2*(D1+D2)^{-1}) * (bz[:m] - bz[m:]) ).

            x[:n] += P.T * (mul(div(d1 - d2, d1 + d2), x[n:]) +
                            mul(2 * D, z[:m] - z[m:]))
            lapack.potrs(A, x)

            # x[n:] := (D1+D2)^{-1} * (bx[n:] - D1*bz[:m] - D2*bz[m:]
            #     + (D1-D2)*P*x[:n])

            u = P * x[:n]
            x[n:] = div(
                x[n:] - mul(d1, z[:m]) - mul(d2, z[m:]) + mul(d1 - d2, u),
                d1 + d2)

            # z[:m] := d1[:m] .* ( P*x[:n] - x[n:] - bz[:m])
            # z[m:] := d2[m:] .* (-P*x[:n] - x[n:] - bz[m:])

            z[:m] = mul(di[:m], u - x[n:] - z[:m])
            z[m:] = mul(di[m:], -u - x[n:] - z[m:])

        return f

    # Initial primal and dual points from least-squares solution.

    # uls minimizes ||P*u-q||_2; rls is the LS residual.
    uls = +q
    lapack.gels(+P, uls)
    rls = P * uls[:n] - q

    # x0 = [ uls;  1.1*abs(rls) ];   s0 = [q;-q] - [P,-I; -P,-I] * x0
    x0 = matrix([uls[:n], 1.1 * abs(rls)])
    s0 = +h
    Fi(x0, s0, alpha=-1, beta=1)

    # z0 = [ (1+w)/2; (1-w)/2 ] where w = (.9/||rls||_inf) * rls
    # if rls is nonzero and w = 0 otherwise.
    if max(abs(rls)) > 1e-10:
        w = .9 / max(abs(rls)) * rls
    else:
        w = matrix(0.0, (m, 1))
    z0 = matrix([.5 * (1 + w), .5 * (1 - w)])

    dims = {'l': 2 * m, 'q': [], 's': []}
    sol = solvers.conelp(c,
                         Fi,
                         h,
                         dims,
                         kktsolver=Fkkt,
                         primalstart={
                             'x': x0,
                             's': s0
                         },
                         dualstart={'z': z0})
    return sol['x'][:n], sol['z'][m:] - sol['z'][:m]
コード例 #49
0
ファイル: qcl1.py プロジェクト: AlbertHolmes/cvxopt
def qcl1(A, b):

    """
    Returns the solution u, z of

        (primal)  minimize    || u ||_1       
                  subject to  || A * u - b ||_2  <= 1

        (dual)    maximize    b^T z - ||z||_2
                  subject to  || A'*z ||_inf <= 1.

    Exploits structure, assuming A is m by n with m >= n. 
    """

    m, n = A.size

    # Solve equivalent cone LP with variables x = [u; v]:
    #
    #     minimize    [0; 1]' * x 
    #     subject to  [ I  -I ] * x <=  [  0 ]   (componentwise)
    #                 [-I  -I ] * x <=  [  0 ]   (componentwise)
    #                 [ 0   0 ] * x <=  [  1 ]   (SOC)
    #                 [-A   0 ]         [ -b ].
    #
    #     maximize    -t + b' * w
    #     subject to  z1 - z2 = A'*w
    #                 z1 + z2 = 1
    #                 z1 >= 0,  z2 >=0,  ||w||_2 <= t.
     
    c = matrix(n*[0.0] + n*[1.0])
    h = matrix( 0.0, (2*n + m + 1, 1))
    h[2*n] = 1.0
    h[2*n+1:] = -b

    def G(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):    
        y *= beta
        if trans=='N':
            # y += alpha * G * x 
            y[:n] += alpha * (x[:n] - x[n:2*n]) 
            y[n:2*n] += alpha * (-x[:n] - x[n:2*n]) 
            y[2*n+1:] -= alpha * A*x[:n] 

        else:
            # y += alpha * G'*x 
            y[:n] += alpha * (x[:n] - x[n:2*n] - A.T * x[-m:])  
            y[n:] -= alpha * (x[:n] + x[n:2*n]) 


    def Fkkt(W): 

        # Returns a function f(x, y, z) that solves
        #
        #     [ 0   G'   ] [ x ] = [ bx ]
        #     [ G  -W'*W ] [ z ]   [ bz ].

        # First factor 
        #
        #     S = G' * W**-1 * W**-T * G
        #       = [0; -A]' * W3^-2 * [0; -A] + 4 * (W1**2 + W2**2)**-1 
        #
        # where
        #
        #     W1 = diag(d1) with d1 = W['d'][:n] = 1 ./ W['di'][:n]  
        #     W2 = diag(d2) with d2 = W['d'][n:] = 1 ./ W['di'][n:]  
        #     W3 = beta * (2*v*v' - J),  W3^-1 = 1/beta * (2*J*v*v'*J - J)  
        #        with beta = W['beta'][0], v = W['v'][0], J = [1, 0; 0, -I].
  
        # As = W3^-1 * [ 0 ; -A ] = 1/beta * ( 2*J*v * v' - I ) * [0; A]
        beta, v = W['beta'][0], W['v'][0]
        As = 2 * v * (v[1:].T * A)
        As[1:,:] *= -1.0
        As[1:,:] -= A
        As /= beta
      
        # S = As'*As + 4 * (W1**2 + W2**2)**-1
        S = As.T * As 
        d1, d2 = W['d'][:n], W['d'][n:]       
        d = 4.0 * (d1**2 + d2**2)**-1
        S[::n+1] += d
        lapack.potrf(S)

        def f(x, y, z):

            # z := - W**-T * z 
            z[:n] = -div( z[:n], d1 )
            z[n:2*n] = -div( z[n:2*n], d2 )
            z[2*n:] -= 2.0*v*( v[0]*z[2*n] - blas.dot(v[1:], z[2*n+1:]) ) 
            z[2*n+1:] *= -1.0
            z[2*n:] /= beta

            # x := x - G' * W**-1 * z
            x[:n] -= div(z[:n], d1) - div(z[n:2*n], d2) + As.T * z[-(m+1):]
            x[n:] += div(z[:n], d1) + div(z[n:2*n], d2) 

            # Solve for x[:n]:
            #
            #    S*x[:n] = x[:n] - (W1**2 - W2**2)(W1**2 + W2**2)^-1 * x[n:]
            
            x[:n] -= mul( div(d1**2 - d2**2, d1**2 + d2**2), x[n:]) 
            lapack.potrs(S, x)
            
            # Solve for x[n:]:
            #
            #    (d1**-2 + d2**-2) * x[n:] = x[n:] + (d1**-2 - d2**-2)*x[:n]
             
            x[n:] += mul( d1**-2 - d2**-2, x[:n])
            x[n:] = div( x[n:], d1**-2 + d2**-2)

            # z := z + W^-T * G*x 
            z[:n] += div( x[:n] - x[n:2*n], d1) 
            z[n:2*n] += div( -x[:n] - x[n:2*n], d2) 
            z[2*n:] += As*x[:n]

        return f

    dims = {'l': 2*n, 'q': [m+1], 's': []}
    sol = solvers.conelp(c, G, h, dims, kktsolver = Fkkt)
    if sol['status'] == 'optimal':
        return sol['x'][:n],  sol['z'][-m:]
    else:
        return None, None