def _generate_clique_alt(variables, obj, inequalities, equalities): n_dim = len(variables) rmat = spmatrix(1.0, range(n_dim), range(n_dim)) for support in get_support(variables, obj): nonzeros = np.nonzero(support)[0] value = random.random() for i in nonzeros: for j in nonzeros: rmat[i, j] = value for polynomial in flatten([inequalities, equalities]): support = np.any(get_support(variables, polynomial), axis=0) nonzeros = np.nonzero(support)[0] value = random.random() for i in nonzeros: for j in nonzeros: rmat[i, j] = value rmat = rmat + 5*n_dim*spmatrix(1.0, range(n_dim), range(n_dim)) # compute symbolic factorization using AMD ordering symb = cp.symbolic(rmat, p=amd.order) ip = symb.ip # symb = cp.symbolic(rmat) # ip = range(n_dim) cliques = symb.cliques() R = np.zeros((len(cliques), n_dim)) for i, clique in enumerate(cliques): for j in range(len(clique)): R[i, ip[cliques[i][j]]] = 1 return R
def _l1tf(corr, delta): """ minimize (1/2) * ||x-corr||_2^2 + delta * sum(y) subject to -y <= D*x <= y Variables x (n), y (n-2). :param x: :return: """ n = corr.size[0] m = n - 2 D = get_second_derivative_matrix(n) P = D * D.T q = -D * corr G = spmatrix([], [], [], (2*m, m)) G[:m, :m] = spmatrix(1.0, range(m), range(m)) G[m:, :m] = -spmatrix(1.0, range(m), range(m)) h = matrix(delta, (2*m, 1), tc='d') res = solvers.qp(P, q, G, h) return corr - D.T * res['x']
def test_pcg(): 'Test function for projected CG.' n = 10 m = 4 H = sprandsym(n,n) A = sp_rand(m,n,0.9) x0 = matrix(1,(n,1)) b = A*x0 c = matrix(1.0,(n,1)) x_pcg = pcg(H,c,A,b,x0) Lhs1 = sparse([H,A]) Lhs2 = sparse([A.T,spmatrix([],[],[],(m,m))]) Lhs = sparse([[Lhs1],[Lhs2]]) rhs = -matrix([c,spmatrix([],[],[],(m,1))]) rhs2 = copy(rhs) linsolve(Lhs,rhs) #print rhs[:10] sol = solvers.qp(H,c,A=A,b=b) print ' cvxopt qp| pCG' print matrix([[sol['x']],[x_pcg]]) print 'Dual variables:' print sol['y'] print 'KKT equation residuals:' print H*sol['x'] + c + A.T*sol['y']
def Norm_inf1 (X,W): # X, W are two matrix of shape respectively f*n et r*n f,n = X.size r = W.size[0] print f,n,r P = matrix(W).trans() F = matrix(1.0,(f,r)) onesn = matrix(1.0,(n,1)) Idn = spmatrix(1.0, range(n),range(n)) Idr = spmatrix(1.0, range(r),range(r)) Zrn = spmatrix(0,[r-1],[n-1]) Zr = spmatrix(0,[r-1],[0]) #Zn = spmatrix(0,[n-1],[0]) A = sparse([ [P,-P,-Idr], [-Idn,-Idn,Zrn] ]) for i in range(f): V = X[i,:].trans() C = matrix([[V,-V,Zr]]) e = matrix([ [Zr, onesn] ]) solution = solvers.lp(e,A,C)['x'] F[i,:] = solution[range(r)].trans() return F
def solve_robust_subproblem_1d(u, parameters, excess_return): b = beta(u, excess_return) eab = expected_alpha_beta(u, parameters, excess_return, numpy.array([[1]])) a = alpha(u, parameters, excess_return[0]) m = 1 n = len(b) g = cvxopt.spmatrix(-1.0, [0,2,3], [0,1,2]) h = cvxopt.matrix([[0.0, 1.0, 0.0, 0.0]]) coeffs = ([0.5] + [v for i in range(0, 2) for v in b]) rows = (range(0, n+1) + [0 for i in range(0,n)]) columns = ([0 for i in range(0, n+1)] + range(1, n+1)) p = cvxopt.spmatrix(coeffs, rows, columns) coeffs = [-a] + [mean_weight*v for v in eab] q = cvxopt.matrix([coeffs]) print g print h print p print q constraint_dimensions = {'l': 1, 'q': [3], 's': []} return cvxopt.solvers.coneqp(p, q, g, h, constraint_dimensions)
def constraints(self): # construct the constraints for the attack routing problem N = self.N u = np.tile(range(N), N) v = np.repeat(range(N),N) w = np.array(range(N*N)) # build constraint matrix A1 = spmatrix(np.repeat(self.nu, N), u, w, (N, N*N)) A2 = -spmatrix(np.repeat(self.nu + self.phi, N), v, w, (N, N*N)) I = np.array(range(N)) J = I + np.array(range(N)) * N A3 = spmatrix(self.phi, I, J, (N, N*N)) tmp = np.dot(np.diag(self.phi), self.delta).transpose() A4 = matrix(np.repeat(tmp, N, axis=1)) A5 = -spmatrix(tmp.flatten(), v, np.tile(J, N), (N, N*N)) A6 = A1 + A2 + A3 + A4 + A5 I = np.array([0]*(N-1)) J = np.array(range(self.k)+range((self.k+1),N)) + N * self.k A7 = spmatrix(1., I, J, (1, N*N)) A = sparse([[A6, -A6, A7, -A7, -spdiag([1.]*(N*N))]]) tmp = np.zeros(2*N + 2 + N*N) tmp[2*N] = 1. tmp[2*N + 1] = -1. b = matrix(tmp) return b, A
def geteq(n,dic): 'generate the equality constraints.' # Equality from the Laplace operator AeqL = -Laplace(n,dic) h = 1.0/(n-1) # Equality from the boundary AeqB = spmatrix([],[],[],(0,n**2+4*n)) for col in range(n): y = spmatrix([],[],[],(2,n**2+4*n)) y[0,dic[-1,col]] = 1 y[0,dic[1,col]] = -1 y[1,dic[n-2,col]] = -1 y[1,dic[n,col]] = 1 AeqB = sparse([AeqB,y]) for row in range(n): y = spmatrix([],[],[],(2,n**2+4*n)) y[0,dic[row,-1]] = 1 y[0,dic[row,1]] = -1 y[1,dic[row,n-2]] = -1 y[1,dic[row,n]] = 1 AeqB = sparse([AeqB,y]) AeqL = sparse([[AeqL],[spmatrix([],[],[],(n**2,n*4))]]) AeqB = sparse([[AeqB],[-identity(4*n,h*2)]]) Aeq = sparse([AeqL,AeqB]) beq = spmatrix([],[],[],(n**2+4*n,1)) return (Aeq, beq)
def embed_SDP(P,order="AMD",cholmod=False): if not isinstance(P,SDP): raise ValueError, "not an SDP object" if order=='AMD': from cvxopt.amd import order elif order=='METIS': from cvxopt.metis import order else: raise ValueError, "unknown ordering: %s " %(order) p = order(P.V) if cholmod: from cvxopt import cholmod V = +P.V + spmatrix([float(i+1) for i in xrange(P.n)],xrange(P.n),xrange(P.n)) F = cholmod.symbolic(V,p=p) cholmod.numeric(V,F) f = cholmod.getfactor(F) fd = [(j,i) for i,j in enumerate(f[:P.n**2:P.n+1])] fd.sort() ip = matrix([j for _,j in fd]) Ve = chompack.tril(chompack.perm(chompack.symmetrize(f),ip)) Ie = misc.sub2ind((P.n,P.n),Ve.I,Ve.J) else: #Vc,n = chompack.embed(P.V,p) symb = chompack.symbolic(P.V,p) #Ve = chompack.sparse(Vc) Ve = symb.sparsity_pattern(reordered=False) Ie = misc.sub2ind((P.n,P.n),Ve.I,Ve.J) Pe = SDP() Pe._A = +P.A; Pe._b = +P.b Pe._A[:,0] += spmatrix(0.0,Ie,[0 for i in range(len(Ie))],(Pe._A.size[0],1)) Pe._agg_sparsity() Pe._pname = P._pname + "_embed" Pe._ischordal = True; Pe._blockstruct = P._blockstruct return Pe
def _l1(signal, regularizer): """ Parameters: signal(np.ndarray): Original, volatile signal regularizer(float): regularizer to keep the balance between smoothing and 'truthfulness' of the signal Returns: trend(np.ndarray): Trend of the signal extracted from l1 regularization Problem Formulation: minimize (1/2) * ||x - signal||_2^2 + regularizer * sum(y) subject to | D*x | <= y """ signal_size = signal.size[0] temp = signal_size - 2 temp_ls = range(temp) D = _second_order_derivative_matrix(signal_size) P = D * D.T q = -D * signal G = spmatrix([], [], [], (2 * temp, temp)) G[:temp, :temp] = spmatrix(1.0, temp_ls, temp_ls) G[temp:, :temp] = -spmatrix(1.0, temp_ls, temp_ls) h = matrix(regularizer, (2 * temp, 1), tc='d') residual = solvers.qp(P, q, G, h) trend = signal - D.T * residual['x'] return trend
def F(x=None, z=None): """Oracle for function value, gradient, and Hessian. """ if x is None: return rows, big_x big_f = cvxopt.matrix(0., (rows, 1)) big_Df = cvxopt.spmatrix(0., [], [], size=(rows, cols)) if z: big_H = cvxopt.spmatrix(0., [], [], size=(cols, cols)) offset = 0 for constr in nonlin_constr: constr_entries = constr.size[0]*constr.size[1] local_x = constr.extract_variables(x, var_offsets) if z: f, Df, H = constr.f(local_x, z[offset:offset + constr_entries]) else: result = constr.f(local_x) if result: f, Df = result else: return None big_f[offset:offset + constr_entries] = f constr.place_Df(big_Df, Df, var_offsets, offset) if z: constr.place_H(big_H, H, var_offsets) offset += constr_entries if z is None: return big_f, big_Df return big_f, big_Df, big_H
def F(x=None,z=None): # Case 1 if(x is None and z is None): x0 = opt.matrix(np.ones((n,1)))*1.0 return (len(fs),x0) # Case 2 elif(x is not None and z is None): in_domain = map(lambda y: y(x),inds) if(reduce(lambda v,w: v and w,in_domain)): f = opt.matrix(0.0,(len(fs),1)) for i in range(0,len(fs),1): f[i] = fs[i](x) Df = opt.spmatrix(0.0,[],[],(0,n)) for i in range(0,len(grads),1): Df = opt.sparse([Df,grads[i](x).T]) return (f,Df) else: return (None,None) # Case 3 else: f = opt.matrix(0.0,(len(fs),1)) for i in range(0,len(fs),1): f[i] = fs[i](x) Df = opt.spmatrix(0.0,[],[],(0,n)) for i in range(0,len(grads),1): Df = opt.sparse([Df,grads[i](x).T]) H = opt.spmatrix(0.0,[],[],(n,n)) for i in range(0,len(hess),1): H = H + z[i]*hess[i](x) return (f,Df,H)
def F(x=None,z=None): # Case 1 if x is None and z is None: x0 = opt.matrix(1., (n,1)) return len(fs),x0 # Case 2 elif x is not None and z is None: if all(list(map(lambda y: y(x),inds))): f = opt.matrix(0.0,(len(fs),1)) for i in range(0,len(fs),1): f[i] = fs[i](x) Df = opt.spmatrix(0.0,[],[],(0,n)) for i in range(0,len(grads),1): Df = opt.sparse([Df,grads[i](x).T]) return f,Df else: return None,None # Case 3 else: f = opt.matrix(0.0,(len(fs),1)) for i in range(0,len(fs),1): f[i] = fs[i](x) Df = opt.spmatrix(0.0,[],[],(0,n)) for i in range(0,len(grads),1): Df = opt.sparse([Df,grads[i](x).T]) H = opt.spmatrix(0.0,[],[],(n,n)) for i in range(0,len(hess),1): H = H + z[i]*hess[i](x) return f,Df,H
def __init__(self, X_linear, X_smooth, train_indices, y, use_l1=False): assert(np.array_equal(X_smooth, np.sort(X_smooth, axis=0))) feature_size = X_linear.shape[1] num_samples = X_smooth.size # we want a 1st order trend filtering, so we want D^2, not D^1 off_diag_D1 = [1] * (num_samples - 1) mid_diag_D1 = off_diag_D1 + [0] simple_d1 = np.matrix(np.diagflat(off_diag_D1, 1) - np.diagflat(mid_diag_D1)) mid_diag = [1.0 / (X_smooth[i + 1, 0] - X_smooth[i, 0]) for i in range(0, num_samples - 1)] + [0] self.D = sp.sparse.coo_matrix(simple_d1 * np.matrix(np.diagflat(mid_diag)) * simple_d1) D_sparse = cvxopt.spmatrix(self.D.data, self.D.row.tolist(), self.D.col.tolist()) train_matrix = sp.sparse.coo_matrix(np.matrix(np.eye(num_samples))[train_indices, :]) train_matrix_sparse = cvxopt.spmatrix(train_matrix.data, train_matrix.row.tolist(), train_matrix.col.tolist()) max_theta_idx = np.amax(np.where(train_indices)) + 1 self.beta = Variable(feature_size) self.theta = Variable(num_samples) self.lambdas = [Parameter(sign="positive"), Parameter(sign="positive")] objective = 0.5 * sum_squares(y - X_linear * self.beta - train_matrix_sparse * self.theta[0:max_theta_idx]) + self.lambdas[0] * norm(self.beta, 1) if use_l1: objective += self.lambdas[1] * norm(D_sparse * self.theta, 1) else: objective += 0.5 * self.lambdas[1] * sum_squares(D_sparse * self.theta) self.problem = Problem(Minimize(objective), [])
def l1_fit(index, y, beta_d2=1.0, beta_d1=1.0, beta_seasonal=1.0, beta_step=5.0, period=12, growth=0.0, step_permissives=None): assert isinstance(y, np.ndarray) assert isinstance(index, np.ndarray) #x must be integer type for seasonality to make sense assert index.dtype.kind == 'i' n = len(y) m = n-2 p = period ys, y_min, y_max = mu.scale_numpy(y) D1 = mu.get_first_derivative_matrix_nes(index) D2 = mu.get_second_derivative_matrix_nes(index) H = mu.get_step_function_matrix(n) T = mu.get_T_matrix(p) B = mu.get_B_matrix_nes(index, p) Q = B*T #define F_matrix from blocks like in paper zero = mu.zero_spmatrix ident = mu.identity_spmatrix gvec = spmatrix(growth, range(m), [0]*m) zero_m = spmatrix(0.0, range(m), [0]*m) zero_p = spmatrix(0.0, range(p), [0]*p) zero_n = spmatrix(0.0, range(n), [0]*n) step_reg = mu.get_step_function_reg(n, beta_step, permissives=step_permissives) F_matrix = sparse([ [ident(n), -beta_d1*D1, -beta_d2*D2, zero(p, n), zero(n)], [Q, zero(m, p-1), zero(m, p-1), -beta_seasonal*T, zero(n, p-1)], [H, zero(m, n), zero(m, n), zero(p, n), step_reg] ]) w_vector = sparse([ mu.np2spmatrix(ys), gvec, zero_m, zero_p, zero_n ]) solution_vector = np.asarray(l1.l1(matrix(F_matrix), matrix(w_vector))).squeeze() #separate xbase = solution_vector[0:n] s = solution_vector[n:n+p-1] h = solution_vector[n+p-1:] #scale back to original if y_max > y_min: scaling = y_max - y_min else: scaling = 1.0 xbase = xbase*scaling + y_min s = s*scaling h = h*scaling seas = np.asarray(Q*matrix(s)).squeeze() steps = np.asarray(H*matrix(h)).squeeze() x = xbase + seas + steps solution = {'xbase': xbase, 'seas': seas, 'steps': steps, 'x': x, 'h': h, 's': s} return solution
def sp_rand(m,n,a): """ Generates an m-by-n sparse 'd' matrix with round(a*m*n) nonzeros. """ if m == 0 or n == 0: return spmatrix([], [], [], (m,n)) nnz = min(max(0, int(round(a*m*n))), m*n) nz = matrix(random.sample(range(m*n), nnz), tc='i') return spmatrix(normal(nnz,1), nz%m, nz/m, (m,n))
def setUp(self): n = 31 nnz = int(round(0.15*n**2)) random.seed(1) nz = matrix(random.sample(range(n**2), nnz), tc='i') self.A = cp.tril(spmatrix(matrix(range(1,nnz+1),tc='d')/nnz, nz%n, matrix([int(ii) for ii in nz/n]), (n,n)))\ + spmatrix(10.0,range(n),range(n)) self.symb = cp.symbolic(self.A, p = amd.order)
def checksol(sol, A, B, C = None, d = None, G = None, h = None): """ Check 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 ||_*. """ p, q = B.size n = A.size[1] if G is None: G = spmatrix([], [], [], (0, n)) if h is None: h = matrix(0.0, (0, 1)) m = h.size[0] if C is None: C = spmatrix(0.0, [], [], (n,n)) if d is None: d = matrix(0.0, (n, 1)) if sol['status'] is 'optimal': res = +d base.symv(C, sol['x'], res, beta = 1.0) base.gemv(G, sol['z'], res, beta = 1.0, trans = 'T') base.gemv(A, sol['Z'], res, beta = 1.0, trans = 'T') print "Dual residual: %e" %blas.nrm2(res) if m: print "Minimum primal slack (scalar inequalities): %e" \ %min(h - G*sol['x']) print "Minimum dual slack (scalar inequalities): %e" \ %min(sol['z']) if p: s = matrix(0.0, (p,1)) X = matrix(A*sol['x'], (p, q)) + B lapack.gesvd(+X, s) nrmX = sum(s) lapack.gesvd(+sol['Z'], s) nrmZ = max(s) print "Norm of Z: %e" %nrmZ print "Nuclear norm of A(x) + B: %e" %nrmX print "Inner product of Z and A(x) + B: %e" \ %blas.dot(sol['Z'], X) elif sol['status'] is 'primal infeasible': res = matrix(0.0, (n,1)) base.gemv(G, sol['z'], res, beta = 1.0, trans = 'T') print "Dual residual: %e" %blas.nrm2(res) print "h' * z = %e" %blas.dot(h, sol['z']) print "Minimum dual slack (scalar inequalities): %e" \ %min(sol['z']) else: pass
def setUp(self): I = list(range(17)) + [2,2,3,3,4,14,4,14,8,14,15,8,15,7,8,14,8,14,14,15,10,12,13,16,12,13,16,12,13,15,16,13,15,16,15,16,15,16,16] J = list(range(17)) + [0,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,9,9,9,9,10,10,10,11,11,11,11,12,12,12,13,13,14,14,15] self.A = spmatrix(matrix(range(len(I)),tc='d'),I,J,(17,17)) n = 23 nz = [1, 2, 10, 12, 13, 14, 15, 16, 19, 24, 48, 58, 71, 76, 81, 85, 91, 103, 108, 109, 111, 114, 116, 117, 118, 134, 143, 145, 161, 174, 178, 180, 183, 192, 194, 202, 203, 205, 212, 214, 219, 224, 226, 227, 228, 229, 235, 240, 241, 243, 247, 255, 256, 260, 269, 273, 275, 279, 280, 314, 315, 320, 321, 328, 340, 342, 344, 345, 349, 350, 357, 359, 370, 372, 375, 384, 385, 394, 399, 402, 411, 412, 419, 420, 422, 433, 439, 441, 447, 452, 454, 458, 460, 474, 476, 479, 481, 483, 485, 497, 506, 517, 519, 523, 526, 527] self.A_nc = cp.tril(spmatrix(matrix(range(1,len(nz)+1),tc='d')/len(nz),[ni%n for ni in nz],[int(ii/n) for ii in nz],(n,n)))\ + spmatrix(10.0,range(n),range(n))
def constraints(sources, adjacency, N): print 'build constraints for the min-cost flow problem ...' # build the constraint matrix for the problem b = matrix(np.concatenate((sources, -sources, np.zeros((N*N,))))) # build the constraint matrix I, J = np.where(adjacency) adj = spmatrix(1., J, J + N*I, (N, N*N)) - spmatrix(1., I, J + N*I, (N, N*N)) A = sparse([[adj, -adj, spmatrix(-np.ones((N*N,)), range(N*N), range(N*N))]]) return b, A
def sparse_polynomial(X, c=1.0, d=2): K = X.T * X S = co.spmatrix(0.0, [], [], K.size) for i in range(1, d+1): cmb = miscs.comb(d, i) A = co.spmatrix(K.V**i, K.I, K.J) S += cmb * c**(d-i) * A return S
def get_cvxopt_matrices(c, g, h, a, b): a = a if a is None else cvxopt.spmatrix(a.data, a.row.tolist(), a.col.tolist(), size=a.shape) g = g if g is None else cvxopt.spmatrix(g.data, g.row.tolist(), g.col.tolist(), size=g.shape) b = b if b is None else cvxopt.matrix(b) c = cvxopt.matrix(c) h = h if h is None else cvxopt.matrix(h) return c, g, h, a, b
def cheb(A, b, Sigma): # Calculates Chebyshev lower bound on Prob(A*x <= b) where # x in R^2 has mean zero and covariance Sigma. # # maximize 1 - tr(Sigma*P) - r # subject to [ P, q - (tauk/2)*ak ] # [ (q - (tauk/2)*ak)', r - 1 + tauk*bk ] >= 0, # k = 0,...,m-1 # [ P, q ] # [ q', r ] >= 0 # tauk >= 0, k=0,...,m-1. # # variables P[0,0], P[1,0], P[1,1], q[0], q[1], r, tau[0], ..., # tau[m-1]. m = A.size[0] novars = 3 + 2 + 1 + m # Cost function. c = matrix(0.0, (novars,1)) c[0], c[1], c[2] = Sigma[0,0], 2*Sigma[1,0], Sigma[1,1] c[5] = 1.0 Gs = [ spmatrix([],[],[], (9,novars)) for k in range(m+1) ] # Coefficients of P, q, r in LMI constraints. for k in range(m+1): Gs[k][0,0] = -1.0 # P[0,0] Gs[k][1,1] = -1.0 # P[1,0] Gs[k][4,2] = -1.0 # P[1,1] Gs[k][2,3] = -1.0 # q[0] Gs[k][5,4] = -1.0 # q[1] Gs[k][8,5] = -1.0 # r # Coefficients of tau. for k in range(m): Gs[k][2, 6+k] = 0.5 * A[k,0] Gs[k][5, 6+k] = 0.5 * A[k,1] Gs[k][8, 6+k] = -b[k] hs = [ matrix(8*[0.0] + [-1.0], (3,3)) for k in range(m) ] + \ [ matrix(0.0, (3,3)) ] # Constraints tau >= 0. Gl, hl = spmatrix(-1.0, range(m), range(6,6+m)), matrix(0.0, (m,1)) sol = solvers.sdp(c, Gl, hl, Gs, hs) P = matrix(sol['x'][[0,1,1,2]], (2,2)) q = matrix(sol['x'][[3,4]], (2,1)) r = sol['x'][5] bound = 1.0 - Sigma[0]*P[0] - 2*Sigma[1]*P[1] - Sigma[3]*P[3] - r # 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
def symsparsmatrix(size, dens): den = size**2*dens*0.5 Dx = np.random.random_integers(0,size-1,den) # generates random x coordinates Dy = np.random.random_integers(0,size-1,den) # generates random y coordinates De = np.random.random_integers(0,100,den) # generates random matrix entries for coordinate (x,y) D = cv.spmatrix(De,Dx,Dy,(size,size)) D += D.trans() + cv.spmatrix(np.random.random_integers(0,50,size),range(size),range(size)) return D # matrix D is a symmetric sparse matrix of dimension (size,size) with density approx. dens
def dual1prox2(Lip, L, oldLambda): k, q = L.shape P = Lip * spdiag(list(hstack((zeros(k), ones(q))))) Q = matrix(-hstack((ones(k), zeros(q)))) rows = arange(k * q) leftG = [spmatrix([1.] * q * k, range(q * k), [r % k for r in range(q * k)], (k * q, k))] rightG = [spmatrix([- 1. / k] * (k * q), range(q * k), [r / k for r in range(k * q)], (k * q, q))] G = sparse([leftG, rightG]) resDict = coneqp(P, Q, G=G, h=matrix((L + (oldLambda / k)).T.flatten(), tc='d')) return array(resDict['x'])[k:].flatten() + oldLambda
def sp_rand(m,n,a): ''' Generates an mxn sparse 'd' matrix with round(a*m*n) nonzeros. Provided by cvxopt. ''' if m == 0 or n == 0: return spmatrix([], [], [], (m,n)) nnz = min(max(0, int(round(a*m*n))), m*n) nz = matrix(random.sample(range(m*n), nnz), tc='i') J = matrix([k//m for k in nz]) return spmatrix(normal(nnz,1), nz%m, J, (m,n))
def main(): data = [[6.0,7,1], [7,7,1], [3,5,-1], [4,5,-1]] Q = spmatrix(2.0, range(3), range(3)) print "EX Ma" EX = spmatrix(-1.0, range(5), range(5)) print EX # print EX[1,1] for i in range(len(EX)): for j in range(len(EX)): print EX[i,j] print "Q mattix" Q[2,2] = 0 print Q p = matrix([0.0, 0.0, 0.0], (3,1)) G = [] h = [] print "G : [[-6.0, -7, -1], [-7, -7, -1], [3, 5, 1], [4, 5, 1]]" for items in data: row = [] if items[2] == 1: row.extend([-1 * item for item in items[:2]]) row.append(-1) # for i in range(len(EX)): # for j in range(len(EX)): # # print EX[0,i] # row.append(EX[i,j]) G.append(row) # G.append((EX[:5])) h.append(-1.0) else: row.extend(items[:2]) row.append(1) # for i in range(len(EX)): # print EX[0,i] # row.append(EX[0,i]) G.append(row) h.append(-1.0) print G for i in range(len(G)): for j in range(len(EX)): G[i].append(EX[i,j]) G = matrix(G).trans() print "After transpsoe" print G
def project(A,r,G = None, fA = None): 'Project r to null(A) by solving the normal equation AA.t v = Ar.' m,n = A.size if G is None: G = spmatrix([1]*n,range(n),range(n)) Lhs1 = sparse([G,A]) Lhs2 = sparse([A.T, spmatrix([],[],[],(m,m))]) Lhs = sparse([[Lhs1],[Lhs2]]) rhs = matrix([r,spmatrix([],[],[],(m,1))]) linsolve(Lhs,rhs) return rhs[:n]
def F(x=None, z=None): if x is None: return 5, matrix(17*[0.0] + 5*[1.0]) if min(x[17:]) <= 0.0: return None f = -x[12:17] + div(Amin, x[17:]) Df = matrix(0.0, (5,22)) Df[:,12:17] = spmatrix(-1.0, range(5), range(5)) Df[:,17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5)) if z is None: return f, Df H = spmatrix( 2.0* mul(z, div(Amin, x[17::]**3)), range(17,22), range(17,22) ) return f, Df, H
def get_feasibility_cvx(A, b, prune=True): """ Solves a pair of primal and dual LPs minimize c'*x subject to G*x + s = h A*x = b s >= 0 maximize -h'*z - b'*y subject to G'*z + A'*y + c = 0 z >= 0. Input arguments. c is n x 1, G is m x n, h is m x 1, A is p x n, b is p x 1. G and A must be dense or sparse 'd' matrices. c, h and b are dense 'd' matrices with one column. The default values for A and b are empty matrices with zero rows. solver is None, 'glpk' or 'mosek'. The default solver (None) uses the cvxopt conelp() function. The 'glpk' solver is the simplex LP solver from GLPK. The 'mosek' solver is the LP solver from MOSEK. """ print("A, b shapes", A.shape, b.shape) if prune: A, b = pre_process(A, b) print("A, b shapes", A.shape, b.shape) # if in coo format: if A.getformat() is not 'coo': A = A.tocoo() # print(A.row) # print(A.col) # print(A.data) # assert(False) x_size = A.shape[1] cvx_A = cvx.spmatrix(1.0, A.row, A.col, size=A.shape, tc='d') cvx_c = cvx.matrix(np.ones(x_size)) cvx_G = cvx.spmatrix(-1.0, range(x_size), range(x_size), tc='d') cvx_h = cvx.matrix(np.zeros(x_size)) cvx_b = cvx.matrix(b) res = cvx.solvers.lp(c=cvx_c,G=cvx_G,h=cvx_h,A=cvx_A,b=cvx_b, # solver=None, solver='mosek', # solver='glpk', ) if res['x']: x_solution = res['x'] Ax = A.dot(x_solution) bT = b[:,np.newaxis] verified = not np.any(Ax - bT) and \ np.all(np.array(x_solution) >= 0) and \ abs(np.sum(np.array(x_solution)) - 1.0) <= 1e-5 res['verified'] = verified return res
def solver_kernal_path(graph, lpmtx, pflow=None, algorithm='Dijkstra', output='dense'): nnode = len(graph.nodes.keys()) npair = len(graph.ODs.keys()) nlink = len(graph.links.keys()) if pflow is not None: flow = lpmtx*pflow G = nx.DiGraph() G.add_nodes_from(graph.nodes.keys()) G.add_edges_from([(key[0],key[1]) for key in graph.links.keys()]) for u,v in G.edges(): link = graph.links[(u,v,1)] if pflow is None: G[u][v]['cost'] = 0. G[u][v]['cost'] += link.delayfunc.compute_delay(link.flow) else: G[u][v]['cost'] = 0. indx = graph.indlinks[(u,v,1)] G[u][v]['cost'] += link.delayfunc.compute_delay(flow[indx]) iod = 0 odentries, pathfentries, Iod, Ipath = [], [], [], [] for odID, OD in graph.ODs.iteritems(): Iod.append(graph.indods[odID]) npath = 0 for nodes_on_path in nx.all_shortest_paths(G, OD.o, OD.d, weight='cost'): indpath = graph.indpaths[tuple(nodes_on_path)] Ipath.append(indpath) npath += 1 for x in xrange(npath): pathfentries.append(OD.flow/npath) cost = 0. for indx in xrange(len(nodes_on_path)-1): u = nodes_on_path[indx] v = nodes_on_path[indx+1] cost += G[u][v]['cost'] odentries.append(cost) odcost = spmatrix(odentries, Iod, len(Iod)*[0], (npair, 1)) npath = len(graph.paths) pathf = spmatrix(pathfentries, Ipath, len(Ipath)*[0], (npath, 1)) pathcost = matrix(0., (npath,1)) for nodes_on_path in graph.paths.iterkeys(): indpath = graph.indpaths[nodes_on_path] cost = 0. for indx in xrange(len(nodes_on_path)-1): u = nodes_on_path[indx] v = nodes_on_path[indx+1] cost += G[u][v]['cost'] pathcost[indpath] = cost return pathf, pathcost, odcost
def fit(self, check_psd_eigs=False): # number of training examples N = self.samples # generate the label kernel Y = self.cy.dot(self.cy.T) # generate the final PDS kernel P = matrix(self.kernel * Y) # check for PSD if check_psd_eigs: eigs = np.linalg.eigvalsh(np.array(P)) if eigs[0] < 0.0: print('Smallest eigenvalue is {0}'.format(eigs[0])) P += spdiag([-eigs[0] for i in range(N)]) # there is no linear part of the objective q = matrix(0.0, (N, 1)) # sum_i y_i alpha_i = A alpha = b = 1.0 A = matrix(self.cy, (1, self.samples), 'd') b = matrix(1.0, (1, 1)) # inequality constraints: G alpha <= h # 1) alpha_i <= C_i # 2) -alpha_i <= 0 G12 = spmatrix(1.0, range(N), range(N)) h1 = matrix(self.cC) h2 = matrix(0.0, (N, 1)) G = sparse([G12, -G12]) h = matrix([h1, h2]) if self.labeled > 0: # 3) kappa <= \sum_i labeled_i alpha_i -> -cl' alpha <= -kappa print('Labeled data found.') G3 = -matrix(self.cl, (1, self.cl.size), 'd') h3 = -matrix(self.kappa, (1, 1)) G = sparse([G12, -G12, G3]) h = matrix([h1, h2, h3]) # solve the quadratic programm sol = qp(P, -q, G, h, A, b) # store solution self.alphas = np.array(sol['x']) # 1. find all support vectors, i.e. 0 < alpha_i <= C # 2. store all support vector with alpha_i < C in 'margins' self.svs = np.where(self.alphas >= ConvexSSAD.PRECISION)[0] # these should sum to one print('Validate solution:') print('- found {0} support vectors'.format(len(self.svs))) print('0 <= alpha_i : {0} of {1}'.format(np.sum(0. <= self.alphas), N)) print('- sum_(i) alpha_i cy_i = {0} = 1.0'.format( np.sum(self.alphas * self.cy))) print('- sum_(i in sv) alpha_i cy_i = {0} ~ 1.0 (approx error)'.format( np.sum(self.alphas[self.svs] * self.cy[self.svs]))) print('- sum_(i in labeled) alpha_i = {0} >= {1} = kappa'.format( np.sum(self.alphas[self.cl == 1]), self.kappa)) print('- sum_(i in unlabeled) alpha_i = {0}'.format( np.sum(self.alphas[self.y == 0]))) print('- sum_(i in positives) alpha_i = {0}'.format( np.sum(self.alphas[self.y == 1]))) print('- sum_(i in negatives) alpha_i = {0}'.format( np.sum(self.alphas[self.y == -1]))) # infer threshold (rho) psvs = np.where(self.y[self.svs] == 0)[0] # case 1: unlabeled support vectors available self.threshold = 0. unl_threshold = -1e12 lbl_threshold = -1e12 if psvs.size > 0: k = self.kernel[:, self.svs] k = k[self.svs[psvs], :] unl_threshold = np.max(self.apply(k)) if np.sum(self.cl) > 1e-12: # case 2: only labeled examples available k = self.kernel[:, self.svs] k = k[self.svs, :] thres = self.apply(k) pinds = np.where(self.y[self.svs] == +1)[0] ninds = np.where(self.y[self.svs] == -1)[0] # only negatives is not possible if ninds.size > 0 and pinds.size == 0: print('ERROR: Check pre-defined PRECISION.') lbl_threshold = np.max(thres[ninds]) elif ninds.size == 0: lbl_threshold = np.max(thres[pinds]) else: # smallest negative + largest positive p = np.max(thres[pinds]) n = np.min(thres[ninds]) lbl_threshold = (n + p) / 2. self.threshold = np.max((unl_threshold, lbl_threshold))
# Support vector classifier. # # minimize t + gamma*(1'*u + 1'*v) # subject to a'*X - b >= 1 - u # a'*Y - b <= -1 + v # u >= 0, v >= 0 # [t*I a; a' t] >= 0 gamma = 0.1 nv = n + 2 + N + M # variables (a, b, t, u, v) ni = 2 * (N + M) c = matrix(0.0, (nv, 1)) c[3], c[4:] = 1.0, gamma IN = spmatrix(1.0, range(N), range(N)) IM = spmatrix(1.0, range(M), range(M)) Gl = matrix(0.0, (ni, nv)) hl = matrix(0.0, (ni, 1)) Gl[:N, :n] = -X.T Gl[:N, n] = 1.0 Gl[:N, n + 2:n + 2 + N] = -IN hl[:N] = -1.0 Gl[N:N + M, :n] = Y.T Gl[N:N + M, n] = -1.0 Gl[N:N + M, -M:] = -IM hl[N:N + M] = -1.0 Gl[N + M:N + M + N, n + 2:n + 2 + N] = -IN Gl[N + M + N:, -M:] = -IM Gs = [spmatrix(0.0, [], [], (9, nv))]
def invert(self, G, d, wgt=None): """ Perform inversion. Parameters ---------- G: (M,N) np.ndarray Input design matrix. d: (M,) np.ndarray Input data. wgt: (M,) np.ndarray, optional Optional weights for the data. Returns ------- status: int Integer flag for failure or success. m: (N,) np.ndarray Output parameter vector. m_wgt: (N,) np.ndarray, optional Weights for parameters. """ # Indices for finite data mask = np.isfinite(d).nonzero()[0] if mask.size < self.n_min: warnings.warn('Not enough data for inversion. Returning None.') return FAIL, None, None Gf, df, wgt = self.apply_mask(mask, G, d, wgt=wgt) arrflag = isinstance(self.penalty, np.ndarray) weightingFunc = self.weightingFunc # Cache design matrix and data vector G_input = Gf.copy() d_input = df.copy() # If weight array provided, pre-multiply design matrix and data if wgt is not None: Gf = dmultl(wgt, Gf) df = wgt * df # If a regularization matrix (prior covariance matrix) has been provided # convert G -> GtG and d -> Gtd (Gram products) if self.regMat is not None: df = np.dot(Gf.T, df) Gf = np.dot(Gf.T, Gf) + self.regMat # Convert Numpy arrays to CVXOPT matrices A = matrix(Gf.T.tolist()) b = matrix(df.tolist()) m, n = A.size reg_indices_n = (self.reg_indices + n).tolist() # Fill q (will modify for re-weighting) q = matrix(0.0, (2 * n, 1)) q[:n] = -A.T * b q[reg_indices_n] = self.penalty # Fill h h = matrix(0.0, (2 * n, 1)) # Fill P P = matrix(0.0, (2 * n, 2 * n)) P[:n, :n] = A.T * A # Add small constant to diagonal for numerical conditioning P[list(range(n)), list(range(n))] += 1.0e-8 # Fill G G = matrix(0.0, (2 * n, 2 * n)) eye = spmatrix(1.0, range(n), range(n)) G[:n, :n] = eye G[:n, n:] = -1.0 * eye G[n:, :n] = -1.0 * eye G[n:, n:] = -1.0 * eye G = sparse(G) # Perform re-weighting by calling solvers.coneqp() for iters in range(self.rwiter): soln = solvers.coneqp(P, q, G=G, h=h) status, x = soln['status'], soln['x'][:n] if status != 'optimal': x = np.nan * np.ones((n, )) break xspl = x[self.reg_indices.tolist()] wnew = weightingFunc(xspl) if arrflag: # if outputting array, use only 1 re-weight iteration q[reg_indices_n] = wnew else: q[reg_indices_n] = self.penalty * wnew x = np.array(x).squeeze() q = np.array(q[n:]).squeeze() # Estimate uncertainty or set to identity if self.estimate_uncertainty: # Get indices for variance reduction best_ind = self._selectBestBasis(G_input, x, d_input) Gsub = G_input[:, best_ind] dsub = d_input # Compute new linear algebra arrays if wgt is not None: Gsub = dmultl(wgt, Gsub) dsub = d_input * wgt if self.regMat is not None: regMat = self.regMat[best_ind, :][:, best_ind] GtG = np.dot(Gsub.T, Gsub) + regMat else: GtG = np.dot(Gsub.T, Gsub) Gtd = np.dot(Gsub.T, dsub) # Inverse and least squares iGtG = self.inv_func(GtG) m = np.dot(iGtG, Gtd) # Place in original locations x = np.zeros(n) Cm = np.zeros((n, n)) x[best_ind] = m row, col = np.meshgrid(best_ind, best_ind) Cm[row, col] = iGtG else: Cm = np.eye(n) return SUCCESS, x, Cm
def incidence(self): """Build incidence matrix into self.C""" self.C = spmatrix(self.u, range(self.n), self.a1, (self.n, self.nb), 'd') -\ spmatrix(self.u, range(self.n), self.a2, (self.n, self.nb), 'd')
def cvxEDA(y, delta, tau0=2., tau1=0.7, delta_knot=10., alpha=8e-4, gamma=1e-2, solver=None, options={'reltol':1e-9}): """CVXEDA Convex optimization approach to electrodermal activity processing This function implements the cvxEDA algorithm described in "cvxEDA: a Convex Optimization Approach to Electrodermal Activity Processing" (http://dx.doi.org/10.1109/TBME.2015.2474131, also available from the authors' homepages). Arguments: y: observed EDA signal (we recommend normalizing it: y = zscore(y)) delta: sampling interval (in seconds) of y tau0: slow time constant of the Bateman function tau1: fast time constant of the Bateman function delta_knot: time between knots of the tonic spline function alpha: penalization for the sparse SMNA driver gamma: penalization for the tonic spline coefficients solver: sparse QP solver to be used, see cvxopt.solvers.qp options: solver options, see: http://cvxopt.org/userguide/coneprog.html#algorithm-parameters The function calculates these values (see paper for details): r: phasic component p: sparse SMNA driver of phasic component t: tonic component l: coefficients of tonic spline d: offset and slope of the linear drift term e: model residuals obj: value of objective function being minimized (eq 15 of paper) The function returns df: dataframe with two component -phasic: phasic component -tonic: tonic component """ n = len(y) y = cv.matrix(y) # bateman ARMA model a1 = 1./min(tau1, tau0) # a1 > a0 a0 = 1./max(tau1, tau0) ar = np.array([(a1*delta + 2.) * (a0*delta + 2.), 2.*a1*a0*delta**2 - 8., (a1*delta - 2.) * (a0*delta - 2.)]) / ((a1 - a0) * delta**2) ma = np.array([1., 2., 1.]) # matrices for ARMA model i = np.arange(2, n) A = cv.spmatrix(np.tile(ar, (n-2,1)), np.c_[i,i,i], np.c_[i,i-1,i-2], (n,n)) M = cv.spmatrix(np.tile(ma, (n-2,1)), np.c_[i,i,i], np.c_[i,i-1,i-2], (n,n)) # spline delta_knot_s = int(round(delta_knot / delta)) spl = np.r_[np.arange(1.,delta_knot_s), np.arange(delta_knot_s, 0., -1.)] # order 1 spl = np.convolve(spl, spl, 'full') spl /= max(spl) # matrix of spline regressors i = np.c_[np.arange(-(len(spl)//2), (len(spl)+1)//2)] + np.r_[np.arange(0, n, delta_knot_s)] nB = i.shape[1] j = np.tile(np.arange(nB), (len(spl),1)) p = np.tile(spl, (nB,1)).T valid = (i >= 0) & (i < n) B = cv.spmatrix(p[valid], i[valid], j[valid]) # trend C = cv.matrix(np.c_[np.ones(n), np.arange(1., n+1.)/n]) nC = C.size[1] # Solve the problem: # .5*(M*q + B*l + C*d - y)^2 + alpha*sum(A,1)*p + .5*gamma*l'*l # s.t. A*q >= 0 #old_options = cv.solvers.options.copy() #cv.solvers.options.clear() #cv.solvers.options.update(options) #options["show_progress"] = False if solver == 'conelp': # Use conelp z = lambda m,n: cv.spmatrix([],[],[],(m,n)) G = cv.sparse([[-A,z(2,n),M,z(nB+2,n)],[z(n+2,nC),C,z(nB+2,nC)], [z(n,1),-1,1,z(n+nB+2,1)],[z(2*n+2,1),-1,1,z(nB,1)], [z(n+2,nB),B,z(2,nB),cv.spmatrix(1.0, range(nB), range(nB))]]) h = cv.matrix([z(n,1),.5,.5,y,.5,.5,z(nB,1)]) c = cv.matrix([(cv.matrix(alpha, (1,n)) * A).T,z(nC,1),1,gamma,z(nB,1)]) res = cv.solvers.conelp(c, G, h, dims={'l':n,'q':[n+2,nB+2],'s':[]}) obj = res['primal objective'] else: # Use qp Mt, Ct, Bt = M.T, C.T, B.T H = cv.sparse([[Mt*M, Ct*M, Bt*M], [Mt*C, Ct*C, Bt*C], [Mt*B, Ct*B, Bt*B+gamma*cv.spmatrix(1.0, range(nB), range(nB))]]) f = cv.matrix([(cv.matrix(alpha, (1,n)) * A).T - Mt*y, -(Ct*y), -(Bt*y)]) res = cvxopt.solvers.qp(H, f, cv.spmatrix(-A.V, A.I, A.J, (n,len(f))), cv.matrix(0., (n,1)), solver= solver) obj = res['primal objective'] + .5 * (y.T * y) #cv.solvers.options.clear() #cv.solvers.options.update(old_options) l = res['x'][-nB:] d = res['x'][n:n+nC] t = B*l + C*d q = res['x'][:n] p = A * q r = M * q e = y - r - t data = {'phasic': np.array(r).ravel() ,'tonic': np.array(t).ravel()} df = pd.DataFrame(data) return (df)
def scipy_sparse_to_spmatrix(A): coo = A.tocoo() SP = spmatrix(coo.data, coo.row.tolist(), coo.col.tolist()) return SP
def _cvx(m, n): return cvxopt.spmatrix([], [], [], (m, n))
def GetHomProp2D_PlaneStress(MetaDesign, E1, nu1, E2, nu2, Amat=np.eye(2)): # Get unit cell full stiffness matrix Kuc - assume plane Strain, thickness = 1 # 1 for stiff material; 0 for soft material nelx = MetaDesign.shape[1] nely = MetaDesign.shape[0] ndof = 2 * (nelx + 1) * (nely + 1) KA = np.array([[12., 3., -6., -3., -6., -3., 0., 3.], [3., 12., 3., 0., -3., -6., -3., -6.], [-6., 3., 12., -3., 0., -3., -6., 3.], [-3., 0., -3., 12., 3., -6., 3., -6.], [-6., -3., 0., 3., 12., 3., -6., -3.], [-3., -6., -3., -6., 3., 12., 3., 0.], [0., -3., -6., 3., -6., 3., 12., -3.], [3., -6., 3., -6., -3., 0., -3., 12.]]) KB = np.array([[-4., 3., -2., 9., 2., -3., 4., -9.], [3., -4., -9., 4., -3., 2., 9., -2.], [-2., -9., -4., -3., 4., 9., 2., 3.], [9., 4., -3., -4., -9., -2., 3., 2.], [2., -3., 4., -9., -4., 3., -2., 9.], [-3., 2., 9., -2., 3., -4., -9., 4.], [4., 9., 2., 3., -2., -9., -4., -3.], [-9., -2., 3., 2., 9., 4., -3., -4.]]) KE1 = E1 / (1 - nu1**2) / 24 * (KA + nu1 * KB) KE2 = E2 / (1 - nu2**2) / 24 * (KA + nu2 * KB) # FE: Build the index vectors for the for coo matrix format. edofMat = np.zeros((nelx * nely, 8), dtype=np.int) for elx in range(nelx): for ely in range(nely): el = ely + elx * nely n1 = (nely + 1) * elx + ely n2 = (nely + 1) * (elx + 1) + ely edofMat[el, :] = np.array([ 2 * n1 + 2, 2 * n1 + 3, 2 * n2 + 2, 2 * n2 + 3, 2 * n2, 2 * n2 + 1, 2 * n1, 2 * n1 + 1 ]) # Construct the index pointers for the coo format iK = np.kron(edofMat, np.ones((8, 1))).flatten() jK = np.kron(edofMat, np.ones((1, 8))).flatten() sK = ( (KE1.flatten()[np.newaxis]).T * MetaDesign.flatten()).flatten('F') + ( (KE2.flatten()[np.newaxis]).T * (1 - MetaDesign).flatten()).flatten('F') Kuc = sp.sparse.coo_matrix((sK, (iK, jK)), shape=(ndof, ndof)).tocsr() # Kuc = 0.5 * (Kuc.T+Kuc) # Kuc = cvxopt.spmatrix(sK,iK,jK,(ndof,ndof)) # Get unit cell periodic topology M = np.eye((nelx + 1) * (nely + 1)) M[0, [nely, (nely + 1) * nelx, (nelx + 1) * (nely + 1) - 1]] = 1 M[1:nely, range(1 + (nely + 1) * nelx, nely + (nely + 1) * nelx)] = np.eye(nely - 1) M[np.arange((nely + 1), (nely + 1) * nelx, (nely + 1)), np.arange(2 * nely + 1, (nely + 1) * nelx, (nely + 1))] = 1 M = M[np.sum(M, axis=0) < 2, :].T # Compute homogenized elasticity tensor B0 = sp.sparse.kron(M, np.eye(2)) # print(B0) Bep = np.array([[Amat[0, 0], 0., Amat[1, 0] / 2], [0., Amat[1, 0], Amat[0, 0] / 2], [Amat[0, 1], 0., Amat[1, 1] / 2], [0., Amat[1, 1], Amat[0, 1] / 2]]) BaTop = np.zeros(((nelx + 1) * (nely + 1), 2), dtype=np.single) BaTop[(nely + 1) * nelx + np.arange(0, nely + 1), 0] = 1 BaTop[np.arange(nely, (nely + 1) * (nelx + 1), (nely + 1)), 1] = -1 Ba = np.kron(BaTop, np.eye(2, dtype=float)) TikReg = sp.sparse.eye(B0.shape[1]) * 1e-8 F = (Kuc.dot(B0)).T.dot(Ba) Kg = (Kuc.dot(B0)).T.dot(B0) + TikReg Kg = (0.5 * (Kg.T + Kg)).tocoo() # Kgc, lower = sp.linalg.cho_factor(0.5 * (Kg.T + Kg)) # D0 = sp.linalg.cho_solve((Kgc,lower),F) # D0 = np.linalg.solve(0.5*(Kg.T + Kg),F) Ksp = cvxopt.spmatrix(Kg.data, Kg.row.astype(np.int), Kg.col.astype(np.int)) Fsp = cvxopt.matrix(F) cvxopt.cholmod.linsolve(Ksp, Fsp) # D0 = sp.sparse.linalg.spsolve(0.5*(Kg.T + Kg), F) D0 = np.array(Fsp) Da = -B0.dot(D0) + Ba Kda = (Kuc.dot(Da)).T.dot(Da) Chom = (Kda.dot(Bep)).T.dot(Bep) / LA.det(Amat) Modes = Da.dot(Bep) # Chris said to replace the output with this: # Chom = sp.linalg.inv(Chom) # nueff = -0.5 * (Chom[1,0]/Chom[0,0] + Chom[0,1]/Chom[1,1]) # Eeff = 0.5*(1/Chom[0,0]+1/Chom[1,1]) # Avg young mod return Chom # change this to nueff, Eeff and optimize both (very stiff?, very negative poisson)
def gcall(self, dae): dae.g += spmatrix(div(mul(self.u, self.P), self.v12), self.v1, [0] * self.n, (dae.m, 1), 'd') dae.g += spmatrix(-div(mul(self.u, self.P), self.v12), self.v2, [0] * self.n, (dae.m, 1), 'd')
def cvxopt_foopsi(fluor, b, c1, g, sn, p, bas_nonneg, verbosity): """Solve the deconvolution problem using cvxopt and picos packages """ try: from cvxopt import matrix, spmatrix, spdiag, solvers import picos except ImportError: raise ImportError( 'Constrained Foopsi requires cvxopt and picos packages.') T = len(fluor) # construct deconvolution matrix (sp = G*c) G = spmatrix(1., list(range(T)), list(range(T)), (T, T)) for i in range(p): G = G + spmatrix(-g[i], np.arange(i + 1, T), np.arange(T - i - 1), (T, T)) gr = np.roots(np.concatenate([np.array([1]), -g.flatten()])) gd_vec = np.max(gr)**np.arange(T) # decay vector for initial fluorescence gen_vec = G * matrix(np.ones(fluor.size)) # Initialize variables in our problem prob = picos.Problem() # Define variables calcium_fit = prob.add_variable('calcium_fit', fluor.size) cnt = 0 if b is None: flag_b = True cnt += 1 b = prob.add_variable('b', 1) if bas_nonneg: b_lb = 0 else: b_lb = np.min(fluor) prob.add_constraint(b >= b_lb) else: flag_b = False if c1 is None: flag_c1 = True cnt += 1 c1 = prob.add_variable('c1', 1) prob.add_constraint(c1 >= 0) else: flag_c1 = False # Add constraints prob.add_constraint(G * calcium_fit >= 0) res = abs( matrix(fluor.astype(float)) - calcium_fit - b * matrix(np.ones(fluor.size)) - matrix(gd_vec) * c1) prob.add_constraint(res < sn * np.sqrt(fluor.size)) prob.set_objective('min', calcium_fit.T * gen_vec) # solve problem try: prob.solve(solver='mosek', verbose=verbosity) except ImportError: warn('MOSEK is not installed. Spike inference may be VERY slow!') prob.solver_selection() prob.solve(verbose=verbosity) # if problem in infeasible due to low noise value then project onto the # cone of linear constraints with cvxopt if prob.status == 'prim_infeas_cer' or prob.status == 'dual_infeas_cer' or prob.status == 'primal infeasible': warn( 'Original problem infeasible. Adjusting noise level and re-solving' ) # setup quadratic problem with cvxopt solvers.options['show_progress'] = verbosity ind_rows = list(range(T)) ind_cols = list(range(T)) vals = np.ones(T) if flag_b: ind_rows = ind_rows + list(range(T)) ind_cols = ind_cols + [T] * T vals = np.concatenate((vals, np.ones(T))) if flag_c1: ind_rows = ind_rows + list(range(T)) ind_cols = ind_cols + [T + cnt - 1] * T vals = np.concatenate((vals, np.squeeze(gd_vec))) P = spmatrix(vals, ind_rows, ind_cols, (T, T + cnt)) H = P.T * P Py = P.T * matrix(fluor.astype(float)) sol = solvers.qp( H, -Py, spdiag([-G, -spmatrix(1., list(range(cnt)), list(range(cnt)))]), matrix(0., (T + cnt, 1))) xx = sol['x'] c = np.array(xx[:T]) sp = np.array(G * matrix(c)) c = np.squeeze(c) if flag_b: b = np.array(xx[T + 1]) + b_lb if flag_c1: c1 = np.array(xx[-1]) sn = old_div(np.linalg.norm(fluor - c - c1 * gd_vec - b), np.sqrt(T)) else: # readout picos solution c = np.squeeze(calcium_fit.value) sp = np.squeeze(np.asarray(G * calcium_fit.value)) if flag_b: b = np.squeeze(b.value) if flag_c1: c1 = np.squeeze(c1.value) return c, b, c1, g, sn, sp
def edmcompletion(A, reordered = True, **kwargs): """ Euclidean distance matrix completion. The routine takes an EDM-completable cspmatrix :math:`A` and returns a dense EDM :math:`X` that satisfies .. math:: P( X ) = A :param A: :py:class:`cspmatrix` :param reordered: boolean """ assert isinstance(A, cspmatrix) and A.is_factor is False, "A must be a cspmatrix" tol = kwargs.get('tol',1e-15) X = matrix(A.spmatrix(reordered = True, symmetric = True)) symb = A.symb n = symb.n snptr = symb.snptr sncolptr = symb.sncolptr snrowidx = symb.snrowidx # visit supernodes in reverse (descending) order for k in range(symb.Nsn-1,-1,-1): nn = snptr[k+1]-snptr[k] beta = snrowidx[sncolptr[k]:sncolptr[k+1]] nj = len(beta) if nj-nn == 0: continue alpha = beta[nn:] nu = beta[:nn] eta = matrix([matrix(range(beta[kk]+1,beta[kk+1])) for kk in range(nj-1)] + [matrix(range(beta[-1]+1,n))]) ne = len(eta) # Compute Yaa, Yan, Yea, Ynn, Yee Yaa = -0.5*X[alpha,alpha] - 0.5*X[alpha[0],alpha[0]] blas.syr2(X[alpha,alpha[0]], matrix(1.0,(nj-nn,1)), Yaa, alpha = 0.5) Ynn = -0.5*X[nu,nu] - 0.5*X[alpha[0],alpha[0]] blas.syr2(X[nu,alpha[0]], matrix(1.0,(nn,1)), Ynn, alpha = 0.5) Yee = -0.5*X[eta,eta] - 0.5*X[alpha[0],alpha[0]] blas.syr2(X[eta,alpha[0]], matrix(1.0,(ne,1)), Yee, alpha = 0.5) Yan = -0.5*X[alpha,nu] - 0.5*X[alpha[0],alpha[0]] Yan += 0.5*matrix(1.0,(nj-nn,1))*X[alpha[0],nu] Yan += 0.5*X[alpha,alpha[0]]*matrix(1.0,(1,nn)) Yea = -0.5*X[eta,alpha] - 0.5*X[alpha[0],alpha[0]] Yea += 0.5*matrix(1.0,(ne,1))*X[alpha[0],alpha] Yea += 0.5*X[eta,alpha[0]]*matrix(1.0,(1,nj-nn)) # EVD: Yaa = Z*diag(w)*Z.T w = matrix(0.0,(Yaa.size[0],1)) Z = matrix(0.0,Yaa.size) lapack.syevr(Yaa, w, jobz='V', range='A', uplo='L', Z=Z) # Pseudo-inverse: Yp = pinv(Yaa) lambda_max = max(w) Yp = Z*spmatrix([1.0/wi if wi > lambda_max*tol else 0.0 for wi in w],range(len(w)),range(len(w)))*Z.T # Compute update tmp = -2.0*Yea*Yp*Yan + matrix(1.0,(ne,1))*Ynn[::nn+1].T + Yee[::ne+1]*matrix(1.0,(1,nn)) X[eta,nu] = tmp X[nu,eta] = tmp.T if reordered: return X else: return X[symb.ip,symb.ip]
def setUp(self): # # Use cvxopt to get ground truth values # from cvxopt import solvers, lapack, matrix, spmatrix solvers.options['show_progress'] = 0 solvers.options['feastol'] = 1e-9 solvers.options['abstol'] = 1e-9 solvers.options['reltol'] = 1e-8 data = load(open_resource('huber.bin', 'rb')) u, v = data['u'], data['v'] m, n = len(u), 2 A = matrix([m * [1.0], [u]]) b = +v self.m, self.n, self.A, self.b = m, n, A, b # Robust least squares. # # minimize sum( h( A*x-b )) # # where h(u) = u^2 if |u| <= 1.0 # = 2*(|u| - 1.0) if |u| > 1.0. # # Solve as a QP (see exercise 4.5): # # minimize (1/2) * u'*u + 1'*v # subject to -u - v <= A*x-b <= u + v # 0 <= u <= 1 # v >= 0 # # Variables x (n), u (m), v(m) novars = n + 2 * m P = spmatrix([], [], [], (novars, novars)) P[n:n + m, n:n + m] = spmatrix(1.0, range(m), range(m)) q = matrix(0.0, (novars, 1)) q[-m:] = 1.0 G = spmatrix([], [], [], (5 * m, novars)) h = matrix(0.0, (5 * m, 1)) # A*x - b <= u+v G[:m, :n] = A G[:m, n:n + m] = spmatrix(-1.0, range(m), range(m)) G[:m, n + m:] = spmatrix(-1.0, range(m), range(m)) h[:m] = b # -u - v <= A*x - b G[m:2 * m, :n] = -A G[m:2 * m, n:n + m] = spmatrix(-1.0, range(m), range(m)) G[m:2 * m, n + m:] = spmatrix(-1.0, range(m), range(m)) h[m:2 * m] = -b # u >= 0 G[2 * m:3 * m, n:n + m] = spmatrix(-1.0, range(m), range(m)) # u <= 1 G[3 * m:4 * m, n:n + m] = spmatrix(1.0, range(m), range(m)) h[3 * m:4 * m] = 1.0 # v >= 0 G[4 * m:, n + m:] = spmatrix(-1.0, range(m), range(m)) self.xh = solvers.qp(P, q, G, h)['x'][:n]
def scipy_sparse_to_spmatrix(A): """Efficient conversion from scipy sparse matrix to cvxopt sparse matrix""" coo = A.tocoo() SP = spmatrix(coo.data.tolist(), coo.row.tolist(), coo.col.tolist(), size=A.shape) return SP
def F(W): """ Custom solver for the system [ It 0 0 Xt' 0 At1' ... Atk' ][ dwt ] [ rwt ] [ 0 0 0 -d' 0 0 ... 0 ][ db ] [ rb ] [ 0 0 0 -I -I 0 ... 0 ][ dv ] [ rv ] [ Xt -d -I -Wl1^-2 ][ dzl1 ] [ rl1 ] [ 0 0 -I -Wl2^-2 ][ dzl2 ] = [ rl2 ] [ At1 0 0 -W1^-2 ][ dz1 ] [ r1 ] [ | | | . ][ | ] [ | ] [ Atk 0 0 -Wk^-2 ][ dzk ] [ rk ] where It = [ I 0 ] Xt = [ -D*X E ] Ati = [ 0 -e_i' ] [ 0 0 ] [ -Pi 0 ] dwt = [ dw ] rwt = [ rw ] [ dt ] [ rt ]. """ # scalings and 'intermediate' vectors # db = inv(Wl1)^2 + inv(Wl2)^2 db = W['di'][:m]**2 + W['di'][m:2 * m]**2 dbi = div(1.0, db) # dt = I - inv(Wl1)*Dbi*inv(Wl1) dt = 1.0 - mul(W['di'][:m]**2, dbi) dtsqrt = sqrt(dt) # lam = Dt*inv(Wl1)*d lam = mul(dt, mul(W['di'][:m], d)) # lt = E'*inv(Wl1)*lam lt = matrix(0.0, (k, 1)) base.gemv(E, mul(W['di'][:m], lam), lt, trans='T') # Xs = sqrt(Dt)*inv(Wl1)*X tmp = mul(dtsqrt, W['di'][:m]) Xs = spmatrix(tmp, range(m), range(m)) * X # Es = D*sqrt(Dt)*inv(Wl1)*E Es = spmatrix(mul(d, tmp), range(m), range(m)) * E # form Ab = I + sum((1/bi)^2*(Pi'*Pi + 4*(v'*v + 1)*Pi'*y*y'*Pi)) + Xs'*Xs # and Bb = -sum((1/bi)^2*(4*ui*v'*v*Pi'*y*ei')) - Xs'*Es # and D2 = Es'*Es + sum((1/bi)^2*(1+4*ui^2*(v'*v - 1)) Ab = matrix(0.0, (n, n)) Ab[::n + 1] = 1.0 base.syrk(Xs, Ab, trans='T', beta=1.0) Bb = matrix(0.0, (n, k)) Bb = -Xs.T * Es # inefficient!? D2 = spmatrix(0.0, range(k), range(k)) base.syrk(Es, D2, trans='T', partial=True) d2 = +D2.V del D2 py = matrix(0.0, (n, 1)) for i in range(k): binvsq = (1.0 / W['beta'][i])**2 Ab += binvsq * Pt[i] dvv = blas.dot(W['v'][i], W['v'][i]) blas.gemv(P[i], W['v'][i][1:], py, trans='T', alpha=1.0, beta=0.0) blas.syrk(py, Ab, alpha=4 * binvsq * (dvv + 1), beta=1.0) Bb[:, i] -= 4 * binvsq * W['v'][i][0] * dvv * py d2[i] += binvsq * (1 + 4 * (W['v'][i][0]**2) * (dvv - 1)) d2i = div(1.0, d2) d2isqrt = sqrt(d2i) # compute a = alpha - lam'*inv(Wl1)*E*inv(D2)*E'*inv(Wl1)*lam alpha = blas.dot(lam, mul(W['di'][:m], d)) tmp = matrix(0.0, (k, 1)) base.gemv(E, mul(W['di'][:m], lam), tmp, trans='T') tmp = mul(tmp, d2isqrt) #tmp = inv(D2)^(1/2)*E'*inv(Wl1)*lam a = alpha - blas.dot(tmp, tmp) # compute M12 = X'*D*inv(Wl1)*lam + Bb*inv(D2)*E'*inv(Wl1)*lam tmp = mul(tmp, d2isqrt) M12 = matrix(0.0, (n, 1)) blas.gemv(Bb, tmp, M12, alpha=1.0) tmp = mul(d, mul(W['di'][:m], lam)) blas.gemv(X, tmp, M12, trans='T', alpha=1.0, beta=1.0) # form and factor M sBb = Bb * spmatrix(d2isqrt, range(k), range(k)) base.syrk(sBb, Ab, alpha=-1.0, beta=1.0) M = matrix([[Ab, M12.T], [M12, a]]) lapack.potrf(M) def f(x, y, z): # residuals rwt = x[:n + k] rb = x[n + k] rv = x[n + k + 1:n + k + 1 + m] iw_rl1 = mul(W['di'][:m], z[:m]) iw_rl2 = mul(W['di'][m:2 * m], z[m:2 * m]) ri = [ z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)] for i in range(k) ] # compute 'derived' residuals # rbwt = rwt + sum(Ai'*inv(Wi)^2*ri) + [-X'*D; E']*inv(Wl1)^2*rl1 rbwt = +rwt for i in range(k): tmp = +ri[i] qscal(tmp, W['beta'][i], W['v'][i], inv=True) qscal(tmp, W['beta'][i], W['v'][i], inv=True) rbwt[n + i] -= tmp[0] blas.gemv(P[i], tmp[1:], rbwt, trans='T', alpha=-1.0, beta=1.0) tmp = mul(W['di'][:m], iw_rl1) tmp2 = matrix(0.0, (k, 1)) base.gemv(E, tmp, tmp2, trans='T') rbwt[n:] += tmp2 tmp = mul(d, tmp) # tmp = D*inv(Wl1)^2*rl1 blas.gemv(X, tmp, rbwt, trans='T', alpha=-1.0, beta=1.0) # rbb = rb - d'*inv(Wl1)^2*rl1 rbb = rb - sum(tmp) # rbv = rv - inv(Wl2)*rl2 - inv(Wl1)^2*rl1 rbv = rv - mul(W['di'][m:2 * m], iw_rl2) - mul(W['di'][:m], iw_rl1) # [rtw;rtt] = rbwt + [-X'*D; E']*inv(Wl1)^2*inv(Db)*rbv tmp = mul(W['di'][:m]**2, mul(dbi, rbv)) rtt = +rbwt[n:] base.gemv(E, tmp, rtt, trans='T', alpha=1.0, beta=1.0) rtw = +rbwt[:n] tmp = mul(d, tmp) blas.gemv(X, tmp, rtw, trans='T', alpha=-1.0, beta=1.0) # rtb = rbb - d'*inv(Wl1)^2*inv(Db)*rbv rtb = rbb - sum(tmp) # solve M*[dw;db] = [rtw - Bb*inv(D2)*rtt; rtb + lt'*inv(D2)*rtt] tmp = mul(d2i, rtt) tmp2 = matrix(0.0, (n, 1)) blas.gemv(Bb, tmp, tmp2) dwdb = matrix([rtw - tmp2, rtb + blas.dot(mul(d2i, lt), rtt)]) lapack.potrs(M, dwdb) # compute dt = inv(D2)*(rtt - Bb'*dw + lt*db) tmp2 = matrix(0.0, (k, 1)) blas.gemv(Bb, dwdb[:n], tmp2, trans='T') dt = mul(d2i, rtt - tmp2 + lt * dwdb[-1]) # compute dv = inv(Db)*(rbv + inv(Wl1)^2*(E*dt - D*X*dw - d*db)) dv = matrix(0.0, (m, 1)) blas.gemv(X, dwdb[:n], dv, alpha=-1.0) dv = mul(d, dv) - d * dwdb[-1] base.gemv(E, dt, dv, beta=1.0) tmp = +dv # tmp = E*dt - D*X*dw - d*db dv = mul(dbi, rbv + mul(W['di'][:m]**2, dv)) # compute wdz1 = inv(Wl1)*(E*dt - D*X*dw - d*db - dv - rl1) wdz1 = mul(W['di'][:m], tmp - dv) - iw_rl1 # compute wdz2 = - inv(Wl2)*(dv + rl2) wdz2 = -mul(W['di'][m:2 * m], dv) - iw_rl2 # compute wdzi = inv(Wi)*([-ei'*dt; -Pi*dw] - ri) wdzi = [] tmp = matrix(0.0, (n, 1)) for i in range(k): blas.gemv(P[i], dwdb[:n], tmp, alpha=-1.0, beta=0.0) tmp1 = matrix([-dt[i], tmp]) blas.axpy(ri[i], tmp1, alpha=-1.0) qscal(tmp1, W['beta'][i], W['v'][i], inv=True) wdzi.append(tmp1) # solution x[:n] = dwdb[:n] x[n:n + k] = dt x[n + k] = dwdb[-1] x[n + k + 1:] = dv z[:m] = wdz1 z[m:2 * m] = wdz2 for i in range(k): z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)] = wdzi[i] return f
def compute_cp_matrices(n_rows,n_cols,T,lam_t,lam_s,lh_trend=True, ifCompute_Gh=False,wrapAround=True): ''' This computes the matrices used in cp optimization. ''' grid_size=n_rows*n_cols if grid_size>200: print(ctime()+'...computing optimization matrices...') if wrapAround:#no. of spatial constraints r_s=T*(2*n_rows*n_cols-n_rows); else: r_s=T*(2*n_rows*n_cols-n_rows-n_cols); r_t=n_rows*n_cols*(T-2);#no. of temporal constraints #===form matrix D=== #---spatial penalty--- I_s=[];J_s=[];x_s=[]; for c in range(n_cols): for r in range(n_rows): #---determine the neighbors of the current point--- if ((r<(n_rows-1)) & (c<(n_cols-1))): r_n=[r+1,r];c_n=[c,c+1] elif ((r==(n_rows-1)) & (c<(n_cols-1))): r_n=[r];c_n=[c+1] elif (c==(n_cols-1)): if wrapAround: r_n=[r+1,r];c_n=[c,0] else: r_n=[r+1];c_n=[c] if (r==(n_rows-1)): continue idx_n=np.ravel_multi_index((r_n,c_n), dims=(n_rows,n_cols),order='F') idx=np.ravel_multi_index((r,c), dims=(n_rows,n_cols),order='F') #---determine the neighbors of the current point--- #---add indices corresponding to current point and its neighbors--- for i in idx_n: I_s.append(len(I_s)*T+np.tile(np.arange(T),(1,2))) J_s.append(np.hstack([np.arange(idx*T,(idx+1)*T), np.arange(i*T,(i+1)*T)])) x_s.append(np.hstack([np.ones(T),-1*np.ones(T)])) #---add indices corresponding to current point and its neighbors--- I_s=np.hstack(I_s).flatten();J_s=np.hstack(J_s).flatten(); x_s=np.hstack(x_s).flatten(); #---spatial penalty--- #---temporal penalty--- m=T-2;p=grid_size ind=np.arange(m) I0=np.tile(ind,(1,3)) J0=np.concatenate((ind,ind+1,ind+2)).reshape((3*ind.size)) x_t=np.tile(np.concatenate((np.ones((1,m)), -2*np.ones((1,m)), np.ones((1,m))),axis=1),p).flatten() #-long-horizon penalty- if lh_trend: n_year=T/52 I_lh0=[];J_lh0=[];x_lh0=[] for i in range(n_year-2): I_lh0.append([i]*3*52) J_lh0.append(np.arange(i*52,i*52+3*52)) x_lh0.append([1.0]*52+[-2.0]*52+[1.0]*52) I_lh0=np.concatenate(I_lh0);J_lh0=np.concatenate(J_lh0); x_lh=np.tile(np.concatenate(x_lh0),(p,)) I_lh=[I_lh0];J_lh=[J_lh0]; #-long-horizon penalty- I_t=[I0];J_t=[J0]; for pp in range(p-1): I_t.append(I0+(pp+1)*m) J_t.append(J0+(pp+1)*T) if lh_trend: I_lh.append(I_lh0+(n_year-2)*(pp+1)) J_lh.append(J_lh0+T*(pp+1)) I_t=np.hstack(I_t).flatten();J_t=np.hstack(J_t).flatten(); #---temporal penalty--- if lh_trend: r_lh=(n_year-2)*p#this is used in computing h below I_lh=np.hstack(I_lh);J_lh=np.hstack(J_lh); I=np.hstack([I_t,I_s+r_t,I_lh+r_s+r_t]); J=np.hstack([J_t,J_s,J_lh]); x=np.hstack([x_t,x_s,x_lh]); D=spmatrix(x,I,J,size=(r_s+r_t+r_lh,T*grid_size)) else: I=np.hstack([I_t,I_s+r_t]);J=np.hstack([J_t,J_s]); x=np.hstack([x_t,x_s]); D=spmatrix(x,I,J,size=(r_s+r_t,T*grid_size)) r_lh=0 #===form matrix D=== #===form matrix G,h=== if ifCompute_Gh: r_D=D.size[0];c_D=D.size[1] if grid_size>200: print('\t'+ctime()+'...computing G...') G=sparse([-D.T,spdiag([1.0]*r_D),spdiag([-1.0]*r_D)]) h=np.atleast_2d(np.hstack(([1.0]*c_D, [lam_t]*r_t,[lam_s]*r_s,[lam_t]*r_lh, [lam_t]*r_t,[lam_s]*r_s,[lam_t]*r_lh))).\ transpose() h=matrix(h) return D,G,h else: return D
def cvxEDA(eda, sampling_rate=1000, tau0=2., tau1=0.7, delta_knot=10., alpha=8e-4, gamma=1e-2, solver=None, verbose=False, options={'reltol': 1e-9}): """ A convex optimization approach to electrodermal activity processing (CVXEDA). This function implements the cvxEDA algorithm described in "cvxEDA: a Convex Optimization Approach to Electrodermal Activity Processing" (Greco et al., 2015). Parameters ---------- eda : list or array raw EDA signal array. sampling_rate : int Sampling rate (samples/second). tau0 : float Slow time constant of the Bateman function. tau1 : float Fast time constant of the Bateman function. delta_knot : float Time between knots of the tonic spline function. alpha : float Penalization for the sparse SMNA driver. gamma : float Penalization for the tonic spline coefficients. solver : bool Sparse QP solver to be used, see cvxopt.solvers.qp verbose : bool Print progress? options : dict Solver options, see http://cvxopt.org/userguide/coneprog.html#algorithm-parameters Returns ---------- phasic : numpy.array The phasic component. Notes ---------- *Authors* - Luca Citi (https://github.com/lciti) - Alberto Greco *Dependencies* - cvxopt - numpy *See Also* - cvxEDA: https://github.com/lciti/cvxEDA References ----------- - Greco, A., Valenza, G., & Scilingo, E. P. (2016). Evaluation of CDA and CvxEDA Models. In Advances in Electrodermal Activity Processing with Applications for Mental Health (pp. 35-43). Springer International Publishing. - Greco, A., Valenza, G., Lanata, A., Scilingo, E. P., & Citi, L. (2016). cvxEDA: A convex optimization approach to electrodermal activity processing. IEEE Transactions on Biomedical Engineering, 63(4), 797-804. """ frequency = 1 / sampling_rate # Normalizing signal eda = z_score(eda) eda = np.array(eda)[:, 0] n = len(eda) eda = eda.astype('double') eda = cv.matrix(eda) # bateman ARMA model a1 = 1. / min(tau1, tau0) # a1 > a0 a0 = 1. / max(tau1, tau0) ar = np.array([(a1 * frequency + 2.) * (a0 * frequency + 2.), 2. * a1 * a0 * frequency**2 - 8., (a1 * frequency - 2.) * (a0 * frequency - 2.)]) / ((a1 - a0) * frequency**2) ma = np.array([1., 2., 1.]) # matrices for ARMA model i = np.arange(2, n) A = cv.spmatrix(np.tile(ar, (n - 2, 1)), np.c_[i, i, i], np.c_[i, i - 1, i - 2], (n, n)) M = cv.spmatrix(np.tile(ma, (n - 2, 1)), np.c_[i, i, i], np.c_[i, i - 1, i - 2], (n, n)) # spline delta_knot_s = int(round(delta_knot / frequency)) spl = np.r_[np.arange(1., delta_knot_s), np.arange(delta_knot_s, 0., -1.)] # order 1 spl = np.convolve(spl, spl, 'full') spl /= max(spl) # matrix of spline regressors i = np.c_[np.arange(-(len(spl) // 2), (len(spl) + 1) // 2)] + np.r_[np.arange( 0, n, delta_knot_s)] nB = i.shape[1] j = np.tile(np.arange(nB), (len(spl), 1)) p = np.tile(spl, (nB, 1)).T valid = (i >= 0) & (i < n) B = cv.spmatrix(p[valid], i[valid], j[valid]) # trend C = cv.matrix(np.c_[np.ones(n), np.arange(1., n + 1.) / n]) nC = C.size[1] # Solve the problem: # .5*(M*q + B*l + C*d - eda)^2 + alpha*sum(A,1)*p + .5*gamma*l'*l # s.t. A*q >= 0 if verbose is False: options["show_progress"] = False old_options = cv.solvers.options.copy() cv.solvers.options.clear() cv.solvers.options.update(options) if solver == 'conelp': # Use conelp z = lambda m, n: cv.spmatrix([], [], [], (m, n)) G = cv.sparse([[-A, z(2, n), M, z(nB + 2, n)], [z(n + 2, nC), C, z(nB + 2, nC)], [z(n, 1), -1, 1, z(n + nB + 2, 1)], [z(2 * n + 2, 1), -1, 1, z(nB, 1)], [ z(n + 2, nB), B, z(2, nB), cv.spmatrix(1.0, range(nB), range(nB)) ]]) h = cv.matrix([z(n, 1), .5, .5, eda, .5, .5, z(nB, 1)]) c = cv.matrix([(cv.matrix(alpha, (1, n)) * A).T, z(nC, 1), 1, gamma, z(nB, 1)]) res = cv.solvers.conelp(c, G, h, dims={ 'l': n, 'q': [n + 2, nB + 2], 's': [] }) obj = res['primal objective'] else: # Use qp Mt, Ct, Bt = M.T, C.T, B.T H = cv.sparse([[Mt * M, Ct * M, Bt * M], [Mt * C, Ct * C, Bt * C], [ Mt * B, Ct * B, Bt * B + gamma * cv.spmatrix(1.0, range(nB), range(nB)) ]]) f = cv.matrix([(cv.matrix(alpha, (1, n)) * A).T - Mt * eda, -(Ct * eda), -(Bt * eda)]) res = cv.solvers.qp(H, f, cv.spmatrix(-A.V, A.I, A.J, (n, len(f))), cv.matrix(0., (n, 1)), solver=solver) obj = res['primal objective'] + .5 * (eda.T * eda) cv.solvers.options.clear() cv.solvers.options.update(old_options) l = res['x'][-nB:] d = res['x'][n:n + nC] tonic = B * l + C * d q = res['x'][:n] p = A * q phasic = M * q e = eda - phasic - tonic phasic = np.array(phasic)[:, 0] # results = (np.array(a).ravel() for a in (r, t, p, l, d, e, obj)) return (tonic, phasic)
def ComputeLocToGlobVarTransform(n_rows,n_cols,T,n_r,n_c): ''' This function computes a matrix :math:`A` which specifies the relationship between the local variables :math:`x_i` and the global variable :math:`z` for a problem in which the data on a grid are devided into several sub-grids. Specifically we have: :math:`z=Ax`, where :math:`x=(x_1,...,x_K)^T` and each :math:`x_i` is the collection of the local variables corresponding to the sub-grid :math:`i`. Parameters --------- n_rows : integer number of rows in the oroginal grid. n_cols : integer number of columns in the oroginal grid. n_r : integer number of rows in each sub-grid. n_c : integer number of columns in each sub-grid. Returns ------- A : sparse The transformation matrix. ''' boundary_rows=np.arange(0,n_rows,n_r-1)[1:-1] boundary_cols=np.arange(0,n_cols,n_c-1)[1:-1] n_boundary_rows=boundary_rows.size;n_boundary_cols=boundary_cols.size n_x_blk=n_r*n_c*T#no. of x variables in each block I_vec=[];J_vec=[] #===determine block=== def determineBlock(r,c): ''' This function determines the block :math:`x_i` to which a given entity of z belongs. It also returns what row and col in that block, the entity is. ''' n1=np.sum((r-boundary_rows)>0) n2=np.sum((c-boundary_cols)>0) blk=n2*(n_boundary_rows+1)+n1#block number r_b=r-n1*(n_r-1);c_b=c-n2*(n_c-1) return (blk,r_b,c_b) #===determine block=== #===corner points=== r1=np.tile(boundary_rows,(n_boundary_cols,1)).flatten('F') c1=np.tile(boundary_cols,(n_boundary_rows,1)).flatten() idx1=np.ravel_multi_index((r1,c1),(n_rows,n_cols),order='F') #these are the conrner points. So they are always the #(n_r,n_c) entery of one block, and the (0,n_c) entry of the block below, #(n_r,0) entery of block ont the right, #and the (0,0) entry of the block diagonal to the first block. for i,idx in enumerate(idx1): I=np.tile(np.arange(idx*T,(idx+1)*T),4) blk1,r_b1,c_b1=determineBlock(r1[i],c1[i]) idx_in_blk1=np.ravel_multi_index((r_b1,c_b1),(n_r,n_c),order='F') J1=np.arange(blk1*n_x_blk+idx_in_blk1*T, blk1*n_x_blk+(idx_in_blk1+1)*T) blk2,r_b2,c_b2=(blk1+1,0,n_c-1) idx_in_blk2=np.ravel_multi_index((r_b2,c_b2),(n_r,n_c),order='F') J2=np.arange(blk2*n_x_blk+idx_in_blk2*T, blk2*n_x_blk+(idx_in_blk2+1)*T) blk3,r_b3,c_b3=(blk1+n_boundary_rows+1,n_r-1,0) idx_in_blk3=np.ravel_multi_index((r_b3,c_b3),(n_r,n_c),order='F') J3=np.arange(blk3*n_x_blk+idx_in_blk3*T, blk3*n_x_blk+(idx_in_blk3+1)*T) blk4,r_b4,c_b4=(blk1+n_boundary_rows+2,0,0) idx_in_blk4=np.ravel_multi_index((r_b4,c_b4),(n_r,n_c),order='F') J4=np.arange(blk4*n_x_blk+idx_in_blk4*T, blk4*n_x_blk+(idx_in_blk4+1)*T) I_vec.append(I);J_vec.append(np.hstack((J1,J2,J3,J4))) #===corner points=== #===row boundary points=== r2=np.tile(boundary_rows,(n_cols-n_boundary_cols,1)).flatten('F') c2=np.tile(np.delete(np.arange(n_cols),boundary_cols), (n_boundary_rows,1)).flatten() idx2=np.ravel_multi_index((r2,c2),(n_rows,n_cols),order='F') #these are the points on the row boundaries. So they are always the #(n_r,c) entery of one block and the (0,c) entry of the block below. for i,idx in enumerate(idx2): blk1,r_b1,c_b1=determineBlock(r2[i],c2[i]) idx_in_blk1=np.ravel_multi_index((r_b1,c_b1),(n_r,n_c),order='F') I=np.tile(np.arange(idx*T,(idx+1)*T),2) J1=np.arange(blk1*n_x_blk+idx_in_blk1*T, blk1*n_x_blk+(idx_in_blk1+1)*T) blk2,r_b2,c_b2=(blk1+1,0,c_b1) idx_in_blk2=np.ravel_multi_index((r_b2,c_b2),(n_r,n_c),order='F') J2=np.arange(blk2*n_x_blk+idx_in_blk2*T, blk2*n_x_blk+(idx_in_blk2+1)*T) I_vec.append(I);J_vec.append(np.hstack((J1,J2))) #===row boundary points=== #===column boundary points=== r3=np.tile(np.delete(np.arange(n_rows),boundary_rows), (n_boundary_cols,1)).flatten() c3=np.tile(boundary_cols,(n_rows-n_boundary_rows,1)).flatten('F') idx3=np.ravel_multi_index((r3,c3),(n_rows,n_cols),order='F') #these are the points on the col boundaries. So they are always the #(r,n_c) entery of one block and the (r,0) entry of the block to the right. for i,idx in enumerate(idx3): blk1,r_b1,c_b1=determineBlock(r3[i],c3[i]) idx_in_blk1=np.ravel_multi_index((r_b1,c_b1),(n_r,n_c),order='F') I=np.tile(np.arange(idx*T,(idx+1)*T),2) J1=np.arange(blk1*n_x_blk+idx_in_blk1*T, blk1*n_x_blk+(idx_in_blk1+1)*T) blk2,r_b2,c_b2=(blk1+n_boundary_rows+1,r_b1,0) idx_in_blk2=np.ravel_multi_index((r_b2,c_b2),(n_r,n_c),order='F') J2=np.arange(blk2*n_x_blk+idx_in_blk2*T, blk2*n_x_blk+(idx_in_blk2+1)*T) I_vec.append(I);J_vec.append(np.hstack((J1,J2))) #===column boundary points=== #===non-boundary points=== idx4=np.delete(np.arange(n_cols*n_rows),np.hstack((idx1,idx2,idx3))) r4,c4=np.unravel_index(idx4,(n_rows,n_cols),'F') for i,idx in enumerate(idx4): blk,r_b,c_b=determineBlock(r4[i],c4[i]) idx_in_blk=np.ravel_multi_index((r_b,c_b),(n_r,n_c),order='F') I=np.arange(idx*T,(idx+1)*T) J=np.arange(blk*n_x_blk+idx_in_blk*T,blk*n_x_blk+(idx_in_blk+1)*T) I_vec.append(I);J_vec.append(J) I_vec=np.hstack(I_vec);J_vec=np.hstack(J_vec) A=spmatrix(np.ones(I_vec.size),I_vec,J_vec, size=(I_vec.max()+1,J_vec.max()+1)) #===non-boundary points=== return A
def main(argv=None): if argv is None: argv = sys.argv try: try: opts, args = getopt.getopt(argv[1:], "h", ["help"]) except getopt.GetoptError, msg: raise Usage(msg) try: #inputDir = argv[1] # Directory for dist and nodes text files. nodesFile="/home/selin/Desktop/AfricaLP/Africa_Updated_match21.shp" #nodesFile="/home/selin/Desktop/AfricaLP/3node/3nodesample.shp" #outputDir=argv[2] #Directory for output shapefile outputDir="/home/selin/Desktop/AfricaLP" except IndexError: raise Error("Not enough arguments provided to script.") solarTransportationCostper1000kmperGW=0.07 windTransportationCostper1000kmperGW=0.06 geoTransportationCostper1000kmperGW=0.03 hydroTransportationCostper1000kmperGW=0.02 numType=4 nodes=readNodesFromShpforAfricaLP(nodesFile) numNodes= len(nodes) dist=generateDistanceDictionary(nodes) variablesFile2 = outputDir + os.sep + "variables_deneme.txt" ''' nodes[0].setSolarSupply(1) nodes[0].setWindSupply(9) nodes[0].setDemand(7) nodes[1].setSolarSupply(3) nodes[1].setWindSupply(2) nodes[1].setDemand(3) nodes[2].setSolarSupply(1) nodes[2].setWindSupply(4) nodes[2].setDemand(2) ''' b=[] for node in nodes.values(): b.append(-1*node.getDemand())# SHOULD BE MULTIPLIED BY -1 for node in nodes.values(): solar, wind,geo,hydro=node.getSupplyAmounts() b.append(solar) b.append(wind) b.append(geo) b.append(hydro) for i in range(0,numNodes*numType): b.append(0) for i in range(0,(numNodes*numNodes-numNodes)*numType+numType*numNodes): b.append(0) print len(b) #numNodes=5 consts={} #First n constraints for ID in range(0,numNodes): consts[ID]=[] for i in range(0,numNodes): for j in range(0, numNodes): if i==j: continue for k in range(1,numType+1): if i==ID: consts[ID].append(1) #print "ONE" if j==ID: consts[ID].append(-1) #print "MINUS" if i!=ID and j!=ID: consts[ID].append(0) # print "ZERO" for l in range(0,numNodes): for k in range(1,numType+1): if l==ID: consts[ID].append(-1) else: consts[ID].append(0) #print "LEN", len(consts[4]) #4n Constraints for all xil<=Sil count=0 for ID in range(numNodes,(numType+1)*numNodes): # su an 2. 4 olacak aslinda consts[ID]=[] for i in range(0,numNodes): for j in range(0, numNodes): if i==j: continue for k in range(1,numType+1): consts[ID].append(0) for l in range(0,numNodes*numType): if l==count: consts[ID].append(1) else: consts[ID].append(0) count+=1 #print "A" #4n Constraints for all Sumj(Yijk)<=Xik count=0 for ID in range((numType+1)*numNodes,2*numType*numNodes+numNodes): consts[ID]=[] for i in range(0,numNodes): for j in range(0,numNodes): if i==j: continue for k in range(1,numType+1): if count/numType==i and count%numType==(k-1): consts[ID].append(1) else: consts[ID].append(0) for l in range(0,numNodes*numType): if l==count: consts[ID].append(-1) else: consts[ID].append(0) count+=1 # variables should be positive constraints I= spmatrix(-1, range((numNodes*numNodes-numNodes)*numType+numType*numNodes), range((numNodes*numNodes-numNodes)*numType+numType*numNodes)) AList=[] for i in range(0,numNodes*(2*numType+1)): # *2 vardi ilk halinde if len(consts[i])!=(numNodes*numNodes-numNodes)*numType+numType*numNodes: print "ERROR in MATRIX CONSTRUCTION" AList.append(consts[i]) print len(AList) #ATrans=matrix(AList,((numNodes*numNodes-numNodes)*numType+numType*numNodes,(2*numType+1)*numNodes),'d') ATrans=matrix(AList,((numNodes*numNodes-numNodes)*numType+numType*numNodes,(2*numType+1)*numNodes),'d') Ahalf=ATrans.trans() A=matrix([Ahalf,I]) print A.size, "SIZE A" B=matrix(b,(((2*numType+1)*numNodes+(numNodes*numNodes-numNodes)*numType+numType*numNodes),1),'d') #B=matrix(b,((numType+1)*numNodes+(numNodes*numNodes-numNodes)*numType+numType*numNodes,1),'d') # Built cost array (c) c=[] for i in range(0,numNodes): for j in range(0, numNodes): if i==j: continue for k in range(1,numType+1): if k==1: c.append(dist[(nodes[i].getID(),nodes[j].getID())]*solarTransportationCostper1000kmperGW/1000000) if k==2: c.append(dist[(nodes[i].getID(),nodes[j].getID())]*windTransportationCostper1000kmperGW/1000000) if k==3: c.append(dist[(nodes[i].getID(),nodes[j].getID())]*geoTransportationCostper1000kmperGW/1000000) if k==4: c.append(dist[(nodes[i].getID(),nodes[j].getID())]*hydroTransportationCostper1000kmperGW/1000000) for i in range(0,numNodes): for k in range(1,numType+1): if k==1: c.append(nodes[i].getSolarProdCost()) if k==2: c.append(nodes[i].getWindProdCost()) if k==3: c.append(nodes[i].getGeoProdCost()) if k==4: c.append(nodes[i].getHydroProdCost()) print B.size C=array(c) C2=matrix(C,((numNodes*numNodes-numNodes)*numType+numType*numNodes, 1),'d') sol=solvers.lp(C2,A,B) variablesFile = outputDir + os.sep + "variables_march21.txt" indexFile=outputDir+os.sep+"index_march21.txt" writeSolutionToTxt(sol, variablesFile) print sol['status'] print sol['x'] ofile = open(indexFile, "w") for i in range(0,numNodes): for k in range(1,numType+1): ofile.write(" %(i)i %(k)i\n" %vars()) for i in c: ofile.write(" %(i)f \n" %vars()) ofile.write("END\n") ofile.close() sum=0 for i in range(0,len(c)): for l in range(0,len(sol['x'])): if l==i: sum=sum+c[i]*sol['x'][l] print "OBJECTIVE VALUE", sum
def test_numpy_scalars(self): n = 6 eps = 1e-6 cvxopt.setseed(10) P0 = cvxopt.normal(n, n) eye = cvxopt.spmatrix(1.0, range(n), range(n)) P0 = P0.T * P0 + eps * eye print P0 P1 = cvxopt.normal(n, n) P1 = P1.T * P1 P2 = cvxopt.normal(n, n) P2 = P2.T * P2 P3 = cvxopt.normal(n, n) P3 = P3.T * P3 q0 = cvxopt.normal(n, 1) q1 = cvxopt.normal(n, 1) q2 = cvxopt.normal(n, 1) q3 = cvxopt.normal(n, 1) r0 = cvxopt.normal(1, 1) r1 = cvxopt.normal(1, 1) r2 = cvxopt.normal(1, 1) r3 = cvxopt.normal(1, 1) slack = Variable() # Form the problem x = Variable(n) objective = Minimize(0.5 * quad_form(x, P0) + q0.T * x + r0 + slack) constraints = [ 0.5 * quad_form(x, P1) + q1.T * x + r1 <= slack, 0.5 * quad_form(x, P2) + q2.T * x + r2 <= slack, 0.5 * quad_form(x, P3) + q3.T * x + r3 <= slack, ] # We now find the primal result and compare it to the dual result # to check if strong duality holds i.e. the duality gap is effectively zero p = Problem(objective, constraints) primal_result = p.solve(solver=SCS_MAT_FREE, verbose=True, equil_steps=1, max_iters=5000, equil_p=2, stoch=True, samples=10, precond=True) # Note that since our data is random, we may need to run this program multiple times to get a feasible primal # When feasible, we can print out the following values print x.value # solution lam1 = constraints[0].dual_value lam2 = constraints[1].dual_value lam3 = constraints[2].dual_value print type(lam1) P_lam = P0 + lam1 * P1 + lam2 * P2 + lam3 * P3 q_lam = q0 + lam1 * q1 + lam2 * q2 + lam3 * q3 r_lam = r0 + lam1 * r1 + lam2 * r2 + lam3 * r3 dual_result = -0.5 * q_lam.T.dot(P_lam).dot(q_lam) + r_lam print dual_result.shape self.assertEquals(intf.size(dual_result), (1, 1))
def robsvm(X, d, gamma, P, e): """ Solves the following robust SVM training problem: minimize (1/2) w'*w + gamma*sum(v) subject to diag(d)*(X*w + b*1) >= 1 - v + E*u || S_j*w ||_2 <= u_j, j = 1...t v >= 0 The variables are w, b, v, and u. The matrix E is a selector matrix with zeros and one '1' per row. E_ij = 1 means that the i'th training vector is associated with the j'th uncertainty ellipsoid. A custom KKT solver that exploits low-rank structure is used, and a positive definite system of equations of order n is formed and solved at each iteration. ARGUMENTS X m-by-n matrix with training vectors as rows d m-vector with training labels (-1,+1) P list of t symmetric matrices of order n e m-vector where e[i] is the index of the uncertainty ellipsoid associated with the i'th training vector RETURNS w n-vector b scalar u t-vector v m-vector iters number of interior-point iterations """ m, n = X.size assert type( P ) is list, "P must be a list of t symmtric positive definite matrices of order n." k = len(P) if k > 0: assert e.size == (m, 1), "e must be an m-vector." assert max(e) < k and min(e) >= 0, "e[i] must be in {0,1,...,k-1}." E = spmatrix(1., e, range(m), (k, m)).T d = matrix(d, tc='d') q = matrix(0.0, (n + k + 1 + m, 1)) q[n + k + 1:] = gamma h = matrix(0.0, (2 * m + k * (n + 1), 1)) h[:m] = -1.0 # linear operators Q and G def Q(x, y, alpha=1.0, beta=0.0, trans='N'): y[:n] = alpha * x[:n] + beta * y[:n] def G(x, y, alpha=1.0, beta=0.0, trans='N'): """ Implements the linear operator [ -DX E -d -I ] [ 0 0 0 -I ] [ 0 -e_1' 0 0 ] G = [ -P_1' 0 0 0 ] [ . . . . ] [ 0 -e_k' 0 0 ] [ -P_k' 0 0 0 ] and its adjoint G'. """ if trans == 'N': tmp = +y[:m] # y[:m] = alpha*(-DXw + Et - d*b - v) + beta*y[:m] base.gemv(E, x[n:n + k], tmp, alpha=alpha, beta=beta) blas.axpy(x[n + k + 1:], tmp, alpha=-alpha) blas.axpy(d, tmp, alpha=-alpha * x[n + k]) y[:m] = tmp base.gemv(X, x[:n], tmp, alpha=alpha, beta=0.0) tmp = mul(d, tmp) y[:m] -= tmp # y[m:2*m] = -v y[m:2 * m] = -alpha * x[n + k + 1:] + beta * y[m:2 * m] # SOC 1,...,k for i in range(k): l = 2 * m + i * (n + 1) y[l] = -alpha * x[n + i] + beta * y[l] y[l + 1:l + 1 + n] = -alpha * P[i] * x[:n] + beta * y[l + 1:l + 1 + n] else: tmp1 = mul(d, x[:m]) tmp2 = y[:n] blas.gemv(X, tmp1, tmp2, trans='T', alpha=-alpha, beta=beta) for i in range(k): l = 2 * m + 1 + i * (n + 1) blas.gemv(P[i], x[l:l + n], tmp2, trans='T', alpha=-alpha, beta=1.0) y[:n] = tmp2 tmp2 = y[n:n + k] base.gemv(E, x[:m], tmp2, trans='T', alpha=alpha, beta=beta) blas.axpy(x[2 * m:2 * m + k * (1 + n):n + 1], tmp2, alpha=-alpha) y[n:n + k] = tmp2 y[n + k] = -alpha * blas.dot(d, x[:m]) + beta * y[n + k] y[n + k + 1:] = -alpha * (x[:m] + x[m:2 * m]) + beta * y[n + k + 1:] # precompute products Pi'*Pi Pt = [] for p in P: y = matrix(0.0, (n, n)) blas.syrk(p, y, trans='T') Pt.append(y) # scaled hyperbolic Householder transformations def qscal(u, beta, v, inv=False): """ Transforms the vector u as u := beta * (2*v*v' - J) * u if 'inv' is False and as u := (1/beta) * (2*J*v*v'*J - J) * u if 'inv' is True. """ if not inv: tmp = blas.dot(u, v) u[0] *= -1 u += 2 * v * tmp u *= beta else: u[0] *= -1.0 tmp = blas.dot(v, u) u[0] -= 2 * v[0] * tmp u[1:] += 2 * v[1:] * tmp u /= beta # custom KKT solver def F(W): """ Custom solver for the system [ It 0 0 Xt' 0 At1' ... Atk' ][ dwt ] [ rwt ] [ 0 0 0 -d' 0 0 ... 0 ][ db ] [ rb ] [ 0 0 0 -I -I 0 ... 0 ][ dv ] [ rv ] [ Xt -d -I -Wl1^-2 ][ dzl1 ] [ rl1 ] [ 0 0 -I -Wl2^-2 ][ dzl2 ] = [ rl2 ] [ At1 0 0 -W1^-2 ][ dz1 ] [ r1 ] [ | | | . ][ | ] [ | ] [ Atk 0 0 -Wk^-2 ][ dzk ] [ rk ] where It = [ I 0 ] Xt = [ -D*X E ] Ati = [ 0 -e_i' ] [ 0 0 ] [ -Pi 0 ] dwt = [ dw ] rwt = [ rw ] [ dt ] [ rt ]. """ # scalings and 'intermediate' vectors # db = inv(Wl1)^2 + inv(Wl2)^2 db = W['di'][:m]**2 + W['di'][m:2 * m]**2 dbi = div(1.0, db) # dt = I - inv(Wl1)*Dbi*inv(Wl1) dt = 1.0 - mul(W['di'][:m]**2, dbi) dtsqrt = sqrt(dt) # lam = Dt*inv(Wl1)*d lam = mul(dt, mul(W['di'][:m], d)) # lt = E'*inv(Wl1)*lam lt = matrix(0.0, (k, 1)) base.gemv(E, mul(W['di'][:m], lam), lt, trans='T') # Xs = sqrt(Dt)*inv(Wl1)*X tmp = mul(dtsqrt, W['di'][:m]) Xs = spmatrix(tmp, range(m), range(m)) * X # Es = D*sqrt(Dt)*inv(Wl1)*E Es = spmatrix(mul(d, tmp), range(m), range(m)) * E # form Ab = I + sum((1/bi)^2*(Pi'*Pi + 4*(v'*v + 1)*Pi'*y*y'*Pi)) + Xs'*Xs # and Bb = -sum((1/bi)^2*(4*ui*v'*v*Pi'*y*ei')) - Xs'*Es # and D2 = Es'*Es + sum((1/bi)^2*(1+4*ui^2*(v'*v - 1)) Ab = matrix(0.0, (n, n)) Ab[::n + 1] = 1.0 base.syrk(Xs, Ab, trans='T', beta=1.0) Bb = matrix(0.0, (n, k)) Bb = -Xs.T * Es # inefficient!? D2 = spmatrix(0.0, range(k), range(k)) base.syrk(Es, D2, trans='T', partial=True) d2 = +D2.V del D2 py = matrix(0.0, (n, 1)) for i in range(k): binvsq = (1.0 / W['beta'][i])**2 Ab += binvsq * Pt[i] dvv = blas.dot(W['v'][i], W['v'][i]) blas.gemv(P[i], W['v'][i][1:], py, trans='T', alpha=1.0, beta=0.0) blas.syrk(py, Ab, alpha=4 * binvsq * (dvv + 1), beta=1.0) Bb[:, i] -= 4 * binvsq * W['v'][i][0] * dvv * py d2[i] += binvsq * (1 + 4 * (W['v'][i][0]**2) * (dvv - 1)) d2i = div(1.0, d2) d2isqrt = sqrt(d2i) # compute a = alpha - lam'*inv(Wl1)*E*inv(D2)*E'*inv(Wl1)*lam alpha = blas.dot(lam, mul(W['di'][:m], d)) tmp = matrix(0.0, (k, 1)) base.gemv(E, mul(W['di'][:m], lam), tmp, trans='T') tmp = mul(tmp, d2isqrt) #tmp = inv(D2)^(1/2)*E'*inv(Wl1)*lam a = alpha - blas.dot(tmp, tmp) # compute M12 = X'*D*inv(Wl1)*lam + Bb*inv(D2)*E'*inv(Wl1)*lam tmp = mul(tmp, d2isqrt) M12 = matrix(0.0, (n, 1)) blas.gemv(Bb, tmp, M12, alpha=1.0) tmp = mul(d, mul(W['di'][:m], lam)) blas.gemv(X, tmp, M12, trans='T', alpha=1.0, beta=1.0) # form and factor M sBb = Bb * spmatrix(d2isqrt, range(k), range(k)) base.syrk(sBb, Ab, alpha=-1.0, beta=1.0) M = matrix([[Ab, M12.T], [M12, a]]) lapack.potrf(M) def f(x, y, z): # residuals rwt = x[:n + k] rb = x[n + k] rv = x[n + k + 1:n + k + 1 + m] iw_rl1 = mul(W['di'][:m], z[:m]) iw_rl2 = mul(W['di'][m:2 * m], z[m:2 * m]) ri = [ z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)] for i in range(k) ] # compute 'derived' residuals # rbwt = rwt + sum(Ai'*inv(Wi)^2*ri) + [-X'*D; E']*inv(Wl1)^2*rl1 rbwt = +rwt for i in range(k): tmp = +ri[i] qscal(tmp, W['beta'][i], W['v'][i], inv=True) qscal(tmp, W['beta'][i], W['v'][i], inv=True) rbwt[n + i] -= tmp[0] blas.gemv(P[i], tmp[1:], rbwt, trans='T', alpha=-1.0, beta=1.0) tmp = mul(W['di'][:m], iw_rl1) tmp2 = matrix(0.0, (k, 1)) base.gemv(E, tmp, tmp2, trans='T') rbwt[n:] += tmp2 tmp = mul(d, tmp) # tmp = D*inv(Wl1)^2*rl1 blas.gemv(X, tmp, rbwt, trans='T', alpha=-1.0, beta=1.0) # rbb = rb - d'*inv(Wl1)^2*rl1 rbb = rb - sum(tmp) # rbv = rv - inv(Wl2)*rl2 - inv(Wl1)^2*rl1 rbv = rv - mul(W['di'][m:2 * m], iw_rl2) - mul(W['di'][:m], iw_rl1) # [rtw;rtt] = rbwt + [-X'*D; E']*inv(Wl1)^2*inv(Db)*rbv tmp = mul(W['di'][:m]**2, mul(dbi, rbv)) rtt = +rbwt[n:] base.gemv(E, tmp, rtt, trans='T', alpha=1.0, beta=1.0) rtw = +rbwt[:n] tmp = mul(d, tmp) blas.gemv(X, tmp, rtw, trans='T', alpha=-1.0, beta=1.0) # rtb = rbb - d'*inv(Wl1)^2*inv(Db)*rbv rtb = rbb - sum(tmp) # solve M*[dw;db] = [rtw - Bb*inv(D2)*rtt; rtb + lt'*inv(D2)*rtt] tmp = mul(d2i, rtt) tmp2 = matrix(0.0, (n, 1)) blas.gemv(Bb, tmp, tmp2) dwdb = matrix([rtw - tmp2, rtb + blas.dot(mul(d2i, lt), rtt)]) lapack.potrs(M, dwdb) # compute dt = inv(D2)*(rtt - Bb'*dw + lt*db) tmp2 = matrix(0.0, (k, 1)) blas.gemv(Bb, dwdb[:n], tmp2, trans='T') dt = mul(d2i, rtt - tmp2 + lt * dwdb[-1]) # compute dv = inv(Db)*(rbv + inv(Wl1)^2*(E*dt - D*X*dw - d*db)) dv = matrix(0.0, (m, 1)) blas.gemv(X, dwdb[:n], dv, alpha=-1.0) dv = mul(d, dv) - d * dwdb[-1] base.gemv(E, dt, dv, beta=1.0) tmp = +dv # tmp = E*dt - D*X*dw - d*db dv = mul(dbi, rbv + mul(W['di'][:m]**2, dv)) # compute wdz1 = inv(Wl1)*(E*dt - D*X*dw - d*db - dv - rl1) wdz1 = mul(W['di'][:m], tmp - dv) - iw_rl1 # compute wdz2 = - inv(Wl2)*(dv + rl2) wdz2 = -mul(W['di'][m:2 * m], dv) - iw_rl2 # compute wdzi = inv(Wi)*([-ei'*dt; -Pi*dw] - ri) wdzi = [] tmp = matrix(0.0, (n, 1)) for i in range(k): blas.gemv(P[i], dwdb[:n], tmp, alpha=-1.0, beta=0.0) tmp1 = matrix([-dt[i], tmp]) blas.axpy(ri[i], tmp1, alpha=-1.0) qscal(tmp1, W['beta'][i], W['v'][i], inv=True) wdzi.append(tmp1) # solution x[:n] = dwdb[:n] x[n:n + k] = dt x[n + k] = dwdb[-1] x[n + k + 1:] = dv z[:m] = wdz1 z[m:2 * m] = wdz2 for i in range(k): z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)] = wdzi[i] return f # solve cone QP and return solution sol = solvers.coneqp(Q, q, G, h, dims={ 'l': 2 * m, 'q': [n + 1 for i in range(k)], 's': [] }, kktsolver=F) return sol['x'][:n], sol['x'][ n + k], sol['x'][n:n + k], sol['x'][n + k + 1:], sol['iterations']
def gcall(self, dae): dae.g[self.Idc] = dae.x[self.IL] + dae.y[self.Idc] dae.g -= spmatrix(dae.y[self.Idc], self.v1, [0] * self.n, (dae.m, 1), 'd') dae.g += spmatrix(dae.y[self.Idc], self.v2, [0] * self.n, (dae.m, 1), 'd')
def ilp(c, G, h, A=None, b=None, I=None, taskfile=None, **kwargs): """ Solves the mixed integer LP minimize c'*x subject to G*x + s = h A*x = b s >= 0 xi integer, forall i in I using MOSEK 8. solsta, x = ilp(c, G, h, A=None, b=None, I=None, taskfile=None). Input arguments G is m x n, h is m x 1, A is p x n, b is p x 1. G and A must be dense or sparse 'd' matrices. h and b are dense 'd' matrices with one column. The default values for A and b are empty matrices with zero rows. I is a Python set with indices of integer elements of x. By default all elements in x are constrained to be integer, i.e., the default value of I is I = set(range(n)) Dual variables are not returned for MOSEK. Optionally, the interface can write a .task file, required for support questions on the MOSEK solver. Return values solsta is a MOSEK solution status key. If solsta is mosek.solsta.integer_optimal, then x contains the solution. If solsta is mosek.solsta.unknown, then x is None. Other return values for solsta include: mosek.solsta.near_integer_optimal in which case the x value may not be well-defined, c.f., section 17.48 of the MOSEK Python API manual. x is the solution Options are passed to MOSEK solvers via the msk.options dictionary, e.g., the following turns off output from the MOSEK solvers >>> msk.options = {mosek.iparam.log: 0} see the MOSEK Python API manual. """ with mosek.Env() as env: if type(c) is not matrix or c.typecode != 'd' or c.size[1] != 1: raise TypeError("'c' must be a dense column matrix") n = c.size[0] if n < 1: raise ValueError("number of variables must be at least 1") if (type(G) is not matrix and type(G) is not spmatrix) or \ G.typecode != 'd' or G.size[1] != n: raise TypeError("'G' must be a dense or sparse 'd' matrix "\ "with %d columns" %n) m = G.size[0] if m is 0: raise ValueError("m cannot be 0") if type(h) is not matrix or h.typecode != 'd' or h.size != (m, 1): raise TypeError("'h' must be a 'd' matrix of size (%d,1)" % m) if A is None: A = spmatrix([], [], [], (0, n), 'd') if (type(A) is not matrix and type(A) is not spmatrix) or \ A.typecode != 'd' or A.size[1] != n: raise TypeError("'A' must be a dense or sparse 'd' matrix "\ "with %d columns" %n) p = A.size[0] if b is None: b = matrix(0.0, (0, 1)) if type(b) is not matrix or b.typecode != 'd' or b.size != (p, 1): raise TypeError("'b' must be a dense matrix of size (%d,1)" % p) if I is None: I = set(range(n)) if type(I) is not set: raise TypeError("invalid argument for integer index set") for i in I: if type(i) is not int: raise TypeError("invalid integer index set I") if len(I) > 0 and min(I) < 0: raise IndexError("negative element in integer index set I") if len(I) > 0 and max(I) > n - 1: raise IndexError( "maximum element in in integer index set I is larger than n-1") bkc = m * [mosek.boundkey.up] + p * [mosek.boundkey.fx] blc = m * [-inf] + [bi for bi in b] buc = list(h) + list(b) bkx = n * [mosek.boundkey.fr] blx = n * [-inf] bux = n * [+inf] colptr, asub, acof = sparse([G, A]).CCS aptrb, aptre = colptr[:-1], colptr[1:] with env.Task(0, 0) as task: task.set_Stream(mosek.streamtype.log, streamprinter) # set MOSEK options options = kwargs.get('options', globals()['options']) for (param, val) in options.items(): if str(param)[:6] == "iparam": task.putintparam(param, val) elif str(param)[:6] == "dparam": task.putdouparam(param, val) elif str(param)[:6] == "sparam": task.putstrparam(param, val) else: raise ValueError("invalid MOSEK parameter: " + str(param)) task.inputdata( m + p, # number of constraints n, # number of variables list(c), # linear objective coefficients 0.0, # objective fixed value list(aptrb), list(aptre), list(asub), list(acof), bkc, blc, buc, bkx, blx, bux) task.putobjsense(mosek.objsense.minimize) # Define integer variables if len(I) > 0: task.putvartypelist(list(I), len(I) * [mosek.variabletype.type_int]) task.putintparam(mosek.iparam.mio_mode, mosek.miomode.satisfied) if taskfile: task.writetask(taskfile) task.optimize() task.solutionsummary(mosek.streamtype.msg) if len(I) > 0: solsta = task.getsolsta(mosek.soltype.itg) else: solsta = task.getsolsta(mosek.soltype.bas) x = n * [0.0] if len(I) > 0: task.getsolutionslice(mosek.soltype.itg, mosek.solitem.xx, 0, n, x) else: task.getsolutionslice(mosek.soltype.bas, mosek.solitem.xx, 0, n, x) x = matrix(x) if (solsta is mosek.solsta.unknown): return (solsta, None) else: return (solsta, x)
print('netD_epoch_{}_Giter_{}.pth loaded!'.format(epoch, Giter)) netG.load_state_dict( torch.load('{}/netG_epoch_{}_Giter_{}.pth'.format( checkpoint_path, epoch, Giter))) print('netG_epoch_{}_Giter_{}.pth loaded!'.format(epoch, Giter)) Giter += 1 return epoch, Giter ############################################################################### ###################### Prepare linear programming solver ###################### solvers.options['show_progress'] = False solvers.options['glpk'] = {'msg_lev': 'GLP_MSG_OFF'} A = spmatrix(1.0, range(batchSize), [0] * batchSize, (batchSize, batchSize)) for i in range(1, batchSize): Ai = spmatrix(1.0, range(batchSize), [i] * batchSize, (batchSize, batchSize)) A = sparse([A, Ai]) D = spmatrix(-1.0, range(batchSize), range(batchSize), (batchSize, batchSize)) DM = D for i in range(1, batchSize): DM = sparse([DM, D]) A = sparse([[A], [DM]]) cr = matrix([-1.0 / batchSize] * batchSize) cf = matrix([1.0 / batchSize] * batchSize) c = matrix([cr, cf])
def qp(P, q, G=None, h=None, A=None, b=None, taskfile=None, **kwargs): """ Solves a quadratic program minimize (1/2)*x'*P*x + q'*x subject to G*x <= h A*x = b. using MOSEK 8. solsta, x, z, y = qp(P, q, G=None, h=None, A=None, b=None, taskfile=None) Return values solsta is a MOSEK solution status key. If solsta is mosek.solsta.optimal, then (x, y, z) contains the primal-dual solution. If solsta is mosek.solsta.prim_infeas_cer, then (x, y, z) is a certificate of primal infeasibility. If solsta is mosek.solsta.dual_infeas_cer, then (x, y, z) is a certificate of dual infeasibility. If solsta is mosek.solsta.unknown, then (x, y, z) are all None. Other return values for solsta include: mosek.solsta.dual_feas mosek.solsta.near_dual_feas mosek.solsta.near_optimal mosek.solsta.near_prim_and_dual_feas mosek.solsta.near_prim_feas mosek.solsta.prim_and_dual_feas mosek.solsta.prim_feas in which case the (x,y,z) value may not be well-defined. x, z, y the primal-dual solution. Options are passed to MOSEK solvers via the msk.options dictionary, e.g., the following turns off output from the MOSEK solvers >>> msk.options = {mosek.iparam.log: 0} see the MOSEK Python API manual. Optionally, the interface can write a .task file, required for support questions on the MOSEK solver. """ with mosek.Env() as env: if (type(P) is not matrix and type(P) is not spmatrix) or \ P.typecode != 'd' or P.size[0] != P.size[1]: raise TypeError("'P' must be a square dense or sparse 'd' matrix ") n = P.size[0] if n < 1: raise ValueError("number of variables must be at least 1") if type(q) is not matrix or q.typecode != 'd' or q.size != (n, 1): raise TypeError("'q' must be a 'd' matrix of size (%d,1)" % n) if G is None: G = spmatrix([], [], [], (0, n), 'd') if (type(G) is not matrix and type(G) is not spmatrix) or \ G.typecode != 'd' or G.size[1] != n: raise TypeError("'G' must be a dense or sparse 'd' matrix "\ "with %d columns" %n) m = G.size[0] if h is None: h = matrix(0.0, (0, 1)) if type(h) is not matrix or h.typecode != 'd' or h.size != (m, 1): raise TypeError("'h' must be a 'd' matrix of size (%d,1)" % m) if A is None: A = spmatrix([], [], [], (0, n), 'd') if (type(A) is not matrix and type(A) is not spmatrix) or \ A.typecode != 'd' or A.size[1] != n: raise TypeError("'A' must be a dense or sparse 'd' matrix "\ "with %d columns" %n) p = A.size[0] if b is None: b = matrix(0.0, (0, 1)) if type(b) is not matrix or b.typecode != 'd' or b.size != (p, 1): raise TypeError("'b' must be a dense matrix of size (%d,1)" % p) if m + p is 0: raise ValueError("m + p must be greater than 0") c = list(q) bkc = m * [mosek.boundkey.up] + p * [mosek.boundkey.fx] blc = m * [-inf] + [bi for bi in b] buc = list(h) + list(b) bkx = n * [mosek.boundkey.fr] blx = n * [-inf] bux = n * [+inf] colptr, asub, acof = sparse([G, A]).CCS aptrb, aptre = colptr[:-1], colptr[1:] with env.Task(0, 0) as task: task.set_Stream(mosek.streamtype.log, streamprinter) # set MOSEK options options = kwargs.get('options', globals()['options']) for (param, val) in options.items(): if str(param)[:6] == "iparam": task.putintparam(param, val) elif str(param)[:6] == "dparam": task.putdouparam(param, val) elif str(param)[:6] == "sparam": task.putstrparam(param, val) else: raise ValueError("invalid MOSEK parameter: " + str(param)) task.inputdata( m + p, # number of constraints n, # number of variables c, # linear objective coefficients 0.0, # objective fixed value list(aptrb), list(aptre), list(asub), list(acof), bkc, blc, buc, bkx, blx, bux) Ps = sparse(P) I, J = Ps.I, Ps.J tril = [k for k in range(len(I)) if I[k] >= J[k]] task.putqobj(list(I[tril]), list(J[tril]), list(Ps.V[tril])) task.putobjsense(mosek.objsense.minimize) if taskfile: task.writetask(taskfile) task.optimize() task.solutionsummary(mosek.streamtype.msg) solsta = task.getsolsta(mosek.soltype.itr) x = n * [0.0] task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, 0, n, x) x = matrix(x) if m is not 0: z = m * [0.0] task.getsolutionslice(mosek.soltype.itr, mosek.solitem.suc, 0, m, z) z = matrix(z) else: z = matrix(0.0, (0, 1)) if p is not 0: yu, yl = p * [0.0], p * [0.0] task.getsolutionslice(mosek.soltype.itr, mosek.solitem.suc, m, m + p, yu) task.getsolutionslice(mosek.soltype.itr, mosek.solitem.slc, m, m + p, yl) y = matrix(yu) - matrix(yl) else: y = matrix(0.0, (0, 1)) if (solsta is mosek.solsta.unknown): return (solsta, None, None, None) else: return (solsta, x, z, y)
def cnls_vrs(x, y, solver): # Number of the input(s) m = np.shape(x)[1] # Number of the DMUs n = len(y) # Number of the variables nvars = n * (m + 1) # Define the matrix P P = spmatrix(1.0, range(n), range(n), (nvars, nvars)) # define the matrix q q = matrix(0.0, (nvars, 1)) q[:n] = -y # Define the matrix G G = spmatrix([], [], [], (n**2 + m * n, nvars)) I = spmatrix(-1.0, range(n), range(n)) # FIRST CONSTAINT: Afriat inequalities for i in range(n): # coefficients of yhat[i] G[list(range(i * n, (i + 1) * n)), i] = -1.0 # coefficients of yhat[j] G[list(range(i * n, (i + 1) * n)), list(range(n))] -= I for i in range(n): for j in range(m): # coefficients of beta[i,j] G[list(range(i * n, (i + 1) * n)), (j + 1) * n + i] = x[i, j] - x[:, j] # SECOND CONSTAINT: monotonicity # coefficients of beta G[n**2 + i + n * j, (j + 1) * n + i] = -1.0 # Define the matrix h h = matrix(0.0, (n**2 + m * n, 1)) if (solver == 'CVXOPT'): # default solver sol = cvxopt.solvers.qp(P, q, G, h) if (solver == 'MOSEK'): # Alternative solver cvxopt.solvers.options['mosek'] = { mosek.dparam.optimizer_max_time: 100.0, mosek.iparam.intpnt_solve_form: mosek.solveform.dual } cvxopt.solvers.options['verbose'] = False sol = cvxopt.solvers.qp(P, q, G, h, solver='mosek') # store yhat and g estimates in 'res' res = sol['x'] return res
def socp(c, Gl=None, hl=None, Gq=None, hq=None, taskfile=None, **kwargs): """ Solves a pair of primal and dual SOCPs minimize c'*x subject to Gl*x + sl = hl Gq[k]*x + sq[k] = hq[k], k = 0, ..., N-1 sl >= 0, sq[k] >= 0, k = 0, ..., N-1 maximize -hl'*zl - sum_k hq[k]'*zq[k] subject to Gl'*zl + sum_k Gq[k]'*zq[k] + c = 0 zl >= 0, zq[k] >= 0, k = 0, ..., N-1. using MOSEK 8. solsta, x, zl, zq = socp(c, Gl = None, hl = None, Gq = None, hq = None, taskfile=None) Return values solsta is a MOSEK solution status key. If solsta is mosek.solsta.optimal, then (x, zl, zq) contains the primal-dual solution. If solsta is mosek.solsta.prim_infeas_cer, then (x, zl, zq) is a certificate of dual infeasibility. If solsta is mosek.solsta.dual_infeas_cer, then (x, zl, zq) is a certificate of primal infeasibility. If solsta is mosek.solsta.unknown, then (x, zl, zq) are all None Other return values for solsta include: mosek.solsta.dual_feas mosek.solsta.near_dual_feas mosek.solsta.near_optimal mosek.solsta.near_prim_and_dual_feas mosek.solsta.near_prim_feas mosek.solsta.prim_and_dual_feas mosek.solsta.prim_feas in which case the (x,y,z) value may not be well-defined. x, zl, zq the primal-dual solution. Options are passed to MOSEK solvers via the msk.options dictionary, e.g., the following turns off output from the MOSEK solvers >>> msk.options = {mosek.iparam.log: 0} see the MOSEK Python API manual. Optionally, the interface can write a .task file, required for support questions on the MOSEK solver. """ with mosek.Env() as env: if type(c) is not matrix or c.typecode != 'd' or c.size[1] != 1: raise TypeError("'c' must be a dense column matrix") n = c.size[0] if n < 1: raise ValueError("number of variables must be at least 1") if Gl is None: Gl = spmatrix([], [], [], (0, n), tc='d') if (type(Gl) is not matrix and type(Gl) is not spmatrix) or \ Gl.typecode != 'd' or Gl.size[1] != n: raise TypeError("'Gl' must be a dense or sparse 'd' matrix "\ "with %d columns" %n) ml = Gl.size[0] if hl is None: hl = matrix(0.0, (0, 1)) if type(hl) is not matrix or hl.typecode != 'd' or \ hl.size != (ml,1): raise TypeError("'hl' must be a dense 'd' matrix of " \ "size (%d,1)" %ml) if Gq is None: Gq = [] if type(Gq) is not list or [ G for G in Gq if (type(G) is not matrix and type(G) is not spmatrix) or G.typecode != 'd' or G.size[1] != n ]: raise TypeError("'Gq' must be a list of sparse or dense 'd' "\ "matrices with %d columns" %n) mq = [G.size[0] for G in Gq] a = [k for k in range(len(mq)) if mq[k] == 0] if a: raise TypeError("the number of rows of Gq[%d] is zero" % a[0]) if hq is None: hq = [] if type(hq) is not list or len(hq) != len(mq) or [ h for h in hq if (type(h) is not matrix and type(h) is not spmatrix) or h.typecode != 'd' ]: raise TypeError("'hq' must be a list of %d dense or sparse "\ "'d' matrices" %len(mq)) a = [k for k in range(len(mq)) if hq[k].size != (mq[k], 1)] if a: k = a[0] raise TypeError("'hq[%d]' has size (%d,%d). Expected size "\ "is (%d,1)." %(k, hq[k].size[0], hq[k].size[1], mq[k])) N = ml + sum(mq) h = matrix(0.0, (N, 1)) if type(Gl) is matrix or [Gk for Gk in Gq if type(Gk) is matrix]: G = matrix(0.0, (N, n)) else: G = spmatrix([], [], [], (N, n), 'd') h[:ml] = hl G[:ml, :] = Gl ind = ml for k in range(len(mq)): h[ind:ind + mq[k]] = hq[k] G[ind:ind + mq[k], :] = Gq[k] ind += mq[k] bkc = n * [mosek.boundkey.fx] blc = list(-c) buc = list(-c) bkx = ml * [mosek.boundkey.lo] + sum(mq) * [mosek.boundkey.fr] blx = ml * [0.0] + sum(mq) * [-inf] bux = N * [+inf] c = -h colptr, asub, acof = sparse([G.T]).CCS aptrb, aptre = colptr[:-1], colptr[1:] with env.Task(0, 0) as task: task.set_Stream(mosek.streamtype.log, streamprinter) # set MOSEK options options = kwargs.get('options', globals()['options']) for (param, val) in options.items(): if str(param)[:6] == "iparam": task.putintparam(param, val) elif str(param)[:6] == "dparam": task.putdouparam(param, val) elif str(param)[:6] == "sparam": task.putstrparam(param, val) else: raise ValueError("invalid MOSEK parameter: " + str(param)) task.inputdata( n, # number of constraints N, # number of variables list(c), # linear objective coefficients 0.0, # objective fixed value list(aptrb), list(aptre), list(asub), list(acof), bkc, blc, buc, bkx, blx, bux) task.putobjsense(mosek.objsense.maximize) for k in range(len(mq)): task.appendcone( mosek.conetype.quad, 0.0, list(range(ml + sum(mq[:k]), ml + sum(mq[:k + 1])))) if taskfile: task.writetask(taskfile) task.optimize() task.solutionsummary(mosek.streamtype.msg) solsta = task.getsolsta(mosek.soltype.itr) xu, xl, zq = n * [0.0], n * [0.0], sum(mq) * [0.0] task.getsolutionslice(mosek.soltype.itr, mosek.solitem.slc, 0, n, xl) task.getsolutionslice(mosek.soltype.itr, mosek.solitem.suc, 0, n, xu) task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, ml, N, zq) x = matrix(xu) - matrix(xl) zq = [ matrix(zq[sum(mq[:k]):sum(mq[:k + 1])]) for k in range(len(mq)) ] if ml: zl = ml * [0.0] task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, 0, ml, zl) zl = matrix(zl) else: zl = matrix(0.0, (0, 1)) if (solsta is mosek.solsta.unknown): return (solsta, None, None, None) else: return (solsta, x, zl, zq)
def _LMPC_BuildMatIneqConst(LMPC): N = LMPC.N n = LMPC.n numSS_Points = LMPC.numSS_Points # Buil the matrices for the state constraint in each region. In the region i we want Fx[i]x <= bx[b] Fx = np.array([[0., 0., 0., 0., 0., 1.], [0., 0., 0., 0., 0., -1.]]) bx = np.array([ [LMPC.halfWidth], # max ey [LMPC.halfWidth] ]) # max ey # Buil the matrices for the input constraint in each region. In the region i we want Fx[i]x <= bx[b] Fu = np.array([[1., 0.], [-1., 0.], [0., 1.], [0., -1.]]) bu = np.array([ [0.5], # Max Steering [0.5], # Max Steering [1.], # Max Acceleration [1.] ]) # Max Acceleration # Now stuck the constraint matrices to express them in the form Fz<=b. Note that z collects states and inputs # Let's start by computing the submatrix of F relates with the state rep_a = [Fx] * (N) Mat = linalg.block_diag(*rep_a) NoTerminalConstr = np.zeros( (np.shape(Mat)[0], n)) # No need to constraint also the terminal point Fxtot = np.hstack((Mat, NoTerminalConstr)) bxtot = np.tile(np.squeeze(bx), N) # Let's start by computing the submatrix of F relates with the input rep_b = [Fu] * (N) Futot = linalg.block_diag(*rep_b) butot = np.tile(np.squeeze(bu), N) # Let's stack all together rFxtot, cFxtot = np.shape(Fxtot) rFutot, cFutot = np.shape(Futot) Dummy1 = np.hstack((Fxtot, np.zeros((rFxtot, cFutot)))) Dummy2 = np.hstack((np.zeros((rFutot, cFxtot)), Futot)) FDummy = np.vstack((Dummy1, Dummy2)) I = -np.eye(numSS_Points) FDummy2 = linalg.block_diag(FDummy, I) Fslack = np.zeros((FDummy2.shape[0], n)) F_hard = np.hstack((FDummy2, Fslack)) LaneSlack = np.zeros((F_hard.shape[0], 2 * N)) colIndex = range(2 * N) rowIndex = [] for i in range(0, N): rowIndex.append(i * Fx.shape[0] + 0) # Slack on second element of Fx rowIndex.append(i * Fx.shape[0] + 1) # Slack on third element of Fx LaneSlack[rowIndex, colIndex] = 1.0 F = np.hstack((F_hard, LaneSlack)) # np.savetxt('F.csv', F, delimiter=',', fmt='%f') # pdb.set_trace() # np.savetxt('F.csv', F, delimiter=',', fmt='%f') b = np.hstack((bxtot, butot, np.zeros(numSS_Points))) if LMPC.Solver == "CVX": F_sparse = spmatrix(F[np.nonzero(F)], np.nonzero(F)[0].astype(int), np.nonzero(F)[1].astype(int), F.shape) F_return = F_sparse else: F_return = F return F_return, b
def lp(c, G, h, A=None, b=None, taskfile=None, **kwargs): """ Solves a pair of primal and dual LPs minimize c'*x maximize -h'*z - b'*y subject to G*x + s = h subject to G'*z + A'*y + c = 0 A*x = b z >= 0. s >= 0 using MOSEK 8. (solsta, x, z, y) = lp(c, G, h, A=None, b=None). Input arguments c is n x 1, G is m x n, h is m x 1, A is p x n, b is p x 1. G and A must be dense or sparse 'd' matrices. c, h and b are dense 'd' matrices with one column. The default values for A and b are empty matrices with zero rows. Optionally, the interface can write a .task file, required for support questions on the MOSEK solver. Return values solsta is a MOSEK solution status key. If solsta is mosek.solsta.optimal, then (x, y, z) contains the primal-dual solution. If solsta is mosek.solsta.prim_infeas_cer, then (x, y, z) is a certificate of primal infeasibility. If solsta is mosek.solsta.dual_infeas_cer, then (x, y, z) is a certificate of dual infeasibility. If solsta is mosek.solsta.unknown, then (x, y, z) are all None. Other return values for solsta include: mosek.solsta.dual_feas mosek.solsta.near_dual_feas mosek.solsta.near_optimal mosek.solsta.near_prim_and_dual_feas mosek.solsta.near_prim_feas mosek.solsta.prim_and_dual_feas mosek.solsta.prim_feas in which case the (x,y,z) value may not be well-defined. x, y, z the primal-dual solution. Options are passed to MOSEK solvers via the msk.options dictionary. For example, the following turns off output from the MOSEK solvers >>> msk.options = {mosek.iparam.log: 0} see the MOSEK Python API manual. """ with mosek.Env() as env: if type(c) is not matrix or c.typecode != 'd' or c.size[1] != 1: raise TypeError("'c' must be a dense column matrix") n = c.size[0] if n < 1: raise ValueError("number of variables must be at least 1") if (type(G) is not matrix and type(G) is not spmatrix) or \ G.typecode != 'd' or G.size[1] != n: raise TypeError("'G' must be a dense or sparse 'd' matrix "\ "with %d columns" %n) m = G.size[0] if m is 0: raise ValueError("m cannot be 0") if type(h) is not matrix or h.typecode != 'd' or h.size != (m, 1): raise TypeError("'h' must be a 'd' matrix of size (%d,1)" % m) if A is None: A = spmatrix([], [], [], (0, n), 'd') if (type(A) is not matrix and type(A) is not spmatrix) or \ A.typecode != 'd' or A.size[1] != n: raise TypeError("'A' must be a dense or sparse 'd' matrix "\ "with %d columns" %n) p = A.size[0] if b is None: b = matrix(0.0, (0, 1)) if type(b) is not matrix or b.typecode != 'd' or b.size != (p, 1): raise TypeError("'b' must be a dense matrix of size (%d,1)" % p) bkc = m * [mosek.boundkey.up] + p * [mosek.boundkey.fx] blc = m * [-inf] + [bi for bi in b] buc = list(h) + list(b) bkx = n * [mosek.boundkey.fr] blx = n * [-inf] bux = n * [+inf] colptr, asub, acof = sparse([G, A]).CCS aptrb, aptre = colptr[:-1], colptr[1:] with env.Task(0, 0) as task: task.set_Stream(mosek.streamtype.log, streamprinter) # set MOSEK options options = kwargs.get('options', globals()['options']) for (param, val) in options.items(): if str(param)[:6] == "iparam": task.putintparam(param, val) elif str(param)[:6] == "dparam": task.putdouparam(param, val) elif str(param)[:6] == "sparam": task.putstrparam(param, val) else: raise ValueError("invalid MOSEK parameter: " + str(param)) task.inputdata( m + p, # number of constraints n, # number of variables list(c), # linear objective coefficients 0.0, # objective fixed value list(aptrb), list(aptre), list(asub), list(acof), bkc, blc, buc, bkx, blx, bux) task.putobjsense(mosek.objsense.minimize) if taskfile: task.writetask(taskfile) task.optimize() task.solutionsummary(mosek.streamtype.msg) solsta = task.getsolsta(mosek.soltype.bas) x, z = n * [0.0], m * [0.0] task.getsolutionslice(mosek.soltype.bas, mosek.solitem.xx, 0, n, x) task.getsolutionslice(mosek.soltype.bas, mosek.solitem.suc, 0, m, z) x, z = matrix(x), matrix(z) if p is not 0: yu, yl = p * [0.0], p * [0.0] task.getsolutionslice(mosek.soltype.bas, mosek.solitem.suc, m, m + p, yu) task.getsolutionslice(mosek.soltype.bas, mosek.solitem.slc, m, m + p, yl) y = matrix(yu) - matrix(yl) else: y = matrix(0.0, (0, 1)) if (solsta is mosek.solsta.unknown): return (solsta, None, None, None) else: return (solsta, x, z, y)
def _eda_phasic_cvxeda(eda_signal, sampling_rate=1000, tau0=2., tau1=0.7, delta_knot=10., alpha=8e-4, gamma=1e-2, solver=None, reltol=1e-9): """ A convex optimization approach to electrodermal activity processing (CVXEDA). This function implements the cvxEDA algorithm described in "cvxEDA: a Convex Optimization Approach to Electrodermal Activity Processing" (Greco et al., 2015). Parameters ---------- eda : list or array raw EDA signal array. sampling_rate : int Sampling rate (samples/second). tau0 : float Slow time constant of the Bateman function. tau1 : float Fast time constant of the Bateman function. delta_knot : float Time between knots of the tonic spline function. alpha : float Penalization for the sparse SMNA driver. gamma : float Penalization for the tonic spline coefficients. solver : bool Sparse QP solver to be used, see cvxopt.solvers.qp reltol : float Solver options, see http://cvxopt.org/userguide/coneprog.html#algorithm-parameters """ # Try loading cvx try: import cvxopt except ImportError: raise ImportError( "NeuroKit error: eda_decompose(): the 'cvxopt' " "module is required for this method to run. ", "Please install it first (`pip install cvxopt`).") # Internal functions def _cvx(m, n): return cvxopt.spmatrix([], [], [], (m, n)) frequency = 1 / sampling_rate n = len(eda_signal) eda = cvxopt.matrix(eda_signal) # bateman ARMA model a1 = 1. / min(tau1, tau0) # a1 > a0 a0 = 1. / max(tau1, tau0) ar = np.array([(a1 * frequency + 2.) * (a0 * frequency + 2.), 2. * a1 * a0 * frequency**2 - 8., (a1 * frequency - 2.) * (a0 * frequency - 2.)]) / ((a1 - a0) * frequency**2) ma = np.array([1., 2., 1.]) # matrices for ARMA model i = np.arange(2, n) A = cvxopt.spmatrix(np.tile(ar, (n - 2, 1)), np.c_[i, i, i], np.c_[i, i - 1, i - 2], (n, n)) M = cvxopt.spmatrix(np.tile(ma, (n - 2, 1)), np.c_[i, i, i], np.c_[i, i - 1, i - 2], (n, n)) # spline delta_knot_s = int(round(delta_knot / frequency)) spl = np.r_[np.arange(1., delta_knot_s), np.arange(delta_knot_s, 0., -1.)] # order 1 spl = np.convolve(spl, spl, 'full') spl /= max(spl) # matrix of spline regressors i = np.c_[np.arange(-(len(spl) // 2), (len(spl) + 1) // 2)] + np.r_[np.arange( 0, n, delta_knot_s)] nB = i.shape[1] j = np.tile(np.arange(nB), (len(spl), 1)) p = np.tile(spl, (nB, 1)).T valid = (i >= 0) & (i < n) B = cvxopt.spmatrix(p[valid], i[valid], j[valid]) # trend C = cvxopt.matrix(np.c_[np.ones(n), np.arange(1., n + 1.) / n]) nC = C.size[1] # Solve the problem: # .5*(M*q + B*l + C*d - eda)^2 + alpha*sum(A, 1)*p + .5*gamma*l'*l # s.t. A*q >= 0 old_options = cvxopt.solvers.options.copy() cvxopt.solvers.options.clear() cvxopt.solvers.options.update({'reltol': reltol, 'show_progress': False}) if solver == 'conelp': # Use conelp G = cvxopt.sparse([[-A, _cvx(2, n), M, _cvx(nB + 2, n)], [_cvx(n + 2, nC), C, _cvx(nB + 2, nC)], [_cvx(n, 1), -1, 1, _cvx(n + nB + 2, 1)], [_cvx(2 * n + 2, 1), -1, 1, _cvx(nB, 1)], [ _cvx(n + 2, nB), B, _cvx(2, nB), cvxopt.spmatrix(1.0, range(nB), range(nB)) ]]) h = cvxopt.matrix([_cvx(n, 1), .5, .5, eda, .5, .5, _cvx(nB, 1)]) c = cvxopt.matrix([(cvxopt.matrix(alpha, (1, n)) * A).T, _cvx(nC, 1), 1, gamma, _cvx(nB, 1)]) res = cvxopt.solvers.conelp(c, G, h, dims={ 'l': n, 'q': [n + 2, nB + 2], 's': [] }) obj = res['primal objective'] else: # Use qp Mt, Ct, Bt = M.T, C.T, B.T H = cvxopt.sparse( [[Mt * M, Ct * M, Bt * M], [Mt * C, Ct * C, Bt * C], [ Mt * B, Ct * B, Bt * B + gamma * cvxopt.spmatrix(1.0, range(nB), range(nB)) ]]) f = cvxopt.matrix([(cvxopt.matrix(alpha, (1, n)) * A).T - Mt * eda, -(Ct * eda), -(Bt * eda)]) res = cvxopt.solvers.qp(H, f, cvxopt.spmatrix(-A.V, A.I, A.J, (n, len(f))), cvxopt.matrix(0., (n, 1)), solver=solver) obj = res['primal objective'] + .5 * (eda.T * eda) cvxopt.solvers.options.clear() cvxopt.solvers.options.update(old_options) tonic_splines = res['x'][-nB:] drift = res['x'][n:n + nC] tonic = B * tonic_splines + C * drift q = res['x'][:n] smna_driver = A * q phasic = M * q residuals = eda - phasic - tonic out = pd.DataFrame({ "EDA_Tonic": np.array(tonic)[:, 0], "EDA_Phasic": np.array(phasic)[:, 0] }) return out
def fit(self, X, max_iter=-1): """ :param X: Data matrix is assumed to be feats x samples. :param max_iter: *ignored*, just for compatibility. :return: Alphas and threshold for dual SVDDs. """ self.X = X.copy() dims, self.samples = X.shape if self.samples < 1: print('Invalid training data.') return -1 # number of training examples N = self.samples kernel = get_kernel(X, X, self.kernel, self.kparam) norms = np.diag(kernel).copy() if self.nu >= 1.0: print("Center-of-mass solution.") self.alphas = np.ones(self.samples) / float(self.samples) self.radius2 = 0.0 self.svs = np.array(range(self.samples), dtype='i') self.pobj = 0.0 # TODO: calculate real primal objective self.cTc = self.alphas[self.svs].T.dot(kernel[self.svs, :][:, self.svs].dot(self.alphas[self.svs])) return self.alphas, self.radius2 C = 1. / np.float(self.samples*self.nu) # generate a kernel matrix P = 2.0*matrix(kernel) # this is the diagonal of the kernel matrix q = -matrix(norms) # sum_i alpha_i = A alpha = b = 1.0 A = matrix(1.0, (1, N)) b = matrix(1.0, (1, 1)) # 0 <= alpha_i <= h = C G1 = spmatrix(1.0, range(N), range(N)) G = sparse([G1, -G1]) h1 = matrix(C, (N, 1)) h2 = matrix(0.0, (N, 1)) h = matrix([h1, h2]) sol = qp(P, q, G, h, A, b) # store solution self.alphas = np.array(sol['x'], dtype=np.float) self.pobj = -sol['primal objective'] # find support vectors self.svs = np.where(self.alphas > self.PRECISION)[0] # self.cTc = self.alphas[self.svs].T.dot(kernel[self.svs, :][:, self.svs].dot(self.alphas[self.svs])) self.cTc = self.alphas.T.dot(kernel.dot(self.alphas)) # find support vectors with alpha < C for threshold calculation self.radius2 = 0. thres = self.predict(X[:, self.svs]) self.radius2 = np.min(thres) return self.alphas, thres