Okay -- I'll make two separate posts -- the code below can serve as a
template, the next post contains code for the same example, but solved
using conjugate-gradient iteration on the positive definite matrix P
+G.T*W'*W*G.
--Jeff
from cvxopt import solvers, matrix, normal, setseed
from cvxopt.lapack import *
from cvxopt.blas import *
import cvxopt.misc as misc
import numpy as np
"""
Create random matrices c, B, Gq for the problem
minimize c.T*x + x.T*B*x/2
subject to nrm2(Gq*x) <= 1.0
x >= 0.0
"""
# problem size
n =25
# size of Gq
gq=15
# size of Gl
gl=n
setseed(1)
c=normal(n,1)
B=normal(n,n)
B=B.T*B
"""
linear portion of
G, b stored in Gl, bl
quad portion are in Gq, bq
"""
Gl=-matrix(np.eye(gl), tc='d')
hl= matrix(0., (gl,1))
Gq=normal(gq,n)
Gq[0,:]=0.
hq=matrix(0., (gq,1))
hq[0]=1
h=matrix([hl,hq])
G=matrix([Gl,Gq])
dims = {'l': gl, 'q': [gq], 's': []}
"""
y:= alpha*G*x + beta*y, trans=='N'
y:= alpha*G.T*x + beta*y, otherwise
"""
def Gfun(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):
gemv(G,x,y,alpha=alpha, beta=beta,trans=trans)
def Fkkt(W):
"""
to solve block matrix
(A B)(x)=(a)
(C D)(y)=(b)
First solve for x:
(A-BD^{-1}C)x = a-BD^{-1}b (*)
(A-BD^{-1}C) is positive definite
Next solve for y:
Cx+Dy=b so y= D^{-1}(b-Cx) (**)
"""
def f(bx, by, bz):
n=len(bx)
m=len(bz)
a = matrix(0. ,(n,1))
b = matrix(0. ,(m,1))
"""
Get the right hand side of (*)
"""
copy(bz, b, m)
misc.scale(b, W, inverse='I', trans='T')
misc.scale(b, W, inverse='I', trans='N')
Gfun(b, a, trans='T')
axpy(bx, a)
"""
solve (*) using favorite solver
"""
"""
begin CUSTOM SOLVER
"""
H=+G
misc.scale(H, W, inverse='I', trans='T')
misc.scale(H, W, inverse='I', trans='N')
H=B+G.T*H
sysv(H,a)
copy(a,bx)
"""
end CUSTOM SOLVER
"""
"""
now solve (**)
"""
Gfun(bx,b)
scal(-1, b)
axpy(bz, b)
misc.scale(b, W, inverse='I', trans='T')
scal(-1, b)
copy(b, bz)
return f
sol1=solvers.coneqp(B, c, Gfun, h, dims, kktsolver=Fkkt)
x1=sol1['x']
z1=sol1['z']
sol2=solvers.coneqp(B, c, G, h, dims)
x2=sol2['x']
z2=sol2['z']
print ""
print "Error of custom FKKT solution: ", nrm2(x1-x2)
print "Error of custom FKKT dual: ", nrm2(z1-z2)
print "Is nrm2(Gq*x1) <= 1?"
print " nrm2(Gq*x1)=", nrm2(Gq*x1)
print "Is min(x1)>=0?"
print " min(x1)=", min(x1)