近期在使用MATLABcvx进行优化问题求解的过程中遇到了各种各样的问题,bug不断,明明看起来很合理的表达式却一再报错,最终经过一个多月的调试终于将优化问题求解了出来。在调试期间,用到了很多方法,例如问题和约束条件的转化,非凸转化为近似凸,查阅资料,改变公式写法等等手段,本文记录一下编程过程中遇到的错误、bug,希望能够帮到有相同问题的秃友们。
b=rand(3,2);cvx_beginvariablea;variablec;%c为variable变量c=a*b;%因为c是variable变量,所以进行该操作会出现错误minimizef(x)subjecttoa<=10;cvx_end将上述代码中的variablec;修改为expressionc;即可得到正确代码。
正确代码:
报错提示:Thisisoftenanindicationthatanequalityconstraintwaswrittenwithoneequals‘=’insteadoftwo‘==’.Themodelmustberewrittenbeforecvxcanproceed.
错误原因:cvx中的variable变量不是允许人为赋值的,只有在最后得出结果才会被结果覆盖,使用等号对某一个变量进行赋值是不允许的,cvx会动态优化变量,不允许人为复制。
解决方法:查看那个变量中的数据是无效的,修改该变量的值,或者调整初始化参数,或者检查哪一步运算出现了无效数据,修改该语句,进而消除无效数据。
解决方法:例如:x./y报错用inv_pos(y)来代替y,上式修改为x*inv_pos(y)
cvx_beginvariablea;variableb;%c为variable变量minimize(a*inv_pos(b))%不要用a/bsubjecttoa<=10;cvx_end知识点总结:cvx中inv_pos函数在CVX中,inv_pos(x)是一个原子函数,用于求一个正数x的倒数,即1/x。但是,在定义该函数的时候,需要加上一个前缀“inv_pos”来表示参数x必须是正数,否则会产生未定义的结果。
在优化问题中,经常需要对矩阵或向量的逆进行求解。但是,如果涉及到非正定或奇异矩阵,逆运算是无法进行的。因此,为了确保矩阵或向量是正定的,可以使用CVX中的inv_pos函数,它会自动判断变量的正定性并求解其逆。当变量不是正定的时候,inv_pos函数会返回inf(无穷大)或NaN(非数值)。
例如,在求解下面的凸优化问题的时候:
cvx_beginvariablexminimize(inv_pos(x)-1)subjecttox>=0.5;cvx_end上面这个问题要求求解一个变量x,使得1/x最小,且x要大于等于0.5。在这个例子中,因为我们使用了inv_pos函数,所以x必须是正数,否则会出现一个错误。最后,CVX将求解出一个正数x,使得1/x最小。
解决方法:使用rel_entr表示log函数rel_entr(x,y)=xlog(x/y)当你知道了上述表达式表示的含义后,你可以将你的log表达式进行变形,然后使用多个rel_entr函数的组合来表示的想要表达的式子。例如:wlog(1+p/w),借助数学公式log(1/x)=-log(x),可得表达式:wlog(1+p/w)=-rel_entr(w,w+p),注意负号
%想要计算log(1+1/x)a=rel_entr(x+1,x)+rel_entr(x,x+1);知识点总结:cvx中rel_entr函数在CVX中,rel_entr(x,y)是一个原子函数,表示KL散度的一部分,即xlog(x/y)。其中,x和y具有相同的尺寸和形状,元素之间进行逐项计算。
rel_entr函数的第一个参数x可以是任何非负实数或实数向量(或矩阵),而第二个参数y也是非负实数或实数向量(或矩阵),并且y中不能存在0的项。当x和y相等时,rel_entr(x,y)的值是0。在CVX问题中,rel_entr(x,y)通常用在求解最大熵问题、信息论问题、对数几率回归等一些特殊问题。
代码示例:
cvx_beginvariablex(n);maximize(sum(rel_entr(x,p)));subjecttosum(x)==1;x>=0;cvx_end其中,x是一个n维列向量,p也是一个相同尺寸和形状的列向量,CVX会自动将所有元素之间的操作转换成相应的KL散度公式。在这个例子中,CVX将每个x(i)和p(i)进行逐项相除,然后计算KL散度公式的一部分并相加,从而求解满足约束条件的最大化x的问题。
错误原因:无效数据与凸表达式相加,错误原因及处理方法与错误3类似,不再赘述。
错误原因:正实数除以仿射函数,很明显该表达式是一个非凸的,cvx作为一个凸优化工具箱是无法解决非凸问题的。
解决方法:将表达式转化为凸表达式,重新转化约束条件或目标函数。不再使用cvx工具箱,使用其他求解优化问题的工具箱,例如Gurobi、CPLEX等。
上面总结了几个cvx编程中常见的错误,能力有限,不一定能准确解决各位遇到的现实问题,cvx编程看起来简单,实际上水很深,希望大家不要放弃,掌握好编程技巧,一起进步,祝各位的论文仿真早日成功!