Matlab和python的svd函数简介
前言
Matlab和python的svd函数简介。
Matlab svd函数
Matlab的svd函数用来求奇异值分解,共有三种调用形式:
- [U,S,V] = svd(A)
- [U,S,V] = svd(A,‘econ’)
- [U,S,V] = svd(A,0)
看一下函数说明:
[U,S,V] = svd(A)奇异值分解出U,S,V, A = U * S * V’。
[U,S,V] = svd(A,‘econ’)进行的是节省内存的奇异值分解。对一个m行n列的矩阵A:
m > n — 只有前n列的U被计算,S是n阶方阵。
m = n — svd(A,‘econ’)和svd(A)结果相同。
m < n — 只有前m列的V被计算,S是m阶方阵。
[U,S,V] = svd(A,0) 也是一种节省内存的奇异值分解。区别在于:
m > n — svd(A,0)和svd(A,‘econ’)结果相同。
m <= n — svd(A,0)和svd(A)结果相同。
下面来看几个例子:
1. m > n时,svd(A)是完整的奇异值分解:
A = [1 2; 3 4; 5 6; 7 8]
A =
1 2
3 4
5 6
7 8
[U,S,V] = svd(A)
U =
-0.1525 -0.8226 -0.3945 -0.3800
-0.3499 -0.4214 0.2428 0.8007
-0.5474 -0.0201 0.6979 -0.4614
-0.7448 0.3812 -0.5462 0.0407
S =
14.2691 0
0 0.6268
0 0
0 0
V =
-0.6414 0.7672
-0.7672 -0.6414
svd(A,0)和svd(A,‘econ’)结果相同,是节省内存的奇异值分解,只有前n列的U被计算,S是n阶方阵:
[U,S,V] = svd(A,0) 或 [U,S,V] = svd(A,‘econ’)
U =
-0.1525 -0.8226
-0.3499 -0.4214
-0.5474 -0.0201
-0.7448 0.3812
S =
14.2691 0
0 0.6268
V =
-0.6414 0.7672
-0.7672 -0.6414
2. m = n时,三种形式结果完全相同:
A = [1 2; 3 4]
A =
1 2
3 4
[U,S,V] = svd(A) 或 [U,S,V] = svd(A,0) 或 [U,S,V] = svd(A,‘econ’)
U =
-0.4046 -0.9145
-0.9145 0.4046
S =
5.4650 0
0 0.3660
V =
-0.5760 0.8174
-0.8174 -0.5760
3. m < n时,svd(A,0)和svd(A)结果相同:
A = [1 3 5 7; 2 4 6 8]
A =
1 3 5 7
2 4 6 8
[U,S,V] = svd(A) 或 [U,S,V] = svd(A,0)
U =
-0.6414 -0.7672
-0.7672 0.6414
S =
14.2691 0 0 0
0 0.6268 0 0
V =
-0.1525 0.8226 -0.3945 -0.3800
-0.3499 0.4214 0.2428 0.8007
-0.5474 0.0201 0.6979 -0.4614
-0.7448 -0.3812 -0.5462 0.0407
svd(A,‘econ’)是节省内存的奇异值分解,只有前m列的V被计算,S是m阶方阵。
[U,S,V] = svd(A,‘econ’)
U =
-0.6414 -0.7672
-0.7672 0.6414
S =
14.2691 0
0 0.6268
V =
-0.1525 0.8226
-0.3499 0.4214
-0.5474 0.0201
-0.7448 -0.3812
总结一下,就是
m > n时,svd(A)是完整的奇异值分解,svd(A,0)和svd(A,‘econ’)是节省内存的奇异值分解。
m = n时,svd(A),svd(A,0)和svd(A,‘econ’)结果相同。
m < n时,svd(A)和svd(A,0)是完整的奇异值分解,svd(A,‘econ’)是节省内存的奇异值分解。
python svd函数
python奇异值分解可以通过numpy.linalg.svd或scipy.linalg.svd调用实现。
通过设置svd()的第二个参数full_matrices=0,进行节省内存的奇异值分解。
import numpy as np
from scipy import linalg
A = np.array([[1,2],[3,4],[5,6],[7,8]])
print(A)
U,S,V = linalg.svd(A)
print(U,S,V)
U,S,V = linalg.svd(A, 0)
print(U,S,V)
A = np.array([[1,2],[3,4]])
print(A)
U,S,V = linalg.svd(A)
print(U,S,V)
U,S,V = linalg.svd(A, 0)
print(U,S,V)
A = np.array([[1,3,5,7],[2,4,6,8]])
print(A)
U,S,V = linalg.svd(A)
print(U,S,V)
U,S,V = linalg.svd(A, 0)
print(U,S,V)
运行以上代码结果发现,linalg.svd()的右奇异向量V对比Matlab是经过转置的,其余结果相同。