Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# 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))
base.gemm(spmatrix(W['dnli'], list(range(mnl)),
list(range(mnl))), Df, F['Dfs'], partial=True)
# Gs = Wl^{-1} * G.
base.gemm(spmatrix(W['di'], list(range(ml)), list(range(ml))),
G, F['Gs'], partial=True)
if F['firstcall']:
base.syrk(F['Gs'], F['S'], trans='T')
if mnl:
base.syrk(F['Dfs'], F['S'], trans='T', beta=1.0)
if H is not None:
F['S'] += H
try:
if type(F['S']) is matrix:
lapack.potrf(F['S'])
else:
F['Sf'] = cholmod.symbolic(F['S'])
cholmod.numeric(F['S'], F['Sf'])
except ArithmeticError:
F['singular'] = True
if type(A) is matrix and type(F['S']) is spmatrix:
F['S'] = matrix(0.0, (n, n))
base.syrk(F['Gs'], F['S'], trans='T')
if mnl:
base.syrk(F['Dfs'], F['S'], trans='T', beta=1.0)
base.syrk(A, F['S'], trans='T', beta=1.0)
if H is not None:
F['S'] += H
if type(F['S']) is matrix:
lapack.potrf(F['S'])
else:
# 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]:
#
# 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
if type(F['S']) is matrix:
blas.trsv(F['S'], x)
else:
cholmod.solve(F['Sf'], x, sys=7)
cholmod.solve(F['Sf'], x, sys=4)
# y := K^{-1} * (Asc*x - y)
# = K^{-1} * (A * S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz) - by)
# (if not F['singular'])
# = K^{-1} * (A * S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz +
# A'*by) - by)
# (if F['singular']).
base.gemv(Asct, x, y, trans='T', beta=-1.0)
if type(F['K']) is matrix:
lapack.potrs(F['K'], y)
else:
cholmod.solve(Kf, y)
# x := P' * L^{-T} * (x - Asc'*y)
# = S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz - A'*y)
# (if not F['singular'])
# = S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz + A'*by - A'*y)
# (if F['singular'])
base.gemv(Asct, y, x, alpha=-1.0, beta=1.0)
if type(F['S']) is matrix:
blas.trsv(F['S'], x, trans='T')
else:
cholmod.solve(F['Sf'], x, sys=5)
cholmod.solve(F['Sf'], x, sys=8)
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
# 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])
def g(x, y, z):
x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + \
mul(d1, z[:n] + mul(d3, z[:n])) - \
mul(d2, z[n:] - mul(d3, z[n:])) )
x[:n] = div( x[:n], ds)
# Solve
#
# S * v = 0.5 * A * D^-1 * ( bx[:n]
# - (D2-D1)*(D1+D2)^-1 * bx[n:]
# + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bz[:n]
# - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bz[n:] )
blas.gemv(Asc, x, v)
lapack.potrs(S, v)
# x[:n] = D^-1 * ( rhs - A'*v ).
blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T')
x[:n] = div(x[:n], ds)
# x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bz[:n] - D2*bz[n:] )
# - (D2-D1)*(D1+D2)^-1 * x[:n]
x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 )\
- mul( d3, x[:n] )
# z[:n] = D1^1/2 * ( x[:n] - x[n:] - bz[:n] )
# z[n:] = D2^1/2 * ( -x[:n] - x[n:] - bz[n:] ).
z[:n] = mul( W['di'][:n], x[:n] - x[n:] - z[:n] )
z[n:] = mul( W['di'][n:], -x[:n] - x[n:] - z[n:] )
# lmbda[ dims['l'] + sum(dims['q']) : -1 ]
W['r'] = [ matrix(0.0, (m,m)) for m in dims['s'] ]
W['rti'] = [ matrix(0.0, (m,m)) for m in dims['s'] ]
work = matrix(0.0, (max( [0] + dims['s'] )**2, 1))
Ls = matrix(0.0, (max( [0] + dims['s'] )**2, 1))
Lz = matrix(0.0, (max( [0] + dims['s'] )**2, 1))
ind2 = ind
for k in range(len(dims['s'])):
m = dims['s'][k]
r, rti = W['r'][k], W['rti'][k]
# Factor sk = Ls*Ls'; store Ls in ds[inds[k]:inds[k+1]].
blas.copy(s, Ls, offsetx = ind2, n = m**2)
lapack.potrf(Ls, n = m, ldA = m)
# Factor zs[k] = Lz*Lz'; store Lz in dz[inds[k]:inds[k+1]].
blas.copy(z, Lz, offsetx = ind2, n = m**2)
lapack.potrf(Lz, n = m, ldA = m)
# SVD Lz'*Ls = U*diag(lambda_k)*V'. Keep U in work.
for i in range(m):
blas.scal(0.0, Ls, offset = i*m, n = i)
blas.copy(Ls, work, n = m**2)
blas.trmm(Lz, work, transA = 'T', ldA = m, ldB = m, n = m, m = m)
lapack.gesvd(work, lmbda, jobu = 'O', ldA = m, m = m, n = m,
offsetS = ind)
# r = Lz^{-T} * U
blas.copy(work, r, n = m*m)
blas.trsm(Lz, r, transA = 'T', m = m, n = m, ldA = m)
def factor(W, H = None, Df = None):
blas.scal(0.0, K)
if H is not None: K[:n, :n] = H
K[n:,:n] = A
for k in range(n):
if mnl: g[:mnl] = Df[:,k]
g[mnl:] = G[:,k]
scale(g, W, trans = 'T', inverse = 'I')
scale(g, W, inverse = 'I')
if mnl: base.gemv(Df, g, K, trans = 'T', beta = 1.0, n = n-k,
offsetA = mnl*k, offsety = (ldK + 1)*k)
sgemv(G, g, K, dims, trans = 'T', beta = 1.0, n = n-k,
offsetA = G.size[0]*k, offsetx = mnl, offsety =
(ldK + 1)*k)
if p: lapack.sytrf(K, ipiv)
else: lapack.potrf(K)
def solve(x, y, z):
# Solve
#
# [ H + GG' * W^{-1} * W^{-T} * GG A' ] [ ux ]
# [ ] * [ ]
# [ A 0 ] [ uy ]
#
# [ bx + GG' * W^{-1} * W^{-T} * bz ]
# = [ ]
# [ by ]
#
# and return x, y, W*z = W^{-T} * (GG*x - bz).