摘自:
https://github.com/lizhengnss/CVX-Chinese
大家一起进步
CVX强制遵守规范的凸编程规则集或简称DCP规则集所规定的约定。 当CVX遇到任何违反规则的问题时,都会发出错误消息,因此在开始构建模型之前了解它们很重要。 这些规则是根据凸分析的基本原理得出的,一旦您接触了凸分析和凸优化,就易于学习。
DCP规则集是一组足够但不是必需的凸性条件。 因此,可以构造违反规则集但实际上是凸的表达式。 例如,考虑熵函数-Pn i = 1 xi log xi(定义为x> 0,它是凹的)。 如果表示为
sum( x .\* log( x ) )
CVX将拒绝它,因为它的凹度不遵循任何组成规则。 (特别是,它违反了表达式规则中描述的无积规则。)但是,可以通过显式使用熵函数来解决涉及熵的问题,
sum( entr( x ) )
在基础CVX库中,因此被CVX识别为凹面。 如果CVX未将凸(或凹)函数识别为凸或凹,则可以将其添加为新原子;否则,可以将其添加为新原子。 请参阅Adding new functions to the atom library
作为另一个示例,考虑函数px2 + 1 = k [x 1] k2,它是凸的。 如果写成
norm( [ x 1 ] )
(假设x是标量变量或仿射表达式),它将被CVX识别为凸表达式,因此可用于(适当的)约束和目标。 但是如果写成
sqrt( x^2 + 1 )
CVX将拒绝它,因为此函数的凸度不遵循CVX规则集。
在有规则的凸规划中,标量表达式按其曲率分类。 曲率分为四类:常数,仿射,凸和凹。 对于函数f:Rn! 在所有Rn上定义的R,类别具有以下含义:
常 量 f ( α x + ( 1 − α ) y ) = f ( x ) 8 x ; y 2 R n ; α 2 R 仿 射 f ( α x + ( 1 − α ) y ) = α f ( x ) + ( 1 − α ) f ( y ) 8 x ; y 2 R n ; α 2 R 凸 函 数 f ( α x + ( 1 − α ) y ) ≤ α f ( x ) + ( 1 − α ) f ( y ) 8 x ; y 2 R n ; α 2 [ 0 ; 1 ] 凹 函 数 f ( α x + ( 1 − α ) y ) ≥ α f ( x ) + ( 1 − α ) f ( y ) 8 x ; y 2 R n ; α 2 [ 0 ; 1 ] 常量 f(αx + (1 - α)y) = f(x) 8x; y 2 Rn; α 2 R\\ 仿射 f(αx + (1 - α)y) = αf(x) + (1 - α)f(y) 8x; y 2 Rn; α 2 R\\ 凸函数 f(αx + (1 - α)y) ≤ αf(x) + (1 - α)f(y) 8x; y 2 Rn; α 2 [0; 1]\\ 凹函数 f(αx + (1 - α)y) ≥ αf(x) + (1 - α)f(y) 8x; y 2 Rn; α 2 [0; 1] 常量f(αx+(1−α)y)=f(x)8x;y2Rn;α2R仿射f(αx+(1−α)y)=αf(x)+(1−α)f(y)8x;y2Rn;α2R凸函数f(αx+(1−α)y)≤αf(x)+(1−α)f(y)8x;y2Rn;α2[0;1]凹函数f(αx+(1−α)y)≥αf(x)+(1−α)f(y)8x;y2Rn;α2[0;1]
当然,这些类别之间存在很大的重叠。 例如,常数表达式也是仿射,(实数)仿射表达式既是凸的又是凹的。
根据定义,凹凸表达式是实数。 可以构造复杂的常量和仿射表达式,但是它们的使用受到更多限制; 例如,它们不能显示为不等式约束的左侧或右侧。
CVX支持三种不同类型的规则凸程序:
纪律凸程序中可以指定三种约束:
禁止使用〜=构造非等式约束。 (这种约束不是凸面的。)
等式约束的一侧或两侧可能很复杂; 另一方面,不平等约束必须是真实的。 复数相等约束等于两个实数相等约束,一个代表实部,一个代表虚部。 具有实边和复杂边的等式约束具有将复杂边的虚部约束为零的效果。
如集合成员资格中所述,CVX使用相等性约束来强制集合成员资格约束(例如x 2 S)。 相等约束的双方都必须仿射的规则也适用于设置成员资格约束。 实际上,像semidefinite()和lorentz()这样的集合原子的返回值是仿射的,因此只需验证集合成员关系约束的其余部分就足够了。 对于{x,y}这样的复合值,每个元素都必须是仿射的。
如约束中所述,严格不等式<,>的解释方式与非严格不等式> =,<=相同。 重要的是要注意,CVX无法保证在其计算的解决方案中严格满足不等式。 这不仅仅是我们在CVX中所做的选择; 这是基础数学和凸优化求解器设计的自然结果。 因此,我们强烈不建议在CVX中使用严格的不等式,将来的版本可能会完全消除它们。
当严格的不平等对于模型至关重要时,您可能需要采取其他步骤来确保合规性。 在某些情况下,这可以通过规范化来实现。 例如,考虑一组齐次方程和不等式:
Ax = 0; Cx 0; x 0
除了严格的不等式外,x = 0是可以接受的解决方案。 确实,避免起源的必要性是造成严重不平等的根本原因。 但是,请注意,如果给定的x满足这些约束,则所有α> 0的αx也会满足。通过归一化消除这种自由度,我们可以消除严格的不等式; 例如:
Ax = 0; Cx 0; x 0; 1T x = 1
如果规范化不是您模型的有效方法,则可能只需要通过添加一个小的偏移量就可以将严格的不等式转换为非严格的不等式。 例如,将x> 0转换为x> = 1e-4。 请注意,边界必须足够大,以便基础求解器将其视为数字上有意义的。
最后,请注意,对于某些函数,例如log(x)和inv_pos(x),它们具有由严格不等式定义的域,域限制由函数本身处理。 您无需向模型添加显式约束x>0以确保解为正。
到目前为止,所陈述的规则并没有特别的限制,因为所有凸出的程序(有纪律的或其他的)通常都遵守它们。 有规则的凸规划与更一般的凸规划的区别是控制目标函数和约束中所用表达式构造的规则。
严格的凸规划通过递归应用以下规则来确定标量表达式的曲率。 虽然这个列表看起来很长,但它在大多数情况下是凸分析的基本规则的枚举,用于组合凸,凹和仿射形式:求和,标量相乘等。
如果此规则集无法对表达式进行分类,则CVX会拒绝该表达式。 对于矩阵和数组表达式,这些规则是在元素基础上应用的。 我们注意到上面列出的规则是多余的; 有更小的等价规则集
需要特别注意的是,这些表达式规则通常禁止非恒定表达式之间的乘积,但标量二次形式除外。 例如,表达式x * sqrt(x)恰好是x的凸函数,但是其凸度无法使用CVX规则集进行验证,因此被拒绝。 (但是,可以将其表示为pow_p(x,3/2)。)我们将此称为无积规则,对此予以密切关注将大大确保您构造的表达式有效。
在CVX中,函数分为两个属性:曲率(常数,仿射,凸或凹)和单调性(不递减,不增加或非单调)。 曲率根据上面给出的表达式规则确定它们在表达式中出现的条件。 单调性决定了它们如何在函数组合中使用,我们将在下一部分中看到
对于只有一个参数的函数,分类很简单。 下表列出了一些示例
函数 | 数学公式 | 曲率 | 单调性 |
---|---|---|---|
sun(x) | 13" Pro | 仿射 | 不减 |
abs(x) | Plus | 凸 | 非单调 |
log(x) | Series 3 | 凹 | 不减 |
sqrt(x) | HD650 | 凹 | 不减 |
按照凸分析的标准做法,当参数在函数的范围之外时,凸函数被解释为+1,而当参数在其范围之外时,凹函数被解释为-1。 换句话说,CVX中的凸函数和凹函数被解释为其扩展值扩展
这具有自动将函数的参数约束在函数域中的作用,例如,如果我们在CVX规范中形成sqrt(x + 1),其中x是变量,则x将被自动约束为 大于或等于-1。 无需添加单独的约束x> =-1来强制执行此操作。
函数的单调性是在扩展意义上确定的,即包括其域外的参数值。 例如,sqrt(x)被确定为不递减,因为对于其参数的负值,其值是常数(-1); 然后对于参数0跳至0,并对其参数的正值增加。
即使CVX仅在函数域的一部分上,它也不认为函数是凸的或凹的,即使参数被约束为位于这些部分之一中也是如此。 例如,考虑函数1 = x。 对于x> 0,此函数是凸的;对于x <0,此函数是凹的。但是,即使施加了x> = 1之类的约束,也无法在CVX中写1 / x(除非x为常数)。 位于函数1 = x的凸部分。 您可以使用CVX函数inv-pos(x),对于x> 0,将其定义为1 = x;否则,对于1 = x的凸部,请使用1。 CVX将此功能识别为凸且不递增的。 在CVX中,您可以使用-inv-pos(-x)表示1 = x的凹面部分,其中x为负数,它将被正确识别为凹面且不增加
对于具有多个自变量的函数,曲率始终被共同考虑,但是可以在逐个参数的基础上考虑单调性。 例如,函数quad_over_lin(x,y)
fquad_over_lin(x; y) = (j +x1j2=y y > y ≤ 0 0
在x和y上共同凸,但仅在y上单调(不增加)
某些函数仅对于其参数的子集是凸,凹或仿射的。 例如,函数norm(x,p)其中p \ geq 1仅在其第一个参数中是凸的。 每当在CVX规范中使用此函数时,其余参数必须为常数,否则CVX将发出错误消息。 这些自变量对应于数学术语中函数的参数; 例如。
fp (x) : Rn ! R; fp(x) , kxk
因此,在这种情况下,我们也应该将此类参数称为参数似乎是合适的。 从今以后,每当我们说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-norm(A _ x-b))\)。CVX认识到\(min\)是凹且不递减的,因此它可以接受凹参数。 CVX认识到\(1.3-norm(A*x-b)\)是凹的,因为它是常数和凸函数的差。 因此CVX得出结论,第二项也是凹的。 然后将整个表达式识别为凹面,因为它是两个凹面函数的和
组成规则足以使分类正确,但并非必需,因此实际上是凸形或凹形的某些表达式将无法满足它们,因此将被CVX拒绝。 例如,如果x是向量变量,则表达式
sqrt( sum( square( x ) ) )
之所以被CVX拒绝,是因为没有规则控制凹非降函数与凸函数的并置。 当然,这种情况下的解决方法很简单:请使用\(norm(x)\),因为norm在原子库中,并且CVX知道它是凸的。
单调性是非线性合成规则的关键方面。 正如我们将在此处举例说明的那样,这带来的后果并不那么明显。 考虑表达
square( square( x ) + 1 )
其中x是标量变量。 该表达式实际上是凸的,因为(x2 +1)2 = x4 + 2x2 +1是凸的。 但是CVX将拒绝该表达式,因为外部平方不能接受凸形参数。 实际上,凸函数的平方通常不是凸的:例如,(x2-1)2 = x4-2x2 +1不是凸的。
有多种方法可以修改上面的表达式以符合规则集。 一种方法是将其写为\(x4+2*x2+1\),CVX会将其写为凸形,因为CVX允许使用^运算符提供正偶数幂。 (请注意,由于函数的第二项是凹的,因此应用于函数(x2-1)2的相同技术将失败。)
另一种方法是使用CVX库中包含的替代外部函数\(square_pos\),它表示函数(x +)2,其中x + = maxf0; xg。 显然,\(square\)和\(square_pos\)的参数为非负数时会重合。 但是\(square_pos\)不会减少,因此可以接受凸参数。 因此,表达
s q u a r e p o s ( s q u a r e ( x ) + 1 ) ‘ square_pos( square( x ) + 1 ) ` squarepos(square(x)+1)‘`
在数学上等效于上面的拒绝版本(因为外部函数的参数始终为正),但是它满足DCP规则集,因此被CVX接受。
这就是CVX原子库中的几种功能以两种形式出现的原因:“天然”形式,以及一种以单调方式进行修改的功能,因此可以在合成物中使用。 其他此类“单调扩展”包括\(sum_square_pos\)和\(quad_pos_over_lin\)。 如果您自己实现一个新功能,则不妨考虑该功能的单调扩展是否也有用。
以其纯格式,DCP规则集甚至禁止使用简单的二次表达式,例如x * x(假设x是标量变量)。 出于实际原因,我们选择对规则集设置例外,以允许识别某些特定的二次形式,这些形式直接映射到CVX原子库中的某些凸二次函数(或其凹负):
\(x .* x\) | square( x ) (real x) |
\(conj( x ) .* x\) | square_abs( x ) |
\(y’ * y\) | sum_square_abs( y ) |
\((A*x-b)’Q(Ax-b)\) | quad_form( A*x - b, Q ) |
CVX检测二次表达式(例如,左上方的二次表达式),并确定它们是凸形还是凹形; 如果是这样,则将它们转换为等效的函数调用,例如右上方的函数。
CVX检查仿射表达式的每个单个乘积,以及仿射表达式的每个单平方,以检查凸度; 例如,它不会检查仿射表达式的乘积之和。 例如,给定标量变量x和y,表达式
x^2 + 2 * x * y + y ^ 2
将在CVX中引起错误,因为三个项2 * x * y
中的第二个既不是凸面也不是凹面。 但是等价的表达
( x + y ) ^ 2
( x + y ) * ( x + y )
会被接受
CVX遇到标量二次形式时实际上会完成正方形,因此该形式不必是对称的。 例如,如果z是向量变量,a,b是常数,并且Q是正定,则
( z + a )' * Q * ( z + b )
将被识别为凸面。 一旦CVX验证了二次形式,就可以按照表达规则中的描述自由使用正常凸或凹表达式可以使用的任何形式
实际上,在有规则的凸编程中使用二次形式的频率要比在更传统的数学编程框架中使用的频率低,在后者中,二次形式通常是人们真正希望使用的非光滑形式的平滑替代。 在CVX中,由于它支持非平滑功能,因此很少需要进行此类替换。 例如,约束
sum( ( A * x - b ) .^ 2 ) <= 1
用欧几里得范式等效表示:
norm( A * x - b ) <= 1
对于现代求解器,第二种形式更自然地使用二阶圆锥约束表示,因此第二种形式实际上可能更有效。 实际上,根据我们的经验,非平方形式通常会更准确地处理。 因此,我们强烈建议您根据规范化凸编程提供的新功能,重新评估模型中二次形式的使用