
上QQ阅读APP看书,第一时间看更新
3.3.1 解线性方程组
numpy.linalg.solve(A, b)和scipy.linalg.solve(A, b)可以用来解线性方程组A x=b,也就是计算x=A-1 b。这里,A是m×n的方形矩阵,x和b是长为m的向量。有时候A是固定的,需要对多组b进行求解,因此第二个参数也可以是m×n的矩阵B。这样计算出来的X也是m×n的矩阵,相当于计算A-1 B。
在一些矩阵公式中经常会出现类似于A-1 B的运算,它们都可以用solve(A,B)计算,这要比直接计算逆矩阵然后做矩阵乘法更快捷一些,下面的程序比较solve( )和逆矩阵的运算速度:
import numpy as np from scipy import linalg m, n = 500, 50 A = np.random.rand(m, m) B = np.random.rand(m, n) X1 = linalg.solve(A, B) X2 = np.dot(linalg.inv(A), B) print np.allclose(X1, X2) %timeit linalg.solve(A, B) %timeit np.dot(linalg.inv(A), B) True 100 loops, best of 3: 10.1 ms per loop 10 loops, best of 3: 20 ms per loop
若需要对多组B进行求解,但是又不好将它们合并成一个矩阵,例如某些矩阵公式中可能会有A-1 B、A-1 C、A-1 D等乘法,而B、C、D是通过某种方式逐次计算的。这时可以采用lu_factor( )和lu_solve( )。先调用lu_factor(A)对矩阵A进行LU分解,得到一个元组:(LU矩阵,排序数组)。将这个元组传递给lu_solve( ),即可对不同的B进行求解。由于已经对A进行了LU分解,lu_solve( )能够很快得出结果。
luf = linalg.lu_factor(A) X3 = linalg.lu_solve(luf, B) np.allclose(X1, X3) True
除了使用lu_factor( )和lu_solve( )之外,可以先通过inv( )计算逆矩阵,然后通过dot( )计算矩阵乘积。下面比较二者的速度,可以看出lu_factor( )比inv( )要快很多,而lu_solve( )和dot( )的运算速度几乎相同:
M, N = 1000, 100 np.random.seed(0) A = np.random.rand(M, M) B = np.random.rand(M, N) Ai = linalg.inv(A) luf = linalg.lu_factor(A) %timeit linalg.inv(A) %timeit np.dot(Ai, B) %timeit linalg.lu_factor(A) %timeit linalg.lu_solve(luf, B) 10 loops, best of 3: 131 ms per loop 100 loops, best of 3: 9.65 ms per loop 10 loops, best of 3: 52.6 ms per loop 100 loops, best of 3: 13.8 ms per loop