def test_llt(self): A = cp.cspmatrix(self.symb) + self.A cp.cholesky(A) cp.llt(A) Am = A.spmatrix(reordered=False) diff = list((Am - self.A).V) self.assertAlmostEqualLists(diff, len(diff) * [0.0])
def test_projected_inverse(self): Y = cp.cspmatrix(self.symb) + self.A Am = Y.spmatrix(symmetric=True,reordered=False) cp.cholesky(Y) cp.projected_inverse(Y) Ym = Y.spmatrix(symmetric=True,reordered=False) self.assertAlmostEqual((Ym.V.T*(Am.V))[0], self.symb.n)
def test_projected_inverse(self): Y = cp.cspmatrix(self.symb) + self.A Am = Y.spmatrix(symmetric=True, reordered=False) cp.cholesky(Y) cp.projected_inverse(Y) Ym = Y.spmatrix(symmetric=True, reordered=False) self.assertAlmostEqual((Ym.V.T * (Am.V))[0], self.symb.n)
def __init__(self, X, V, a=None, p=None): self._n = X.size[0] self._V = +V assert X.size[0] == X.size[1], 'X must be a square matrix' assert X.size[0] == V.size[ 0], 'V must have have the same number of rows as X' assert isinstance(V, matrix), 'V must be a dense matrix' if isinstance(X, cspmatrix) and X.is_factor is False: self._L0 = X.copy() cp.cholesky(self._L0) cp.trsm(self._L0, self._V) elif isinstance(X, cspmatrix) and X.is_factor is True: self._L0 = X cp.trsm(self._L0, self._V) elif isinstance(X, spmatrix): symb = symbolic(X, p=p) self._L0 = cspmatrix(symb) + X cp.cholesky(self._L0) cp.trsm(self._L0, self._V) elif isinstance(X, matrix): raise NotImplementedError else: raise TypeError if a is None: a = matrix(1.0, (self._n, 1)) self._L = matrix(0.0, V.size) self._B = matrix(0.0, V.size) pfchol(a, self._V, self._L, self._B) return
def test_llt(self): A = cp.cspmatrix(self.symb) + self.A cp.cholesky(A) cp.llt(A) Am = A.spmatrix(reordered=False) diff = list( (Am - self.A).V ) self.assertAlmostEqualLists(diff, len(diff)*[0.0])
def test_completion_fu(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) L2 = L.copy() cp.projected_inverse(L2) cp.completion(L2, factored_updates = True) diff = list((L.spmatrix()-L2.spmatrix()).V) self.assertAlmostEqualLists(diff, len(diff)*[0.0])
def test_completion_fu(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) L2 = L.copy() cp.projected_inverse(L2) cp.completion(L2, factored_updates=True) diff = list((L.spmatrix() - L2.spmatrix()).V) self.assertAlmostEqualLists(diff, len(diff) * [0.0])
def test_hessian_fu(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) Y = L.copy() cp.projected_inverse(Y) U = cp.cspmatrix(self.symb) + 0.1*self.A cp.hessian(L, Y, U, adj = False, inv = False, factored_updates = True) cp.hessian(L, Y, U, adj = True, inv = False, factored_updates = True) cp.hessian(L, Y, U, adj = True, inv = True, factored_updates = True) cp.hessian(L, Y, U, adj = False, inv = True, factored_updates = True) diff = list((0.1*self.A-U.spmatrix(reordered=False,symmetric=False)).V) self.assertAlmostEqualLists(diff, len(diff)*[0.0])
def test_hessian_fu(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) Y = L.copy() cp.projected_inverse(Y) U = cp.cspmatrix(self.symb) + 0.1 * self.A cp.hessian(L, Y, U, adj=False, inv=False, factored_updates=True) cp.hessian(L, Y, U, adj=True, inv=False, factored_updates=True) cp.hessian(L, Y, U, adj=True, inv=True, factored_updates=True) cp.hessian(L, Y, U, adj=False, inv=True, factored_updates=True) diff = list( (0.1 * self.A - U.spmatrix(reordered=False, symmetric=False)).V) self.assertAlmostEqualLists(diff, len(diff) * [0.0])
def test_trmm(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) B = cp.eye(self.symb.n) cp.trmm(L, B) diff = list((L.spmatrix(reordered=True) - B[self.symb.p,self.symb.p])[:]) self.assertAlmostEqualLists(diff, len(diff)*[0.0]) B = cp.eye(self.symb.n) cp.trmm(L, B, trans = 'T') diff = list((L.spmatrix(reordered=True).T - B[self.symb.p,self.symb.p])[:]) self.assertAlmostEqualLists(diff, len(diff)*[0.0])
def test_trmm(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) B = cp.eye(self.symb.n) cp.trmm(L, B) diff = list( (L.spmatrix(reordered=True) - B[self.symb.p, self.symb.p])[:]) self.assertAlmostEqualLists(diff, len(diff) * [0.0]) B = cp.eye(self.symb.n) cp.trmm(L, B, trans='T') diff = list( (L.spmatrix(reordered=True).T - B[self.symb.p, self.symb.p])[:]) self.assertAlmostEqualLists(diff, len(diff) * [0.0])
def mk_rand(V, cone='posdef', seed=0): """ Generates random matrix U with sparsity pattern V. - U is positive definite if cone is 'posdef'. - U is completable if cone is 'completable'. """ if not (cone == 'posdef' or cone == 'completable'): raise ValueError, "cone must be 'posdef' (default) or 'completable' " from cvxopt import amd setseed(seed) n = V.size[0] U = +V U.V *= 0.0 for i in xrange(n): u = normal(n, 1) / sqrt(n) base.syrk(u, U, beta=1.0, partial=True) # test if U is in cone: if not, add multiple of identity t = 0.1 Ut = +U p = amd.order(Ut) # Vc, NF = chompack.embed(U,p) symb = chompack.symbolic(U, p) Vc = chompack.cspmatrix(symb) + U while True: # Uc = chompack.project(Vc,Ut) Uc = chompack.cspmatrix(symb) + Ut try: if cone == 'posdef': # positive definite? # Y = chompack.cholesky(Uc) Y = Uc.copy() chompack.cholesky(Y) elif cone == 'completable': # completable? # Y = chompack.completion(Uc) Y = Uc.copy() chompack.completion(Y) # Success: Ut is in cone U = +Ut break except: Ut = U + spmatrix(t, xrange(n), xrange(n), (n, n)) t *= 2.0 return U
def mk_rand(V,cone='posdef',seed=0): """ Generates random matrix U with sparsity pattern V. - U is positive definite if cone is 'posdef'. - U is completable if cone is 'completable'. """ if not (cone=='posdef' or cone=='completable'): raise ValueError("cone must be 'posdef' (default) or 'completable' ") from cvxopt import amd setseed(seed) n = V.size[0] U = +V U.V *= 0.0 for i in range(n): u = normal(n,1)/sqrt(n) base.syrk(u,U,beta=1.0,partial=True) # test if U is in cone: if not, add multiple of identity t = 0.1; Ut = +U p = amd.order(Ut) # Vc, NF = chompack.embed(U,p) symb = chompack.symbolic(U,p) Vc = chompack.cspmatrix(symb) + U while True: # Uc = chompack.project(Vc,Ut) Uc = chompack.cspmatrix(symb) + Ut try: if cone=='posdef': # positive definite? # Y = chompack.cholesky(Uc) Y = Uc.copy() chompack.cholesky(Y) elif cone=='completable': # completable? # Y = chompack.completion(Uc) Y = Uc.copy() chompack.completion(Y) # Success: Ut is in cone U = +Ut break except: Ut = U + spmatrix(t,range(n),range(n),(n,n)) t*=2.0 return U
def test_trsm(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) B = cp.eye(self.symb.n) Bt = matrix(B)[self.symb.p, :] Lt = matrix(L.spmatrix(reordered=True, symmetric=False)) cp.trsm(L, B) blas.trsm(Lt, Bt) diff = list((B - Bt[self.symb.ip, :])[:]) self.assertAlmostEqualLists(diff, len(diff) * [0.0]) B = cp.eye(self.symb.n) Bt = matrix(B)[self.symb.p, :] Lt = matrix(L.spmatrix(reordered=True, symmetric=False)) cp.trsm(L, B, trans='T') blas.trsm(Lt, Bt, transA='T') diff = list(B - Bt[self.symb.ip, :])[:] self.assertAlmostEqualLists(diff, len(diff) * [0.0])
def test_trsm(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) B = cp.eye(self.symb.n) Bt = matrix(B)[self.symb.p,:] Lt = matrix(L.spmatrix(reordered=True,symmetric=False)) cp.trsm(L, B) blas.trsm(Lt,Bt) diff = list((B-Bt[self.symb.ip,:])[:]) self.assertAlmostEqualLists(diff, len(diff)*[0.0]) B = cp.eye(self.symb.n) Bt = matrix(B)[self.symb.p,:] Lt = matrix(L.spmatrix(reordered=True,symmetric=False)) cp.trsm(L, B, trans = 'T') blas.trsm(Lt,Bt,transA='T') diff = list(B-Bt[self.symb.ip,:])[:] self.assertAlmostEqualLists(diff, len(diff)*[0.0])
def Fkkt(W): """ Custom KKT solver for [ Qinv 0 0 -D 0 ] [ ux_y ] [ bx_y ] [ 0 0 0 -d' 0 ] [ ux_b ] [ bx_b ] [ 0 0 0 -I -I ] [ ux_v ] = [ bx_v ] [ -D -d -I -D1 0 ] [ uz_z ] [ bz_z ] [ 0 0 -I 0 -D2 ] [ uz_w ] [ bz_w ] with D1 = diag(d1), D2 = diag(d2), d1 = W['d'][:N]**2, d2 = W['d'][N:])**2. """ d1, d2 = W['d'][:N]**2, W['d'][N:]**2 d3, d4 = (d1 + d2)**-1, (d1**-1 + d2**-1)**-1 # Factor the chordal matrix K = Qinv + (D_1+D_2)^-1. K.V = Qinv.V K[::N + 1] = K[::N + 1] + d3 L = chompack.cspmatrix(symb) + K chompack.cholesky(L) # Solve (Qinv + (D1+D2)^-1) * dy2 = (D1 + D2)^{-1} * 1 blas.copy(d3, dy2) chompack.trsm(L, dy2, trans='N') chompack.trsm(L, dy2, trans='T') def g(x, y, z): # Solve # # [ K d3 ] [ ux_y ] # [ ] [ ] = # [ d3' 1'*d3 ] [ ux_b ] # # [ bx_y ] [ D ] # [ ] - [ ] * D3 * (D2 * bx_v + bx_z - bx_w). # [ bx_b ] [ d' ] x[:N] -= mul(d, mul(d3, mul(d2, x[-N:]) + z[:N] - z[-N:])) x[N] -= blas.dot(d, mul(d3, mul(d2, x[-N:]) + z[:N] - z[-N:])) # Solve dy1 := K^-1 * x[:N] blas.copy(x, dy1, n=N) chompack.trsm(L, dy1, trans='N') chompack.trsm(L, dy1, trans='T') # Find ux_y = dy1 - ux_b * dy2 s.t # # d3' * ( dy1 - ux_b * dy2 + ux_b ) = x[N] # # i.e. x[N] := ( x[N] - d3'* dy1 ) / ( d3'* ( 1 - dy2 ) ). x[N] = ( x[N] - blas.dot(d3, dy1) ) / \ ( blas.asum(d3) - blas.dot(d3, dy2) ) x[:N] = dy1 - x[N] * dy2 # ux_v = D4 * ( bx_v - D1^-1 (bz_z + D * (ux_y + ux_b)) # - D2^-1 * bz_w ) x[-N:] = mul( d4, x[-N:] - div(z[:N] + mul(d, x[:N] + x[N]), d1) - div(z[N:], d2)) # uz_z = - D1^-1 * ( bx_z - D * ( ux_y + ux_b ) - ux_v ) # uz_w = - D2^-1 * ( bx_w - uz_w ) z[:N] += base.mul(d, x[:N] + x[N]) + x[-N:] z[-N:] += x[-N:] blas.scal(-1.0, z) # Return W['di'] * uz blas.tbmv(W['di'], z, n=2 * N, k=0, ldA=1) return g
def test_cholesky(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) Lm = L.spmatrix(reordered=True) diff = list((cp.tril(cp.perm(Lm * Lm.T, self.symb.ip)) - self.A).V) self.assertAlmostEqualLists(diff, len(diff) * [0.0])
print("Computing symbolic factorization..") p = amd.order symb = symbolic(As, p = p, merge_function = fmerge) print("Order of matrix : %i" % (symb.n)) print("Number of nonzeros : %i" % (symb.nnz)) print("Number of supernodes : %i" % (symb.Nsn)) print("Largest supernode : %i" % (max([symb.snptr[k+1]-symb.snptr[k] for k in range(symb.Nsn)]))) print("Largest clique : %i\n" % (symb.clique_number)) A = cspmatrix(symb) # create new cspmatrix from symbolic factorization A += As # add spmatrix 'As' to cspmatrix 'A'; this ignores the upper triangular entries in As print("Computing Cholesky factorization..") L = A.copy() # make a copy of A cholesky(L) # compute Cholesky factorization; overwrites L print("Computing Cholesky product..") At = L.copy() # make a copy of L llt(At) # compute Cholesky product; overwrites At print("Computing projected inverse..") Y = L.copy() # make a copy of L projected_inverse(Y) # compute projected inverse; overwrites Y print("Computing completion..") Lc = Y.copy() # make a copy of Y completion(Lc, factored_updates = False) # compute completion; overwrites Lc print("Computing completion with factored updates..") Lc2 = Y.copy() # make a copy of Y
def test_cholesky(self): L = cp.cspmatrix(self.symb) + self.A cp.cholesky(L) Lm = L.spmatrix(reordered=True) diff = list( (cp.tril(cp.perm(Lm*Lm.T,self.symb.ip)) - self.A).V ) self.assertAlmostEqualLists(diff, len(diff)*[0.0])