还在为学习数学而发愁吗?看完这篇文章,希望Python能帮助你消灭数学恐惧症。
用NumPy进行线性代数运算
线性代数是数学的一个重要分支,比如,我们可以使用线性代数来解决线性回归问题。子程序包numpy.linalg提供了许多线性代数例程,我们可以用它来计算矩阵的逆、计算特征值、求解线性方程或计算行列式等。对于NumPy来说,矩阵可以用ndarray的一个子类来表示。
- 用NumPy求矩阵的逆
在线性代数中,假设A是一个方阵或可逆矩阵,如果存在一个矩阵A -1 ,满足矩阵A -1 与原矩阵A相乘后等于单位矩阵I这一条件,那么就称矩阵A -1 是A的逆,相应的数学方程如下所示:
A A-1 = I
子程序包numpy.linalg中的inv()函数就是用来求矩阵的逆的。下面通过一个例子进行说明,具体步骤如下所示。
1.创建一个示例矩阵。
利用mat()函数创建一个示例矩阵:
A = np.mat("2 4 6;4 2 6;10 -4 18")print "A", A
矩阵A的内容如下所示:
A[[ 2 4 6] [ 4 2 6] [10 -4 18]]]
2.求矩阵的逆。
现在可以利用inv()子例程来计算逆矩阵了:
inverse = np.linalg.inv(A)print "inverse of A", inverse
逆矩阵显示如下:
inverse of A[[-0.41666667 0.66666667 -0.08333333] [ 0.08333333 0.16666667 -0.08333333] [ 0.25 -0.33333333 0.08333333]]
小技巧:
如果该矩阵是奇异的,或者非方阵,那么就会得到LinAlgError消息。如果你喜欢的话,也可以通过手算来验证这个计算结果。这就当作是留给你的一个作业吧。NumPy库中的pinv()函数可以用来求伪逆矩阵,它适用于任意矩阵,包括非方阵。
3.利用乘法进行验算。
下面,我们将inv()函数的计算结果乘以原矩阵,验算结果是否正确:
print "Check", A * inverse
不出所料,果然得到了一个单位矩阵(当然,前提是一些小误差忽略不计):
Check[[ 1.00000000e+00 0.00000000e+00 -5.55111512e-17] [ -2.22044605e-16 1.00000000e+00 -5.55111512e-17] [ -8.88178420e-16 8.88178420e-16 1.00000000e+00]]
将上面的计算机结果减去3×3的单位矩阵,会得到求逆过程中出现的误差:
print "Error", A * inverse - np.eye(3)
一般来说,这些误差通常忽略不计,但是在某些情况下,细微的误差也可能导致不良后果:
[[ -1.11022302e-16 0.00000000e+00 -5.55111512e-17] [ -2.22044605e-16 4.44089210e-16 -5.55111512e-17] [ -8.88178420e-16 8.88178420e-16 -1.11022302e-16]]
这种情况下,我们需要使用精度更高的数据类型,或者更高级的算法。上面,我们使用了numpy.linalg子程序包的inv()例程来计算矩阵的逆。下面,我们用矩阵乘法来验证这个逆矩阵是否符合我们的要求(详见本书代码包中的inversion.py文件):
import numpy as npA = np.mat("2 4 6;4 2 6;10 -4 18")print "A", Ainverse = np.linalg.inv(A)print "inverse of A", inverseprint "Check", A * inverseprint "Error", A * inverse - np.eye(3)
- 用NumPy解线性方程组
矩阵可以通过线性方式把一个向量变换成另一个向量,因此从数值计算的角度看,这种操作对应于一个线性方程组。Numpy.linalg中的solve()子例程可以求解类似Ax = b这种形式的线性方程组,其中A是一个矩阵,b是一维或者二维数组,而x是未知量。下面介绍如何使用dot()函数来计算两个浮点型数组的点积(dot product)。
这里举例说明解线性方程组的过程,具体步骤如下所示。
1.创建矩阵A和数组b,代码如下所示:
A = np.mat("1 -2 1;0 2 -8;-4 5 9")print "A", Ab = np.array([0, 8, -9])print "b", b
矩阵A和数组(向量)b的定义如下所示:
2.调用solve()函数。
接下来,我们用solve()函数来解这个线性方程组:
x = np.linalg.solve(A, b)print "Solution", x
线性方程组的解如下所示:
Solution [ 29. 16. 3.]
3.利用dot()函数进行验算。
利用dot()函数验算这个解是否正确:
print "Check", np.dot(A , x)
结果不出所料:
Check[[ 0. 8. -9.]]
前面,我们通过NumPy的linalg子程序包中的solve()函数求出了线性方程组的解,并利用dot()函数(详见本书代码包中的solution.py文件)验算了结果,下面把这些代码放到一起:
import numpy as npA = np.mat("1 -2 1;0 2 -8;-4 5 9")print "A", Ab = np.array([0, 8, -9])print "b", bx = np.linalg.solve(A, b)print "Solution", xprint "Check", np.dot(A , x)
点击"更多"购买秘笈消灭数学恐惧症。