几何规划的规范化

规范化几何规划(DGP)是对于*对数对数凸*函数(即,相对于几何平均值而不是算术平均值凸性的正变量函数)的DPC的模拟。

虽然DPC是一种用于构造凸程序的规则集,DGP是一种用于对数对数凸程序(LLCP)的规则集,即在将变量、目标函数和约束函数替换为它们的对数之后仍然是凸的问题,我们将这个操作称为*对数对数*变换。每个几何规划(GP)和广义几何规划(GGP)都是LLCP,但是有些LLCP既不是GP也不是GGP。

CVXPY允许您形成和解决DGP问题,就像对于DCP问题一样。例如,以下代码解决了一个简单的几何规划问题,

import cvxpy as cp

# DGP要求通过`pos=True`声明变量为正。
x = cp.Variable(pos=True)
y = cp.Variable(pos=True)
z = cp.Variable(pos=True)

objective_fn = x * y * z
constraints = [
  4 * x * y * z + 2 * x * z <= 10, x <= 2*y, y <= 2*x, z >= 1]
problem = cp.Problem(cp.Maximize(objective_fn), constraints)
problem.solve(gp=True)
print("Optimal value: ", problem.value)
print("x: ", x.value)
print("y: ", y.value)
print("z: ", z.value)

并打印以下结果。

Optimal value: 1.9999999938309496
x: 0.9999999989682057
y: 1.999999974180587
z: 1.0000000108569758

注意,要解决DGP问题,必须向 solve() 方法传递选项 gp=True

本节解释了什么是DGP,并介绍了如何使用CVXPY构造和解决DGP问题。本节最后列出了可用于 DGP 问题的所有原子,与 DCP atoms 一节中的表格类似。

关于DGP的深入参考,请参见我们的 配套论文 。关于交互式代码示例,请查看我们的 notebooks

注意:DGP是CVXPY最近增加的内容。如果您有反馈意见,请在 Github 上提出问题或拉动请求。

对数曲率

正如CVXPY中的每个Expression都有一个曲率(常数、仿形、凸、凹或未知),每个Expression也有一个对数曲率。

一个函数 \(f : D \subseteq \mathbf{R}^n_{++} \to \mathbf{R}\) 被称为对数凸,如果函数 \(F(u) = \log f(e^u)\) ,其域为 \(\{u \in \mathbf{R}^n : e^u \in D\}\) 是凸的(其中 \(\mathbf{R}^n_{++}\) 表示正实数的集合,对数和指数是指元素性的); 该函数 \(F\) 被称为 f 的对数-对数变换。 \(f\) 是对数凹的,如果 \(F\) 是凹的,如果 \(F\) 是仿形的,则是对数仿形的。

每个对数仿生函数的形式是

\[f(x) = cx_1^{a_1}x_2^{a_2} \ldots x_n^{a_n}\]

其中 \(x\)\(\mathbf{R}^n_{++}\) 中, \(a_i\) 是实数, \(c\) 是正标量。在几何规划的上下文中,这样的函数被称为单项式函数。一组单项式的和在几何规划中被称为一个幂函数,它是 log-log 凸函数。所有具有已知 log-log 曲率的 原子 的表格在本页面末尾显示。

在下面的表格中,\(F\)\(f\) 的 log-log 转换,\(u=\log x\)\(v=\log y\),其中 \(x\)\(y\)\(f\) 的定义域中。

Log-Log 曲率

含义

log-log 常数

\(F\) 是一个常数(所以 f 是一个正常数)

log-log 仿射

\(F(\theta u + (1-\theta)v) = \theta F(u) + (1-\theta)F(v), \; \forall u, \; v,\; \theta \in [0,1]\)

log-log 凸

\(F(\theta u + (1-\theta)v) \leq \theta F(u) + (1-\theta)F(v), \; \forall u, \; v,\; \theta \in [0,1]\)

log-log 凹

\(F(\theta u + (1-\theta)v) \geq \theta F(u) + (1-\theta)F(v), \; \forall u, \; v,\; \theta \in [0,1]\)

未知

DGP 分析无法确定曲率

CVXPY 的 log-log 曲率分析可以标记表达式为未知,即使它们是 log-log 凸函数或 log-log 凹函数。请注意,任何 log-log 常量表达式也是 log-log 仿射的,任何 log-log 仿射表达式也是 log-log 凸的和 log-log 凹的。

表达式的 log-log 曲率存储在其 .log_log_curvature 属性中。例如,运行以下脚本:

import cvxpy as cp

x = cp.Variable(pos=True)
y = cp.Variable(pos=True)

constant = cp.Constant(2.0)
monomial = constant * x * y
posynomial = monomial + (x ** 1.5) * (y ** -1)
reciprocal = posynomial ** -1
unknown = reciprocal + posynomial

print(constant.log_log_curvature)
print(monomial.log_log_curvature)
print(posynomial.log_log_curvature)
print(reciprocal.log_log_curvature)
print(unknown.log_log_curvature)

打印以下输出。

LOG-LOG CONSTANT
LOG-LOG AFFINE
LOG-LOG CONVEX
LOG-LOG CONCAVE
UNKNOWN

您还可以通过调用以下方法来检查表达式的对数-对数曲率 is_log_log_constant()is_log_log_affine()is_log_log_convex()is_log_log_concave() 。例如, posynomial.is_log_log_convex() 将返回 True

对数-对数曲率规则

要使一个表达式具有已知的对数-对数曲率,它引用的所有常量、变量和参数都必须是逐元素正数。如果 常量的数值为正,则它是正数。变量和参数仅在构造函数中提供关键字参数 pos=True (例如, x = cvxpy.Variable(shape=(), pos=True) )时为正数。总之, 在制定DGP问题时,所有常量都应是逐元素正数,所有变量和参数必须使用属性 pos=True 进行构造。

DGP分析与DCP分析完全类似。它是基于具有已知单调性和对数-对数曲率的原子(函数) 库和单个组合规则。 原子库 在本页面末尾展示; 组合规则如下所述。

函数 \(f(expr_1, expr_2, ..., expr_n)\) 在以下条件之一成立时是对数-对数凸的:

  • \(f\) 在参数 \(i\) 上增加,且 \(expr_{i}\) 是对数-对数凸的。

  • \(f\) 在参数 \(i\) 上减少,且 \(expr_{i}\) 是对数-对数凹的。

  • \(expr_{i}\) 是对数-对数仿射的。

函数 \(f(expr_1, expr_2, ..., expr_n)\) 在以下条件之一成立时是对数-对数凹的:

  • \(f\) 在参数 \(i\) 上是递增的,且 \(expr_{i}\) 是对数-对数凹函数。

  • \(f\) 在参数 \(i\) 上是递减的,且 \(expr_{i}\) 是对数-对数凸函数。

  • \(expr_{i}\) 是对数-对数仿射函数。

函数 \(f(expr_1, expr_2, ..., expr_n)\) 是对数-对数仿射函数当且仅当 \(\text{ } f\) 是对数-对数仿射函数,且每个 \(expr_{i}\) 都是对数-对数仿射函数。

如果这三条规则都不适用,表达式 \(f(expr_1, expr_2, ..., expr_n)\) 会被标记为曲率未知。

如果一个表达式满足合成规则,我们俗称该表达式 “是DGP”。您可以通过调用方法 is_dgp() 来检查一个表达式是否是DGP。例如,下面代码块中的断言将通过。

import cvxpy as cp

x = cp.Variable(pos=True)
y = cp.Variable(pos=True)

monomial = 2.0 * constant * x * y
posynomial = monomial + (x ** 1.5) * (y ** -1)

assert monomial.is_dgp()
assert posynomial.is_dgp()

一个表达式是DGP,当且仅当它具有已知的对数-对数曲率,这意味着至少有一个方法 is_log_log_constant()is_log_log_affine()is_log_log_convex()is_log_log_concave() 将返回 True

DGP 问题

Problem 是由目标和约束列表构建的。如果问题遵循 DGP 规则, 它将保证是一个 LLCP 问题,并且可以通过 CVXPY 求解。DGP 规则要求问题目标有以下两种形式之一:

  • 最小化 (对数对数凸)

  • 最大化 (对数对数凹)

根据 DGP 规则,唯一有效的约束条件是:

  • 对数对数仿射 == 对数对数仿射

  • 对数对数凸 <= 对数对数凹

  • 对数对数凹 >= 对数对数凸

您可以通过调用 object.is_dgp() 检查问题、约束或目标是否满足 DGP 规则。 以下是一些 DGP 和非 DGP 问题的示例:

import cvxpy as cp

#DGP 要求变量通过 `pos=True` 声明为正数。
x = cp.Variable(pos=True)
y = cp.Variable(pos=True)
z = cp.Variable(pos=True)

objective_fn = x * y * z
constraints = [
  4 * x * y * z + 2 * x * z <= 10, x <= 2*y, y <= 2*x, z >= 1]
assert objective_fn.is_log_log_concave()
assert all(constraint.is_dgp() for constraint in constraints)
problem = cp.Problem(cp.Maximize(objective_fn), constraints)
assert problem.is_dgp()

# 所有变量必须声明为正数,才能使一个表达式成为DGP。
w = cp.Variable()
objective_fn = w * x * y
assert not objective_fn.is_dgp()
problem = cp.Problem(cp.Maximize(objective_fn), constraints)
assert not problem.is_dgp()

如果在一个非DGP问题上调用 problem.solve(gp=True) ,CVXPY将引发异常。

DGP原子

本教程的这一部分介绍了DGP原子库,即已知具有对数-对数弯曲率和单调性的原子函数。 CVXPY使用本节中的函数信息和DGP规则来标记具有对数-对数弯曲的表达式。请注意,每个DGP表达式都是正的。

中缀运算符

中缀运算符 +、*、/ 被视为原子。运算符 */ 是对数-对数仿射函数。运算符 + 在其两个参数中是对数-对数凸的。

请注意,在CVXPY中,当 expr1expr2 是矩阵时, expr1 * expr2 表示矩阵乘法;如果你使用的是Python 3,你还可以使用 @ 运算符进行矩阵乘法。无论你的Python版本如何,你也可以使用 matmul atom 来对两个矩阵进行乘法运算。要对两个数组或矩阵进行逐元素乘法,请使用 multiply atom 。最后,要求一个Expression的所有元素的乘积,请使用 prod atom

转置

可以使用语法 expr.T 来获得任何表达式的转置。转置是一个对数-对数仿射函数。

幂函数

对于任何CVXPY表达式 expr ,幂运算符 expr**p 等同于函数 power(expr, p) 。取幂是一个对数-对数仿射函数。

标量函数

标量函数接受一个或多个标量、向量或矩阵作为参数,并返回一个标量。需要注意的是,这些原子可以沿着一个轴应用;有关详细信息,请参阅API参考或 DCP atoms tutorial

Function

Meaning

Domain

Log-log curvature 

Monotonicity

geo_mean(x)

geo_mean(x, p)

\(p \in \mathbf{R}^n_{+}\)

\(p \neq 0\)

\(x_1^{1/n} \cdots x_n^{1/n}\)

\(\left(x_1^{p_1} \cdots x_n^{p_n}\right)^{\frac{1}{\mathbf{1}^T p}}\)

\(x \in \mathbf{R}^n_{+}\)

affine log-log affine

incr incr.

harmonic_mean(x)

\(\frac{n}{\frac{1}{x_1} + \cdots + \frac{1}{x_n}}\)

\(x \in \mathbf{R}^n_{+}\)

concave log-log concave

incr incr.

max(X)

\(\max_{ij}\left\{ X_{ij}\right\}\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

convex log-log convex

incr incr.

min(X)

\(\min_{ij}\left\{ X_{ij}\right\}\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

concave log-log concave

incr incr.

norm(x)

norm(x, 2)

\(\sqrt{\sum_{i} \lvert x_{i} \rvert^2 }\)

\(X \in\mathbf{R}^{n}_{++}\)

convex log-log convex

incr incr.

norm(X, “fro”)

\(\sqrt{\sum_{ij}X_{ij}^2 }\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

convex log-log convex

incr incr.

norm(X, 1)

\(\sum_{ij}\lvert X_{ij} \rvert\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

convex log-log convex

incr incr.

norm(X, “inf”)

\(\max_{ij} \{\lvert X_{ij} \rvert\}\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

convex log-log convex

incr incr.

pnorm(X, p)

\(p \geq 1\)

or p = 'inf'

\(\|X\|_p = \left(\sum_{ij} |X_{ij}|^p \right)^{1/p}\)

\(X \in \mathbf{R}^{m \times n}_{++}\)

convex log-log convex

incr incr.

pnorm(X, p)

\(0 < p < 1\)

\(\|X\|_p = \left(\sum_{ij} X_{ij}^p \right)^{1/p}\)

\(X \in \mathbf{R}^{m \times n}_{++}\)

convex log-log convex

incr incr.

prod(X)

\(\prod_{ij}X_{ij}\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

affine log-log affine

incr incr.

quad_form(x, P)

\(x^T P x\)

\(x \in \mathbf{R}^n\), \(P \in \mathbf{R}^{n \times n}_{++}\)

convex log-log convex

incr incr.

quad_over_lin(X, y)

\(\left(\sum_{ij}X_{ij}^2\right)/y\)

\(x \in \mathbf{R}^n_{++}\)

\(y > 0\)

convex log-log convex

incr in \(X_{ij}\)

decr decr. in \(y\)

sum(X)

\(\sum_{ij}X_{ij}\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

convex log-log convex

incr incr.

sum_squares(X)

\(\sum_{ij}X_{ij}^2\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

convex log-log convex

incr incr.

trace(X)

\(\mathrm{tr}\left(X \right)\)

\(X \in\mathbf{R}^{n \times n}_{++}\)

convex log-log convex

incr incr.

pf_eigenvalue(X)

spectral radius of \(X\)

\(X \in\mathbf{R}^{n \times n}_{++}\)

convex log-log convex

incr incr.

逐元素函数

这些函数作用于它们参数的每个元素。例如,如果 X 是一个 5x4 的矩阵变量,则 sqrt(X) 是一个 5x4 的矩阵表达式。 sqrt(X)[1, 2] 相当于 sqrt(X[1, 2])

对于接受多个参数的逐元素函数,如 maximummultiply ,它们在每个参数的对应元素上进行操作。例如,如果 XY 都是 3x3 的矩阵变量,则 maximum(X, Y) 是一个 3x3 的矩阵表达式。 maximum(X, Y)[2, 0] 相当于 maximum(X[2, 0], Y[2, 0]) 。这意味着所有参数必须具有相同的维度或者是标量,如果是标量,则会被升级。

Function

Meaning

Domain

Curvature 

Monotonicity

diff_pos(x, y)

\(x - y\)

\(0 < y < x\)

concave log-log concave

incr incr. in \(x\)

decr decr. in \(y\)

entr(x)

\(-x \log (x)\)

\(0 < x < 1\)

concave log-log concave

None

exp(x)

\(e^x\)

\(x > 0\)

convex log-log convex

incr incr.

log(x)

\(\log(x)\)

\(x > 1\)

concave log-log concave

incr incr.

maximum(x, y)

\(\max \left\{x, y\right\}\)

\(x,y > 0\)

convex log-log convex

incr incr.

minimum(x, y)

\(\min \left\{x, y\right\}\)

\(x, y > 0\)

concave log-log concave

incr incr.

multiply(x, y)

\(x*y\)

\(x, y > 0\)

affine log-log affine

incr incr.

one_minus_pos(x)

\(1 - x\)

\(0 < x < 1\)

concave log-log concave

decr decr.

power(x, 0)

\(1\)

\(x > 0\)

constant

constant

power(x, p)

\(x\)

\(x > 0\)

affine log-log affine

incr for \(p > 0\)

decr for \(p < 0\)

sqrt(x)

\(\sqrt x\)

\(x > 0\)

affine log-log affine

incr incr.

square(x)

\(x^2\)

\(x > 0\)

affine log-log affine

incr incr.

xexp(x)

\(x e^x\)

\(x > 0\)

convex log-log convex

incr incr.

向量/矩阵函数

向量/矩阵函数接受一个或多个标量、向量或矩阵作为参数,并返回一个向量或矩阵。

Function

Meaning

Domain

Curvature 

Monotonicity

bmat([[X11,…,X1q], …, [Xp1,…,Xpq]])

\(\left[\begin{matrix} X^{(1,1)} & \cdots & X^{(1,q)} \\ \vdots & & \vdots \\ X^{(p,1)} & \cdots & X^{(p,q)} \end{matrix}\right]\)

\(X^{(i,j)} \in\mathbf{R}^{m_i \times n_j}_{++}\)

affine log-log affine

incr incr.

diag(x)

\(\left[\begin{matrix}x_1 & & \\& \ddots & \\& & x_n\end{matrix}\right]\)

\(x \in\mathbf{R}^{n}_{++}\)

affine log-log affine

incr incr.

diag(X)

\(\left[\begin{matrix}X_{11} \\\vdots \\X_{nn}\end{matrix}\right]\)

\(X \in\mathbf{R}^{n \times n}_{++}\)

affine log-log affine

incr incr.

eye_minus_inv(X)

\((I - X)^{-1}\)

\(X \in\mathbf{R}^{n \times n}_{++}, \lambda_{\text{pf}}(X) < 1\)

convex log-log convex

incr incr.

gmatmul(A, x)

\(A \in \mathbf{R}^{m \times n}\)

\(\left[\begin{matrix}\prod_{j=1}^n x_j^{A_{1j}} \\\vdots \\\prod_{j=1}^n x_j^{A_{mj}}\end{matrix}\right]\)

\(x \in \mathbf{R}^n_{++}\)

affine log-log affine

incr for \(A_{ij} \geq 0\)

decr for \(A_{ij} \leq 0\)

hstack([X1, …, Xk])

\(\left[\begin{matrix}X^{(1)} \cdots X^{(k)}\end{matrix}\right]\)

\(X^{(i)} \in\mathbf{R}^{m \times n_i}_{++}\)

affine log-log affine

incr incr.

matmul(X, Y)

\(XY\)

\(X \in\mathbf{R}^{m \times n}_{++}, Y \in\mathbf{R}^{n \times p}_{++}`\)

convex log-log convex

incr incr.

resolvent(X)

\((sI - X)^{-1}\)

\(X \in\mathbf{R}^{n \times n}_{++}, \lambda_{\text{pf}}(X) < s\)

convex log-log convex

incr incr.

reshape(X, (m’, n’))

\(X' \in\mathbf{R}^{m' \times n'}\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

\(m'n' = mn\)

affine log-log affine

incr incr.

vec(X)

\(x' \in\mathbf{R}^{mn}\)

\(X \in\mathbf{R}^{m \times n}_{++}\)

affine log-log affine

incr incr.

vstack([X1, …, Xk])

\(\left[\begin{matrix}X^{(1)} \\ \vdots \\X^{(k)}\end{matrix}\right]\)

\(X^{(i)} \in\mathbf{R}^{m_i \times n}_{++}\)

affine log-log affine

incr incr.