牛客题解 | 奇异值分解 (SVD)
题目
奇异值分解是一种将矩阵分解为三个矩阵的方法,它通过将矩阵分解为三个矩阵,来得到矩阵的奇异值和奇异向量。其数学表达式为:
\[A = U \times \Sigma \times V^T
\]
其中,\(A\) 是输入矩阵,\(U\) 是左奇异向量,\(\Sigma\) 是奇异值,\(V^T\) 是右奇异向量。
通过\(\Sigma\)的维度选择,可以实现矩阵的降维。
Jacobi方法是一种计算奇异值分解的方法,常用于小矩阵,其具体步骤如下:
1. 初始化矩阵
- 创建一个与输入矩阵 \(A\) 相关的矩阵 \(a\) 和 \(a_2\)。
- 数学表达式为:
\[a = A
\]
\[a_2 = a^T \times a
\]
2. 计算旋转角度
- 计算旋转角度 \(\theta\)。
- 数学表达式为:
\[\theta = \frac{\pi}{4}
\]
更一般地说,Jacobi方法的计算公式为:
\[\theta = \frac{1}{2} \arctan\left(\frac{2a_{12}}{a_{11} - a_{22}}\right)
\]
3. 计算旋转矩阵
- 计算旋转矩阵 \(r\)。
- 数学表达式为:
\[r = \begin{bmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{bmatrix}
\]
4. 计算旋转后的矩阵
- 计算旋转后的矩阵 \(d\)。
- 数学表达式为:
\[d = r^T \times a \times r
\]
5. 更新矩阵
- 更新矩阵 \(a_2\)。
- 数学表达式为:
\[a_2 = d
\]
6. 计算奇异值
- 计算奇异值 \(s\)。
- 数学表达式为:
\[s = \sqrt{[d[0,0], d[1,1]]}
\]
7. 计算右奇异向量矩阵 \(V\)。
- 数学表达式为:
\[V = r
\]
8. 计算奇异值矩阵 \(S\)。
- 数学表达式为:
\[S = \text{diag}(s)
\]
9. 计算左奇异向量矩阵
- 计算左奇异向量矩阵 \(U\)。
- 数学表达式为:
\[U = a \times v \times \text{inv}(S)
\]
标准代码如下
def svd_2x2_singular_values(A):
a = A
a_t = np.transpose(a)
a_2 = a_t @ a
v = np.eye(2)
for _ in range(1):
if a_2[0,0] == a_2[1,1]:
theta = np.pi/4
else:
theta = 0.5 * np.arctan2(2 * a_2[0,1], a_2[0,0] - a_2[1,1])
r = np.array(
[
[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]
]
)
d = np.transpose(r) @ a_2 @ r
a_2 = d
v = v @ r
s = np.sqrt([d[0,0], d[1,1]])
s_inv = np.array([[1/s[0], 0], [0, 1/s[1]]])
u = a @ v @ s_inv
return (u, s, v.T)

浙公网安备 33010602011771号