1. 环境的建立

在做实验之前需要建构计算机计算环境,具体的做法参考我的另一篇博文

在起始阶段加载如下的包

from scipy import linalg as la
import sympy
import numpy as np

第一行导入线性代数包,第二行导入符号计算包,第三行导入数值计算包

2. 输入矩阵

第一种方法是使用numpy包中的linalg包, 但是计算结果全部是浮点数, 例如

A=np.array([[2,3],[5,4]])
np.linalg.det(A)

结果是 -6.99999999999

我们一般要求计算结果为精确值,所以后面采用sympy包提供的命令计算向量,矩阵等计算.

A=sympy.Matrix([[2,3],[5,4]])
sympy.det(A)

这里输入的时候要注意Matrix是首字母大写的,和其它命令不同. 矩阵整体用[]包围,每一行元素也用[], 元素之间用逗号分割.

输入符号矩阵

ld=sympy.symbols('lambda')
A=sympy.Matrix([[2,ld],[5,4]])
sympy.det(A)

首先定义变量ld是希腊字母λ, 然后在矩阵中就可以使用这个变量了,在显示时则是直接显示8-5λ.

3. 输入向量

输入列向量

v=sympy.Matrix([3,4])
v

输入行向量

w=sympy.Matrix([[3,4]])
w

注意:要输入行向量时,用[[]]包围向量元素. 向量和矩阵类似也可以包含符号元素.

计算内积

v.dot(w)
w.dot(v)

这两个命令效果一样,都是计算两个向量的内积,这里无所谓是行向量还是列向量都可以.

向量的模

v.norm()

4.计算行列式

计算行列式使用sympy.det()命令,前面已经有示例

5. 矩阵计算

A=sympy.Matrix([[1,2],[3,4]])
B=sympy.Matrix([[4,6],[-2,5]])
A+B
A-B
2*B
A*B
A.T
A.T*B
A*B.T
A.inv()
A**(-1)
A.rank()
A.trace()

其中A.T表示对A求转置,或者sympy.transpose(A)也可以

计算逆矩阵方法和转置类似,是矩阵的一种方法,而不是函数. A.inv()或者用幂A**(-1)也可以

计算矩阵的秩,迹

以上运算中,矩阵可以包含符号变量

6. 矩阵的操作

提取子矩阵

A=sympy.Matrix([[1,2,3],[4,5,6],[7,8,9]])
A[:,:2]

这里的冒号表示一个范围,第一个参数表示行,第二个则是表示列. :表示取全部,一定要记住一点: python中的范围都是从0开始的, 包括起始的数字,但是不包括最后的数字, 比如:2表示从0到1(不包括2), 因此这里返回的是A矩阵的前两列子矩阵.

矩阵的拼接

A=sympy.Matrix([[1,2,3],[4,5,6],[7,8,9]])
B=sympy.Matrix([[A[:,:2],A[:,1:]]])
B

这里把A的前两列和A的后两列横向拼接成一个3*4矩阵,注意这里的[[]].

A=sympy.Matrix([[1,2,3],[4,5,6],[7,8,9]])
B=sympy.Matrix([A[:,:2],A[:,1:]])
B

这里则是纵向拼接,注意其中的差别就在于[]和[[]].

当然,可以把两个向量或者向量和矩阵拼接.

行最简形

A.rref()

返回结果中第一项就是行最简形

7. 线性方程组

p=sympy.symbols("p",positive=True)
A=sympy.Matrix([[1,sympy.sqrt(p)],[1,1/sympy.sqrt(p)]])
b=sympy.Matrix([1,2])
x=A.solve(b)

这是一个含有参数p的线性方程组, 使用sympy.solve()方法求解得到唯一解

x_vars=sympy.symbols("x_1,x_2,x_3")
A=sympy.Matrix([[1,2,3],[4,5,6]])
x=sympy.Matrix(x_vars)
b=sympy.Matrix([7,8])
sympy.solve(A*x-b,x_vars)

这个例子中定义了两个方程,其中含有三个未知数, 方程有无穷多组解, 答案中选择x3作为自由未知量把另外两个变量表示出来, 从而给出了通解.

基础解系

A.nullspace()

返回AX=0的基础解系, 每一列都是一个列向量, 所有的列向量构成了基础解系.

8. 特征值与特征向量

A=sympy.Matrix([[1,2,3],[4,5,6],[7,8,9]])
A.eigenvals()

返回结果{15/2 - 3*sqrt(33)/2: 1, 15/2 + 3*sqrt(33)/2: 1, 0: 1},这是一个字典结构,其中的键表示特征值,而之后的值表示重数,即这个特征值的代数重数.

A=sympy.Matrix([[1,2,3],[4,5,6],[7,8,9]])
A.eigenvects()

返回很长的一个列表, [(0, 1, [Matrix([ [ 1], [-2], [ 1]])]), (15/2 - 3*sqrt(33)/2, 1, [Matrix([ [-3*sqrt(33)/22 - 1/2], [ 1/4 - 3*sqrt(33)/44], [ 1]])]), (15/2 + 3*sqrt(33)/2, 1, [Matrix([ [-1/2 + 3*sqrt(33)/22], [ 1/4 + 3*sqrt(33)/44], [ 1]])])], 列表第一项中的0是特征值,它的代数重数是1, 再之后的矩阵Matrix([ [ 1], [-2], [ 1]])]就是属于特征值0的特征向量, 另外两个的含义也是同样的道理.