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

文章介绍了如何使用CVXQUAD来提高CVX在处理涉及log、exp和熵函数时的精度。CVXQUAD通过PadeApproximation提供更精确的近似,避免了原始CVX可能存在的不准确和失败情况。对于log函数,可以用rel_entr_quad函数进行替换,而对于exp函数,可以利用指数锥exponential进行替换。文章通过具体例子展示了如何转换代码并实现等效优化问题的求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

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

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

https://blog.youkuaiyun.com/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

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

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值