## 内容索引¶

1. 矩阵 --- mat函数
2. 线性代数 --- numpy.linalg中的逆矩阵函数inv函数、行列式det函数、求解线性方程组的solve函数、内积dot函数、特征分解eigvals函数、eig函数、奇异值分解svd函数、广义逆矩阵的pinv函数
In [1]:
import numpy as np


## 1. 矩阵¶

### 1.1 创建矩阵¶

mat函数创建矩阵时，若输入已经为matrix或ndarray对象，则不会为它们创建副本。因此，调用mat函数和调用matrix(data, copy=False)等价。

In [2]:
A = np.mat('1 2 3; 4 5 6; 7 8 9')
print "Creation from string:\n", A

Creation from string:
[[1 2 3]
[4 5 6]
[7 8 9]]

In [3]:
# 转置
print "Transpose A :\n", A.T

# 逆矩阵
print "Inverse A :\n", A.I

Transpose A :
[[1 4 7]
[2 5 8]
[3 6 9]]
Inverse A :
[[ -4.50359963e+15   9.00719925e+15  -4.50359963e+15]
[  9.00719925e+15  -1.80143985e+16   9.00719925e+15]
[ -4.50359963e+15   9.00719925e+15  -4.50359963e+15]]

In [4]:
# 通过NumPy数组创建矩阵
print "Creation from array: \n", np.mat(np.arange(9).reshape(3,3))

Creation from array:
[[0 1 2]
[3 4 5]
[6 7 8]]


### 1.2 从已有矩阵创建新矩阵¶

In [5]:
A = np.eye(2)
print "A:\n", A

B = 2 * A
print "B:\n", B

# 使用字符串创建复合矩阵
print "Compound matrix:\n", np.bmat("A B")
print "Compound matrix:\n", np.bmat("A B; B A")

A:
[[ 1.  0.]
[ 0.  1.]]
B:
[[ 2.  0.]
[ 0.  2.]]
Compound matrix:
[[ 1.  0.  2.  0.]
[ 0.  1.  0.  2.]]
Compound matrix:
[[ 1.  0.  2.  0.]
[ 0.  1.  0.  2.]
[ 2.  0.  1.  0.]
[ 0.  2.  0.  1.]]


## 2. 线性代数¶

### 2.1 计算逆矩阵¶

In [6]:
A = np.mat("0 1 2; 1 0 3; 4 -3 8")
print "A:\n", A
inverse = np.linalg.inv(A)
print "inverse of A:\n", inverse

print "check inverse:\n", inverse * A

A:
[[ 0  1  2]
[ 1  0  3]
[ 4 -3  8]]
inverse of A:
[[-4.5  7.  -1.5]
[-2.   4.  -1. ]
[ 1.5 -2.   0.5]]
check inverse:
[[ 1.  0.  0.]
[ 0.  1.  0.]
[ 0.  0.  1.]]


### 2.2 行列式¶

In [7]:
A = np.mat("3 4; 5 6")
print "A:\n", A

print "Determinant:\n", np.linalg.det(A)

A:
[[3 4]
[5 6]]
Determinant:
-2.0


### 2.3 求解线性方程组¶

In [8]:
A = np.mat("1 -2 1; 0 2 -8; -4 5 9")
print "A:\n", A
b = np.array([0,8,-9])
print "b:\n", b

A:
[[ 1 -2  1]
[ 0  2 -8]
[-4  5  9]]
b:
[ 0  8 -9]

In [9]:
x = np.linalg.solve(A, b)
print "Solution:\n", x

# check
print "Check:\n",b == np.dot(A, x)
print np.dot(A, x)

Solution:
[ 29.  16.   3.]
Check:
[[ True  True  True]]
[[ 0.  8. -9.]]


### 2.4 特征值和特征向量¶

In [10]:
A = np.mat("3 -2; 1 0")
print "A:\n", A

print "Eigenvalues:\n", np.linalg.eigvals(A)

eigenvalues, eigenvectors = np.linalg.eig(A)
print "Eigenvalues:\n", eigenvalues
print "Eigenvectors:\n", eigenvectors

A:
[[ 3 -2]
[ 1  0]]
Eigenvalues:
[ 2.  1.]
Eigenvalues:
[ 2.  1.]
Eigenvectors:
[[ 0.89442719  0.70710678]
[ 0.4472136   0.70710678]]

In [11]:
# check
# 计算 Ax = ax的左右两部分的值
for i in range(len(eigenvalues)):
print "Left:\n", np.dot(A, eigenvectors[:,i])
print "Right:\n", np.dot(eigenvalues[i], eigenvectors[:,i])
print

Left:
[[ 1.78885438]
[ 0.89442719]]
Right:
[[ 1.78885438]
[ 0.89442719]]

Left:
[[ 0.70710678]
[ 0.70710678]]
Right:
[[ 0.70710678]
[ 0.70710678]]



### 2.5 奇异值分解¶

SVD(Singular Value Decomposition，奇异值分解)是一种因子分解运算，将一个矩阵分解为3个矩阵的乘积。奇异值分解是特征值分解的一种推广。

In [12]:
from IPython.display import Latex
Latex(r"$M=U \Sigma V^*$")

Out[12]:
$M=U \Sigma V^*$

*号表示共轭转置

In [13]:
A = np.mat("4 11 14;8 7 -2")
print "A:\n", A

U, Sigma, V = np.linalg.svd(A, full_matrices=False)
print "U:\n", U
print "Sigma:\n", Sigma
print "V:\n", V

A:
[[ 4 11 14]
[ 8  7 -2]]
U:
[[-0.9486833  -0.31622777]
[-0.31622777  0.9486833 ]]
Sigma:
[ 18.97366596   9.48683298]
V:
[[-0.33333333 -0.66666667 -0.66666667]
[ 0.66666667  0.33333333 -0.66666667]]

In [14]:
# Sigma矩阵是奇异值矩阵对角线上的值
np.diag(Sigma)

Out[14]:
array([[ 18.97366596,   0.        ],
[  0.        ,   9.48683298]])
In [17]:
# check
M = U*np.diag(Sigma)*V
print "Product:\n", M

Product:
[[  4.  11.  14.]
[  8.   7.  -2.]]


### 2.6 广义逆矩阵¶

In [18]:
A = np.mat("4 11 14; 8 7 -2")
print "A:\n", A

A:
[[ 4 11 14]
[ 8  7 -2]]

In [19]:
pseudoinv = np.linalg.pinv(A)
print "Pseudo inverse:\n", pseudoinv

Pseudo inverse:
[[-0.00555556  0.07222222]
[ 0.02222222  0.04444444]
[ 0.05555556 -0.05555556]]

In [20]:
# check
print "Check pseudo inverse:\n", A*pseudoinv

Check pseudo inverse:
[[  1.00000000e+00   0.00000000e+00]
[  8.32667268e-17   1.00000000e+00]]


In [21]:
A = np.mat("0 1 2; 1 0 3; 4 -3 8")
print "A:\n", A
inverse = np.linalg.inv(A)
print "inverse of A:\n", inverse
print "check inverse:\n", inverse * A

pseudoinv = np.linalg.pinv(A)
print "Pseudo inverse:\n", pseudoinv
print "Check pseudo inverse:\n", A*pseudoinv

A:
[[ 0  1  2]
[ 1  0  3]
[ 4 -3  8]]
inverse of A:
[[-4.5  7.  -1.5]
[-2.   4.  -1. ]
[ 1.5 -2.   0.5]]
check inverse:
[[ 1.  0.  0.]
[ 0.  1.  0.]
[ 0.  0.  1.]]
Pseudo inverse:
[[-4.5  7.  -1.5]
[-2.   4.  -1. ]
[ 1.5 -2.   0.5]]
Check pseudo inverse:
[[  1.00000000e+00  -2.66453526e-15   8.88178420e-16]
[  8.88178420e-16   1.00000000e+00   2.22044605e-16]
[  0.00000000e+00   3.55271368e-15   1.00000000e+00]]