原子函数
本教程的本节描述了可以应用于CVXPY表达式的原子函数。 CVXPY使用本节中的函数信息和 DCP规则 来标记表达式的符号和曲率。
运算符
中缀运算符 +, -, *, /, @
被视为函数。 +
和 -
运算符始终是仿射函数。
当一个表达式是常数时,表达式 expr1*expr2
是CVXPY中的仿射函数,
当 expr2
是标量常数时,表达式 expr1/expr2
是仿射的。
在历史上,CVXPY使用 expr1 * expr2
来表示矩阵相乘。
这一方法现已弃用。从Python 3.5开始,用户可以使用 expr1 @ expr2
进行矩阵相乘和点积。
自CVXPY 1.1版本开始,我们采用了一个新的标准:
@
应该用于矩阵-矩阵和矩阵-向量乘法,*
应该用于矩阵-标量和向量-标量乘法
可以使用 multiply 函数进行逐元素乘法。
索引和切片
在CVXPY中,索引与 NumPy ndarrays 完全遵循相同的语义。
例如,如果 expr
的形状为 (5,)
,则 expr[1]
给出第二个元素。
更一般地, expr[i:j:k]
选择每个第k个元素,从 i
开始,直到 j-1
结束。
如果 expr
是一个矩阵,则 expr[i:j:k]
选择行,而 expr[i:j:k, r:s:t]
选择行和列。
索引会丢弃维度,而切片会保留维度。
例如,
x = cvxpy.Variable(5)
print("0 dimensional", x[0].shape)
print("1 dimensional", x[0:1].shape)
O dimensional: ()
1 dimensional: (1,)
转置
可以使用 expr.T
语法获得任何表达式的转置。转置是一个仿射函数。
幂运算
对于任何CVXPY表达式 expr
,
幂运算符 expr**p
等同于函数 power(expr, p)
。
标量函数
标量函数接受一个或多个标量、向量或矩阵作为参数,并返回一个标量。
Function |
Meaning |
Domain |
Sign |
Curvature |
Monotonicity |
---|---|---|---|---|---|
constant \(W \in \mathbf{R}^{o \times p}\) |
\(\langle sort\left(vec(X)\right), sort\left(vec(W)\right) \rangle\) |
\(X \in \mathbf{R}^{m \times n}\) |
depends on \(X\), \(W\) |
||
\(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_{+}\) |
|||
\(\frac{n}{\frac{1}{x_1} + \cdots + \frac{1}{x_n}}\) |
\(x \in \mathbf{R}^n_{+}\) |
||||
\((x_1\cdots x_n)^{-1}\) |
\(x \in \mathbf{R}^n_+\) |
||||
\(\lambda_{\max}(X)\) |
\(X \in \mathbf{S}^n\) |
None |
|||
\(\lambda_{\min}(X)\) |
\(X \in \mathbf{S}^n\) |
None |
|||
\(k = 1,\ldots, n\) |
\(\text{sum of $k$ largest}\\ \text{eigenvalues of $X$}\) |
\(X \in\mathbf{S}^{n}\) |
None |
||
\(k = 1,\ldots, n\) |
\(\text{sum of $k$ smallest}\\ \text{eigenvalues of $X$}\) |
\(X \in\mathbf{S}^{n}\) |
None |
||
\(\log \left(\det (X)\right)\) |
\(X \in \mathbf{S}^n_+\) |
None |
|||
\(\log \left(\sum_{ij}e^{X_{ij}}\right)\) |
\(X \in\mathbf{R}^{m \times n}\) |
||||
\(x^T P^{-1} x\) |
\(x \in \mathbf{R}^n\) \(P \in\mathbf{S}^n_{++}\) |
None |
|||
\(\max_{ij}\left\{ X_{ij}\right\}\) |
\(X \in\mathbf{R}^{m \times n}\) |
same as X |
|||
\(\frac{1}{m n}\sum_{ij}\left\{ X_{ij}\right\}\) |
\(X \in\mathbf{R}^{m \times n}\) |
same as X |
|||
\(\min_{ij}\left\{ X_{ij}\right\}\) |
\(X \in\mathbf{R}^{m \times n}\) |
same as X |
|||
\(\left(\sum_k\left(\sum_l\lvert x_{k,l}\rvert^p\right)^{q/p}\right)^{1/q}\) |
\(X \in\mathbf{R}^{n \times n}\) |
None |
|||
norm(x, 2) |
\(\sqrt{\sum_{i} \lvert x_{i} \rvert^2 }\) |
\(X \in\mathbf{R}^{n}\) |
|||
\(\sum_{i}\lvert x_{i} \rvert\) |
\(x \in\mathbf{R}^{n}\) |
||||
\(\max_{i} \{\lvert x_{i} \rvert\}\) |
\(x \in\mathbf{R}^{n}\) |
||||
\(\sqrt{\sum_{ij}X_{ij}^2 }\) |
\(X \in\mathbf{R}^{m \times n}\) |
||||
\(\max_{j} \|X_{:,j}\|_1\) |
\(X \in\mathbf{R}^{m \times n}\) |
||||
\(\max_{i} \|X_{i,:}\|_1\) |
\(X \in\mathbf{R}^{m \times n}\) |
||||
\(\mathrm{tr}\left(\left(X^T X\right)^{1/2}\right)\) |
\(X \in\mathbf{R}^{m \times n}\) |
None |
|||
norm(X, 2) |
\(\sqrt{\lambda_{\max}\left(X^T X\right)}\) |
\(X \in\mathbf{R}^{m \times n}\) |
None |
||
\(sf(x/s)\) |
\(x \in \mathop{\bf dom} f\) \(s \geq 0\) |
same as f |
same as \(f\) |
None |
|
\(p \geq 1\) or |
\(\|X\|_p = \left(\sum_{ij} |X_{ij}|^p \right)^{1/p}\) |
\(X \in \mathbf{R}^{m \times n}\) |
|||
\(p < 1\), \(p \neq 0\) |
\(\|X\|_p = \left(\sum_{ij} X_{ij}^p \right)^{1/p}\) |
\(X \in \mathbf{R}^{m \times n}_+\) |
|||
\(\max_{ij} X_{ij} - \min_{ij} X_{ij}\) |
\(X \in \mathbf{R}^{m \times n}\) |
None |
|||
constant \(P \in \mathbf{S}^n_+\) |
\(x^T P x\) |
\(x \in \mathbf{R}^n\) |
|||
constant \(P \in \mathbf{S}^n_-\) |
\(x^T P x\) |
\(x \in \mathbf{R}^n\) |
|||
constant \(c \in \mathbf{R}^n\) |
\(c^T X c\) |
\(X \in\mathbf{R}^{n \times n}\) |
depends on c, X |
depends on c |
|
\(\left(\sum_{ij}X_{ij}^2\right)/y\) |
\(x \in \mathbf{R}^n\) \(y > 0\) |
||||
\(\sqrt{\frac{1}{mn} \sum_{ij}\left(X_{ij} - \frac{1}{mn}\sum_{k\ell} X_{k\ell}\right)^2}\) |
\(X \in\mathbf{R}^{m \times n}\) |
None |
|||
\(\sum_{ij}X_{ij}\) |
\(X \in\mathbf{R}^{m \times n}\) |
same as X |
|||
\(k = 1,2,\ldots\) |
\(\text{sum of } k\text{ largest }X_{ij}\) |
\(X \in\mathbf{R}^{m \times n}\) |
same as X |
||
\(k = 1,2,\ldots\) |
\(\text{sum of } k\text{ smallest }X_{ij}\) |
\(X \in\mathbf{R}^{m \times n}\) |
same as X |
||
\(\sum_{ij}X_{ij}^2\) |
\(X \in\mathbf{R}^{m \times n}\) |
||||
\(\mathrm{tr}\left(X \right)\) |
\(X \in\mathbf{R}^{n \times n}\) |
same as X |
|||
\(\mathrm{tr}\left(X^{-1} \right)\) |
\(X \in\mathbf{S}^n_{++}\) |
None |
|||
\(\sum_{i}|x_{i+1} - x_i|\) |
\(x \in \mathbf{R}^n\) |
None |
|||
\(\sum_{ij}\left\| \left[\begin{matrix} X_{i+1,j} - X_{ij} \\ X_{i,j+1} -X_{ij} \end{matrix}\right] \right\|_2\) |
\(X \in \mathbf{R}^{m \times n}\) |
None |
|||
\(\sum_{ij}\left\| \left[\begin{matrix} X_{i+1,j}^{(1)} - X_{ij}^{(1)} \\ X_{i,j+1}^{(1)} -X_{ij}^{(1)} \\ \vdots \\ X_{i+1,j}^{(k)} - X_{ij}^{(k)} \\ X_{i,j+1}^{(k)} -X_{ij}^{(k)} \end{matrix}\right] \right\|_2\) |
\(X^{(i)} \in\mathbf{R}^{m \times n}\) |
None |
|||
\({\frac{1}{mn} \sum_{ij}\left(X_{ij} - \frac{1}{mn}\sum_{k\ell} X_{k\ell}\right)^2}\) |
\(X \in\mathbf{R}^{m \times n}\) |
None |
|||
\(-\operatorname{tr}(X\operatorname{logm}(X))\) |
\(X \in \mathbf{S}^{n}_+\) |
None |
标量函数的澄清
域 \(\mathbf{S}^n\) 指的是对称矩阵的集合。 \(\mathbf{S}^n_+\) 和 \(\mathbf{S}^n_-\) 分别指正半定和负半定矩阵的集合。类似地, \(\mathbf{S}^n_{++}\) 和 \(\mathbf{S}^n_{--}\) 分别指正定和负定矩阵的集合。
对于向量表达式 x
,norm(x)
和 norm(x, 2)
给出的是欧几里德范数。但对于矩阵表达式 X
,norm(X)
和 norm(X, 2)
给出的是谱范数。
函数 norm(X, "fro")
被称为 Frobenius范数 而 norm(X, "nuc")
是 核范数。核范数也可以定义为 X
的奇异值之和。
函数 max
和 min
分别给出单个表达式中的最大和最小项。这些函数不应与 maximum
和 minimum
混淆(参见 逐元素函数)。使用 maximum
和 minimum
来找到一组标量表达式的最大值或最小值。
CVXPY 函数 sum
对单个表达式中的所有项求和。Python 内置函数 sum
应该用于将一组表达式相加。例如,以下代码对三个表达式的列表求和:
expr_list = [expr1, expr2, expr3]
expr_sum = sum(expr_list)
沿轴的函数
函数 sum
、 norm
、 max
、 min
、 mean
、 std
、 var
和 ptp
可以沿着某个轴应用。
给定一个 m
行 n
列的表达式 expr
,语法 func(expr, axis=0, keepdims=True)
将 func
应用到每一列,返回一个 1 行 n
列的表达式。
语法 func(expr, axis=1, keepdims=True)
将 func
应用到每一行,返回一个 m
行 1 列的表达式。
默认情况下,keepdims=False
,即长度为 1 的维度被删除。
例如,以下代码在矩阵变量的列和行上求和:
X = cvxpy.Variable((5, 4))
col_sums = cvxpy.sum(X, axis=0, keepdims=True) # 大小为 (1, 4)
col_sums = cvxpy.sum(X, axis=0) # 大小为 (4,)
row_sums = cvxpy.sum(X, axis=1) # 大小为 (5,)
逐元素函数
这些函数对其参数的每个元素进行操作。例如,如果 X
是一个 5 行 4 列的矩阵变量,
那么 abs(X)
是一个 5 行 4 列的矩阵表达式。abs(X)[1, 2]
等价于 abs(X[1, 2])
。
接受多个参数的逐元素函数,如 maximum
和 multiply
,对应参数的元素进行操作。
例如,如果 X
和 Y
都是 3 行 3 列的矩阵变量,那么 maximum(X, Y)
是一个 3 行 3 列的矩阵表达式。
maximum(X, Y)[2, 0]
等价于 maximum(X[2, 0], Y[2, 0])
。这意味着所有参数必须具有相同的维度或者是
标量值,会自动转为对应的维度。
Function |
Meaning |
Domain |
Sign |
Curvature |
Monotonicity |
---|---|---|---|---|---|
\(\lvert x \rvert\) |
\(x \in \mathbf{C}\) |
||||
complex conjugate |
\(x \in \mathbf{C}\) |
None |
|||
\(-x \log (x)\) |
\(x > 0\) |
None |
|||
\(e^x\) |
\(x \in \mathbf{R}\) |
||||
\(M \geq 0\) |
\(\begin{cases}x^2 &|x| \leq M \\2M|x| - M^2&|x| >M\end{cases}\) |
\(x \in \mathbf{R}\) |
|||
imaginary part of a complex number |
\(x \in \mathbf{C}\) |
none |
|||
\(1/x\) |
\(x > 0\) |
||||
\(x \log(x/y) - x + y\) |
\(x > 0\) \(y > 0\) |
None |
|||
\(\log(x)\) |
\(x > 0\) |
||||
approximate log of the standard normal CDF |
\(x \in \mathbf{R}\) |
||||
\(\log(x+1)\) |
\(x > -1\) |
same as x |
|||
\(x > 0\) |
None |
||||
\(\log(1 + e^{x})\) |
\(x \in \mathbf{R}\) |
||||
\(\max \left\{x, y\right\}\) |
\(x,y \in \mathbf{R}\) |
depends on x,y |
|||
\(\min \left\{x, y\right\}\) |
\(x, y \in \mathbf{R}\) |
depends on x,y |
|||
\(c \in \mathbf{R}\) |
c*x |
\(x \in\mathbf{R}\) |
\(\mathrm{sign}(cx)\) |
depends on c |
|
\(\max \left\{-x, 0 \right\}\) |
\(x \in \mathbf{R}\) |
||||
\(\max \left\{x, 0 \right\}\) |
\(x \in \mathbf{R}\) |
||||
\(1\) |
\(x \in \mathbf{R}\) |
constant |
|
||
\(x\) |
\(x \in \mathbf{R}\) |
same as x |
|||
\(p = 2, 4, 8, \ldots\) |
\(x^p\) |
\(x \in \mathbf{R}\) |
|||
\(p < 0\) |
\(x^p\) |
\(x > 0\) |
|||
\(0 < p < 1\) |
\(x^p\) |
\(x \geq 0\) |
|||
\(p > 1,\ p \neq 2, 4, 8, \ldots\) |
\(x^p\) |
\(x \geq 0\) |
|||
real part of a complex number |
\(x \in \mathbf{C}\) |
||||
\(x \log(x/y)\) |
\(x > 0\) \(y > 0\) |
None in \(x\) |
|||
\(\text{alpha} \geq 0\) \(\text{beta} \geq 0\) |
\(\alpha\mathrm{pos}(x)+ \beta\mathrm{neg}(x)\) |
\(x \in \mathbf{R}\) |
|||
\(\sqrt x\) |
\(x \geq 0\) |
||||
\(x^2\) |
\(x \in \mathbf{R}\) |
||||
\(x e^x\) |
\(x \geq 0\) |
逐元素函数的澄清
函数 log_normcdf
和 loggamma
使用近似定义。log_normcdf
在范围 -4 到 4 内具有最高精度,而 loggamma
在所有正实数上具有类似的精度。
有关近似的详细信息,请参见 CVXPY GitHub PR #1224
和 CVXPY GitHub Issue #228。
向量/矩阵函数
向量/矩阵函数接受一个或多个标量、向量或矩阵作为参数,并返回一个向量或矩阵。
CVXPY 在确定由这些函数之一返回的 Expression 的符号时非常保守。 如果这些函数的任何一个参数的符号未知,则返回的 Expression 也将具有未知符号。 如果所有参数都有已知的符号,但是 CVXPY 可以确定返回的 Expression 在不同的条目中具有不同的符号(例如,当堆叠一个正的 Expression 和一个负的 Expression 时), 那么返回的 Expression 将具有未知符号。
Function |
Meaning |
Domain |
Curvature |
Monotonicity |
---|---|---|---|---|
\(\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}\) |
|||
\(c\in\mathbf{R}^m\) |
\(c*x\) |
\(x\in \mathbf{R}^n\) |
depends on c |
|
cumulative sum along given axis. |
\(X \in \mathbf{R}^{m \times n}\) |
|||
\(\left[\begin{matrix}x_1 & & \\& \ddots & \\& & x_n\end{matrix}\right]\) |
\(x \in\mathbf{R}^{n}\) |
|||
\(\left[\begin{matrix}X_{11} \\\vdots \\X_{nn}\end{matrix}\right]\) |
\(X \in\mathbf{R}^{n \times n}\) |
|||
\(k \in 0,1,2,\ldots\) |
kth order differences along given axis |
\(X \in\mathbf{R}^{m \times n}\) |
||
\(\left[\begin{matrix}X^{(1)} \cdots X^{(k)}\end{matrix}\right]\) |
\(X^{(i)} \in\mathbf{R}^{m \times n_i}\) |
|||
constant \(X\in\mathbf{R}^{p \times q}\) |
\(\left[\begin{matrix}X_{11}Y & \cdots & X_{1q}Y \\ \vdots & & \vdots \\ X_{p1}Y & \cdots & X_{pq}Y \end{matrix}\right]\) |
\(Y \in \mathbf{R}^{m \times n}\) |
depends on \(X\) |
|
constant \(Y\in\mathbf{R}^{m \times n}\) |
\(\left[\begin{matrix}X_{11}Y & \cdots & X_{1q}Y \\ \vdots & & \vdots \\ X_{p1}Y & \cdots & X_{pq}Y \end{matrix}\right]\) |
\(X \in \mathbf{R}^{p \times q}\) |
depends on \(Y\) |
|
constant \(y \in \mathbf{R}^m\) |
\(x y^T\) |
\(x \in \mathbf{R}^n\) |
depends on \(y\) |
|
partial trace |
\(X \in\mathbf{R}^{n \times n}\) |
|||
partial transpose |
\(X \in\mathbf{R}^{n \times n}\) |
|||
\(X' \in\mathbf{R}^{m' \times n'}\) |
\(X \in\mathbf{R}^{m \times n}\) \(m'n' = mn\) |
|||
flatten the strictly upper-triangular part of \(X\) |
\(X \in \mathbf{R}^{n \times n}\) |
|||
\(x' \in\mathbf{R}^{mn}\) |
\(X \in\mathbf{R}^{m \times n}\) |
|||
vec_to_upper_tri(X, strict=False) |
\(x' \in\mathbf{R}^{n(n-1)/2}\) for \(x' \in\mathbf{R}^{n(n+1)/2}\) for |
\(X \in\mathbf{R}^{n \times n}\) |
||
\(\left[\begin{matrix}X^{(1)} \\ \vdots \\X^{(k)}\end{matrix}\right]\) |
\(X^{(i)} \in\mathbf{R}^{m_i \times n}\) |
如何理解向量和矩阵函数
\(\texttt{bmat}\) 的输入是一个 CVXPY 表达式的列表列表。它构造一个块矩阵。每个内部列表的元素水平堆叠, 然后将得到的块矩阵垂直堆叠。
输出 \(y = \mathbf{convolve}(c, x)\) 的大小为 \(n+m-1\) ,定义如下: \(y_k =\sum_{j=0}^{k} c[j]x[k-j]\) 。
输出 \(y = \mathbf{vec}(X)\) 是将矩阵 \(X\) 按列主序展开为一个向量。 具体地说, \(y_i = X_{i \bmod{m}, \left \lfloor{i/m}\right \rfloor }\) 。
输出 \(Y = \mathbf{reshape}(X, (m', n'), \text{order='F'})\) 是将矩阵 \(X\) 转换为一个 \(m' \times n'\) 的矩阵。 其中元素按列主序从 \(X\) 中获取,并按列主序存储到 \(Y\) 中。 具体地, \(Y_{ij} = \mathbf{vec}(X)_{m'j + i}\) 。 如果 order=’C’,则将按行主序读取 \(X\) ,并按行主序写入 \(Y\) 。
输出 \(y = \mathbf{upper\_tri}(X)\) 通过连接 \(X\) 的部分行形成。 即, \(y = (X[0,1{:}],\, X[1, 2{:}],\, \ldots, X[n-1, n])\)。