def verify(G, a, C=None, b=None): xf0, f0 = solve_qp(G, a, C, b)[0:2] xf1, f1 = solve_qp(scipy.linalg.inv(scipy.linalg.cholesky(G)), a, C, b, factorized=True)[0:2] np.testing.assert_array_almost_equal(xf0, xf1) np.testing.assert_almost_equal(f0, f1)
def get_markowitz_weight(mktIndex, tickers, est_mean, est_cov, risk_level=1, short=False): m = est_mean[tickers] s = est_cov[tickers].loc[tickers] # Sum of weights is 1 A = np.ones((len(tickers), 1)) B = np.ones(1) # All weights should be positive if ~short: A2 = np.identity(len(tickers)) B2 = 1e-15 * np.ones(len(tickers)) A = np.hstack([A, A2]) B = np.hstack([B, B2]) if risk_level == 0: weight = [1 if ticker == m.argmax() else 0 for ticker in tickers] elif risk_level == 'inf': weight = quadprog.solve_qp(s.values, 0 * m.values, A, B, 1)[0] else: weight = quadprog.solve_qp(risk_level * s.values, m.values, A, B, 1)[0] return dict(zip(tickers, weight))
def quadprog_solve_qp(G, g, C=None, d=None, A=None, b=None): # python solve_qp requires # Minimize 1/2 x^T G x - a^T x # Subject to C.T x >= b qp_G = .5 * (G + G.T) # make sure P is symmetric qp_a = -g.T if A is not None and C is not None: qp_C = -np.vstack([A, C]).T qp_b = -np.hstack([b, d]) meq = A.shape[0] elif C is not None and A is None: # only inequality constraints qp_C = -C.T qp_b = -d meq = 0 elif C is None and A is not None: #only equality constraints # no equality constraint qp_C = -A.T qp_b = -b meq = A.shape[0] else: print( "quadprog_solve_qp error: you need to set at least one inequality or equality constraint" ) return 0 if isinstance(qp_a, np.matrix) or isinstance(qp_b, np.matrix): return solve_qp(qp_G, qp_a.A1, qp_C, qp_b.A1, meq)[0] else: return solve_qp(qp_G, qp_a, qp_C, qp_b, meq)[0]
def my_quadprog(Bigtheeta, row_theeta, col_theeta, number_sensors): Big_theeta = np.transpose(Bigtheeta) row = col_theeta col = row_theeta W_o = Big_theeta[:, col - 1:col] A = Big_theeta[:, 0:1] # print np.shape(A) A_y = np.diag(A[:, 0]) # print A_y print np.shape(A_y) print np.shape(Big_theeta) Weight_u = Big_theeta[:, 1:col - 1] print np.shape(Weight_u) H = np.identity(col - 2) y_des = 24.0 * np.ones((number_sensors, 1)) y_init = 20.9 * np.ones((number_sensors, 1)) beq = y_des - np.matmul(A_y, y_init) - W_o Aeq = Weight_u A = np.vstack((Aeq, -Aeq)) A = -A print col A = np.vstack((A, np.identity(col - 2))) A = np.vstack((A, -1 * np.identity(col - 2))) delta = 2 b = np.vstack((beq + delta, -beq - delta)) b = -b b = np.vstack((b, 150.0 * np.ones((col - 2, 1)))) b = np.vstack((b, 500 * np.ones((col - 2, 1)))) print np.shape(b) qp.solve_qp(H, np.zeros((col - 2, 1)), np.transpose(A), b, 0)
def quadprog_solve_qp(self, P, q, G=None, h=None, A=None, b=None, initvals=None): ''' Solve a Quadratic Program defined as: minimize (1/2) * x.T * P * x + q.T * x subject to G * x <= h A * x == b using quadprog <https://pypi.python.org/pypi/quadprog/>. Parameters ---------- P : numpy.array Symmetric quadratic-cost matrix. q : numpy.array Quadratic-cost vector. G : numpy.array Linear inequality constraint matrix. h : numpy.array Linear inequality constraint vector. A : numpy.array, optional Linear equality constraint matrix. b : numpy.array, optional Linear equality constraint vector. initvals : numpy.array, optional Warm-start guess vector (not used). Returns ------- x : numpy.array Solution to the QP, if found, otherwise ``None``. Note ---- The quadprog solver only considers the lower entries of `P`, therefore it will use a wrong cost function if a non-symmetric matrix is provided. ''' if initvals is not None: print("quadprog: note that warm-start values ignored by wrapper") qp_G = P qp_a = -q if G is not None and h is not None: if A is not None: qp_C = -vstack([A, G]).T qp_b = -hstack([b, h]) meq = A.shape[0] # print("EQUALITY AND INEQUALITY CONSTRAINTS") else: # no equality constraint qp_C = -G.T qp_b = -h meq = 0 # print("NO EQUALITY CONSTRAINT") return solve_qp(qp_G, qp_a, qp_C, qp_b, meq)[0] else: # print("UNCONSTRAINED OPTIMIZATION") return solve_qp(qp_G, qp_a)[0]
def quadprog(self, x, hessian, gradient, constraint_array): """ Returns the primal and dual solutions to the QP subproblem. :param np.array x: (n, 1) Primal variables. :param np.array hessian: (n, n) Hessian of the Lagrangian w.r.t. xx, assumed to be positive-definite. :param np.array gradient: (n, 1) Gradient of the objective function w.r.t x. :param np.array constraint_array: (m, 1) Values of each of the constraints. :return list: [(n, 1), (m, 1)] Primal and dual solution variables. Uses the quadprog package to solve the quadratic programming (QP) subproblem. See this package for more details. The form of the problem assumed in the package is: Minimize_x 1/2 x^T G x - a^T x Subject to C.T x >= b The problem we want to solve is: Minimize_x 1/2 d^T H d + grad[f(x)]^T d Subject to grad[h(x)]^T d + h(x) <= 0 So we set: G = hessian (H) a = -gradient (-grad[f(x)]) C = -constraint_grads (-grad[h(x)]) b = constraint_array (h(x)) The constraints are multiplied by -1. to obtain the form C.T <= b assumed in the SQP algorithm. Therefore, no factor is applied to constraint_array since the result is -1 * -1 * constraint_array to move it to the rhs. Note the "solve_qp" function states that the returned value "lagrangian" is the "vector with the Lagrangian at the solution", however more specifically this is the vector of Lagrange multipliers (dual variables). For the actual definition see the solve.QP.c file (https://github.com/rmcgibbo/quadprog/tree/master/quadprog, 29/08/18). """ b = constraint_array.reshape(-1) if len(b) == 0: qp_solution = solve_qp(hessian, -1. * gradient.reshape(-1)) else: constraint_grads = -1 * self.get_constraint_gradient_array(x) qp_solution = solve_qp(hessian, -1. * gradient.reshape(-1), constraint_grads, b) d_x = qp_solution[0] if len(b) > 0: d_lambda = qp_solution[4] else: d_lambda = np.array([]) return [d_x.reshape(len(d_x), 1), d_lambda.reshape(len(d_lambda), 1)]
def allocate(self, global_thrust, relax=True, current_state=None): if self.n_problem == 0: raise AllocationError("""At least one thruster must be added to the allocator-object before attempting an allocation!""") G, a = self.problem_formulation(relax) disjuncts = [] for t in self._thrusters: disjuncts.append(range(t.disjunctions)) results = {} for combination in itertools.product(*disjuncts): C, b, n_eq = self.assemble_constraints(global_thrust, relax, combination, current_state!=None) try: res = quadprog.solve_qp(G, a, C, b, n_eq) results[res[1]] = res except ValueError: warn_str = """This constraint combination has no solution: {}""".format(combination) warnings.warn(warn_str, UserWarning) if not results: raise AllocationError("""This problem has no solution! Try adding slack variables by setting relax=True""") res = results[min(results.keys())] return res[0][:self.n_problem], res
def getWeights(basket): # Calculate rates of change roc = [] for asset in basket: roc.append([ right['price'] / left['price'] for left, right in zip(asset['history'],asset['history'][1:]) ]) X = np.array(roc[:-1]).astype(float) # ROC of base assets y = np.array(roc[-1]).astype(float) # ROC of target asset # Calculate weights cols = len(basket) - 1 G = np.cov(X) X = np.transpose(X) a = np.dot(y.T - y.mean(), X - X.mean(axis=0)) / (y.shape[0]-1) c1 = np.full(cols,1) c2 = np.zeros( (cols,cols) ) np.fill_diagonal( c2, 1) C = np.transpose(np.vstack([c1, c2])).astype(float) wmin = np.full(cols,0) b = np.insert(wmin, 0, 1).astype(float) return qp.solve_qp( G, a, C = C, b = b, meq = 1 )[0] # Weights
def quadprog_solve_qp(P, q=None, G=None, h=None, A=None, b=None): """ Wrapper for https://pypi.org/project/quadprog/ https://github.com/rmcgibbo/quadprog/blob/master/quadprog/quadprog.pyx """ qp_G = .5 * (P + P.T) # make sure P is symmetric if q is not None: qp_a = -q else: qp_a = np.zeros(qp_G.shape[0]) if A is not None and G is not None: # Mixed equality and inequality constraints qp_C = -np.vstack([A, G]).T qp_b = -np.hstack([b, h]) meq = A.shape[0] elif A is not None and G is None: # Only equality constraint (x = a reformed as -a <= x <= a) qp_C = -A.T qp_b = -b meq = A.shape[0] else: # Only ineqality constraint qp_C = -G.T qp_b = -h meq = 0 return quadprog.solve_qp(qp_G, qp_a, qp_C, qp_b, meq, False)[0]
def solve_qp(P, q, G, h, A, b): # Solves # min 1/2 x^T P x + q^T x # s.t. # Gx \coneleq h # Ax = b if qp_solver == 'cvx': P = .5 * (P + P.T) # make sure P is symmetric args = [P, q, G, h, A, b] args = [cvxopt.matrix(arg) for arg in args] solution = cvxopt.solvers.qp(*args) return np.ravel(solution['x']) elif qp_solver == 'quadprog': qp_G = .5 * (P + P.T) while not is_pos_def(qp_G): qp_G += np.identity(qp_G.shape[0]) * 1e-8 qp_a = -q qp_C = -np.vstack([A, G]).T qp_b = -np.vstack([b, h]) meq = A.shape[0] solution = quadprog.solve_qp(qp_G, qp_a.squeeze(), qp_C, qp_b.squeeze(), meq) # print(solution[1]) return solution[0] else: raise NotImplementedError('no {}'.format(qp_solver))
def iterate(self): wk = self.portfolio.weights g = self.gvec(wk) A = np.ascontiguousarray(self.Amat(wk)) At = np.transpose(A) Q = 2 * At @ A + self._tauI q = 2 * np.matmul(At, g) - np.matmul(Q, wk) if self.portfolio.has_variance: Q += self.portfolio.lmd * self.portfolio.covariance if self.portfolio.has_mean_return: q -= self.portfolio.alpha * self.portfolio.mean w_hat = quadprog.solve_qp(Q, -q, C=self.CCmat, b=self.bvec, meq=self.meq)[0] self.portfolio.weights = wk + self.gamma * (w_hat - wk) fun_next = self.get_objective_function_value() self.objective_function.append(fun_next) has_w_converged = (np.abs(self.portfolio.weights - wk) <= .5 * self.wtol * (np.abs(self.portfolio.weights) + np.abs(wk))).all() has_fun_converged = (np.abs(self._funk - fun_next) <= .5 * self.funtol * (np.abs(self._funk) + np.abs(fun_next))).all() if has_w_converged or has_fun_converged: return False self.gamma = self.gamma * (1 - self.zeta * self.gamma) self._funk = fun_next return True
def whichSignaturesQP(self, counts): """ Deconstucts the counts for the trinucleotide contexts into the weight of each of the signatures saved in this object This method is based on the math from the paper: 'Decomposition of mutational context signatures using quadratic programming methods' :param counts The numpy array of counts with each instance being a row and each context being a column """ if counts.shape[1] != self.nTypes: error( f"The counts provided ({counts.shape}) do not match the loaded signature ({self.df.shape}), you might need to load a different signature" ) return None normalisedCounts = counts / counts.sum(axis=1)[:, None] # create the input vector of observed counts D = matmul(normalisedCounts, self.data) debug("Estimating contributions of signatures to counts") weights = array( [solve_qp(self.G, d, self.C, self.b, meq=1)[0] for d in D]) # floats are a bit wonky sometimes, so we check that everything is still > 0 and renormalise weights[weights < 0] = 0 weights = weights / weights.sum(axis=1)[:, None] # # TODO: Add "unexplained" percentage return weights
def project2cone2(gradient, memories, fisher, margin=0.5, eps=1e-3, reg=0.5): """ Solves the GEM dual QP described in the paper given a proposed gradient "gradient", and a memory of task gradients "memories". Overwrites "gradient" with the final projected update. We also use the fisher information diagonal to weight the dot product constraints. input: gradient, p-vector, fisher-diagonal input: memories, (t * p)-vector output: x, p-vector """ memories_np = memories.cpu().t().double().numpy() gradient_np = gradient.cpu().contiguous().view(-1).double().numpy() fisher_np = fisher.double().numpy() t = memories_np.shape[0] P = np.dot(memories_np, memories_np.transpose()) P = 0.5 * (P + P.transpose()) + np.eye(t) * eps # Multiplying the gradient with the fisher information diagonal to get weighted constraints q = np.dot(memories_np, reg * fisher_np * gradient_np) * -1 G = np.eye(t) h = np.zeros(t) + margin v = quadprog.solve_qp(P, q, G, h)[0] x = np.dot(v, memories_np) + gradient_np gradient.copy_(torch.Tensor(x).view(-1, 1))
def predict(self, X, method='friedman-mm'): n_classes = len(self.classes_) Up = np.zeros((len(X), n_classes)) if n_classes == 2: Up = (self.estimators_[1].predict_proba(X) >= self.train_prevs) else: for n_clf, (clf_cls, clf) in enumerate(self.estimators_.items()): Up[:, n_clf] = (clf.predict_proba(X)[:, 1] >= self.train_prevs[n_clf]) U = Up.mean(axis=0) G = self.V.T.dot(self.V) if not is_pd(G): G = nearest_pd(G) a = U.dot(self.V) C = np.vstack([np.ones((1, n_classes)), np.eye(n_classes)]).T b = np.array([1] + [0] * n_classes, dtype=np.float) sol = quadprog.solve_qp(G=G, a=a, C=C, b=b) p = sol[0] return p
def iterate(self): wk = self.portfolio.weights g = self.portfolio.risk_concentration.risk_concentration_vector() A = self.portfolio.risk_concentration.jacobian_risk_concentration_vector( ) At = tf.transpose(A) Q = 2 * At @ A + self._tauI q = 2 * tf.linalg.matvec(At, g) - tf.linalg.matvec(Q, wk) if self.portfolio.has_variance: Q += self.portfolio.lmd * self.portfolio.covariance if self.portfolio.has_mean_return: q -= self.portfolio.alpha * self.portfolio.mean w_hat = quadprog.solve_qp(Q.numpy(), -q.numpy(), C=self.CCmat, b=self.bvec, meq=self.meq)[0] #w_hat = qp.solve(Qmat=Q.numpy(), qvec=q.numpy(), Cmat=self.Cmat, cvec=self.cvec, # Dmat=self.Dmat, dvec=self.dvec, w0=wk, maxiter=self.maxiter, # tol=self.wtol) self.portfolio.weights = wk + self.gamma * (w_hat - wk) fun_next = self.get_objective_function_value() self.objective_function.append(fun_next.numpy()) has_w_converged = ( tf.abs(self.portfolio.weights - wk) <= .5 * self.wtol * (tf.abs(self.portfolio.weights) + tf.abs(wk))).numpy().all() has_fun_converged = ( tf.abs(self._funk - fun_next) <= .5 * self.funtol * (tf.abs(self._funk) + tf.abs(fun_next))).numpy().all() if has_w_converged or has_fun_converged: return False self.gamma = self.gamma * (1 - self.zeta * self.gamma) self._funk = fun_next return True
def project2cone2(gradient, memories, margin=0.5, eps=1e-3): """ Solves the GEM dual QP described in the paper given a proposed gradient "gradient", and a memory of task gradients "memories". Overwrites "gradient" with the final projected update. input: gradient, p-vector input: memories, (t * p)-vector output: x, p-vector """ # edit: add normalization to avoid overflow memories_np = memories.cpu().t().double().numpy() gradient_np = gradient.cpu().contiguous().view(-1).double().numpy() t = memories_np.shape[0] P = np.dot(memories_np, memories_np.transpose()) P = 0.5 * (P + P.transpose()) + np.eye(t) * eps q = np.dot(memories_np, gradient_np) * -1 G = np.eye(t) h = np.zeros(t) + margin # below is our edition to avoid overflow in the original version scale = np.linalg.norm(q) q = q / scale P = P / scale v = quadprog.solve_qp(P, q, G, h)[0] x = np.dot(v, memories_np) + gradient_np gradient.copy_(torch.Tensor(x).view(-1, 1))
def solve_qp(H, f=None, A=None, b=None, A_eq=None, b_eq=None): """ Solve the QP: min 1/2 x^T H x + f^T x s.t. A x <= b A_eq x = b_eq Args: H [n x n]: Symmetric positive definite matrix f [n]: Numpy array of size n A [m x n]: Inequality constraint matrix b [m]: Inequality constraint bias A_eq [m_eq x n]: Equality constraint matrix b_eq [m_eq]: Equality constraint bias """ import quadprog n = H.shape[0] if f is None: f = np.zeros(n) if A is None and A_eq is None: return np.linalg.solve(H, -f) if A is None: A = np.zeros((0, n)) b = np.zeros(0) if A_eq is None: A_eq = np.zeros((0, n)) b_eq = np.zeros(0) m_eq = b_eq.shape[0] C = -np.hstack((A_eq.T, A.T)) d = -np.hstack((b_eq, b)) return quadprog.solve_qp(H, -f, C, d, m_eq)[0]
def test_constraint_satisfaction(self): np.random.seed(0) n_eq = 10 n_ineq = 10 hessian, weights, coeffs, constants, n_eq, x = self.create_problem( 100, n_eq, n_ineq) sol = sys_quadprog.solve_qp(hessian, weights, coeffs, constants, n_eq) my_sol = solve_qp(hessian, weights, coeffs, constants, n_eq) violation = coeffs.T.dot(sol[0]) - constants print("Quadprog equality violations: ", violation[:n_eq]) print("Quadprog inquality violations: ", violation[n_eq:]) assert np.linalg.norm( violation[:n_eq] ) <= 1e-4, "Equality constraints were not satisfied by quadprog" assert np.min( violation[n_eq:] ) > -1e-4, "Inequality constraints were not satisfied by quadprog" violation = coeffs.T.dot(my_sol[0]) - constants print("My quadprog equality violations: ", violation[:n_eq]) print("Norm: %e" % np.linalg.norm(violation[:n_eq])) print("My quadprog inquality violations: ", violation[n_eq:]) assert np.linalg.norm( violation[:n_eq] ) <= 1e-4, "Equality constraints were not satisfied by my_quadprog" assert np.min( violation[n_eq:] ) > -1e-4, "Inequality constraints were not satisfied by my_quadprog"
def quadprog_solve_qp(P, q, G=None, h=None, A=None, b=None, bounds=None): n = P.shape[0] if bounds is not None: I = np.eye(n) LB = -I UB = I if G is None: G = np.vstack([LB, UB]) h = np.array( np.hstack([-to_array(bounds[:, 0]), to_array(bounds[:, 1])])) else: G = np.vstack([G, LB, UB]) h = np.array( np.hstack([h, -to_array(bounds[:, 0]), to_array(bounds[:, 1])])) qp_a = -q qp_G = P if A is not None: qp_C = -np.vstack([A, G]).T qp_b = -np.hstack([b, h]) meq = A.shape[0] else: # no equality constraint qp_C = -G.T qp_b = -h meq = 0 return quadprog.solve_qp(qp_G, qp_a, qp_C, qp_b, meq)[0]
def qplcp(P, q, G, h, A, b): qp_G = 0.5 * (P + P.T) # make sure P is symmetric qp_a = -q.flatten() qp_C = np.concatenate([A, G], axis=0).T qp_b = np.concatenate([b, h], axis=0).flatten() meq = A.shape[0] return solve_qp(qp_G, qp_a, qp_C, qp_b, meq)[0:3]
def quadprog_solve_qp(P, q, G=None, h=None, C=None, d=None, verbose=False): """ min (1/2)x' P x + q' x subject to G x <= h subject to C x = d """ # qp_G = .5 * (P + P.T) # make sure P is symmetric qp_G = .5 * (P + P.T) # make sure P is symmetric qp_a = -q qp_C = None qp_b = None meq = 0 if C is not None: if G is not None: qp_C = -vstack([C, G]).T qp_b = -hstack([d, h]) else: qp_C = -C.transpose() qp_b = -d meq = C.shape[0] elif G is not None: # no equality constraint qp_C = -G.T qp_b = -h res = quadprog.solve_qp(qp_G, qp_a, qp_C, qp_b, meq) if verbose: return res # print('qp status ', res) return res[0]
def project2cone2(gradient, memories, device, margin=0.5, eps=1e-3): """ Source: https://github.com/ElectronicTomato/continue_leanrning_agem/blob/master/agents/exp_replay.py#L317 Solves the GEM dual QP described in the paper given a proposed gradient "gradient", and a memory of task gradients "memories". Overwrites "gradient" with the final projected update. input: gradient, p-vector input: memories, (t * p)-vector output: x, p-vector Modified from: https://github.com/facebookresearch/GradientEpisodicMemory/blob/master/model/gem.py#L70 """ memories_np = memories.cpu().contiguous().double().numpy() gradient_np = gradient.cpu().contiguous().view(-1).double().numpy() t = memories_np.shape[0] # print(memories_np.shape, gradient_np.shape) P = np.dot(memories_np, memories_np.transpose()) P = 0.5 * (P + P.transpose()) q = np.dot(memories_np, gradient_np) * -1 G = np.eye(t) P = P + G * eps h = np.zeros(t) + margin v = quadprog.solve_qp(P, q, G, h)[0] x = np.dot(v, memories_np) + gradient_np new_grad = torch.Tensor(x).view(-1) new_grad = new_grad.to(device) return new_grad
def predict(self, X, method='fac'): n_classes = len(self.classes_) Up = np.zeros((len(X), n_classes)) if n_classes == 2: Up = self.estimators_[1].predict_proba(X) Up = Up / Up.sum(axis=1, keepdims=True) Up = (Up > self.train_prevs).astype(np.int) else: for n_clf, (clf_cls, clf) in enumerate(self.estimators_.items()): Up[:, n_clf] = clf.predict_proba(X)[:, 1] Up = Up / Up.sum(axis=1, keepdims=True) Up = (Up > self.train_prevs).astype(np.int) U = Up.mean(axis=0) G = self.V.T.dot(self.V) if not is_pd(G): G = nearest_pd(G) a = U.dot(self.V) C = np.vstack([-np.ones((1, n_classes)), np.eye(n_classes)]).T b = np.array([-1] + [0] * n_classes, dtype=np.float) sol = quadprog.solve_qp(G=G, a=a, C=C, b=b) p = sol[0] return p
def predict(self, X, test_items): confidence_df, scores_df = self.ensemble.predict(X, test_items) labels_order = confidence_df.columns # Create the constraints matrix constraints_matrix = [] for row_label in labels_order: for constraint_label in self.label_graph.source_to_targets[ row_label]: row = [] for label in labels_order: if label == row_label: row.append(1.0) elif label == constraint_label: row.append(-1.0) else: row.append(0.0) constraints_matrix.append(row) b = np.zeros(len(constraints_matrix)) constraints_matrix = np.array(constraints_matrix).T pred_da = [] for q_i in range(len(X)): Q = np.eye(len(labels_order), len(labels_order)) predictions = np.array(confidence_df[labels_order].iloc[q_i], dtype=np.double) print("Running solver on item {}/{}...".format(q_i + 1, len(X))) xf, f, xu, iters, lagr, iact = solve_qp(Q, predictions, constraints_matrix, b) pred_da.append(xf) pred_df = pd.DataFrame(data=pred_da, columns=labels_order, index=test_items) return pred_df, confidence_df
def solve_QP(Q, c, A, b, E=None, d=None): """ Solves the following quadratic program: minimize (1/2)x^T Q x + c^T x subject to Ax <= b and Ex=d (Adapted from: https://scaron.info/blog/quadratic-programming-in-python.html) :param Q 2D Numpy matrix in the equation above :param c 1D Numpy matrix in the equation above :param A 2D Numpy matrix in the equation above :param b 1D Numpy matrix in the equation above :param E 2D Numpy matrix in the equation above :param b 1D Numpy matrix in the equation above :return A 1D Numpy array contaning the values of the variables in the optimal solution """ # Perturb Q so it is positive definite qp_G = Q + 10**(-9) * np.identity(Q.shape[0]) qp_a = -c if E is not None: qp_C = -np.vstack([E, A]).T qp_b = -np.hstack([d.T, b.T]) meq = E.shape[0] else: # no equality constraint qp_C = -A.T qp_b = -b meq = 0 return quadprog.solve_qp(qp_G.astype(np.float64), qp_a.astype(np.float64), qp_C.astype(np.float64), qp_b.astype(np.float64), meq)[0]
def prox(self, x, r): """Proximal operator. Return solution to argmin_u <u,Au> + r/2 || u - x||^2 """ res = solve_qp(self.matrix + r * np.eye(self.dim, self.dim), r * x) return res[0]
def _predict_hdy(self, X): if not self.b: raise ValueError( "If HDy predictions are in order, the quantifier must be trained with the parameter `b`" ) n_classes = len(self.classes_) if n_classes == 2: preds = self.estimators_[1].predict_proba(X)[:, 1] pdf, _ = np.histogram(preds, self.b, range=(0, 1)) test_dist = pdf / float(X.shape[0]) else: test_dist = np.zeros((self.b, len(self.estimators_))) for n_clf, (clf_cls, clf) in enumerate(self.estimators_.items()): preds = clf.predict_proba(X)[:, 1] pdf, _ = np.histogram(preds, self.b, range=(0, 1)) test_dist[:, n_clf] = pdf / float(X.shape[0]) test_dist = test_dist.reshape(-1, 1).squeeze() G = self.train_dist_.T.dot(self.train_dist_) if not is_pd(G): G = nearest_pd(G) a = self.train_dist_.T.dot(test_dist) C = np.vstack([np.ones((1, n_classes)), np.eye(n_classes)]).T b = np.array([1] + [0] * n_classes, dtype=np.float) sol = quadprog.solve_qp(G=G, a=a, C=C, b=b, meq=1) p = sol[0] return p
def solveDualParameters(self, kernel): G = np.zeros((self.total_input, self.total_input)) for i in range(self.total_input): for j in range(self.total_input): dot = self.y[i] * self.y[j] * self.kernelTrick( kernel, self.X[i], self.X[j]) G[i][j], G[j][i] = dot, dot # make it a positive definite matrix if kernel == "Polynomial": G += np.eye(self.total_input) * 1e-3 a = np.ones((self.total_input, )) equality_C = self.y eq_b = np.array([0.]) inequality_C = np.eye(self.total_input) ineq_b = np.zeros((self.total_input, )) qp_C = np.vstack([equality_C, inequality_C]).T qp_b = np.hstack([eq_b, ineq_b]) meq = 1 alpha = solve_qp(G, a, qp_C, qp_b, meq)[0] return alpha
def quadprog_solve_qp(P, q, G=None, h=None, A=None, b=None, initvals=None): """ Solve a Quadratic Program defined as: minimize (1/2) * x.T * P * x + q.T * x subject to G * x <= h A * x == b using quadprog <https://pypi.python.org/pypi/quadprog/>. Parameters ---------- P : numpy.array Symmetric quadratic-cost matrix. q : numpy.array Quadratic-cost vector. G : numpy.array Linear inequality constraint matrix. h : numpy.array Linear inequality constraint vector. A : numpy.array, optional Linear equality constraint matrix. b : numpy.array, optional Linear equality constraint vector. initvals : numpy.array, optional Warm-start guess vector (not used). Returns ------- x : numpy.array Solution to the QP, if found, otherwise ``None``. Note ---- The quadprog solver only considers the lower entries of `P`, therefore it will use a wrong cost function if a non-symmetric matrix is provided. """ if initvals is not None: print("quadprog: note that warm-start values ignored by wrapper") qp_G = P qp_a = -q if A is not None: if A.ndim == 1: A = A.reshape((1, A.shape[0])) if G is None: qp_C = -A.T qp_b = -b else: qp_C = -vstack([A, G]).T qp_b = -hstack([b, h]) meq = A.shape[0] else: # no equality constraint qp_C = -G.T if G is not None else None qp_b = -h if h is not None else None meq = 0 return solve_qp(qp_G, qp_a, qp_C, qp_b, meq)[0]
def test_solve_qp(): Q = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 1]]) + np.eye(3) * 1e-5 p = np.zeros(3) c = np.ones(4) A = np.array([[-1, 0, 0], [-1, -2, -2], [1, 2, 0], [1, 3, 0]]).astype(np.float64).T result = solve_qp(Q, p, A, c) assert np.isclose(np.array(result[0]), np.array([-1, 1, -1])).all()
def quadprog_solve_qp(P, q, G=None, h=None, A=None, b=None): qp_G = .5 * (P + P.T) qp_a = -q if A is not None: qp_C = -np.vstack([A, G]).T qp_b = -np.hstack([b, h]) meq = A.shape[0] else: # no equality constraint qp_C = -G.T qp_b = -h meq = 0 return quadprog.solve_qp(qp_G, qp_a, qp_C, qp_b, meq)[0]
def quadprog_solve_qp(P, q, G=None, h=None, A=None, b=None, initvals=None): """ Solve a Quadratic Program defined as: minimize (1/2) * x.T * P * x + q.T * x subject to G * x <= h A * x == b using quadprog <https://pypi.python.org/pypi/quadprog/>. Parameters ---------- P : numpy.array Symmetric quadratic-cost matrix. q : numpy.array Quadratic-cost vector. G : numpy.array Linear inequality constraint matrix. h : numpy.array Linear inequality constraint vector. A : numpy.array, optional Linear equality constraint matrix. b : numpy.array, optional Linear equality constraint vector. initvals : numpy.array, optional Warm-start guess vector (not used). Returns ------- x : numpy.array Solution to the QP, if found, otherwise ``None``. Note ---- The quadprog solver only considers the lower entries of `P`, therefore it will use a wrong cost function if a non-symmetric matrix is provided. """ if initvals is not None: print("quadprog: note that warm-start values ignored by wrapper") qp_G = P qp_a = -q if A is not None: qp_C = -vstack([A, G]).T qp_b = -hstack([b, h]) meq = A.shape[0] if A.ndim > 1 else 1 else: # no equality constraint qp_C = -G.T qp_b = -h meq = 0 return solve_qp(qp_G, qp_a, qp_C, qp_b, meq)[0]
def test_1(): G = np.eye(3, 3) a = np.array([0, 5, 0], dtype=np.double) C = np.array([[-4, 2, 0], [-3, 1, -2], [0, 0, 1]], dtype=np.double) b = np.array([-8, 2, 0], dtype=np.double) xf, f, xu, iters, lagr, iact = solve_qp(G, a, C, b) np.testing.assert_array_almost_equal(xf, [0.4761905, 1.0476190, 2.0952381]) np.testing.assert_almost_equal(f, -2.380952380952381) np.testing.assert_almost_equal(xu, [0, 5, 0]) np.testing.assert_array_equal(iters, [3, 0]) np.testing.assert_array_almost_equal(lagr, [0.0000000, 0.2380952, 2.0952381]) verify(G, a, C, b)
def verify(G, a, C=None, b=None): xf, f, xu, iters, lagr, iact = solve_qp(G, a, C, b) result = solve_qp_scipy(G, a, C, b) np.testing.assert_array_almost_equal(result.x, xf) np.testing.assert_array_almost_equal(result.fun, f)
(0, 2): (2, 0), (2, 3): (1, 1), (2, 1): (1, 10) }, 'source': 0, 'sink': 3 } N = len(graph['edges']) C = np.zeros((N, N)) for i, e in enumerate(graph['edges']): C[i, i] = graph['edges'][e][0] b = np.zeros((N,)) for i, e in enumerate(graph['edges']): b[i] = graph['edges'][e][1] P = len(graph['vertices']) A = np.zeros((P, N)) for i in graph['vertices']: for j, e in enumerate(graph['edges']): if e[0] == i: A[i, j] = 1 if e[1] == i: A[i, j] = -1 f = np.zeros((P,)) f[graph['source']] = 1 f[graph['sink']] = -1 print(qp.solve_qp( C, -b, np.vstack([A, np.eye(N)]).T, np.hstack([f, np.zeros(N)]), P)[0])
covD = dict() for tranch in idx: covD[tranch] = returns[idx[tranch]][-1*(126+int(tranch)+1):-1*(int(tranch)+1)].cov() covP = pd.Panel(covD) # Find weights based on the GMV portfolio with no shorts resultD = pd.DataFrame() for tranch in idx: mat = covP[tranch][idx[tranch]].loc[idx[tranch]] N = mat.shape[1] Dmat = 2*mat.values dvec = np.zeros(N) Amat = np.concatenate((np.ones((N,1)),np.diag(np.diag(np.ones((N,N))))), axis=1) bvec = np.concatenate((np.ones(1),np.zeros(N))) result = qp.solve_qp(Dmat, dvec, Amat, bvec, 1)[0] resultS = pd.Series(result,index=mat.index, name=tranch) resultD = resultD.append(resultS) # Combine the ranking with the weights and replace NA with 0 rank_weight = ranking.T*resultD rank_weight.fillna(0,inplace=True) # Create tranch weighting function x = list() for i in range(0,tran_look+1, tran_days): x.append(np.exp(-(i**2)/(((tran_look+1)/4)**2))) # Gaussian distribution # Combine tranch weighting function with rank_weight and average columns rank_weight = rank_weight.multiply(x,axis=0) rank_weight = rank_weight.mean(axis=0)