用于MATLAB 的cvx套件可以解决下面的(看似无辜的)优化问题,但对于我正在使用的大型完整矩阵来说,它相当慢.我希望这是因为使用cvx是过度的,并且问题实际上有一个分析解决方案,或者巧妙地使用一些内置的MATLAB函数可以更快地完成这项工作.
背景:它是公知的,这两个x1=A\b
和x2=pinv(A)*b
解决最小二乘问题:
minimize norm(A*x-b)
Run Code Online (Sandbox Code Playgroud)
区别于此norm(x2)<=norm(x1)
.事实上,这x2
是解决问题的最小规范解决方案,因此norm(x2)<=norm(x)
对于所有可能的解决方案x
.
定义D=norm(A*x2-b)
(等效D=norm(A*x1-b)
),然后x2
解决问题
minimize norm(x)
subject to
norm(A*x-b) == D
Run Code Online (Sandbox Code Playgroud)
问题:我想找到解决方案:
minimize norm(x)
subject to
norm(A*x-b) <= D+threshold
Run Code Online (Sandbox Code Playgroud)
换句话说,我不需要norm(A*x-b)
尽可能小,只要在一定的容忍范围内.我想最小范数解x
的是得到A*x
内D+threshold
的b
.
我无法在网上或手工找到问题的解析解(比如在经典的最小二乘问题中使用伪逆).我一直在搜索诸如"具有非线性约束的最小二乘"和"具有阈值的最小二乘"之类的东西.
任何见解都会非常感激,但我想我的真正问题是:在MATLAB中解决这个"阈值化"最小二乘问题的最快方法是 什么?
我一直在尝试将一些代码从Matlab传递给Python.我在Matlab上有相同的凸优化问题但是我在将它传递给CVXPY或CVXOPT时遇到了问题.
n = 1000;
i = 20;
y = rand(n,1);
A = rand(n,i);
cvx_begin
variable x(n);
variable lambda(i);
minimize(sum_square(x-y));
subject to
x == A*lambda;
lambda >= zeros(i,1);
lambda'*ones(i,1) == 1;
cvx_end
Run Code Online (Sandbox Code Playgroud)
这是我尝试使用Python和CVXPY.
import numpy as np
from cvxpy import *
# Problem data.
n = 100
i = 20
np.random.seed(1)
y = np.random.randn(n)
A = np.random.randn(n, i)
# Construct the problem.
x = Variable(n)
lmbd = Variable(i)
objective = Minimize(sum_squares(x - y))
constraints = [x == …
Run Code Online (Sandbox Code Playgroud) 我正在寻找一种在R中进行非负分位数和Huber回归的快速方法(即约束所有系数都> 0).我尝试使用CVXR
包进行分位数和Huber回归以及quantreg
用于分位数回归的包,但是当我使用非负性约束时,CVXR
它非常慢并且quantreg
看起来很麻烦.有人知道R中的一个好的和快速的解决方案,例如使用Rcplex
包或R gurobi API,从而使用更快的CPLEX或gurobi优化器?
请注意,我需要运行一个大小低于80 000次的问题大小,我只需要y
在每次迭代中更新向量,但仍然使用相同的预测矩阵X
.从这个意义上讲,我认为CVXR
现在我必须obj <- sum(quant_loss(y - X %*% beta, tau=0.01)); prob <- Problem(Minimize(obj), constraints = list(beta >= 0))
在每次迭代中做到这一点是低效的,当问题实际上保持不变并且我想要更新的时候y
.有没有想过要做得更好/更快?
最小的例子:
## Generate problem data
n <- 7 # n predictor vars
m <- 518 # n cases
set.seed(1289)
beta_true <- 5 * matrix(stats::rnorm(n), nrow = n)+20
X <- matrix(stats::rnorm(m * n), nrow = m, ncol = …
Run Code Online (Sandbox Code Playgroud) 我最初的问题是如何在集群上运行 CVX 工具箱(具有学术许可证)。我无法找到直接的方法来做到这一点,所以我决定以不同的方式解决这个问题。
CVX 许可证依赖于硬件,每个学术许可证与 4 个硬件绑定。我想将其中一个节点(可能是两个)添加到许可证列表中。为此,我需要始终在相同的硬件或节点上运行 CVX(我知道这可能不是一种有效的方法)。有什么办法可以做到吗?
由于某种原因,cvx不能为我开箱即用.
我使用windows x64,cvx x64和Matlab x64 R2012a
但是,当我运行简单的例子(\ cvx\examples\quickstart.m)时,它给我一个错误:
>> quickstart
has_quadprog = exist( 'quadprog' );
has_quadprog = has_quadprog == 2 | has_quadprog == 3;
has_linprog = exist( 'linprog' );
has_linprog = has_linprog == 2 | has_linprog == 3;
rnstate = randn( 'state' ); randn( 'state', 1 );
s_quiet = cvx_quiet(true);
s_pause = cvx_pause(false);
cvx_clear; echo on
prob = evalin( 'caller', 'cvx_problem', '[]' );
if isa( prob, 'cvxprob' ),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SECTION 2.1: LEAST SQUARES %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input …
Run Code Online (Sandbox Code Playgroud) 在 Matlab 的 CVX 包中,我想最小化像 $|Ax-b|_2^2$ 这样的函数。意思是 2 范数的平方。我如何在 CVX 中编码?我都试过:
minimize (norm(A*x-b,2)^2);
Run Code Online (Sandbox Code Playgroud)
和
minimize (norm(A*x-b,2)*norm(A*x-b,2));
Run Code Online (Sandbox Code Playgroud)
但两者都抛出了错误。是否有我应该使用的内置函数?
(注意,实际上我试图最小化该范数的平方加上另一个范数的总和,这minimize (norm(A*x-b,2)^2 + norm(x,1));
就是为什么我试图指定范数的平方,而不仅仅是满足于找到未平方范数的最小值。)
我正在尝试使用 R 包 CVXR 解决具有线性约束的二次优化问题。尽管默认求解器能够解决优化问题,但 Mosek 求解器却不能。我希望使用 Mosek 的原因是因为我需要解决具有 250 多个约束的更大问题,而默认求解器给出的解决方案不准确,因此我希望使用 Mosek 解决更大的问题。这是一个简单的例子,Mosek 不工作:
suppressMessages(suppressWarnings(library(CVXR)))
Run Code Online (Sandbox Code Playgroud)
set.seed(10)
n <- 10
SAMPLES <- 100
mu <- matrix(abs(rnorm(n)), nrow = n)
Sigma <- matrix(rnorm(n^2), nrow = n, ncol = n)
Sigma <- t(Sigma) %*% Sigma
Run Code Online (Sandbox Code Playgroud)
w <- Variable(n)
ret <- t(mu) %*% w
risk <- quad_form(w, Sigma)
constraints <- list(w >= 0, sum(w) == 1,ret==mean(mu))
Run Code Online (Sandbox Code Playgroud)
prob <- Problem(Minimize(risk), constraints)
result <- solve(prob,solver='MOSEK')
Run Code Online (Sandbox Code Playgroud)
它给出了以下错误。
Error in py_call_impl(callable, dots$args, dots$keywords) :
TypeError: …
Run Code Online (Sandbox Code Playgroud) 我已经安装了 3 次 Mosek。它在 python 中工作,但 CVXR(r 包)函数 installed_solvers() 无法找到 MOSEK。
我正在研究 MACos Mojave。我通过 conda 命令安装了 Mosek,获得了学术许可证,在主目录中创建了一个名为 mosek 的文件夹,并将许可证文件放入其中。然后我在 jupyter 实验室中测试了以下脚本https://docs.mosek.com/8.1/pythonapi/design.html#hello-world-in-mosek并得到结果 Solution x = 2.0 ,所以 Mosek 正在工作。然后我安装了reticulate,使用默认目录,替换为 use_python("/Users/apple/anaconda3") 和 use_python("/Users/apple/anaconda3/lib/python3.6") 中的任何一个,函数installed_solvers () 找到了mosek。我的会话信息如下
https://cvxr.rbind.io/cvxr_examples/cvxr_using-other-solvers/中的文档并没有真正说明如何解决问题。有人找到了解决方案吗?谢谢
我想将以下 SDP(它只是验证约束的可行性)从 CVX (MATLAB) 转换为 CVXPY (Python):
Ah = [1.0058, -0.0058; 1, 0];
Bh = [-1; 0];
Ch = [1.0058, -0.0058; -0.9829, 0.0056];
Dh = [-1; 1];
M = [0, 1;1, 0];
ni = size(M,1)/2;
n = size(Ah,1);
rho = 0.5;
cvx_begin sdp quiet
variable P(n,n) semidefinite
variable lambda(ni) nonnegative
Mblk = M*kron(diag(lambda),eye(2));
lambda(ni) == 1 % break homogeneity (many ways to do this...)
[Ah Bh]'*P*[Ah Bh] - rho^2*blkdiag(P,0) + [Ch Dh]'*Mblk*[Ch Dh] <= 0
cvx_end
switch cvx_status
case 'Solved' …
Run Code Online (Sandbox Code Playgroud)