MatLab凸优化工具箱CVX-A quick start

   安装了CVX,就可以通过在Matlab脚本或函数中输入CVX代码或直接从命令提示符开始使用它。 为了从Matlab代码去别出CVX代码,它以cvx_begin开始,以cvx_end语句结尾。 CVX代码可以包含一般的Matlab语句和用于声明原始、对偶优化变量以及特定约束、目标函数的CVX命令。

    在CVX规范中,优化变量没有数值,它们是特殊的Matlab对象。这使Matlab能够区分普通命令和CVX目标函数和约束。当CVX读取问题规范时,它会构建优化问题的内部表示。如果遇到违反DCP规则的情况(例如使用无效的构图规则或无效约束),则会产生错误信息。当Matlab执行到cvx_end命令时,就完成了CVX规范到Matlab正常形式的转换,并调用底层核心解析器来解决它。

    如果优化问题成功解决,则将CVX规范中声明的优化变量从对象转换为可用于Matlab计算的普通数值。 另外,CVX还给一些其他相关的Matlab变量赋值。 例如,可以给出了问题的状态(即是否找到了最佳解决方案,或问题是否被确定为不可行或无界)。 或者可以给出问题的最优值。 对偶变量也可以赋值。

    介绍一些简单的例子后,这个流程会变得更加清晰。 我们邀请读者在Matlab中运行CVX发行版examples子目录中的quickstart脚本。 例如,如果你在Windows上的E:\Matlab\Install\bin\e.g\cvx中安装了CVX发行版,那么你应该键入:

cd E:\Matlab\Install\bin\e.g\cvx\examples
quickstart

 在Matlab命令提示符下,该脚本将自动打印其代码的关键摘要,并定期暂停,以便您可以检查其输出。 (按“Enter”或“Return”可以恢复进度。)

Least squares 最小二乘

    首先我们考虑最基本的凸优化问题-最小二乘(也叫线性回归)。在最小二乘问题中,我们寻找使得最小。其中是满秩的(例如m>=n,并且Rank(A)=n)。为Matlab中的一个小测试问题创建数据:

m = 16; n = 8;
A = randn(m,n);
b = randn(m,1);

最小二乘的解用反斜杠算子 \ 很容易计算出来:

x_ls = A \ b;

使用CVX,同样的问题解决如下:

cvx_begin
    variable x(n)
    minimize( norm(A*x-b) )
cvx_end

(缩进纯粹是为了容易阅读)下面我们逐行查看这段CVX代码:

  • cvx_begin为新的CVX规范创建一个占位符,并准备让Matlab接受变量声明,约束,目标函数等等。
  • variable x(n)声明x是n维的优化变量。CVX要求所有问题变量在用于目标函数或约束之前都要声明。
  • minimize(norm(A*x-b))指定要最小化的目标函数。
  • cvx_end表示CVX规范的结束,并且问题得到解决。

显然没有理由使用CVX来解决简单的最小二乘问题。 但是这个例子在CVX中像“Hello world!”程序一样; 即最简单的代码确实有用。

    当Matlab运行到cvx_end命令时,最小二乘问题得到解决,并且Matlab变量x被最小二乘问题的解所替代(overwritten),即:。现在x是一个长度为n的数值向量,与传统方法中得到的数值向量相同。另外还创建了几个Matlab变量:

  • cvx_optval是目标函数的值。
  • cvx_status是描述计算状态的字符串(可以参见Interpreting the results)。

这些所有的量x,cvx_optval,cvx_status等等,现在都可以在其他Matlab语句像其他数字或字符串值一样自由使用。

Bound-constrained least squares约束最小二乘

假设我们希望上述最小二乘问题增加一些简单的上下限,即:


其中 lu 是所给的和x相同维数的数据向量。向量不等式是各分量的比较,即对所有i来说uivi.

我们不能再使用简单的反斜杠符号来解决这个问题,但它可以被转换成二次规划(QP)来求解。

下面我们为l和u赋值:

bnds = randn(n,2);
l = min( bnds, [], 2 );
u = max( bnds, [], 2 );

如有你有Matlab Optimization Toolbox,你可以使用quadprog来解决问题:

x_qp = quadprog( 2*A'*A, -2*A'*b, [], [], [], [], l, u );

这实际上最小化了范数的平方,这与最小化范数本身相同。 相比之下,可用下面的CVX规范实现:

cvx_begin
    variable x(n)
    minimize( norm(A*x-b) )
    subject to
        l <= x <= u
cvx_end

CVX规范中添加了两行新CVX代码:

  • subject to 语句不做任何事—CVX提供此声明只是为了使得规范更具可读性。与缩进一样,它是可选的。
  • l<=x<=u表示2n个不等式约束。

如前所示,当执行到cvx_end命令时,问题就解决了,数值解赋值给变量x。 顺便说一下,CVX不会通过把目标平方化来将此问题转化为QP; 相反,它会将其转化为SOCP。 结果是一样的,转换是自动完成的。

在这个例子中,和前面的例子一样,CVX规范比对应的Matlab语句更长。另一方面,很容易读懂CVX规范并且把它和原问题联系起来。

Other norms and functions


现在我们考虑一些最小二乘问题的替代方案。 范数极小化问题可以被重新表述为LPs,并利用Matlab优化工具箱中的线性规划求解程序(如linprog)来求解,可以参见: Convex Optimization中6.1节的例子。

然而,由于这些范数是CVX基本库函数中的一部分,所以CVX可以直接解决这些问题。

例如。为了找到最小化切比雪夫范数 中x的值,我们可以利用Matlab优化工具箱中的linprog命令:

f    = [ zeros(n,1); 1          ];
Ane  = [ +A,         -ones(m,1)  ; ...
         -A,         -ones(m,1) ];
bne  = [ +b;         -b         ];
xt   = linprog(f,Ane,bne);
x_cheb = xt(1:n,:);

利用CVX,同样的问题可用下述代码完成:

cvx_begin
    variable x(n)
    minimize( norm(A*x-b,Inf) )
cvx_end

基于linprog的代码和CVX代码都能解决上述切比雪夫范数最小化问题。

 

Other constraints

因为CVX用来解决凸优化问题,所以它必须能够验证问题是凸的。为此,CVX采用一定的规则来约束如何构造约束函数和目标函数。  CVX要求等式约束的左右两边都是仿射的。因此,如下所示的约束:

norm(x,Inf) == 1;

将导致如下错误:

??? Error using ==> cvx.eq
Disciplined convex programming error:
Both sides of an equality constraint must be affine.

只有当f是凸函数,g是凹函数的时候,f(x)<=g(x)或者g(x)>=f(x)形式的不等式约束才能用CVX。所以如下约束:

norm(x,Inf) >= 1;

返回下述错误信息:

??? Error using ==> cvx.ge
Disciplined convex programming error:
The left-hand side of a ">=" inequality must be concave.

DCP规则集中更详细地讨论了CVX的细节。如果你知道凸分析和凸优化的基础知识,这些规则是相对直观的。

An optimal trade-off curve 最优折衷曲线

在本节最后一个例子中,我们将展示如何将传统Matlab代码和CVX规范代码混合在一起解决多个优化问题。下面的代码解决 问题。gamma的值是正的对数间隔的向量。
gamma = logspace( -2, 2, 20 );
l2norm = zeros(size(gamma));
l1norm = zeros(size(gamma));
fprintf( 1, '   gamma       norm(x,1)    norm(A*x-b)\n' );
fprintf( 1, '---------------------------------------\n' );
for k = 1:length(gamma),
    fprintf( 1, '%8.4e', gamma(k) );
    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);
    fprintf( 1, '   %8.4e   %8.4e\n', l1norm(k), l2norm(k) );
end
plot( l1norm, l2norm );
xlabel( 'norm(x,1)' );
ylabel( 'norm(A*x-b)' );
grid on

上面的minimize语句是 The DCP ruleset中要讨论的构造规则之一。凸分析的一个基本原则是:凸函数可以乘以非负标量,或者加上另一个凸函数,结果也是凸的。CVX识别这样的组合,并允许在任何地方使用简单的凸函数——例如最小化的目标函数,或者在不等式约束的适当的一侧。所以在例子中,下述表达:

norm(A*x-b)+gamma(k)*norm(x,1)

只要gamma(k)是非负值,CVX都认为上述表达是凸的。如果gamma(k)是负的,那么这个表达式就变成了凸函数和凹函数的和,这会引起CVX产生下述错误信息:

??? Error using ==> cvx.plus
Disciplined convex programming error:
Addition of convex and concave terms is forbidden.
  1. 如果在命令提示符中键入who或whos,你也可能看到其他不熟悉的变量。任何以前缀cvx_开头的变量都被CVX保留为内部使用,并且不应该被改变。
  2. 也有一些专门设计用来解决边界约束最小二乘问题的解决方案,比如 BCLS by Michael Friedlander
  3. 实际上,在上述的cvx_end命令之后,您可能会发现返回的大部分值都是0。这是因为,像许多数值算法一样,解决方案只能在一些非零的数值范围内确定。所以等式约束条件会得到很好的满足,但通常不完全满足。
  • 21
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值