CVX基本语法
声明问题类型或控制屏幕输出
cpp
cvx_begin // 开始优化
cvx_begin quiet // 不输出log
cvx_begin sdp // 半定规划
cvx_begin gp // 几何规划
定义变量
cpp
variable x(20) // 20维的决策变量
variable y(20, 30) complex // 20X30的复数矩阵
variable X(20, 20) symmetric // 20X20的对称方阵
variables x(20) Y(10, 20) // 同时定义多个变量
目标函数(必须是凸函数)
- 线性:cTx,trace(A∗X)
- 二次:xTQx
- 二阶范数:norm(Ax−b)
约束条件
- 线性:bTx≤a,ATx≤b
- 二次:xTQx≤a
- SOCP:x21+x22−x23≤0,x3≥0
- SDP:X≥0,X是半正定矩阵,特征值都大于等于0
定义集合
- 非负集:
x == nonnegative(n)
,等价于x>=0
,n维向量,两个等号表示属于 - simplex:
x == simplex(n)
,等价于∑ni=1xi=1,x>=0 - 半定矩阵:
X == semidefine(n)
,等价于X>=0,symmetric
调整精度
cvx_precision default/low/medium/high/best
选择求解器
cvx_solver Mosek
最小二乘问题
cpp
m = 4;
n = 3;
A = randn(m, n);
b = randn(m, 1);
cvx_begin quiet
variable x(n) // n维变量
minimize( norm(A*x-b) ) // 目标函数为二阶范数
cvx_end
有约束的最小二乘问题
cpp
m = 4;
n = 3;
A = randn(m, n);
b = randn(m, 1);
bnds = rand(n, 2);
l = min(bnds, [], 2); // 每行的最小值组成的列
u = max(bnds, [], 2); // 每行的最大值组成的列
cvx_begin quiet
variable x(n)
minimize( norm(A*x-b) )
subject to
l <= x <= u;
cvx_end
其他范数
无穷范数
cpp
cvx_begin quiet
variable x(n)
minimize( norm(A*x-b, Inf) )
cvx_end
1阶范数
cpp
cvx_begin quiet
variable x(n)
minimize( norm(A*x-b, 1) )
cvx_end
凸函数乘以一个整数或者和凸函数相加,结果还是凸函数
‖Ax−b‖2+γ‖x‖1cpp
m = 4;
n = 3;
A = randn(m, n);
b = randn(m, 1);
gamma = logspace(-2, 2, 10);
l2norm = zeros(size(gamma));
l1norm = zeros(size(gamma));
for k = 1:length(gamma) // 不同gamma值对目标的影响
cvx_begin
variable x(n)
minimize( norm(A*x-b) + gamma(k)*norm(x, 1) )
cvx_end
l1norm(k) = norm(x, 1);
l2norm(k) = norm(A*x-b);
end
DCPDisciplinedConvexProgramming
不能将√x2+1写成sqrt(x^2+1)
,因为开根号是一种非凸运算,但可以将其转化为
所以编写为norm([x 1])
,这样就可以了
不能直接写
1/x
,而是需要调用inv_pos(x)
,其默认定义域为R++,所以是凸函数,单调递减