目前还在学习阶段,所以关于DCP可以参考知乎的一篇问答:https://www.zhihu.com/question/49902644 本文的斜体是可以在CVX的document中找到的,下面就不一一说明了。
CVX强制遵守纪律( disciplined )凸编程规则集或DCP规则集的约定。 每当遇到任何规则违规时,CVX都会发出一条错误消息,所以在开始构建模型之前,理解它们是非常重要的。 规则是从凸分析的基本原理绘制的,并且一旦您已经接触到凸分析和凸优化,便于学习。
DCP规则集是凸性的一组充分条件,但不是必需条件。 所以有可能构造违反规则集的表达式,但实际上是凸的。 作为例子,考虑熵函数,,其定义为x> 0,这是凹的。 如果它被表示为
- sum( x .* log( x ) )
CVX会拒绝它,因为它的凹陷不符合任何构图规则(composition rules)。 (具体来说,它违反了 Expression rules中描述的无产品规则。)然而,涉及熵的问题可以通过明确地使用熵函数来解决,
sum( entr( x ) )
它位于基本的CVX库中,因此被CVX识别为凹面。 如果一个凸(或凹)函数没有被CVX识别为凸或凹,它可以作为一个新的原子加入; 请参阅将新功能添加到原子库。
作为另一个例子,考虑函数,它是凸的。 如果写成
norm( [ x 1 ] )
(假设x是一个标量变量或仿射表达式),它将被CVX识别为一个凸表达式,因此可以用在(适当的)约束和目标中。 但如果写成
sqrt( x^2 + 1 )
CVX将拒绝它,因为这个函数的凸性并不遵循CVX规则集。
曲率分类
在有规律的凸规划中,标量表达式按其曲率分类。 有四类曲率:常数,仿射,凸和凹。 对于在所有Rn上定义的函数,类别具有以下含义:
当然,这些类别有重大的重叠。 例如,常量表达式也是仿射的,并且(实)仿射表达式是凸和凹的。
凸和凹表达式根据定义是真实的。 可以构造复常量和仿射表达式,但是它们的使用更有限; 例如,它们不能出现在不等式约束的左侧或右侧。
顶级规则
CVX支持三种不同类型的纪律凸面程序:
最小化问题,由一个凸目标函数和零个或多个约束组成。
最大化问题,由一个凹目标函数和零个或多个约束组成。
一个可行性问题,由一个或多个约束和没有目标组成
约束
有纪律的凸面程序可以指定三种类型的约束:
使用==构造的等式约束,其中双方都是仿射的。
小于不等式约束,使用<=,其中左侧是凸的,右侧是凹的。
大于不等式约束,使用> =,其中左侧是凹的,右侧是凸的。
不允许使用〜=构造的不等式约束。 (这种约束不是凸的。)
平等约束的一方或双方可能是复杂的; 另一方面,不平等约束必须是实的。 复杂的等式约束相当于两个实际的等式约束,一个是实部,另一个是虚部。 具有实边和复边的等式约束具有将复边的虚部限制为零的效果。
正如“集成员资格”中所讨论的,CVX使用等式约束来强化集合成员约束(例如,x∈S)。 平等约束的双方必须仿射的规则也适用于设置成员约束。 实际上,像semidefinite()和lorentz()这样的集合原子的返回值是仿射的,所以仅仅验证集合成员约束的剩余部分就足够了。 对于像{x,y}这样的复合值,每个元素必须是仿射的。
严格的不平等
正如在约束中提到的,严格不等式<,>被解释为与非严格不等式> =,<=相同的方式。 重要的是要注意,CVX不能保证在计算的解决方案中严格满足不等式。 这不仅仅是我们在CVX上做出的选择, 这是基础数学和凸优化求解器设计的自然结果。 因此,我们强烈建议不要在CVX中使用严格的不平等,未来的版本可能会将其彻底清除。
严格的不平等对于您的模型至关重要时,您可能需要采取额外措施来确保合规性。 在某些情况下,这可以通过标准化来完成。 例如,考虑一组齐次方程和不等式:
除了严格的不等式,x = 0将是一个可接受的解决方案; 事实上,避免起源的必要性是严重不平等的根本原因。 但是,请注意,如果给定的xx满足这些约束条件,那么αx对于所有α> 0也是如此。 通过消除这种正常化的自由度,我们可以消除严格的不平等; 例如:
如果规范化对于你的模型不是一个有效的方法,你可能只需要通过增加一个小的偏移量来将严格的不等式转换成非严格的不等式。 例如将x> 0转换成比如x> = 1e-4。 请注意,界限必须足够大,以便底层解算器认为它在数值上很重要。
最后,请注意,对于具有由严格不等式定义的域的log(x)和inv_pos(x)等函数,域限制由函数本身处理。 您不需要为模型添加明确的约束x> 0来保证解决方案是正确的。
表达规则
到目前为止,所述的规则并没有特别的限制,因为所有凸面的程序(有纪律的或其他的)通常都遵守它们。 有纪律的凸面编程与更一般的凸面编程的区别在于管理在目标函数和约束中使用的表达式的构造的规则。
受训凸编程通过递归地应用以下规则来确定标量表达式的曲率。 虽然这个列表可能看起来很长,但大多数情况下,凸数分析的基本规则的列举是凸,凹和仿射形式的组合:和,乘以标量等等。
1、一个有效的常量表达式是
任何形式良好的Matlab表达式,评估为有限的值。
2、一个有效的仿射表达式是
一个有效的常量表达式
一个声明的变量;
有效地调用原子库中具有仿射结果的函数;
仿射表达式的总和或差别;
仿射表达式和常量的乘积。
3、一个有效的凸表达式是
一个有效的常量或仿射表达式;
一个有效的调用函数在原子库中的凸结果;
一个仿射标量上升到一个恒定的功率p≥1,p≠3,5,7,9,…
一个凸的标量二次形式 - 见标量二次形式;
两个或多个凸表达式的总和;
凸表达式和凹表达式之间的区别;
凸表达式和非负常数的乘积;
凹表达与非正定常数的乘积;
否定的凹面表达。
4、一个有效的凹面表达式是
一个有效的常量或仿射表达式;
对原子库中的函数进行有效的调用,结果为凹形;
p∈(0,1)的凹标量;
一个凹标量二次形式 - 见标量二次形式;
两个或多个凹面表情的总和;
凹表达式和凸表达式之间的差异;
凹表示和非负常数的乘积;
凸表达式与非正定常数的乘积;
否定凸表达式。
如果一个表达式不能被这个规则集分类,它将被CVX拒绝。 对于矩阵和数组表达式,这些规则是以元素为基础应用的。 我们注意到上面列出的规则是多余的; 有相当小的一套规则。
特别值得注意的是,这些表达规则通常禁止非恒定表达式之间的产品,除了标量二次形式。 例如,表达式x * sqrt(x)恰好是x的一个凸函数,但是它的凸性不能使用CVX规则集来验证,因此被拒绝。 (然而,它可以表示为pow_p(x,3/2))。我们称之为无产品规则,密切关注它会大大地保证你构造的表达式是有效的。
函数
在CVX中,函数被分为两个属性:曲率(常量,仿射,凸或凹)和单调性(非递减,非递增或非单调)。 曲率根据上面给出的表达式确定它们可以在表达式中出现的条件。 单调性决定了它们如何用于函数组合中,我们将在下一节中看到。
对于只有一个参数的函数,分类很简单。 下表给出了一些例子。
根据凸分析的标准实践,当参数在函数域外时,凸函数被解释为+∞,当参数在域外时,凹函数被解释为-∞。 换句话说,CVX中的凸函数和凹函数被解释为它们的扩展值扩展。
这具有自动约束函数的参数在函数的域中的效果。 例如,如果我们在一个CVX规范中构造sqrt(x + 1),其中x是一个变量,那么x将被自动约束为大于或等于-1-1。 没有必要添加一个单独的约束,x> = - 1来执行此操作。
函数的单调性在扩展意义上被确定,即包括在其域之外的自变量的值。 例如,sqrt(x)被确定为非递减的,因为其参数的负值是常数(-∞); 然后在参数为零时跳到0。
即使参数限制在这些部分之一中,CVX也不认为函数是凸或凹的,如果仅仅是它的一部分域的话。 作为一个例子,考虑函数1 / x。 这个函数对于x> 0是凸的,对于x <0是凹的。 但是,即使已经施加了约束条件(如x> = 1),将x限制在函数1 / x的凸起部分,您也不能在CVX中写入1 / x(除非x是常量)。 你可以使用CVX函数inv_pos(x),定义为1 / x对于x> 0,否则对于凸起部分1 / x定义为∞; CVX认识到这个函数是凸和不增加的。 在CVX中,可以使用-inv_pos(-x)来表示1 / x的凹入部分,其中x是负的,这将被正确识别为凹和不增加。(这段话的意思应该是在CVX中,要整个函数的定义域是凸/凹的,例如1/x在大于零的部分,可以指定x为负时,1/x为∞)。
对于具有多个参数的函数,曲率总是被认为是共同的,但是可以在逐个参数的基础上考虑单调性。 例如,函数quad_over_lin(x,y)
在x和y中都是共凸的,但是在y中是单调的(不增加)。
一些函数是凸的,凹的,或者仿射它的参数的一个子集。 例如,函数norm(x,p)其中p \ geq 1仅在其第一个参数中是凸的。 无论何时在CVX规范中使用此函数,其余参数必须是常量,否则CVX将发出错误消息。 这些参数对应于数学术语中的函数参数; 例如
所以我们也应该把这样的论点作为参数在这个范围内引用。 从此以后,每当我们将CVX函数称为凸,凹或仿射时,我们将假设其参数是已知的并且已经被给予适当的,恒定的值。
组成
凸分析的一个基本规则是在仿射映射的组合下凸性是封闭的。 这也是DCP规则集的一部分:
凸,凹或仿射函数可以接受仿射表达式(兼容大小)作为参数。 结果分别是凸面,凹面或仿射。
例如,考虑在CVX原子库中提供的函数square(x)。 这个函数对其论点进行了平方 即它计算x * x(对于数组参数,它独立地对每个元素进行平方)。它在CVX原子库中,并且已知是凸的,只要它的参数是实的。 所以如果x是维数n的实变量,则a是一个常数n向量,而b是一个常量,即表达式
square( a' * x + b )
会被CVX接受,它知道它是凸的。
上面的仿射合成规则是一个更复杂的合成规则的特例,我们现在描述它。 我们考虑一个具有
已知曲率和单调性的函数,它接受多个参数。 对于凸函数,规则是:
如果函数在参数中不减少,那么参数必须是凸的。
如果这个函数在一个论证中是不增加的,那么这个论证就必须是凹的。
如果这个函数在一个论证中既不是非递减的也不是非递增的,那么这个论证必须是仿射的。
如果函数的每个参数满足这些规则,则表达式被CVX接受,并被分类为凸。 回想一下,常数或仿射表达式既是凸凹的,所以任何参数都可以是仿射的,包括作为特例的常量。
凹函数的相应规则如下:
如果函数在参数中不减少,则该参数必须是凹形的。
如果函数在参数中不增加,则该参数必须是凸的。
如果这个函数在一个论证中既不是非递减的也不是非递增的,那么这个论证必须是仿射的。
在这种情况下,表达式被CVX接受,并被分类为凹面。
有关这些组合规则的更多背景信息,请参见凸面优化,第3.2.4节。 事实上,除了标量二次表达式之外,整个DCP规则集可以被认为是这六条规则的特例。
让我们来看一些例子。 最大函数在每个参数中都是凸和不减的,所以它可以接受任何凸的表达式作为参数。 例如,如果x是一个向量变量,那么
max( abs( x ) )
遵循六个组合规则中的第一个,因此被CVX接受,并被归类为凸面。 作为另一个例子,考虑和函数,既是凸函数又是凹函数(因为它是仿射的),而且在每个参数中都是非递减的。 因此表达式
sum( square( x ) )
sum( sqrt( x ) )
在CVX中被认为是有效的,分别被分类为凸和凹。 第一个是凸函数的第一条规则; 第二个是凹函数的第一条规则。
大多数知道基本凸分析的人喜欢用更具体的规则来思考这些例子:凸函数的最大值是凸的,凸(凹)函数的总和是凸的(凹的)。 但是这些规则只是上面一般构成规则的特例。 一般合成规则中的一些其他众所周知的基本规则是:
凸(凹)函数的非负多项是凸(凹)的;
凸(凹)函数的非正共轭是凹(凸)的。
现在我们深入考虑一个更复杂的例子。 假设x是一个向量变量,A,b和f是具有适当维度的常量。 CVX识别表达式
sqrt(f'*x) + min(4,1.3-norm(A*x-b))
作为凹面。 考虑术语sqrt(f’* x)。 CVX认识到sqrt是凹的,f’* x是仿射的,所以它得出sqrt(f’* x)是凹的。 现在考虑第二项min(4,1.3范数(A * x-b))。 CVX认识到min是凹的而非减的,所以它可以接受凹面的论点。 CVX认识到1.3范数(A * x-b)是凹的,因为它是常数和凸函数的差别。 所以CVX认为第二个词也是凹的。 整个表达式被认为是凹的,因为它是两个凹函数的和。
构图规则(composition rules)是足够的,但对于分类的正确性来说并不是必须的,所以一些实际上是凸面或凹面的表达将不能满足它们,因此将被CVX拒绝。 例如,如果x是一个向量变量,则表达式
sqrt( sum( square( x ) ) )
被CVX拒绝,因为没有规则来规定具有凸函数的凹非递减函数的组成。 当然,在这种情况下,解决方法很简单:使用norm(x),因为norm在原子库中,并且由CVX知道是凸的。
非线性组合中的单调性
单调性是非线性成分规则的一个重要方面。 这有一些不是很明显的后果,我们将在这里举例说明。 考虑这个表达
square( square( x ) + 1 )
其中x是一个标量变量。 这个表达式实际上是凸的,因为 是凸的。 但是CVX会拒绝这个表达式,因为外方不能接受一个凸参数。 事实上,凸函数的平方一般不是凸的:例如,不是凸的。
有几种方法可以修改上面的表达式以符合规则集。 一种方法是将其写为x ^ 4 + 2 * x ^ 2 + 1,CVX认为是凸的,因为CVX允许使用^运算符为正整数。 (请注意,应用于函数的相同技术将失败,因为它的第二项是凹的。)
另一种方法是使用代表函数,其中x + = max {0,x}的可选外部函数square_pos,包含在CVX库中。 显然,square和square_pos当它们的参数是非负的时候是重合的。 但是square_pos是非递减的,所以它可以接受一个凸的参数。 因此,表达
square_pos( square( x ) + 1 )
在数学上等同于上面的拒绝版本(因为外部函数的参数总是正数),但它满足DCP规则集,因此被CVX接受。
这就是CVX原子库中的几个函数有两种形式的原因:“自然”形式,以及被修改为单调的形式,因此可用于合成。 其他这样的“单调扩展”包括sum_square_pos和quad_pos_over_lin。 如果你正在自己实现一个新的功能,你可能想考虑一下这个功能的单调扩展也是有用的。
标量二次形式
在其纯粹形式中,DCP规则集甚至禁止使用简单的二次表达式,如x * x(假设x是一个标量变量)。 出于实际的原因,我们选择规则集的一个例外,以允许识别直接映射到CVX原子库中的某些凸二次函数(或它们的凹面底片)的某些特定的二次形式:
CVX检测诸如左上方的二次表达式,并确定它们是凸起的还是凹入的; 如果是的话,将它们转换为等价的函数调用,比如上面的那些。
CVX检查仿射表达式的每个单一乘积,并且仿射表达式的每一个平方,检查凸性; 它不会检查例如仿射表达式的产品的总和。 例如,给定标量变量x和y,表达式
x ^ 2 + 2 * x * y + y ^2
会导致CVX中的错误,因为三个项2 * x * y中的第二个既不是凸的也不是凹的。 但是等同的表达
( x + y ) ^ 2( x + y ) * ( x + y )
会被接受。
当CVX碰到一个标量二次形式时,CVX实际上完成了这个正方形,所以这个形式不需要是对称的。 例如,如果z是一个向量变量,则a,b是常数,那么Q是正定的
( z + a )' * Q * ( z + b )
将被识别为凸。 一旦CVX验证了一个二次形式,它就可以以任何正常的凸或凹表达式的方式自由使用,如表达式规则中所述。
在有纪律的凸规划中,实际上应该使用较少的二次形式,而不是在更传统的数学规划框架中,其中二次形式往往是一个真正希望使用的非光滑形式的平滑替代。 在CVX中,由于支持非平滑函数,所以这种替换很少是必需的。 例如,约束
sum( ( A * x - b ) .^ 2 ) <= 1
用欧几里得规范等价地表示:
norm( A * x - b ) <= 1
使用现代求解器,第二种形式更自然地使用二阶锥约束表示 - 所以第二种形式实际上可能更有效。 事实上,根据我们的经验,这个非平方的形式往往会被更准确地处理。 所以我们强烈建议您根据纪律凸函数提供的新功能重新评估模型中二次形式的使用。