N = R.shape[1] np.random.seed(8888) BenchmarkIndex = R.dot(np.tile(1.0/N, N)) + st.norm(0.0, 3.0).rvs(T) #%% トラッキングエラー最小化問題のバックテスト MovingWindow = 96 BackTesting = T - MovingWindow V_Tracking = np.zeros(BackTesting) Weight = cvx.Variable(N) Error = cvx.Variable(MovingWindow) TrackingError = cvx.sum_squares(Error) Asset_srT = R / np.sqrt(T) Index_srT = BenchmarkIndex / np.sqrt(T) for Month in range(0, BackTesting): Asset = Asset_srT.values[Month:(Month + MovingWindow), :] Index = Index_srT.values[Month:(Month + MovingWindow)] Min_TrackingError = cvx.Problem(cvx.Minimize(TrackingError), [Index - Asset*Weight == Error, cvx.sum(Weight) == 1.0, Weight >= 0.0]) Min_TrackingError.solve() V_Tracking[Month] = R.values[Month + MovingWindow, :].dot(Weight.value) #%% バックテストの結果のグラフ fig1 = plt.figure(1, facecolor='w') plt.plot(list(range(1, BackTesting + 1)), BenchmarkIndex[MovingWindow:], 'k-') plt.plot(list(range(1, BackTesting + 1)), V_Tracking, 'k--') plt.legend([u'ベンチマーク・インデックス', u'インデックス・ファンド'], loc='best', frameon=False, prop=jpfont) plt.xlabel(u'運用期間(年)', fontproperties=jpfont) plt.ylabel(u'収益率(%)', fontproperties=jpfont) plt.xticks(list(range(12, BackTesting + 1, 12)), pd.date_range(R.index[MovingWindow], periods=BackTesting//12,
def cal_fund_regression_exposure_index(self, reg_code, beg_date, end_date, period="D"): """ 回归单只基金区间内指数暴露 用指数去你基金收益率 最小化跟踪误差的前提 指数权重之和为1 指数不能做空 指数和上期权重换手不能太大 """ date_series = Date().get_trade_date_series(beg_date, end_date, period) data_beg_date = Date().get_trade_date_offset(beg_date, -self.regression_period) end_date = Date().change_to_str(end_date) code_list = [reg_code] code_list.extend(self.index_code_list) data = self.asset_pct.loc[data_beg_date:end_date, code_list] data = data.dropna(subset=[reg_code]) if len(data) < self.regression_period: return None print("Regression %s With %s" % (reg_code, self.index_code_list)) print("Length of Return Data Is %s " % len(data)) date_series = list(set(date_series) & set(data.index)) date_series.sort() # 上次计算的风格 last_date = Date().get_trade_date_offset(date_series[0], -1) params_old = self.get_fund_regression_exposure_index_date( reg_code, last_date) params_old = params_old.T print("old", params_old) for i_date in range(0, len(date_series)): # 回归所需要的数据 过去60个交易日 period_end_date = date_series[i_date] period_beg_date = Date().get_trade_date_offset( period_end_date, -self.regression_period) data_end_date = Date().get_trade_date_offset(period_end_date, -0) period_date_series = Date().get_trade_date_series( period_beg_date, data_end_date) data_periods = data.loc[period_date_series, :] data_periods = data_periods.dropna(subset=[reg_code]) data_periods = data_periods.T.dropna(how='all').T data_periods = data_periods.T.fillna(data_periods.mean(axis=1)).T data_periods = data_periods.dropna() print( "########## Calculate Regression Exposure %s %s %s %s ##########" % (reg_code, period_beg_date, period_end_date, len(data_periods))) if len(data_periods) > self.regression_period_min and (len( data_periods.columns) > 1): y = data_periods.iloc[:, 0].values x = data_periods.iloc[:, 1:].values n = x.shape[1] if params_old.empty or params_old.sum().sum() < 0.5: params_old = pd.DataFrame(n * [1 / n], columns=[period_end_date], index=data_periods.columns[1:]).T turnover = self.turnover params_old = params_old.loc[:, data_periods.columns[1:]] params_old = params_old.fillna(0.0) weight_old = params_old.values[0] w = cvx.Variable(n) sigma = y - x * w prob = cvx.Problem(cvx.Minimize(cvx.sum_squares(sigma)), [ cvx.sum(w) == 1, w >= 0, cvx.sum(cvx.abs(w - weight_old)) <= turnover ]) prob.solve() print('Solver Status : ', prob.status) # 计算回归 R2 n = len(y) k = x.shape[1] tss = np.sum((y - np.mean(y))**2) / n y_res = y - np.dot(x, w.value) rss = np.sum(y_res**2) / (n - k - 1) r2 = 1 - rss / tss params_add = pd.DataFrame(w.value, columns=[period_end_date], index=data_periods.columns[1:]).T params_add.loc[period_end_date, "R2"] = r2 print('new', params_add) params_old = params_add else: last_date = Date().get_trade_date_offset(period_end_date, -1) params_old = self.get_fund_regression_exposure_index_date( reg_code, last_date) params_old = params_old.T print("old", params_old) params_add = params_old if i_date == 0: params_new = params_add else: params_new = pd.concat([params_new, params_add], axis=0) # 合并新数据 file = '%s_%s_%s.csv' % (self.file_prefix, self.folder_name, reg_code) out_file = os.path.join(self.index_exposure_path, file) if os.path.exists(out_file): params_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') params_old.index = params_old.index.map(str) params = FactorOperate().pandas_add_row(params_old, params_new) else: params = params_new params.to_csv(out_file)
# M = 500 intensity_vec = [] for i in range(0, M): mask = mask_vec[i] masked = mask * X intensity = np.sum(masked) intensity_vec.append(intensity) # do L1 optimization AX = A[0:M, :] print AX.shape vx = cvx.Variable(nx * ny) objective = cvx.Minimize(cvx.norm(vx, 1)) constraints = [AX * vx == intensity_vec] prob = cvx.Problem(objective, constraints) result = prob.solve(verbose=True) Xat2 = np.array(vx.value).squeeze() # reconstruct signal Xat = Xat2.reshape(nx, ny).T # stack columns Xa = idct2(Xat) Xa = Xa.astype("float64") X = X.astype("float64") print ssim(Xa, X) ssim_vec.append(ssim(Xa, X)) M_vec.append(M) plt.figure()
def regress_fund(self, fund_code, beg_date, end_date): """ 回归单只基金区间内指数暴露 """ period = "W" date_series = Date().get_trade_date_series(beg_date, end_date, period) fund_return = self.fund_pct[fund_code] fund_return = fund_return.dropna() date_series = list(set(date_series) & set(fund_return.index)) date_series.sort() # 季报持仓 quarter_weight = Fund().get_fund_holding_quarter(fund_code) r2_series = pd.DataFrame([], index=date_series, columns=['r2']) for i_date in range(0, len(date_series)): # 时间确定 ed_date = date_series[i_date] ed_date = Date().get_trade_date_offset(ed_date, -0) quarter_date = Date().get_last_fund_quarter_date(ed_date) bg_date = Date().get_trade_date_offset(ed_date, -(self.regression_len - 1)) bg_date = max(bg_date, quarter_date) bg_date = Date().get_trade_date_offset(bg_date, -0) date_diff = Date().get_trade_date_diff(bg_date, ed_date) # 上期持仓 try: stock_weight = pd.DataFrame(quarter_weight[quarter_date]) stock_weight = stock_weight.dropna() stock_weight.columns = ['Weight'] # 收益率数据 data = pd.concat([fund_return, self.stock_pct, self.bold_pct], axis=1) data['885062.WI'] = data['885062.WI'].fillna(0.0) regress_date_series = Date().get_trade_date_series(bg_date, ed_date) data = data.loc[regress_date_series, :] data = data.T.dropna(thresh=self.regression_min_len).T data = data.fillna(data.mean(axis=1)) # 股票池 stock_pool = list(stock_weight.index) stock_pool = list(set(stock_pool) & set(data.columns[1:])) stock_pool.sort() stock_pool.append("885062.WI") stock_ratio = self.get_fund_stock_ratio(fund_code, quarter_date) stock_weight['Weight'] /= stock_weight['Weight'].sum() stock_weight['Weight'] *= stock_ratio stock_weight.loc["885062.WI", "Weight"] = 100 - stock_ratio stock_weight /= 100.0 stock_weight = stock_weight.loc[stock_pool, :] stock_weight['Weight'] /= stock_weight['Weight'].sum() print("## Cal Regress %s %s %s %s %s ##" % (fund_code, quarter_date, bg_date, ed_date, len(data))) if (len(data) > self.regression_min_len) and (len(stock_pool) > 4): # 利用指数去你和基金收益率 最小化跟踪误差的前提 # 指数权重之和为1 指数不能做空 指数和上期权重换手不能太大 y = data[fund_code].values / 100.0 x = data[stock_pool].values / 100.0 n = len(y) k = x.shape[1] weight_old = stock_weight.T.values[0] turnover = date_diff * 0.8 / 100 print("TurnOver %s " % turnover) ############################################################################## w = cvx.Variable(k) sigma = y - x * w prob = cvx.Problem(cvx.Minimize(cvx.sum_squares(sigma)), [cvx.sum(w) == 1.0, w >= 0, cvx.sum(cvx.abs(w - weight_old)) <= turnover ]) prob.solve() ############################################################################## tss = np.sum((y - np.mean(y)) ** 2) / n y_res = y - np.dot(x, w.value) rss = np.sum(y_res ** 2) / (n - k - 1) r2 = 1 - rss / tss r2_series.loc[ed_date, "r2"] = r2 ############################################################################## print('Solver Status : ', prob.status) params_add = pd.DataFrame(w.value, columns=[ed_date], index=stock_pool) # print(params_add.T) # print(pd.concat([stock_weight, params_add], axis=1)) else: params_add = pd.DataFrame([], columns=[ed_date], index=stock_pool) except Exception as e: params_add = pd.DataFrame([], columns=[ed_date]) if i_date == 0: params_new = params_add else: params_new = pd.concat([params_new, params_add], axis=1) # 合并新数据 #################################################################### params_new = params_new.T out_file = os.path.join(self.data_path_exposure, fund_code + '.csv') if os.path.exists(out_file): params_old = pd.read_csv(out_file, index_col=[0], encoding='gbk') params_old.index = params_old.index.map(str) params = FactorOperate().pandas_add_row(params_old, params_new) else: params = params_new params.to_csv(out_file) r2_series = r2_series.dropna() out_file = os.path.join(self.data_path_exposure, fund_code + '_r2.csv') r2_series.to_csv(out_file)
def test_intro(self): """Test examples from cvxpy.org introduction. """ import numpy # cvx.Problem data. m = 30 n = 20 numpy.random.seed(1) A = numpy.random.randn(m, n) b = numpy.random.randn(m) # Construct the problem. x = cvx.Variable(n) objective = cvx.Minimize(cvx.sum_squares(A @ x - b)) constraints = [0 <= x, x <= 1] prob = cvx.Problem(objective, constraints) # The optimal objective is returned by p.solve(). prob.solve() # The optimal value for x is stored in x.value. print(x.value) # The optimal Lagrange multiplier for a constraint # is stored in constraint.dual_value. print(constraints[0].dual_value) ######################################## # Create two scalar variables. x = cvx.Variable() y = cvx.Variable() # Create two constraints. constraints = [x + y == 1, x - y >= 1] # Form objective. obj = cvx.Minimize(cvx.square(x - y)) # Form and solve problem. prob = cvx.Problem(obj, constraints) prob.solve() # Returns the optimal value. print("status:", prob.status) print("optimal value", prob.value) print("optimal var", x.value, y.value) ######################################## # Create two scalar variables. x = cvx.Variable() y = cvx.Variable() # Create two constraints. constraints = [x + y == 1, x - y >= 1] # Form objective. obj = cvx.Minimize(cvx.square(x - y)) # Form and solve problem. prob = cvx.Problem(obj, constraints) prob.solve() # Returns the optimal value. print("status:", prob.status) print("optimal value", prob.value) print("optimal var", x.value, y.value) self.assertEqual(prob.status, cvx.OPTIMAL) self.assertAlmostEqual(prob.value, 1.0) self.assertAlmostEqual(x.value, 1.0) self.assertAlmostEqual(y.value, 0) ######################################## # Replace the objective. prob = cvx.Problem(cvx.Maximize(x + y), prob.constraints) print("optimal value", prob.solve()) self.assertAlmostEqual(prob.value, 1.0, places=3) # Replace the constraint (x + y == 1). constraints = prob.constraints constraints[0] = (x + y <= 3) prob = cvx.Problem(prob.objective, constraints) print("optimal value", prob.solve()) self.assertAlmostEqual(prob.value, 3.0, places=2) ######################################## x = cvx.Variable() # An infeasible problem. prob = cvx.Problem(cvx.Minimize(x), [x >= 1, x <= 0]) prob.solve() print("status:", prob.status) print("optimal value", prob.value) self.assertEqual(prob.status, cvx.INFEASIBLE) self.assertAlmostEqual(prob.value, np.inf) # An unbounded problem. prob = cvx.Problem(cvx.Minimize(x)) prob.solve() print("status:", prob.status) print("optimal value", prob.value) self.assertEqual(prob.status, cvx.UNBOUNDED) self.assertAlmostEqual(prob.value, -np.inf) ######################################## # A scalar variable. cvx.Variable() # Column vector variable of length 5. x = cvx.Variable(5) # Matrix variable with 4 rows and 7 columns. A = cvx.Variable((4, 7)) ######################################## import numpy # cvx.Problem data. m = 10 n = 5 numpy.random.seed(1) A = numpy.random.randn(m, n) b = numpy.random.randn(m) # Construct the problem. x = cvx.Variable(n) objective = cvx.Minimize(cvx.sum_squares(A @ x - b)) constraints = [0 <= x, x <= 1] prob = cvx.Problem(objective, constraints) print("Optimal value", prob.solve()) print("Optimal var") print(x.value) # A numpy matrix. self.assertAlmostEqual(prob.value, 4.14133859146) ######################################## # Positive scalar parameter. m = cvx.Parameter(nonneg=True) # Column vector parameter with unknown sign (by default). cvx.Parameter(5) # Matrix parameter with negative entries. G = cvx.Parameter((4, 7), nonpos=True) # Assigns a constant value to G. G.value = -numpy.ones((4, 7)) ######################################## # Create parameter, then assign value. rho = cvx.Parameter(nonneg=True) rho.value = 2 # Initialize parameter with a value. rho = cvx.Parameter(nonneg=True, value=2) ######################################## import numpy # cvx.Problem data. n = 15 m = 10 numpy.random.seed(1) A = numpy.random.randn(n, m) b = numpy.random.randn(n) # gamma must be positive due to DCP rules. gamma = cvx.Parameter(nonneg=True) # Construct the problem. x = cvx.Variable(m) error = cvx.sum_squares(A @ x - b) obj = cvx.Minimize(error + gamma*cvx.norm(x, 1)) prob = cvx.Problem(obj) # Construct a trade-off curve of ||Ax-b||^2 vs. ||x||_1 sq_penalty = [] l1_penalty = [] x_values = [] gamma_vals = numpy.logspace(-4, 6) for val in gamma_vals: gamma.value = val prob.solve() # Use expr.value to get the numerical value of # an expression in the problem. sq_penalty.append(error.value) l1_penalty.append(cvx.norm(x, 1).value) x_values.append(x.value) ######################################## import numpy X = cvx.Variable((5, 4)) A = numpy.ones((3, 5)) # Use expr.size to get the dimensions. print("dimensions of X:", X.size) print("dimensions of sum(X):", cvx.sum(X).size) print("dimensions of A @ X:", (A @ X).size) # ValueError raised for invalid dimensions. try: A + X except ValueError as e: print(e)
def fit(self, x, y, c_factor): x = check_feature_input(x) y = check_target_input(y) self.features = x.shape[1] x = Normalizer.normalize(x, self.normalize, self.axis) sample_num, feature_num = x.shape class_num = y.shape[1] class_info = AllLabelInfo() """ Franke and Wolfe Method applied on the optimization problem """ # organize labels for preparation for sample_index in range(sample_num): sample_y = y[sample_index] labels = [] not_labels = [] for label_index in range(class_num): if sample_y[label_index] == 1: labels.append(label_index) else: not_labels.append(label_index) class_info.append(labels, not_labels) """ Alpha ought to have 3-dimensions. For convenience, it is flattened into a list. It's length is sum(yi*nyi) for i in range(samle_num) """ alpha = np.zeros(class_info.totalProduct) alpha_var = cvx.Variable(class_info.totalProduct) """ C has 4 dimensions, which is hard to present. In this program it has 2 dimensions, which is i(sample index) and k(class index). Each c[i][k] contains a yi*nyi array, which is initialized according to the original paper. """ c = [[0 for k in range(class_num)] for i in range(sample_num)] for i in range(sample_num): sample_shape, labels, not_labels = class_info.get_shape(i, True) for k in range(class_num): matrix = np.zeros(sample_shape) if k in labels: index = labels.index(k) matrix[index, :] = 1 else: index = not_labels.index(k) matrix[:, index] = -1 c[i][k] = matrix.flatten() c = np.array(c) beta = np.zeros((class_num, sample_num)) beta_new = np.zeros((class_num, sample_num)) wx_inner = np.zeros((class_num, sample_num)) # TODO: this can cut half of the running time x_inner = np.array([[np.inner(x[i], x[j]) for j in range(sample_num)] for i in range(sample_num)]) g_ikl = np.zeros(class_info.totalProduct) """ prepare for the first linear programming """ c_i = class_info.eachProduct bnds = [] for i in range(sample_num): bnds += [c_factor / c_i[i] for j in range(c_i[i])] bnds = np.array(bnds) zeros = np.zeros(class_info.totalProduct) zeros.fill(1e-5) A_lp = [] for k in range(1, class_num): A_lp.append(np.concatenate(c[:, k]).tolist()) A_lp = np.array(A_lp) b_lp = np.zeros(class_num - 1) cons = [ zeros <= alpha_var, alpha_var <= bnds, A_lp * alpha_var == b_lp ] converge = False iteration_count = 0 # iterate training until converge while not converge: iteration_count += 1 # compute beta for i in range(sample_num): alpha_range = class_info.get_range(i) alpha_piece = alpha[alpha_range[0]:alpha_range[1]] c_list = c[i] for k in range(class_num): beta[k][i] = np.inner(c_list[k], alpha_piece) # compute <w_k, x_j> for k in range(class_num): beta_list = beta[k] for j in range(sample_num): x_innerlist = x_inner[:, j] wx_inner[k][j] = np.inner(beta_list, x_innerlist) # compute g_ikl for i in range(sample_num): g_range = class_info.get_range(i) shape, labels, not_labels = class_info.get_shape(i, True) wx_list = wx_inner[:, i] g_ikl[g_range[0]:g_range[1]] = np.repeat( wx_list[labels], shape[1]) - np.tile( wx_list[not_labels], shape[0]) - 1 """ optimization problem 1: solve min<g, alpha_new> with corresponding constraints """ if self.print_procedure: print('iteration %d...' % iteration_count) """ cvxopt.solvers.lp 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. cvxopt.solvers.lp(c, G, h[, A, b[, solver[, primalstart[, dualstart]]]]) """ obj = cvx.Minimize(cvx.sum_entries(g_ikl * alpha_var)) prob = cvx.Problem(obj, cons) prob.solve() alpha_new = np.array(alpha_var.value).T[0] """ now the problem collapse into a really simple qp problem """ # compute beta_new for i in range(sample_num): alpha_range = class_info.get_range(i) alpha_piece = alpha_new[alpha_range[0]:alpha_range[1]] c_list = c[i] for k in range(class_num): beta_new[k][i] = np.inner(c_list[k], alpha_piece) """ We need to find lambda which will make W(alpha + lambda*alpha_new) be maximum and alpha + lambda*alpha_new satisfies the previous constraints. After calculating the formula, it is now: new_W = old_W + [sum formula of beta_new and beta] + [sum formula of beta and beta_new] + [sum formula of beta_new and beta_new] + [sum of the new alpha] old_W is fixed and has no effect on the choice of the lambda during the maximum process. Then we can calculate the coeffient of lambda. The final problem will look like: maximize a*lambda_square + b*lambda c <= lambda <= d It is apparently easy to solve. """ # init coeffient of lambda lambda_11 = np.sum(beta_new.T.dot(beta) * x_inner) lambda_12 = np.sum(beta.T.dot(beta_new) * x_inner) lambda_13 = np.sum(alpha_new) # coefficient of lambda lambda_1 = lambda_13 - lambda_11 / 2 - lambda_12 / 2 # coefficient of lambda square lambda_2 = np.sum(beta_new.T.dot(beta_new) * x_inner) / (-2) # prepare constraints left_vec = -alpha right_vec = bnds - alpha left = float('-inf') right = float('inf') for alpha_index in range(class_info.totalProduct): if not alpha_new[alpha_index] == 0: left = max(left_vec[alpha_index] / alpha_new[alpha_index], left) right = min( right_vec[alpha_index] / alpha_new[alpha_index], right) optifunc = lambda z: lambda_2 * z * z + lambda_1 * z # decide lambda's value if lambda_2 < 0: opti_lambda = -lambda_1 / (lambda_2 * 2) if opti_lambda < left: final_lambda = left elif opti_lambda > right: final_lambda = right else: final_lambda = opti_lambda elif lambda_2 == 0: if lambda_1 >= 0: final_lambda = right else: final_lambda = left else: worst_lambda = -lambda_1 / (lambda_2 * 2) if worst_lambda < left: final_lambda = right elif worst_lambda > right: final_lambda = left else: final_lambda = left if optifunc(left) >= optifunc( right) else right if self.print_procedure: print("final lambda: " + str(final_lambda)) print("optifunc: " + str(optifunc(final_lambda))) # converge condition if optifunc(final_lambda) <= 1 or final_lambda <= 1e-3: converge = True else: alpha += final_lambda * alpha_new """ compute w and b via KKT conditions """ w = [0 for i in range(class_num)] for k in range(class_num): beta_vec = np.asarray([beta[k]]) w[k] = beta_vec.dot(x)[0] w = np.array(w) b = np.zeros(class_num) # use x[0] to compute differences of b x_list = x[0] shape, labels, not_labels = class_info.get_shape(0, True) """ We know that once the differences between each element and the first element is known we can get all the values of the list. As the classification system is based on ranking, we can make any element 0 as a start of calculation, which will not affect the final ranking. """ # make the first label's b=0, it won't affect the fianl ranking for l in not_labels: b[l] = np.inner(w[labels[0]] - w[l], x_list) - 1 # then use b[falselabels[0]] to compute b[actuallabels[1:]] falselabelb = b[not_labels[0]] falselabel_index = not_labels[0] for labelIndex in range(1, len(labels)): b[labels[labelIndex]] = 1 + falselabelb - np.inner( w[labels[labelIndex]] - w[falselabel_index], x_list) # build threshold for labeling x_extend = np.concatenate((x, np.array([np.ones(sample_num)]).T), axis=1) w_extend = np.concatenate((w, np.array([b]).T), axis=1) model_outputs = np.dot(x_extend, w_extend.T) self.threshold = ThresholdFunction(model_outputs, y) self.w = w_extend self.trained = True return self
def cvx_fit(data: np.array, basis_matrix: np.array, weights: Optional[np.array] = None, psd: bool = True, trace: Optional[int] = None, trace_preserving: bool = False, **kwargs ) -> np.array: r""" Reconstruct a quantum state using CVXPY convex optimization. **Objective function** This fitter solves the constrained least-squares minimization: :math:`minimize: ||a * x - b ||_2` subject to: * :math:`x >> 0` (PSD, optional) * :math:`\text{trace}(x) = t` (trace, optional) * :math:`\text{partial_trace}(x)` = identity (trace_preserving, optional) where: * a is the matrix of measurement operators :math:`a[i] = vec(M_i).H` * b is the vector of expectation value data for each projector :math:`b[i] ~ \text{Tr}[M_i.H * x] = (a * x)[i]` * x is the vectorized density matrix (or Choi-matrix) to be fitted **PSD constraint** The PSD keyword constrains the fitted matrix to be postive-semidefinite, which makes the optimization problem a SDP. If PSD=False the fitted matrix will still be constrained to be Hermitian, but not PSD. In this case the optimization problem becomes a SOCP. **Trace constraint** The trace keyword constrains the trace of the fitted matrix. If trace=None there will be no trace constraint on the fitted matrix. This constraint should not be used for process tomography and the trace preserving constraint should be used instead. **Trace preserving (TP) constraint** The trace_preserving keyword constrains the fitted matrix to be TP. This should only be used for process tomography, not state tomography. Note that the TP constraint implicitly enforces the trace of the fitted matrix to be equal to the square-root of the matrix dimension. If a trace constraint is also specified that differs from this value the fit will likely fail. **CVXPY Solvers** Various solvers can be called in CVXPY using the `solver` keyword argument. See the `CVXPY documentation <https://www.cvxpy.org/tutorial/advanced/index.html#solve-method-options>`_ for more information on solvers. Args: data: (vector like) vector of expectation values basis_matrix: (matrix like) measurement operators weights: (vector like) weights to apply to the objective function (default: None) psd: (default: True) enforces the fitted matrix to be positive semidefinite (default: True) trace: trace constraint for the fitted matrix (default: None). trace_preserving: (default: False) Enforce the fitted matrix to be trace preserving when fitting a Choi-matrix in quantum process tomography (default: False). **kwargs: kwargs for cvxpy solver. Raises: ImportError: if cvxpy is not present RuntimeError: In case cvx fitting failes Returns: The fitted matrix rho that minimizes :math:`||basis_matrix * vec(rho) - data||_2`. """ # Check if CVXPY package is installed if not _HAS_CVX: raise ImportError("The CVXPY package is required to use the cvx_fit() " "function. You can install it with 'pip install " "cvxpy' or use a `lstsq` fitter instead of cvx_fit.") # SDP VARIABLES # Since CVXPY only works with real variables we must specify the real # and imaginary parts of rho seperately: rho = rho_r + 1j * rho_i dim = int(np.sqrt(basis_matrix.shape[1])) rho_r = cvxpy.Variable((dim, dim), symmetric=True) rho_i = cvxpy.Variable((dim, dim)) # CONSTRAINTS # The constraint that rho is Hermitian (rho.H = rho) # transforms to the two constraints # 1. rho_r.T = rho_r.T (real part is symmetric) # 2. rho_i.T = -rho_i.T (imaginary part is anti-symmetric) cons = [rho_i == -rho_i.T] # Trace constraint: note this should not be used at the same # time as the trace preserving constraint. if trace is not None: cons.append(cvxpy.trace(rho_r) == trace) # Since we can only work with real matrices in CVXPY we can specify # a complex PSD constraint as # rho >> 0 iff [[rho_r, -rho_i], [rho_i, rho_r]] >> 0 if psd is True: rho = cvxpy.bmat([[rho_r, -rho_i], [rho_i, rho_r]]) cons.append(rho >> 0) # Trace preserving constraint when fitting Choi-matrices for # quantum process tomography. Note that this adds an implicity # trace constraint of trace(rho) = sqrt(len(rho)) = dim # if a different trace constraint is specified above this will # cause the fitter to fail. if trace_preserving is True: sdim = int(np.sqrt(dim)) ptr = partial_trace_super(sdim, sdim) cons.append(ptr @ cvxpy.vec(rho_r) == np.identity(sdim).ravel()) cons.append(ptr @ cvxpy.vec(rho_i) == np.zeros(sdim*sdim)) # Rescale input data and matrix by weights if they are provided if weights is not None: w = np.array(weights) w = w / np.sqrt(sum(w**2)) basis_matrix = w[:, None] * basis_matrix data = w * data # OBJECTIVE FUNCTION # The function we wish to minimize is || arg ||_2 where # arg = bm * vec(rho) - data # Since we are working with real matrices in CVXPY we expand this as # bm * vec(rho) = (bm_r + 1j * bm_i) * vec(rho_r + 1j * rho_i) # = bm_r * vec(rho_r) - bm_i * vec(rho_i) # + 1j * (bm_r * vec(rho_i) + bm_i * vec(rho_r)) # = bm_r * vec(rho_r) - bm_i * vec(rho_i) # where we drop the imaginary part since the expectation value is real bm_r = np.real(basis_matrix) bm_i = np.imag(basis_matrix) # CVXPY doesn't seem to handle sparse matrices very well so we convert # sparse matrices to Numpy arrays. if isinstance(basis_matrix, sps.spmatrix): bm_r = bm_r.todense() bm_i = bm_i.todense() arg = bm_r @ cvxpy.vec(rho_r) - bm_i @ cvxpy.vec(rho_i) - np.array(data) # SDP objective function obj = cvxpy.Minimize(cvxpy.norm(arg, p=2)) # Solve SDP prob = cvxpy.Problem(obj, cons) iters = 5000 max_iters = kwargs.get('max_iters', 20000) # Set default solver if none is specified if 'solver' not in kwargs: if 'CVXOPT' in cvxpy.installed_solvers(): kwargs['solver'] = 'CVXOPT' problem_solved = False while not problem_solved: kwargs['max_iters'] = iters prob.solve(**kwargs) if prob.status in ["optimal_inaccurate", "optimal"]: problem_solved = True elif prob.status == "unbounded_inaccurate": if iters < max_iters: iters *= 2 else: raise RuntimeError( "CVX fit failed, probably not enough iterations for the " "solver") elif prob.status in ["infeasible", "unbounded"]: raise RuntimeError( "CVX fit failed, problem status {} which should not " "happen".format(prob.status)) else: raise RuntimeError("CVX fit failed, reason unknown") rho_fit = rho_r.value + 1j * rho_i.value return rho_fit
def main(self,train,test,true_weights,true_lambda,true_beta): # dataset = 'dataset_100_0_95_0_15_0_85.csv' dataset = 'gammadataset_100_0_35_0_15_0_85.csv' # true_weights = [0.15,0.85] # true_beta = 0.85 # true_lambda = 100 pred_lam = 1 pred_bet = 1 lam_error = {} beta_error = {} fileContent = self.readDataset(dataset) pst = predictStoppingTime() # preparedData = pst.prepareData(fileContent,true_weights) # # preparedData = preparedData[:3] # train = preparedData[:100] # # print("train",train) # test = preparedData[900:] error = {} for i in range(len(train)): # train = train_df[:i+1] num_of_noise_variables = len(train[i]) # for i in range(len(train[i])): # # print(len(train[i])) # num_of_noise_variables += len(train[i]) A = self.generateAmatrix(train[i],num_of_noise_variables) A = np.array(A) # print("A:",A) X = cp.Variable(2+num_of_noise_variables) b = self.generatebVector(train[i]) b = np.array(b) b = np.reshape(b,(b.shape[0],)) # print("b:",b) # print("sahpes: ",A.shape,X.shape,b.shape) beta_limit_matrix = [0,1]+[0 for i in range(num_of_noise_variables)] lambda_limit_matrix = [1,0]+[0 for i in range(num_of_noise_variables)] constraint_matrix = [[1 if i==j and i!=1 else 0 for j in range(num_of_noise_variables+2)] for i in range(num_of_noise_variables+2)] #print(constraint_matrix) constraints = [0 >= beta_limit_matrix@X, [0 for i in range(num_of_noise_variables+2)] <= constraint_matrix@X] if i != 0: objective = cp.Minimize(cp.norm(((A@X)-b),2)+1000*(cp.square(beta_limit_matrix@X - pred_bet))) else: objective = cp.Minimize(cp.norm(((A@X)-b),2)) prob = cp.Problem(objective,constraints) try: prob.solve(solver=cp.ECOS) alpha = 0.7 pred_lam_step = 2**X.value[0] pred_bet_step = 2**X.value[1] pred_lam = alpha*pred_lam + (1-alpha)*pred_lam_step if(i!=0) else pred_lam_step pred_bet = alpha*pred_bet + (1-alpha)*pred_bet_step if(i!=0) else pred_bet_step pred_bet = 1 if pred_bet > 1 else pred_bet except Exception as e: print(str(e)) lam_error[i] = (true_lambda - pred_lam)**2/true_lambda**2 beta_error[i] = (true_beta - pred_bet)**2/true_beta**2 error[i] = pst.calculateError([train[i]],pred_lam,pred_bet) # print(error) # plt.plot(list(error.keys()),list(error.values()),label=r'$E((T-\hat{T})^2/T^2)$') # plt.plot(list(lam_error.keys()),list(lam_error.values()),'r-*',label='Lambda Error') # plt.plot(list(beta_error.keys()),list(beta_error.values()),'g--^',label='Beta Error') # plt.legend() # #plt.ylim(0,1) # plt.xlabel("Number of Simulations") # plt.ylabel("WST Normalized Average Error") # plt.grid() # plt.show() # print(pred_lam,pred_bet) test_rmse = pst.calculateError(test,pred_lam,pred_bet) return error,lam_error,beta_error,test_rmse
def build_qp(self, point_collisions, sweep_collisions, N, theta0, mu, d_safe): """Create the qp problem to be solved. point_collisions is an Iterable of JointObjectInfo storing all point collision sweep_collisions is an Iterable of SweepJointObjectInfo storing all sweeping collisions theta0 is the trajectory at the last step mu is the penalty parameter to constraints warm means only trust region size is updated and we can reuse """ N, dim_x = theta0.shape thetas = cp.Variable((N, dim_x), name="Configurations") trsize = cp.Parameter(name='Trust Region Size') # the sos loss is easy loss = 0 if self.losses is None: loss += cp.sum_squares(thetas[1:] - thetas[:-1]) else: for lossi in self.losses: obj, grad, hess = lossi.compute(theta0.flatten(), 2) delta = thetas.flatten() - theta0.flatten() loss = obj + grad * delta loss += 0.5 * cp.quad_form(delta, hess) # constraints on initial and final configuration # cons = [thetas[0] == self.q0, thetas[-1] == self.qf] cons = [] if self.fixedq0: cons.append(thetas[0] == self.q0) if self.fixedqf: cons.append(thetas[-1] == self.qf) for idx_, con in self.constrs.eqs: for idx in self._indexes(idx_): if (idx == 0 and self.fixedq0) or (idx == N - 1 and self.fixedqf): continue val, jac = con.compute(theta0[idx], grad_level=1) pt = cp.Variable(val.size) loss += mu * cp.sum(pt) cons.append(pt >= val + jac * (thetas[idx] - theta0[idx])) cons.append(pt >= -(val + jac * (thetas[idx] - theta0[idx]))) for idx_, con in self.constrs.ineqs: for idx in self._indexes(idx_): if (idx == 0 and self.fixedq0) or (idx == N - 1 and self.fixedqf): continue val, jac = con.compute(theta0[idx], grad_level=1) ineqpt = cp.Variable(val.size) loss += mu * cp.sum(ineqpt) cons.append(ineqpt >= 0) cons.append(ineqpt >= val + jac * (thetas[idx] - theta0[idx])) if self.config.limit_joint and self.config.joint_limits_by_bound: cons.append( thetas >= np.tile(self.qmin[None, :], (N, 1))) # hope broadcasting works here cons.append(thetas <= np.tile(self.qmax[None, :], (N, 1))) # Now let's handle point_collisions n_point_collide = len(point_collisions) n_collide = n_point_collide + len(sweep_collisions) if n_collide > 0: pt = cp.Variable(n_collide, name='Auxiliary Variable') # all pt are added to the cost function and are positive loss += cp.sum(pt) * mu cons.append(pt >= 0) for i, pc in enumerate(point_collisions): # constraint that t > g_i(x) = d_safe - d0 - n^T J (theta - theta0) lin_coef = pc.normal.dot(pc.jacobian[:3]) qid = pc.qid cons.append( pt[i] >= d_safe - pc.distance - cp.sum(cp.multiply(lin_coef, thetas[qid] - theta0[qid]))) for i, pc in enumerate(sweep_collisions): lin_coef1 = pc.normal.dot(pc.jacobian1[:3]) lin_coef2 = pc.normal.dot(pc.jacobian2[:3]) alpha, beta = pc.alpha, 1 - pc.alpha qid1, qid2 = pc.qid1, pc.qid1 + 1 cons.append( pt[i + n_point_collide] >= d_safe - pc.distance - cp.sum(alpha * (cp.multiply(lin_coef1, thetas[qid1] - theta0[qid1])) + beta * (cp.multiply(lin_coef2, thetas[qid2] - theta0[qid2])))) # add trust region constraints, here I use infinite norm cons.append(cp.pnorm(thetas - theta0, 'inf') <= trsize) # ready to build the problem and cache them prob = cp.Problem(cp.Minimize(loss), cons) self.cp_cache = (prob, trsize, thetas)
def optimization(polygon, param_reg=1.0, param_smh=200.0, param_spacing=1.0, local=True): ''' A pre-mature optimization for given polygon. Referencing to curve optimization detail from [Zhao, et al. 16] without spacing-preserving term ''' # deal with nest polygon structures # space inefficient, but whatever... if local and type(polygon) is list: return [ optimization(nest_polygon, param_reg, param_smh, param_spacing, local) for nest_polygon in polygon ] # original coords m, n = get_xy(polygon, local) mn = np.concatenate((m, n)) # variables to be optimized x = cp.Variable(m.shape) y = cp.Variable(n.shape) # penalty for magnitude of the perturbations, formulated as distance least squares x_reg_cost = cp.sum_squares(x - m) y_reg_cost = cp.sum_squares(y - n) # construct modified scalar for mid-point scheme coords = get_coord_list(polygon) u = [] for i in range(m.shape[0] - 2): u_i = dist(coords[i], coords[i + 1]) / (dist( coords[i], coords[i + 1]) + dist(coords[i + 1], coords[i + 2])) u.append([u_i]) u = np.matrix(u) # construct matrix L, a (n-2)-by-n matrix where n=m.shape, or the number of variables # it encodes scalars for calculating f_smooth L = [] for i in range(m.shape[0] - 2): row_i = [0 for j in range(m.shape[0])] row_i[i] = 1 - u.item(i) row_i[i + 1] = -1 row_i[i + 2] = u.item(i) L.append(row_i) L = np.matrix(L) # smoothness potential, formualted as L2 norm # note that we cannot explicitly write out the whole expression in matrix form # using x.T @ L.T will cause the cvxpy fails to realize the whole objective is actually convex # as it treats x.T and x as two different variable vectors x_smh_ptnt = cp.sum_squares(L @ x) y_smh_ptnt = cp.sum_squares(L @ y) optimize = cp.Problem( cp.Minimize((x_reg_cost + y_reg_cost) * param_reg + (x_smh_ptnt + y_smh_ptnt) * param_smh)) optimize.solve() points = [] for i in range(len(x.value)): points.append((x.value[i][0], y.value[i][0])) # depending on what we optimize on, the output will be in different format if local: return Polygon(points) else: return points
def cvx_fit(data, basis_matrix, weights=None, PSD=True, trace=None, trace_preserving=False, **kwargs): """ Reconstruct a quantum state using CVXPY convex optimization. Args: data (vector like): vector of expectation values basis_matrix (matrix like): matrix of measurement operators weights (vector like, optional): vector of weights to apply to the objective function (default: None) PSD (bool, optional): Enforced the fitted matrix to be positive semidefinite (default: True) trace (int, optional): trace constraint for the fitted matrix (default: None). trace_preserving (bool, optional): Enforce the fitted matrix to be trace preserving when fitting a Choi-matrix in quantum process tomography (default: False). **kwargs (optional): kwargs for cvxpy solver. Returns: The fitted matrix rho that minimizes ||basis_matrix * vec(rho) - data||_2. Additional Information: Objective function ------------------ This fitter solves the constrained least-squares minimization: minimize: ||a * x - b ||_2 subject to: x >> 0 (PSD, optional) trace(x) = t (trace, optional) partial_trace(x) = identity (trace_preserving, optional) where: a is the matrix of measurement operators a[i] = vec(M_i).H b is the vector of expectation value data for each projector b[i] ~ Tr[M_i.H * x] = (a * x)[i] x is the vectorized density matrix (or Choi-matrix) to be fitted PSD constraint -------------- The PSD keyword constrains the fitted matrix to be postive-semidefinite, which makes the optimization problem a SDP. If PSD=False the fitted matrix will still be constrained to be Hermitian, but not PSD. In this case the optimization problem becomes a SOCP. Trace constraint ---------------- The trace keyword constrains the trace of the fitted matrix. If trace=None there will be no trace constraint on the fitted matrix. This constraint should not be used for process tomography and the trace preserving constraint should be used instead. Trace preserving (TP) constraint -------------------------------- The trace_preserving keyword constrains the fitted matrix to be TP. This should only be used for process tomography, not state tomography. Note that the TP constraint implicitly enforces the trace of the fitted matrix to be equal to the square-root of the matrix dimension. If a trace constraint is also specified that differs from this value the fit will likely fail. CVXPY Solvers: ------- Various solvers can be called in CVXPY using the `solver` keyword argument. Solvers included in CVXPY are: 'CVXOPT': SDP and SOCP (default solver) 'SCS' : SDP and SOCP 'ECOS' : SOCP only See the documentation on CVXPY for more information on solvers. """ # Check if CVXPY package is installed if cvxpy is None: raise Exception('CVXPY is not installed. Use `mle_fit` instead.') # Check CVXPY version version = cvxpy.__version__ if not (version[0] == '1' or version[:3] == '0.4'): raise Exception('Incompatible CVXPY version. Install 1.0 or 0.4') # SDP VARIABLES # Since CVXPY only works with real variables we must specify the real # and imaginary parts of rho seperately: rho = rho_r + 1j * rho_i dim = int(np.sqrt(basis_matrix.shape[1])) if version[:3] == '0.4': # Compatibility with legacy 0.4 rho_r = cvxpy.Variable(dim, dim) rho_i = cvxpy.Variable(dim, dim) else: rho_r = cvxpy.Variable((dim, dim)) rho_i = cvxpy.Variable((dim, dim)) # CONSTRAINTS # The constraint that rho is Hermitian (rho.H = rho) # transforms to the two constraints # 1. rho_r.T = rho_r.T (real part is symmetric) # 2. rho_i.T = -rho_i.T (imaginary part is anti-symmetric) cons = [rho_r == rho_r.T, rho_i == -rho_i.T] # Trace constraint: note this should not be used at the same # time as the trace preserving constraint. if trace is not None: cons.append(cvxpy.trace(rho_r) == trace) # Since we can only work with real matrices in CVXPY we can specify # a complex PSD constraint as # rho >> 0 iff [[rho_r, -rho_i], [rho_i, rho_r]] >> 0 if PSD is True: rho = cvxpy.bmat([[rho_r, -rho_i], [rho_i, rho_r]]) cons.append(rho >> 0) # Trace preserving constraint when fiting Choi-matrices for # quantum process tomography. Note that this adds an implicity # trace constraint of trace(rho) = sqrt(len(rho)) = dim # if a different trace constraint is specified above this will # cause the fitter to fail. if trace_preserving is True: sdim = int(np.sqrt(dim)) ptr = partial_trace_super(sdim, sdim) cons.append(ptr * cvxpy.vec(rho_r) == np.identity(sdim).ravel()) # Rescale input data and matrix by weights if they are provided if weights is not None: w = np.array(weights) w = w / np.sqrt(sum(w**2)) basis_matrix = w[:, None] * basis_matrix data = w * data # OBJECTIVE FUNCTION # The function we wish to minimize is || arg ||_2 where # arg = bm * vec(rho) - data # Since we are working with real matrices in CVXPY we expand this as # bm * vec(rho) = (bm_r + 1j * bm_i) * vec(rho_r + 1j * rho_i) # = bm_r * vec(rho_r) - bm_i * vec(rho_i) # + 1j * (bm_r * vec(rho_i) + bm_i * vec(rho_r)) # = bm_r * vec(rho_r) - bm_i * vec(rho_i) # where we drop the imaginary part since the expectation value is real bm_r = np.real(basis_matrix) bm_i = np.imag(basis_matrix) # CVXPY doesn't seem to handle sparse matrices very well so we convert # sparse matrices to Numpy arrays. if isinstance(basis_matrix, sps.spmatrix): bm_r = bm_r.todense() bm_i = bm_i.todense() arg = bm_r * cvxpy.vec(rho_r) - bm_i * cvxpy.vec(rho_i) - np.array(data) # SDP objective function obj = cvxpy.Minimize(cvxpy.norm(arg, p=2)) # Solve SDP prob = cvxpy.Problem(obj, cons) iters = 5000 max_iters = kwargs.get('max_iters', 20000) # Set the default solver to 'CVXOPT' if 'solver' not in kwargs: kwargs['solver'] = 'CVXOPT' problem_solved = False while not problem_solved: kwargs['max_iters'] = iters prob.solve(**kwargs) if prob.status in ["optimal_inaccurate", "optimal"]: problem_solved = True elif prob.status == "unbounded_inaccurate": if iters < max_iters: iters *= 2 else: raise RuntimeError( "CVX fit failed, probably not enough iterations for the " "solver") elif prob.status in ["infeasible", "unbounded"]: raise RuntimeError( "CVX fit failed, problem status {} which should not " "happen".format(prob.status)) else: raise RuntimeError("CVX fit failed, reason unknown") rho_fit = rho_r.value + 1j * rho_i.value return rho_fit
def proj(cvx_set, value): objective = cvx.Minimize(cvx.norm(cvx_set - value, 2)) cvx.Problem(objective).solve(solver=cvx.CVXOPT) return cvx_set.value
def dist(lh_set, rh_set): objective = cvx.Minimize(cvx.norm(lh_set - rh_set, 2)) return cvx.Problem(objective).solve(solver=cvx.CVXOPT)
def contains(cvx_set, value): p = cvx.Problem(cvx.Minimize(0), [cvx_set == value]) p.solve(solver=cvx.CVXOPT) return p.status == cvx.OPTIMAL
def direct_optimization(N, dt, path_state, Ux, path_idx, ds): print('check') print(path_state) s0 = path_state[0] s_dot0 = path_state[1] e0 = path_state[2] e_dot0 = path_state[3] dpsi0 = path_state[4] dpsi_dot0 = path_state[5] est_idx = Ux * N * dt / ds split_idx = est_idx / N K = np.rint(split_idx * np.arange(0, N)) K_dot = np.zeros(N) for idx in range(1, N): K_dot[idx] = K[idx] - K[idx - 1] delta = cp.Variable((N, 1)) s = cp.Variable((N, 1)) s_dot = cp.Variable((N, 1)) e = cp.Variable((N, 1)) e_dot = cp.Variable((N, 1)) dpsi = cp.Variable((N, 1)) dpsi_dot = cp.Variable((N, 1)) f0 = -s[-1] objective = cp.Minimize(f0) #subject to x_i+1 = x_i + hAx_i + hBu_i + hC constraints = [ s[0] == s0, e[0] == e0, dpsi[0] == dpsi0, dpsi_dot[0] == dpsi_dot0, e_dot[0] == e_dot0, s_dot[0] == Ux ] constraints += [delta[0] <= np.radians(25), delta[0] >= np.radians(-25)] for idx in range(1, N): constraints += [s[idx] == s[idx - 1] + s_dot[idx - 1] * dt] constraints += [s_dot[idx] == Ux] constraints += [e[idx] == e[idx - 1] + e_dot[idx - 1] * dt] constraints += [ e_dot[idx] == e_dot[idx - 1] + dt * (-(Ca_f + Ca_r) / (m * Ux) * e_dot[idx - 1] + (Ca_f + Ca_r) / m * dpsi[idx - 1] + (b * Ca_r - a * Ca_f) / (m * Ux) * dpsi_dot[idx - 1]) + dt * (Ca_f / m) * delta[idx - 1] + dt * (-K[idx - 1] * (Ux**2 - (b * Ca_r - a * Ca_f) / m)) ] constraints += [dpsi[idx] == dpsi[idx - 1] + dpsi_dot[idx - 1] * dt] constraints += [ dpsi_dot[idx] == dpsi_dot[idx - 1] + dt * ((b * Ca_r - a * Ca_f) / (Iz * Ux) * e_dot[idx - 1] + (a * Ca_f - b * Ca_r) / Iz * dpsi[idx - 1] - (a**2 * Ca_f + b**2 * Ca_r) / (Iz * Ux) * dpsi_dot[idx - 1]) + dt * a * Ca_f / Iz * delta[idx - 1] + dt * (-K[idx - 1] * (a**2 * Ca_f + b**2 * Ca_r) / Iz - K_dot[idx - 1] * Ux) ] constraints += [ delta[idx] <= np.radians(25), delta[idx] >= np.radians(-25) ] constraints += [ e[idx] <= TRACK_WIDTH / 2.0, e[idx] >= -TRACK_WIDTH / 2.0 ] prob = cp.Problem(objective, constraints) result = prob.solve() return -delta.value[0][0]
def contains(cvx_set, value): p = cp.Problem(cp.Minimize(0), [cvx_set == value]) return cp.get_status(p.solve()) == cp.SOLVED
T, N = R.shape np.random.seed(8888) BenchmarkIndex = R.dot(np.tile(1.0/N, N)) \ + st.norm.rvs(loc=0.0, scale=3.0, size=T) MovingWindow = 96 BackTesting = T - MovingWindow V_Tracking = np.zeros(BackTesting) Weight = cp.Variable(N) Error = cp.Variable(MovingWindow) TrackingError = cp.sum_squares(Error) Asset_srT = R / np.sqrt(T) Index_srT = BenchmarkIndex / np.sqrt(T) for Month in range(0, BackTesting): Asset = Asset_srT.values[Month:(Month + MovingWindow), :] Index = Index_srT.values[Month:(Month + MovingWindow)] Min_TrackingError = cp.Problem(cp.Minimize(TrackingError), [Index - Asset*Weight == Error, cp.sum_entries(Weight) == 1.0, Weight >= 0.0]) Min_TrackingError.solve() V_Tracking[Month] = R.values[Month + MovingWindow, :].dot(Weight.value) fig1 = plt.figure(num=1, facecolor='w') plt.plot(list(range(1, BackTesting + 1)), BenchmarkIndex[MovingWindow:], 'b-') plt.plot(list(range(1, BackTesting + 1)), V_Tracking, 'r--') plt.legend(['benchmark index', 'index fund'], loc='best', frameon=False) plt.xlabel('year') plt.ylabel('return (%)') plt.xticks(list(range(12, BackTesting + 1, 12)), pd.date_range(R.index[MovingWindow], periods=BackTesting//12, freq='AS').year) plt.show()
def dist(lh_set, rh_set): objective = cp.Minimize(cp.norm2(lh_set - rh_set)) return cp.Problem(objective).solve()
def test_gurobi_warm_start(self): """Make sure that warm starting Gurobi behaves as expected Note: This only checks output, not whether or not Gurobi is warm starting internally """ if cvx.GUROBI in cvx.installed_solvers(): import numpy as np A = cvx.Parameter((2, 2)) b = cvx.Parameter(2) h = cvx.Parameter(2) c = cvx.Parameter(2) A.value = np.array([[1, 0], [0, 0]]) b.value = np.array([1, 0]) h.value = np.array([2, 2]) c.value = np.array([1, 1]) objective = cvx.Maximize(c[0] * self.x[0] + c[1] * self.x[1]) constraints = [self.x[0] <= h[0], self.x[1] <= h[1], A * self.x == b] prob = cvx.Problem(objective, constraints) result = prob.solve(solver=cvx.GUROBI, warm_start=True) self.assertEqual(result, 3) self.assertItemsAlmostEqual(self.x.value, [1, 2]) # Change A and b from the original values A.value = np.array([[0, 0], [0, 1]]) # <----- Changed b.value = np.array([0, 1]) # <----- Changed h.value = np.array([2, 2]) c.value = np.array([1, 1]) # Without setting update_eq_constrs = False, # the results should change to the correct answer result = prob.solve(solver=cvx.GUROBI, warm_start=True) self.assertEqual(result, 3) self.assertItemsAlmostEqual(self.x.value, [2, 1]) # Change h from the original values A.value = np.array([[1, 0], [0, 0]]) b.value = np.array([1, 0]) h.value = np.array([1, 1]) # <----- Changed c.value = np.array([1, 1]) # Without setting update_ineq_constrs = False, # the results should change to the correct answer result = prob.solve(solver=cvx.GUROBI, warm_start=True) self.assertEqual(result, 2) self.assertItemsAlmostEqual(self.x.value, [1, 1]) # Change c from the original values A.value = np.array([[1, 0], [0, 0]]) b.value = np.array([1, 0]) h.value = np.array([2, 2]) c.value = np.array([2, 1]) # <----- Changed # Without setting update_objective = False, # the results should change to the correct answer result = prob.solve(solver=cvx.GUROBI, warm_start=True) self.assertEqual(result, 4) self.assertItemsAlmostEqual(self.x.value, [1, 2]) else: with self.assertRaises(Exception) as cm: prob = cvx.Problem(cvx.Minimize(cvx.norm(self.x, 1)), [self.x == 0]) prob.solve(solver=cvx.GUROBI, warm_start=True) self.assertEqual(str(cm.exception), "The solver %s is not installed." % cvx.GUROBI)
def proj(cvx_set, value): objective = cp.Minimize(cp.norm2(cvx_set - value)) cp.Problem(objective).solve() return cvx_set.value
for c in range(4): s += vars[r][c][v] constraints.append(s == 1) for p1 in range(2): for p2 in range(2): for r in range(2 * p1, 2 * p1 + 2): for c in range(2 * p2, 2 * p2 + 2): s = 0 for v in range(4): s += vars[r][c][v] constraints.append(s == 1) constraints.append(vars[0][0][1] == 1) constraints.append(vars[0][1][0] == 1) constraints.append(vars[1][1][2] == 1) constraints.append(vars[3][0][0] == 1) constraints.append(vars[1][2][1] == 1) constraints.append(vars[2][3][3] == 1) prob = cp.Problem(cp.Minimize(0), constraints) prob.solve(solver='ECOS_BB') solution = np.zeros((4, 4)) print(vars[0][0][1].value) for r in range(4): for c in range(4): for v in range(4): if vars[r][c][v].value > 0.9: solution[r][c] = v + 1 print(solution)
def tight_infer_with_partial_graph(y_val, s1_val, s0_val): partial_cbn = load_xml_to_cbn(partial_model) partial_cbn.build_joint_table() S = partial_cbn.v['S'] W = partial_cbn.v['W'] A = partial_cbn.v['A'] Y_hat = partial_cbn.v['Y'] if s1_val == s0_val: # there is no difference when active value = reference value return 0.00, 0.00 else: # define variable for P(r) PR = cvx.Variable(W.domain_size**(S.domain_size)) # define ell functions g = {} for v in {S, W, A, Y_hat}: v_index = v.index v_domain_size = v.domain_size parents_index = partial_cbn.index_graph.pred[v_index].keys() parents_domain_size = np.prod( [partial_cbn.v[i].domain_size for i in parents_index]) g[v_index] = list( product(range(v_domain_size), repeat=int(parents_domain_size))) # format # [(), (), ()] # r corresponds to the tuple # parents corresponds to the location of the tuple # assert the response function. (t function of Pearl, I function in our paper) def Indicator(obs, parents, response): # sort the parents by id par_key = parents.keys() # map the value to index par_index = 0 for k in par_key: par_index = par_index * partial_cbn.v[ k].domain_size + parents.dict[k] return 1 if obs.first_value() == g[ obs.first_key()][response][par_index] else 0 # build the object function weights = np.zeros(shape=[W.domain_size**(S.domain_size)]) for rw in range(W.domain_size**(S.domain_size)): # the first term for pse sum_identity = 0.0 for w1, w0, a1 in product(W.domains.get_all(), W.domains.get_all(), A.domains.get_all()): product_i = Indicator(Event({W: w1}), Event({S: s1_val}), rw) * \ partial_cbn.get_prob(Event({A: a1}), Event({W: w1})) * \ Indicator(Event({W: w0}), Event({S: s0_val}), rw) * \ partial_cbn.get_prob(Event({Y_hat: y_val}), Event({S: s1_val, W: w0, A: a1})) sum_identity += product_i weights[rw] += sum_identity # the second term for pse sum_identity = 0.0 for w0, a0 in product(W.domains.get_all(), A.domains.get_all()): product_i = Indicator(Event({W: w0}), Event({S: s0_val}), rw) * \ partial_cbn.get_prob(Event({A: a0}), Event({W: w0})) * \ partial_cbn.get_prob(Event({Y_hat: y_val}), Event({S: s0_val, W: w0, A: a0})) sum_identity += product_i weights[rw] -= sum_identity # build the objective function objective = weights.reshape(1, -1) @ PR ############################ ### to build the constraints ############################ ### the inferred model is consistent with the observational distribution A_mat = np.zeros((S.domain_size, W.domain_size, A.domain_size, Y_hat.domain_size, W.domain_size**(S.domain_size))) b_vex = np.zeros( (S.domain_size, W.domain_size, A.domain_size, Y_hat.domain_size)) # assert r -> v for s, w, a, y in product(S.domains.get_all(), W.domains.get_all(), A.domains.get_all(), Y_hat.domains.get_all()): # calculate the probability of observation b_vex[s.index, w.index, a.index, y.index] = partial_cbn.get_prob( Event({ S: s, Y_hat: y, W: w, A: a })) # sum of P(r) for rw in range(W.domain_size**(S.domain_size)): product_i = partial_cbn.get_prob(Event({S: s}), Event({})) * partial_cbn.get_prob(Event({Y_hat: y}), Event({S: s, W: w, A: a})) * \ Indicator(Event({W: w}), Event({S: s}), rw) * partial_cbn.get_prob(Event({A: a}), Event({W: w})) A_mat[s.index, w.index, a.index, y.index, rw] = product_i # flatten the matrix and vector A_mat = A_mat.reshape( S.domain_size * W.domain_size * A.domain_size * Y_hat.domain_size, W.domain_size**(S.domain_size)) b_vex = b_vex.reshape(-1, 1) ### the probability <= 1 C_mat = np.identity(W.domain_size**(S.domain_size)) d_vec = np.ones(W.domain_size**(S.domain_size)) ### the probability is positive E_mat = np.identity(W.domain_size**(S.domain_size)) f_vec = np.zeros(W.domain_size**(S.domain_size)) constraints = [ A_mat @ PR == b_vex, # C_mat @ PR == d_vec, C_mat @ PR <= d_vec, E_mat @ PR >= f_vec ] # minimize the causal effect problem = cvx.Problem(cvx.Minimize(objective), constraints) problem.solve() # print('tight lower effect: %f' % (problem.value)) lower = problem.value # maximize the causal effect problem = cvx.Problem(cvx.Maximize(objective), constraints) problem.solve() # print('tight upper effect: %f' % (problem.value)) upper = problem.value return upper, lower
def test_readme_examples(self): import numpy numpy.random.seed(1) # cvx.Problem data. m = 30 n = 20 A = numpy.random.randn(m, n) b = numpy.random.randn(m) # Construct the problem. x = cvx.Variable(n) objective = cvx.Minimize(cvx.sum_squares(A @ x - b)) constraints = [0 <= x, x <= 1] p = cvx.Problem(objective, constraints) # The optimal objective is returned by p.solve(). p.solve() # The optimal value for x is stored in x.value. print(x.value) # The optimal Lagrange multiplier for a constraint # is stored in constraint.dual_value. print(constraints[0].dual_value) #################################################### # Scalar variable. a = cvx.Variable() # Column vector variable of length 5. x = cvx.Variable(5) # Matrix variable with 4 rows and 7 columns. A = cvx.Variable((4, 7)) #################################################### # Positive scalar parameter. m = cvx.Parameter(nonneg=True) # Column vector parameter with unknown sign (by default). cvx.Parameter(5) # Matrix parameter with negative entries. G = cvx.Parameter((4, 7), nonpos=True) # Assigns a constant value to G. G.value = -numpy.ones((4, 7)) # Raises an error for assigning a value with invalid sign. with self.assertRaises(Exception) as cm: G.value = numpy.ones((4, 7)) self.assertEqual(str(cm.exception), "Parameter value must be nonpositive.") #################################################### a = cvx.Variable() x = cvx.Variable(5) # expr is an Expression object after each assignment. expr = 2*x expr = expr - a expr = cvx.sum(expr) + cvx.norm(x, 2) #################################################### import numpy as np # cvx.Problem data. n = 10 m = 5 A = np.random.randn(n, m) b = np.random.randn(n) gamma = cvx.Parameter(nonneg=True) # Construct the problem. x = cvx.Variable(m) objective = cvx.Minimize(cvx.sum_squares(A @ x - b) + gamma*cvx.norm(x, 1)) p = cvx.Problem(objective) # Assign a value to gamma and find the optimal x. def get_x(gamma_value): gamma.value = gamma_value p.solve() return x.value gammas = np.logspace(-1, 2, num=2) # Serial computation. [get_x(value) for value in gammas] #################################################### n = 10 mu = np.random.randn(1, n) sigma = np.random.randn(n, n) sigma = sigma.T.dot(sigma) gamma = cvx.Parameter(nonneg=True) gamma.value = 1 x = cvx.Variable(n) # Constants: # mu is the vector of expected returns. # sigma is the covariance matrix. # gamma is a cvx.Parameter that trades off risk and return. # cvx.Variables: # x is a vector of stock holdings as fractions of total assets. expected_return = mu @ x risk = cvx.quad_form(x, sigma) objective = cvx.Maximize(expected_return - gamma*risk) p = cvx.Problem(objective, [cvx.sum(x) == 1]) p.solve() # The optimal expected return. print(expected_return.value) # The optimal risk. print(risk.value) ########################################### N = 50 M = 40 n = 10 data = [] for i in range(N): data += [(1, np.random.normal(loc=1.0, scale=2.0, size=n))] for i in range(M): data += [(-1, np.random.normal(loc=-1.0, scale=2.0, size=n))] # Construct problem. gamma = cvx.Parameter(nonneg=True) gamma.value = 0.1 # 'a' is a variable constrained to have at most 6 non-zero entries. a = cvx.Variable(n) # mi.SparseVar(n, nonzeros=6) b = cvx.Variable() slack = [cvx.pos(1 - label*(sample.T @ a - b)) for (label, sample) in data] objective = cvx.Minimize(cvx.norm(a, 2) + gamma*sum(slack)) p = cvx.Problem(objective) # Extensions can attach new solve methods to the CVXPY cvx.Problem class. # p.solve(method="admm") p.solve() # Count misclassifications. errors = 0 for label, sample in data: if label*(sample.T @ a - b).value < 0: errors += 1 print("%s misclassifications" % errors) print(a.value) print(b.value)
def test_basic_init(basic_init_fixture, solver_name, i, H, g, x_ineq): """ A basic test case for wrappers. Notice that the input fixture `basic_init_fixture` is known to have two constraints, one velocity and one acceleration. Hence, in this test, I directly formulate an optimization with cvxpy to test the result. Parameters ---------- basic_init_fixture: a fixture with only two constraints, one velocity and one acceleration constraint. """ constraints, path, path_discretization, vlim, alim = basic_init_fixture if solver_name == "cvxpy": from toppra.solverwrapper.cvxpy_solverwrapper import cvxpyWrapper solver = cvxpyWrapper(constraints, path, path_discretization) elif solver_name == 'qpOASES': from toppra.solverwrapper.qpoases_solverwrapper import qpOASESSolverWrapper solver = qpOASESSolverWrapper(constraints, path, path_discretization) elif solver_name == 'hotqpOASES': from toppra.solverwrapper.hot_qpoases_solverwrapper import hotqpOASESSolverWrapper solver = hotqpOASESSolverWrapper(constraints, path, path_discretization) elif solver_name == 'ecos' and H is None: from toppra.solverwrapper.ecos_solverwrapper import ecosWrapper solver = ecosWrapper(constraints, path, path_discretization) elif solver_name == 'seidel' and H is None: from toppra.solverwrapper.cy_seidel_solverwrapper import seidelWrapper solver = seidelWrapper(constraints, path, path_discretization) else: return True # Skip all other tests xmin, xmax = x_ineq xnext_min = 0 xnext_max = 1 # Results from solverwrapper to test solver.setup_solver() result_ = solver.solve_stagewise_optim(i - 2, H, g, xmin, xmax, xnext_min, xnext_max) result_ = solver.solve_stagewise_optim(i - 1, H, g, xmin, xmax, xnext_min, xnext_max) result = solver.solve_stagewise_optim(i, H, g, xmin, xmax, xnext_min, xnext_max) solver.close_solver() # Results from cvxpy, used as the actual, desired values ux = cvxpy.Variable(2) u = ux[0] x = ux[1] _, _, _, _, _, _, xbound = solver.params[0] # vel constraint a, b, c, F, h, ubound, _ = solver.params[1] # accel constraint a2, b2, c2, F2, h2, _, _ = solver.params[2] # random constraint Di = path_discretization[i + 1] - path_discretization[i] v = a[i] * u + b[i] * x + c[i] v2 = a2[i] * u + b2[i] * x + c2[i] cvxpy_constraints = [ x <= xbound[i, 1], x >= xbound[i, 0], F * v <= h, F2[i] * v2 <= h2[i], x + u * 2 * Di <= xnext_max, x + u * 2 * Di >= xnext_min, ] if not np.isnan(xmin): cvxpy_constraints.append(x <= xmax) cvxpy_constraints.append(x >= xmin) if H is not None: objective = cvxpy.Minimize(0.5 * cvxpy.quad_form(ux, H) + g * ux) else: objective = cvxpy.Minimize(g * ux) problem = cvxpy.Problem(objective, cvxpy_constraints) problem.solve(verbose=True) # test with the same solver as cvxpywrapper if problem.status == "optimal": actual = np.array(ux.value).flatten() result = np.array(result).flatten() npt.assert_allclose(result, actual, atol=5e-3, rtol=1e-5) # Very bad accuracy? why? else: assert np.all(np.isnan(result))
delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) writer.writerow( [epoch, epoch_w, loss_l_cum, loss_u_cum, loss_ent_cum]) # update unlabel estimates with cumulative loss: target_var_list = [{'params': estimated_y, 'lr': ETA_Y}] optimizer_y = optim.SGD(target_var_list, momentum=0, weight_decay=0) optimizer_y.step() optimizer_y.zero_grad() estimated_y.grad.data.zero_() # Project onto probability polytope est_y_num = estimated_y.data.cpu().numpy() U = cvxpy.Variable((est_y_num.shape[0], est_y_num.shape[1])) objective = cvxpy.Minimize(cvxpy.sum(cvxpy.square(U - est_y_num))) constraints = [U >= EPSILON, cvxpy.sum(U, axis=1) == 1] prob = cvxpy.Problem(objective, constraints) prob.solve() estimated_y.data = torch.from_numpy(np.float32(U.value)).cuda() # save estimated labels and labeled indexes on unlabeled data: state = { "lab_inds": lab_inds, "estimated_y": estimated_y.data.cpu().numpy(), "epoch": epoch, "y_acc": y_acc, } np.save(Y_U_FOLDER + file_name + '.npy', state)
import matplotlib.pyplot as plt import cvxpy as cp import numpy as np r = 20 np.random.seed(1) A = np.hstack((np.random.randn(r, 1), np.ones([r, 1]))) c = np.array([A[:, 0]]).T b = (10.0 * np.random.randn() * c) + \ + (0.5 * np.random.randn(r, 1)) b = b.T.tolist() x = cp.Variable(2) obj = cp.Minimize(sum(cp.square(A @ x - b))) P = cp.Problem(obj) P.solve(verbose=True) print(x.value) s = np.arange(c.min() - 0.3, c.max() + 0.3, 0.1) t = np.asscalar(x.value[0]) * s + np.asscalar(x.value[1]) plt.plot(s, t) plt.plot(c.T, b, 'ro') plt.show()
n = A.shape[1] q = B.shape[1] summand = 0 for i in range(q): for j in range(n): summand += v[i, j] * e(q, i) * e(n, j).T return A + B * summand def gamma_func(alpha, A, B, C, P, R): """Defined as Gamma(alpha) = A(alpha)'*P + P*A(alpha) - (C'*R + R'*C)""" aff = affine_func(alpha, A, B) return aff.T * P + P * aff - (C.T * R + R.T * C) # Compose variables to optimize over P = cvx.Semidef(4, 'P') R = cvx.Variable(1, 4, 'R') # Compose the LMI block matrix bl1, bl2 = [gamma_func(alpha, A, B, C, P, R) for alpha in V_H] Z = np.zeros((4, 4)) lmi = cvx.vstack(cvx.hstack(bl1, Z), cvx.hstack(Z, bl2)) # Form the input to cvxpy obj = cvx.Minimize(0) consts = [lmi <= -1e-13, P >= 1e-13] prob = cvx.Problem(obj, consts) # Solve the problem prob.solve(verbose=True)
def __solve__(self): """ Solve the optimization problem associated with each point """ # Cones on the plus and minus side sup_plus_vars = cvx.Variable(shape=(len(self.points), self.dim)) inf_plus_vars = cvx.Variable(shape=(len(self.points), self.dim)) sup_minus_vars = cvx.Variable(shape=(len(self.points), self.dim)) inf_minus_vars = cvx.Variable(shape=(len(self.points), self.dim)) constraints = [ sup_plus_vars >= 0, inf_plus_vars >= 0, sup_minus_vars >= 0, sup_plus_vars >= 0 ] # inf/sup relational constraints constraints += [sup_plus_vars >= inf_plus_vars] constraints += [sup_minus_vars <= inf_minus_vars] # Cone constraints for (i, (pone, vone)) in enumerate(self.points.items()): # point i has to be able to project into point j for (j, (ptwo, vtwo)) in enumerate(self.points.items()): if i == j: continue lhs_sup = 0.0 lhs_inf = 0.0 for (di, (poned, ptwod)) in enumerate(zip(pone, ptwo)): run = ptwod - poned supvar = 0.0 infvar = 0.0 if ptwod > poned: supvar = sup_plus_vars[i, di] infvar = inf_plus_vars[i, di] elif ptwod < poned: supvar = sup_minus_vars[i, di] infvar = inf_minus_vars[i, di] lhs_sup += run * supvar lhs_inf += run * infvar constraints += [lhs_sup >= vtwo - vone, lhs_inf <= vtwo - vone] # Optimization : minimize cone width objective = cvx.Minimize( cvx.norm(sup_plus_vars - inf_plus_vars) + cvx.norm(inf_minus_vars - sup_minus_vars)) p = cvx.Problem(objective, constraints) # Run it! p.solve(verbose=False, solver=cvx.CVXOPT, kktsolver='robust', refinement=5) # Post-mortem... if p.status != 'optimal' and p.status != 'optimal_inaccurate': raise ScoreCreationError( "Could not create scoring function: Optimization Failed") return None # Pull out the coefficients from the variables plus_vars = [[(sup_plus_vars[i, j].value, inf_plus_vars[i, j].value) for j in range(self.dim)] for i in range(len(self.points))] minus_vars = [[(sup_minus_vars[i, j].value, inf_minus_vars[i, j].value) for j in range(self.dim)] for i in range(len(self.points))] return plus_vars, minus_vars
def __add_constraints(self, structure, exact=False): """ Add constraints from ``structure`` to problem. Constraints built with slack variables if :attr:`SolverCVXPY.use_slack` is ``True`` at call time. When slacks are used, each slack variable is registered in the dictionary :attr:`SolverCVXPY.slack_vars` under the corresponding constraint's ID as a key for later retrieval of optimal values. A nonnegativity constraint on each slack variable is added to :attr:`SolverCVXPY.problem.constraints`. When ``structure`` includes percentile-type dose constraints, and a convex restriction (i.e., a hinge loss approximation) is used, the reciprocal of the slope of the hinge loss is a variable; each such slope variable is registered in the dictionary :attr:`SolverCVXPY.dvh_vars` under the corresponding constraint's ID as a key for later retrival of optimal values. A nonnegativity constraint on each slope variable is added to :attr:`SolverCVXPY.problem.constraints`. Arguments: structure (:class:`~conrad.medicine.Structure`): Structure from which to read dose matrix and dose constraints. exact (:obj:`bool`, optional): If ``True`` *and* :attr:`SolverCVXPY.use_2pass` is ``True`` *and* ``structure`` has a calculated dose vector, treat percentile-type dose constraints as exact constraints. Otherwise, use convex restrictions. Returns: None Raises: ValueError: If ``exact`` is ``True``, but other conditions for building exact constraints not met. """ # extract dvh constraint from structure, # make slack variable (if self.use_slack), add # slack to self.objective and slack >= 0 to constraints if exact: if not self.use_2pass or structure.y is None: raise ValueError('exact constraints requested, but ' 'cannot be built.\nrequirements:\n' '-input flag "use_2pass" must be ' '"True" (provided: {})\n-structure' ' dose must be calculated\n' '(structure dose: {})\n' ''.format(self.use_2pass, structure.y)) for cid in structure.constraints: c = structure.constraints[cid] cslack = not exact and self.use_slack and c.priority > 0 if cslack: gamma = self.gamma_prioritized(c.priority) slack = cvxpy.Variable(1) self.slack_vars[cid] = slack self.problem.objective += cvxpy.Minimize(gamma * slack) self.problem.constraints += [slack >= 0] if not c.upper: self.problem.constraints += [slack <= c.dose.value] else: slack = 0. self.slack_vars[cid] = None if isinstance(c, MeanConstraint): if c.upper: self.problem.constraints += [ structure.A_mean * self.__x - slack <= c.dose.value ] else: self.problem.constraints += [ structure.A_mean * self.__x + slack >= c.dose.value ] elif isinstance(c, MinConstraint): self.problem.constraints += \ [structure.A * self.__x >= c.dose.value] elif isinstance(c, MaxConstraint): self.problem.constraints += \ [structure.A * self.__x <= c.dose.value] elif isinstance(c, PercentileConstraint): if exact: # build exact constraint dvh_constr = self.__percentile_constraint_exact( structure.A, self.__x, structure.y, c, had_slack=self.use_slack) # add it to problem self.problem.constraints += [dvh_constr] else: # beta = 1 / slope for DVH constraint approximation beta = cvxpy.Variable(1) self.dvh_vars[cid] = beta self.problem.constraints += [beta >= 0] # build convex restriction to constraint dvh_constr = self.__percentile_constraint_restricted( structure.A, self.__x, c, beta, slack) # add it to problem self.problem.constraints += [dvh_constr] self.__constraint_indices[cid] = None self.__constraint_indices[cid] = len( self.problem.constraints) - 1
def test_basic_gp(self): x, y, z = cvxpy.Variable((3, ), pos=True) constraints = [2 * x * y + 2 * x * z + 2 * y * z <= 1.0, x >= 2 * y] problem = cvxpy.Problem(cvxpy.Minimize(1 / (x * y * z)), constraints) problem.solve(SOLVER, gp=True) self.assertAlmostEqual(15.59, problem.value, places=2)