目录
\(XQc\to XCq\)
其中\(X\in R^{n,p},\,Q\in R^{p,k},\, c\in R^{k,1},\, C\in R^{p, kp},\, q\in R^{kp, 1}\),\(n\)表示样本数,\(p\)表示特征维度,\(c\)表示pattern的个数。
推导过程如下:
\[\begin{align*}(XQc)_{r, 1}&=\sum_l(XQ)_{r,l}\,c_{l,1}\\&=\sum_l \sum_m X_{r,m}Q_{m,l}\,c_{l,1}\\&=\sum_m\sum_l X_{r, m} \,c_{l,1}Q_{m,l}\end{align*} \]
令\(m\)先固定,如\(m=1\),\(l=\{1, \cdots ,k\}\)上式为
\[X_{r,1}c_{(1,\cdots,k),1}Q_{1, (1,\cdots,k)} \]
可以看到\(c\)对\(Q\)每一行都做了矩阵乘法,而\(m\)是变动的,不难可以想象出\(I\otimes c.T\),\(Q\)要拉成已为向量。代码如下:
import numpy as np
np.random.seed(10)
X = np.random.randn(5, 10)
Q = np.random.randn(10, 3)
c = np.random.randn(3, 1)
# original
result = X.dot(Q.dot(c))
# transformed
I = np.eye(10)
q = Q.reshape(-1, 1)
#
C = np.outer(I, c.T).reshape(10, -1)
# C = np.multiply.outer(I, c.T).reshape(10, -1)
# C = np.einsum('ab, cd->abcd', I, c.T).reshape(10, -1)
new_result = X.dot(C.dot(q))
print("变换是否等价", np.allclose(result, new_result, rtol=1e-4))