def lnprob(theta, Deltam, nsne, xi, redshiftterm): A, M, sigma, pv = theta if (A <= 0 or sigma < 0 or pv < 0): return -numpy.inf C = A * numpy.array(xi) numpy.fill_diagonal( C, C.diagonal() + sigma**2 / nsne + (pv * redshiftterm)**2) mterm = Deltam - M C = matrix(C) W = matrix(mterm) try: lapack.posv(C, W, uplo='U') except ArithmeticError: return -np.inf logdetC = 2 * numpy.log(numpy.array(C).diagonal()).sum() lp = -0.5 * (logdetC + blas.dot(matrix(mterm), W)) + cauchy.logpdf( sigma, loc=0.08, scale=0.5) + cauchy.logpdf( pv, loc=0, scale=600 / 3e5) if not numpy.isfinite(lp): return -np.inf return lp
def lapack_posv(a, b): """ Inverse using LaPaCK posv (definite positive) algorithm. :param a: :param b: :return: """ b_posv = matrix(b) lapack.posv(matrix(a), b_posv) return b_posv
def PLS2D_getBeta(theta, ZtX, ZtY, XtX, ZtZ, XtY, YtX, YtZ, XtZ, YtY, n, P, tinds, rinds, cinds): # Obtain Lambda Lambda = mapping2D(theta, tinds, rinds, cinds) # Obtain Lambda' Lambdat = spmatrix.trans(Lambda) # Obtain Lambda'Z'Y and Lambda'Z'X LambdatZtY = Lambdat * ZtY LambdatZtX = Lambdat * ZtX # Set the factorisation to use LL' instead of LDL' cholmod.options['supernodal'] = 2 # Obtain the cholesky decomposition LambdatZtZLambda = Lambdat * ZtZ * Lambda I = spmatrix(1.0, range(Lambda.size[0]), range(Lambda.size[0])) chol_dict = sparse_chol2D(LambdatZtZLambda + I, perm=P, retF=True, retP=False, retL=False) F = chol_dict['F'] # Obtain C_u (annoyingly solve writes over the second argument, # whereas spsolve outputs) Cu = LambdatZtY[P, :] cholmod.solve(F, Cu, sys=4) # Obtain RZX RZX = LambdatZtX[P, :] cholmod.solve(F, RZX, sys=4) # Obtain RXtRX RXtRX = XtX - matrix.trans(RZX) * RZX # Obtain beta estimates (note: gesv also replaces the second # argument) betahat = XtY - matrix.trans(RZX) * Cu try: lapack.posv(RXtRX, betahat) except: lapack.gesv(RXtRX, betahat) return (betahat)
def barrier(): # variables kept same from cvxopt example MAXITERS = 100 ALPHA = 0.01 BETA = 0.5 x = matrix(0.0, (n, 1)) H = matrix(0.0, (n, n)) # Symmetrix matrix for iter in range(MAXITERS): # get the gradient of the function d = (b - A * x)**-1 g = A.T * d # print(d[:, n*[0]].size) # print(A.size) """bug here: won't multiply of two matrix of same dimension. code is looking into another dimension?""" # get Hessian # lower diaganol multiplied to constraint matrix, n*[0] is first center x^t(0) h = np.zeros(shape=(m, n)) np.matmul(d[:, n * [0]], A, h) # use the BLAS solver to get the symmetric matrix and get roots blas.syrk(h, H, trans='T') # do Newton's step v = -g # g is our gradient # LAPACK solves the matrix and gives us the tep value to transverse with lapack.posv(H, v) # Stop condition if exceeding tolerance lam = blas.dot(g, v) if sqrt(-lam) < mu: return x # return the orignal value if we're above tolerance # Line search to go to optimal using ALPHA and BETA y = mul(A * v, d) step = 1.0 while 1 - step * max(y) < 0: step *= BETA while True: if -sum(log(1 - step * y)) < (ALPHA * step * lam): break step *= BETA # increment x by the step times the negative gradient otherwise x += step * v
def acent(A, b): """ Computes analytic center of A*x <= b with A m by n of rank n. We assume that b > 0 and the feasible set is bounded. """ MAXITERS = 100 ALPHA = 0.01 BETA = 0.5 TOL = 1e-8 ntdecrs = [] m, n = A.size x = matrix(0.0, (n, 1)) H = matrix(0.0, (n, n)) for iter in range(MAXITERS): # Gradient is g = A^T * (1./(b-A*x)). d = (b - A * x) ** -1 g = A.T * d # Hessian is H = A^T * diag(1./(b-A*x))^2 * A. Asc = mul(d[:, n * [0]], A) blas.syrk(Asc, H, trans="T") # Newton step is v = H^-1 * g. v = -g lapack.posv(H, v) # Directional derivative and Newton decrement. lam = blas.dot(g, v) ntdecrs += [sqrt(-lam)] print("%2d. Newton decr. = %3.3e" % (iter, ntdecrs[-1])) if ntdecrs[-1] < TOL: return x, ntdecrs # Backtracking line search. y = mul(A * v, d) step = 1.0 while 1 - step * max(y) < 0: step *= BETA while True: if -sum(log(1 - step * y)) < ALPHA * step * lam: break step *= BETA x += step * v
def acent(A, b): """ Computes analytic center of A*x <= b with A m by n of rank n. We assume that b > 0 and the feasible set is bounded. """ MAXITERS = 100 ALPHA = 0.01 BETA = 0.5 TOL = 1e-8 ntdecrs = [] m, n = A.size x = matrix(0.0, (n, 1)) H = matrix(0.0, (n, n)) for iter in range(MAXITERS): # Gradient is g = A^T * (1./(b-A*x)). d = (b - A * x)**-1 g = A.T * d # Hessian is H = A^T * diag(1./(b-A*x))^2 * A. Asc = mul(d[:, n * [0]], A) blas.syrk(Asc, H, trans='T') # Newton step is v = H^-1 * g. v = -g lapack.posv(H, v) # Directional derivative and Newton decrement. lam = blas.dot(g, v) ntdecrs += [sqrt(-lam)] print("%2d. Newton decr. = %3.3e" % (iter, ntdecrs[-1])) if ntdecrs[-1] < TOL: return x, ntdecrs # Backtracking line search. y = mul(A * v, d) step = 1.0 while 1 - step * max(y) < 0: step *= BETA while True: if -sum(log(1 - step * y)) < ALPHA * step * lam: break step *= BETA x += step * v
# Nominal problem: minimize || A*x - b ||_2 xnom = +b lapack.gels(+A, xnom) xnom = xnom[:n] # Stochastic problem. # # minimize E || (A+u*B) * x - b ||_2^2 # = || A*x - b||_2^2 + x'*P*x # # with P = E(u^2) * B'*B = (1/3) * B'*B S = A.T * A + (1.0 / 3.0) * B.T * B xstoch = A.T * b lapack.posv(S, xstoch) # Worst case approximation. # # minimize max_{-1 <= u <= 1} ||A*u - b||_2^2. xwc = wcls(A, [B], b) nopts = 500 us = -2.0 + (2.0 - (-2.0)) / (nopts - 1) * matrix(list(range(nopts)), tc='d') rnom = [blas.nrm2((A + u * B) * xnom - b) for u in us] rstoch = [blas.nrm2((A + u * B) * xstoch - b) for u in us] rwc = [blas.nrm2((A + u * B) * xwc - b) for u in us] if pylab_installed: pylab.figure(1, facecolor='w')
def covsel(Y): """ Returns the solution of minimize -log det K + Tr(KY) subject to K_{ij}=0, (i,j) not in indices listed in I,J. Y is a symmetric sparse matrix with nonzero diagonal elements. I = Y.I, J = Y.J. """ I, J = Y.I, Y.J n, m = Y.size[0], len(I) N = I + J*n # non-zero positions for one-argument indexing D = [k for k in range(m) if I[k]==J[k]] # position of diagonal elements # starting point: symmetric identity with nonzero pattern I,J K = spmatrix(0.0, I, J) K[::n+1] = 1.0 # Kn is used in the line search Kn = spmatrix(0.0, I, J) # symbolic factorization of K F = cholmod.symbolic(K) # Kinv will be the inverse of K Kinv = matrix(0.0, (n,n)) for iters in range(100): # numeric factorization of K cholmod.numeric(K, F) d = cholmod.diag(F) # compute Kinv by solving K*X = I Kinv[:] = 0.0 Kinv[::n+1] = 1.0 cholmod.solve(F, Kinv) # solve Newton system grad = 2*(Y.V - Kinv[N]) hess = 2*(mul(Kinv[I,J],Kinv[J,I]) + mul(Kinv[I,I],Kinv[J,J])) v = -grad lapack.posv(hess,v) # stopping criterion sqntdecr = -blas.dot(grad,v) print("Newton decrement squared:%- 7.5e" %sqntdecr) if (sqntdecr < 1e-12): print("number of iterations: ", iters+1) break # line search dx = +v dx[D] *= 2 # scale the diagonal elems f = -2.0 * sum(log(d)) # f = -log det K s = 1 for lsiter in range(50): Kn.V = K.V + s*dx try: cholmod.numeric(Kn, F) except ArithmeticError: s *= 0.5 else: d = cholmod.diag(F) fn = -2.0 * sum(log(d)) + 2*s*blas.dot(v,Y.V) if (fn < f - 0.01*s*sqntdecr): break s *= 0.5 K.V = Kn.V return K
# Worst-case distribution from dual solution. X = [Z[2, :2].T / Z[2, 2] for Z in sol['zs'] if Z[2, 2] > 1e-5] return bound, P, q, r, X # Compute bound for s0 with sigma = 1.0. # Write ellipse {x | x'*P*x + 2*q'*x + r = 1} in the form # {xc + L^{-T}*u | ||u||_2 = 1} Sigma = matrix([1.0, 0.0, 0.0, 1.0], (2, 2)) bnd, P, q, r, X = cheb(A0, b0, Sigma) xc = -q L = +P lapack.posv(L, xc) L /= sqrt(1 - r - blas.dot(q, xc)) if pylab_installed: def makefig1(): pylab.figure(1, facecolor='w', figsize=(6, 6)) pylab.plot(V[0, :].T, V[1, :].T, 'b-') nopts = 1000 angles = matrix([a * 2.0 * pi / nopts for a in range(nopts)], (1, nopts)) circle = matrix(0.0, (2, nopts)) circle[0, :], circle[1, :] = cos(angles), sin(angles) for k in range(len(C)): c = C[k] pylab.plot([c[0]], [c[1]], 'ow')
# Nominal problem: minimize || A*x - b ||_2 xnom = +b lapack.gels(+A, xnom) xnom = xnom[:n] # Stochastic problem. # # minimize E || (A+u*B) * x - b ||_2^2 # = || A*x - b||_2^2 + x'*P*x # # with P = E(u^2) * B'*B = (1/3) * B'*B S = A.T * A + (1.0/3.0) * B.T * B xstoch = A.T * b lapack.posv(S, xstoch) # Worst case approximation. # # minimize max_{-1 <= u <= 1} ||A*u - b||_2^2. xwc = wcls(A, [B], b) nopts = 500 us = -2.0 + (2.0 - (-2.0))/(nopts-1) * matrix(list(range(nopts)),tc='d') rnom = [ blas.nrm2( (A+u*B)*xnom - b) for u in us ] rstoch = [ blas.nrm2( (A+u*B)*xstoch - b) for u in us ] rwc = [ blas.nrm2( (A+u*B)*xwc - b) for u in us ] if pylab_installed:
# Worst-case distribution from dual solution. X = [ Z[2,:2].T / Z[2,2] for Z in sol['zs'] if Z[2,2] > 1e-5 ] return bound, P, q, r, X # Compute bound for s0 with sigma = 1.0. # Write ellipse {x | x'*P*x + 2*q'*x + r = 1} in the form # {xc + L^{-T}*u | ||u||_2 = 1} Sigma = matrix([1.0, 0.0, 0.0, 1.0], (2,2)) bnd, P, q, r, X = cheb(A0, b0, Sigma) xc = -q L = +P lapack.posv(L, xc) L /= sqrt(1 - r - blas.dot(q, xc)) if pylab_installed: def makefig1(): pylab.figure(1, facecolor='w', figsize=(6,6)) pylab.plot(V[0,:].T, V[1,:].T, 'b-') nopts = 1000 angles = matrix( [a*2.0*pi/nopts for a in range(nopts) ], (1,nopts) ) circle = matrix(0.0, (2,nopts)) circle[0,:], circle[1,:] = cos(angles), sin(angles) for k in range(len(C)): c = C[k] pylab.plot([c[0]], [c[1]], 'og') pylab.text(c[0], c[1], "s%d" %k)
def PLS2D_getSigma2(theta, ZtX, ZtY, XtX, ZtZ, XtY, YtX, YtZ, XtZ, YtY, n, P, I, tinds, rinds, cinds): # Obtain Lambda #t1 = time.time() Lambda = mapping2D(theta, tinds, rinds, cinds) #t2 = time.time() #print(t2-t1)#3.170967102050781e-05 9 # Obtain Lambda' #t1 = time.time() Lambdat = spmatrix.trans(Lambda) #t2 = time.time() #print(t2-t1)# 3.5762786865234375e-06 # Obtain Lambda'Z'Y and Lambda'Z'X #t1 = time.time() LambdatZtY = Lambdat * ZtY LambdatZtX = Lambdat * ZtX #t2 = time.time() #print(t2-t1)#1.049041748046875e-05 13 # Obtain the cholesky decomposition #t1 = time.time() LambdatZtZLambda = Lambdat * (ZtZ * Lambda) #t2 = time.time() #print(t2-t1)#3.790855407714844e-05 2 #t1 = time.time() chol_dict = sparse_chol2D(LambdatZtZLambda + I, perm=P, retF=True, retP=False, retL=False) F = chol_dict['F'] #t2 = time.time() #print(t2-t1)#0.0001342296600341797 1 # Obtain C_u (annoyingly solve writes over the second argument, # whereas spsolve outputs) #t1 = time.time() Cu = LambdatZtY[P, :] cholmod.solve(F, Cu, sys=4) #t2 = time.time() #print(t2-t1)#1.5974044799804688e-05 5 # Obtain RZX #t1 = time.time() RZX = LambdatZtX[P, :] cholmod.solve(F, RZX, sys=4) #t2 = time.time() #print(t2-t1)#1.2159347534179688e-05 7 # Obtain RXtRX #t1 = time.time() RXtRX = XtX - matrix.trans(RZX) * RZX #t2 = time.time() #print(t2-t1)#9.775161743164062e-06 11 # Obtain beta estimates (note: gesv also replaces the second # argument) #t1 = time.time() betahat = XtY - matrix.trans(RZX) * Cu try: lapack.posv(RXtRX, betahat) except: lapack.gesv(RXtRX, betahat) #t2 = time.time() #print(t2-t1)#1.7404556274414062e-05 6 # Obtain u estimates #t1 = time.time() uhat = Cu - RZX * betahat cholmod.solve(F, uhat, sys=5) cholmod.solve(F, uhat, sys=8) #t2 = time.time() #print(t2-t1)#1.2874603271484375e-05 8 # Obtain b estimates #t1 = time.time() bhat = Lambda * uhat #t2 = time.time() #print(t2-t1)#2.86102294921875e-06 15 # Obtain residuals sum of squares #t1 = time.time() resss = YtY - 2 * YtX * betahat - 2 * YtZ * bhat + 2 * matrix.trans( betahat) * XtZ * bhat + matrix.trans( betahat) * XtX * betahat + matrix.trans(bhat) * ZtZ * bhat #t2 = time.time() #print(t2-t1)#3.409385681152344e-05 4 # Obtain penalised residual sum of squares #t1 = time.time() pss = resss + matrix.trans(uhat) * uhat return (pss / n)
def covsel(Y): """ Returns the solution of minimize -log det K + tr(KY) subject to K_ij = 0 if (i,j) not in zip(I, J). Y is a symmetric sparse matrix with nonzero diagonal elements. I = Y.I, J = Y.J. """ cholmod.options['supernodal'] = 2 I, J = Y.I, Y.J n, m = Y.size[0], len(I) # non-zero positions for one-argument indexing N = I + J*n # position of diagonal elements D = [ k for k in range(m) if I[k]==J[k] ] # starting point: symmetric identity with nonzero pattern I,J K = spmatrix(0.0, I, J) K[::n+1] = 1.0 # Kn is used in the line search Kn = spmatrix(0.0, I, J) # symbolic factorization of K F = cholmod.symbolic(K) # Kinv will be the inverse of K Kinv = matrix(0.0, (n,n)) for iters in range(100): # numeric factorization of K cholmod.numeric(K, F) d = cholmod.diag(F) # compute Kinv by solving K*X = I Kinv[:] = 0.0 Kinv[::n+1] = 1.0 cholmod.solve(F, Kinv) # solve Newton system grad = 2 * (Y.V - Kinv[N]) hess = 2 * ( mul(Kinv[I,J], Kinv[J,I]) + mul(Kinv[I,I], Kinv[J,J]) ) v = -grad lapack.posv(hess,v) # stopping criterion sqntdecr = -blas.dot(grad,v) print("Newton decrement squared:%- 7.5e" %sqntdecr) if (sqntdecr < 1e-12): print("number of iterations: %d" %(iters+1)) break # line search dx = +v dx[D] *= 2 f = -2.0*sum(log(d)) # f = -log det K s = 1 for lsiter in range(50): Kn.V = K.V + s*dx try: cholmod.numeric(Kn, F) except ArithmeticError: s *= 0.5 else: d = cholmod.diag(F) fn = -2.0 * sum(log(d)) + 2*s*blas.dot(v,Y.V) if (fn < f - 0.01*s*sqntdecr): break else: s *= 0.5 K.V = Kn.V return K
def PLS(theta, ZtX, ZtY, XtX, ZtZ, XtY, YtX, YtZ, XtZ, YtY, P, tinds, rinds, cinds): #t1 = time.time() # Obtain Lambda from theta Lambda = mapping(theta, tinds, rinds, cinds) #t2 = time.time() #print(t2-t1) #t1 = time.time() # Obtain Lambda' Lambdat = spmatrix.trans(Lambda) #t2 = time.time() #print(t2-t1) #t1 = time.time() LambdatZtY = Lambdat * ZtY #t2 = time.time() #print(t2-t1) #t1 = time.time() LambdatZtX = Lambdat * ZtX #t2 = time.time() #print(t2-t1) #t1 = time.time() # Set the factorisation to use LL' instead of LDL' cholmod.options['supernodal'] = 2 #t2 = time.time() #print(t2-t1) # Obtain L #t1 = time.time() LambdatZtZLambda = Lambdat * ZtZ * Lambda #t2 = time.time() #print(t2-t1) #t1 = time.time() I = spmatrix(1.0, range(Lambda.size[0]), range(Lambda.size[0])) #t2 = time.time() #print(t2-t1) #t1 = time.time() chol_dict = sparse_chol(LambdatZtZLambda + I, perm=P, retF=True, retP=False, retL=False) #t2 = time.time() #print(t2-t1) #t1 = time.time() F = chol_dict['F'] #t2 = time.time() #print(t2-t1) # Obtain C_u (annoyingly solve writes over the second argument, # whereas spsolve outputs) #t1 = time.time() Cu = LambdatZtY[P, :] #t2 = time.time() #print(t2-t1) #t1 = time.time() cholmod.solve(F, Cu, sys=4) #t2 = time.time() #print(t2-t1) # Obtain RZX #t1 = time.time() RZX = LambdatZtX[P, :] #t2 = time.time() #print(t2-t1) #t1 = time.time() cholmod.solve(F, RZX, sys=4) #t2 = time.time() #print(t2-t1) # Obtain RXtRX #t1 = time.time() RXtRX = XtX - matrix.trans(RZX) * RZX #t2 = time.time() #print(t2-t1) #print(RXtRX.size) #print(X.size) #print(Y.size) #print(RZX.size) #print(Cu.size) # Obtain beta estimates (note: gesv also replaces the second # argument) #t1 = time.time() betahat = XtY - matrix.trans(RZX) * Cu #t2 = time.time() #print(t2-t1) #t1 = time.time() lapack.posv(RXtRX, betahat) #t2 = time.time() #print(t2-t1) # Obtain u estimates #t1 = time.time() uhat = Cu - RZX * betahat #t2 = time.time() #print(t2-t1) #t1 = time.time() cholmod.solve(F, uhat, sys=5) #t2 = time.time() #print(t2-t1) #t1 = time.time() cholmod.solve(F, uhat, sys=8) #t2 = time.time() #print(t2-t1) # Obtain b estimates #t1 = time.time() bhat = Lambda * uhat #t2 = time.time() #print(t2-t1) # Obtain residuals sum of squares #t1 = time.time() resss = YtY - 2 * YtX * betahat - 2 * YtZ * bhat + 2 * matrix.trans( betahat) * XtZ * bhat + matrix.trans( betahat) * XtX * betahat + matrix.trans(bhat) * ZtZ * bhat #t2 = time.time() #print(t2-t1) # Obtain penalised residual sum of squares #t1 = time.time() pss = resss + matrix.trans(uhat) * uhat #t2 = time.time() #print(t2-t1) # Obtain Log(|L|^2) #t1 = time.time() logdet = 2 * sum(cvxopt.log( cholmod.diag(F))) # this method only works for symm decomps # Need to do tr(R_X)^2 for rml #t2 = time.time() #print(t2-t1) # Obtain log likelihood logllh = -logdet / 2 - X.size[0] / 2 * (1 + np.log(2 * np.pi * pss) - np.log(X.size[0])) #print(L[::(L.size[0]+1)]) # gives diag #print(logllh[0,0]) #print(theta) return (-logllh[0, 0])
def PeLS2D(theta, ZtX, ZtY, XtX, ZtZ, XtY, YtX, YtZ, XtZ, YtY, n, P, I, tinds, rinds, cinds): # Obtain Lambda Lambda = mapping2D(theta, tinds, rinds, cinds) # Obtain Lambda' Lambdat = spmatrix.trans(Lambda) # Obtain Lambda'Z'Y and Lambda'Z'X LambdatZtY = Lambdat * ZtY LambdatZtX = Lambdat * ZtX # Obtain the cholesky decomposition LambdatZtZLambda = Lambdat * (ZtZ * Lambda) chol_dict = sparse_chol2D(LambdatZtZLambda + I, perm=P, retF=True, retP=False, retL=False) F = chol_dict['F'] # Obtain C_u (annoyingly solve writes over the second argument, # whereas spsolve outputs) Cu = LambdatZtY[P, :] cholmod.solve(F, Cu, sys=4) # Obtain RZX RZX = LambdatZtX[P, :] cholmod.solve(F, RZX, sys=4) # Obtain RXtRX RXtRX = XtX - matrix.trans(RZX) * RZX # Obtain beta estimates (note: gesv also replaces the second # argument) betahat = XtY - matrix.trans(RZX) * Cu try: lapack.posv(RXtRX, betahat) except: lapack.gesv(RXtRX, betahat) # Obtain u estimates uhat = Cu - RZX * betahat cholmod.solve(F, uhat, sys=5) cholmod.solve(F, uhat, sys=8) # Obtain b estimates bhat = Lambda * uhat # Obtain residuals sum of squares resss = YtY - 2 * YtX * betahat - 2 * YtZ * bhat + 2 * matrix.trans( betahat) * XtZ * bhat + matrix.trans( betahat) * XtX * betahat + matrix.trans(bhat) * ZtZ * bhat # Obtain penalised residual sum of squares pss = resss + matrix.trans(uhat) * uhat # Obtain Log(|L|^2) logdet = 2 * sum(cvxopt.log(cholmod.diag(F))) # Obtain log likelihood logllh = -logdet / 2 - n / 2 * (1 + np.log(2 * np.pi * pss[0, 0]) - np.log(n)) return (-logllh)