CVX使用CVXQUAD替换CVX中的log、exp等函数

CVX中涉及log、exp、熵的函数都是使用的连续逼近方法来近似原函数,这种逼近慢且精度不高,可能会导致结果出现failed、Inaccurate等情况,导致结果不准确,甚至出现Nan,CVX本身也会出现warning

 

CVXQUAD是基于CVX的一个函数集,其采用更好的Pade Approximation方法,用CVXQUAD中提供的函数来替代对数、指数函数,可以达到更高精度。

CVXQUAD的安装可以直接参考以下帖子

https://blog.csdn.net/fighting5/article/details/114780233

下面具体介绍如何用CVXQUAD中的函数来替换log和exp函数

对于log函数,使用rel_entr_quad函数来近似,比如,对于形如log(f(x))的函数,其中f(x)为关于x的一个凹函数,可以引入松弛变量t,来代替原本的f(x),具体来说:

首先,把原本的log(f(x))替换成-rel_entr_quad(1, t)

然后,加入新的约束:t<=f(x)

这样就可以了(如果f(x)本身是仿射函数,那么不用加入新变量t,直接使用-rel_entr_quad(1, f(x))就行),举个具体的例子,假如有下面这个优化问题:

 

直接使用CVX求解,代码为

cvx_begin
    variables x1 x2
    maximize log(x1)+x2
    subject to
    x1+x2<=log(log(x2))+10;
    x2>=1;
cvx_end

使用 rel_entr_quad函数来近似log函数(当然上面问题很简单,使用原本的代码就可以获得精确解,这里只是举个例子),代码如下

cvx_begin
    variables x1 x2 t2
    maximize -rel_entr_quad(1,x1)+x2
    subject to
    x1+x2<=-rel_entr_quad(1, t2)+10;
    t2<=-rel_entr_quad(1,x2)
cvx_end

其中倒数第二行等价于t2<=log(x2)

在matlab中运行两段代码的结果是一样的。

对于exp函数,我们利用CVXQUAD中的指数锥exponential来替换,具体地说对形如exp(g(x))的函数,其中g(x)为凸函数,类似地,引入新变量r、q

首先把原本的exp(g(x))替换为r

然后加入新的约束:q>=g(x)以及{q,1,r}==exponential(1)就可以了

如果g(x)为仿射函数,则不需要引入q

同样举个例子,考虑下面的优化问题

直接使用cvx求解,代码是这样的

cvx_begin
    variables x1 x2
    minimize exp(x1^2)+exp(x2)
    subject to
    x1+x2<=10;
    x1+x2>=0;
cvx_end

用 CVXQUAD中的函数代替,代码如下

cvx_begin
    variables x1 x2 r1 q1 r2
    minimize r1+r2
    subject to
    q1>=x1^2
    {q1,1,r1}==exponential(1)
    {x2,1,r2}==exponential(1)
    x1+x2<=10;
    x1+x2>=0;
cvx_end

 同样,这两段代码的结果相同。

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值