「SymPy」符号运算(6) 矩阵Matrix及基础运算

目录

  • 导言
  • 创建矩阵
    • 列表初始化
      • 行向量
      • 列向量
    • 维度和数集
    • 二元函数
      • `lambda`函数
    • 特殊矩阵
  • 基本操作
    • 索引
    • 增删
    • 基础运算
    • 向量运算

「SymPy」符号运算(6) 矩阵Matrix及基础运算_第1张图片

导言

在前几篇文章中,我们学习了SymPy基础/高级用法、方程求解、微积分以及向量运算等内容,本节我们学习SymPy核心内容之一Matrix矩阵计算(基础)。

传送链接:
「SymPy」符号运算(1) 简介/符号/变量/函数/表达式/等式/不等式/运算符
「SymPy」符号运算(2) 各种形式输出、表达式的化简合并与展开
「SymPy」符号运算(3) (非)线性方程(组)求解、数列求和、连乘、求极限
「SymPy」符号运算(4) 微积分与有限差分
「SymPy」符号运算(5) Vector向量及运算

sympy.matrices官方文档1:https://docs.sympy.org/latest/tutorials/intro-tutorial/matrices.html?highlight=matrix

创建矩阵

SymPy的矩阵模块具有丰富的矩阵初始化方法,类比于NumPynp.ndarray数组等数据结构的创建方式,Matrix的初始化方法大同小异。

列表初始化

创建一个矩阵M,即创建一个Matrxi实例:

import sympy
from sympy.matrices import Matrix
M = Matrix([[1,0,0], [0,0,0]]);
M

输出:
[ 1 0 0 0 0 0 ] \left[\begin{matrix}1 & 0 & 0\\0 & 0 & 0\end{matrix}\right] [100000]
如果用sympy.pprint()函数输出,则输出为

[1  0  0]
[       ]
[0  0  0]

Matrices模块处理的是二维数据,一维带符号的数据可以用Matrix或上一篇讲过的vector,高维数据可以用tensor中的array,之后会单开一篇讲到。当然三者也是可以相互转换的。

Matrices创建矩阵时,如果是像上述那样利用两层嵌套列表初始化,则里层括号内的数据为一行。

在刚才创建的矩阵M的基础上添加一行:

Matrix([M, (0,0,-1)])
# 或者 Matrix([M, [0,0,-1])

输出:
[ 1 0 0 0 0 0 0 0 − 1 ] \left[\begin{matrix}1 & 0 & 0\\0 & 0 & 0\\0 & 0 & -1\end{matrix}\right] 100000001

行向量

Matrices也可以创建一维数据集,用两层嵌套列表(两个方括号)创建一行数据得到行向量:

Matrix([[1, 2, 3]])

输出:
[ 1 2 3 ] \left[\begin{matrix}1 & 2 & 3\end{matrix}\right] [123]

列向量

而如果只用一个方括号(没有嵌套的列表)产生一维Matrices,则得到列向量:

Matrix([1, 2, 3])

输出:
[ 1 2 3 ] \left[\begin{matrix}1\\2\\3\end{matrix}\right] 123

维度和数集

给定矩阵维度为 2 × 3 2\times 3 2×3,元素为 1 , 2 , … 6 1, 2, \dots6 1,2,6,则Matrix可以自动按照给定的矩阵大小将给定的数据按行优先填充进去:

Matrix(2, 3, [1, 2, 3, 4, 5, 6])
# Matrix(2, 3, [1, 2, 3, 4, 5])	 # 报错ValueError,给定的数据总数需要与矩阵大小相容

[ 1 2 3 4 5 6 ] \left[\begin{matrix}1 & 2 & 3\\4 & 5 & 6\end{matrix}\right] [142536]

二元函数

假设我们想要创建的矩阵为 M a × b M_{a\times b} Ma×b,脚标 a a a b b b对应的元素 m a b m_{ab} mab满足二元函数 f ( a , b ) f(a, b) f(a,b) ,则可以将函数名传递给Matirx函数自动创建矩阵:

def f(a, b):
    if a == b:
        return 1
    elif a > b:
        return 2 * a
    else:
        return 0

# 创建4x4矩阵,元素满足函数f(a, b),其中a,b是整数脚标
Matrix(4, 4, f)

输出:
[ 1 0 0 0 2 1 0 0 4 4 1 0 6 6 6 1 ] \left[\begin{matrix}1 & 0 & 0 & 0\\2 & 1 & 0 & 0\\4 & 4 & 1 & 0\\6 & 6 & 6 & 1\end{matrix}\right] 1246014600160001

lambda函数

lambda构造一个二元函数,和前面讲的双变量函数逻辑一样:

# 创建3x4矩阵,元素为 1 - (i+j) % 2,其中i,j是整数脚标
Matrix(3, 4, lambda i,j: 1 - (i+j) % 2)

特殊矩阵

导入:

from sympy.matrices import Matrix, eye, zeros, ones, diag, GramSchmidt
  1. 单位矩阵:eye(n),单位方阵 n × n n\times n n×n
  2. 零矩阵:zeros(n),零方阵 n × n n\times n n×nzeros(n, m),零矩阵 n × m n\times m n×m
  3. 一矩阵:ones(3),一方阵 n × n n\times n n×nones(n, m),一矩阵 n × m n\times m n×m
  4. 对角阵:diag(a, b, c, ...),对角元素为 a , b , c , … a, b, c,\dots a,b,c,

举例:

from sympy.matrices import Matrix, eye, zeros, ones, diag, GramSchmidt
import sympy
eye(5)

输出:
[ 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 ] \left[\begin{matrix}1 & 0 & 0 & 0 & 0\\0 & 1 & 0 & 0 & 0\\0 & 0 & 1 & 0 & 0\\0 & 0 & 0 & 1 & 0\\0 & 0 & 0 & 0 & 1\end{matrix}\right] 1000001000001000001000001

zeros(3, 4)

[ 0 0 0 0 0 0 0 0 0 0 0 0 ] \left[\begin{matrix}0 & 0 & 0 & 0\\0 & 0 & 0 & 0\\0 & 0 & 0 & 0\end{matrix}\right] 000000000000

x, y = sympy.symbols('x y', real = True)
diag(10, Matrix([[x, 4], [6, y]]), eye(2))

[ 10 0 0 0 0 0 x 4 0 0 0 6 y 0 0 0 0 0 1 0 0 0 0 0 1 ] \left[\begin{matrix}10 & 0 & 0 & 0 & 0\\0 & x & 4 & 0 & 0\\0 & 6 & y & 0 & 0\\0 & 0 & 0 & 1 & 0\\0 & 0 & 0 & 0 & 1\end{matrix}\right] 1000000x60004y000001000001

基本操作

索引

假设有一个 2 × 3 2\times3 2×3的数组, 元素从 1 1 1 6 6 6,由一维数据填充得到:

from sympy.matrices import Matrix
import sympy
M = Matrix(2, 3, [1, 2, 3, 4, 5, 6])

可以通过一维索引,索引到第3个元素4

M[3]
# 输出: 4

也可以通过二维索引,索引到第2行第2列的元素:

M[1, 1]
# 输出: 5

也可以切片,返回一个矩阵类型的副本,原矩阵不受影响

M[0:2, 0:2]

输出:
[ 1 2 4 5 ] \left[\begin{matrix}1 & 2\\4 & 5\end{matrix}\right] [1425]

type(M[0:2, 0:2])
# 输出:sympy.matrices.dense.MutableDenseMatrix

索引不仅可以“查”,也可以“改”,修改矩阵某一个元素为符号 x x x

x = sympy.symbols('x')
M[0] = x
M

输出:
[ x 2 3 4 5 6 ] \left[\begin{matrix}x & 2 & 3\\4 & 5 & 6\end{matrix}\right] [x42536]

增删

除了在初始化部分讲过的添加行/列数据的方式外,还可以通过col_insert()或者row_insert()添加(返回副本)

from sympy.matrices import Matrix
M = Matrix(3, 3, list(range(9)))
M1 = Matrix([100, 101, 102])    # 列向量
M.col_insert(1, M1)

输出:
[ 0 100 1 2 3 101 4 5 6 102 7 8 ] \left[\begin{matrix}0 & 100 & 1 & 2\\3 & 101 & 4 & 5\\6 & 102 & 7 & 8\end{matrix}\right] 036100101102147258

删除行或列(直接在原矩阵上修改,无返回值)

from sympy.matrices import Matrix
import sympy
M = Matrix(([1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]))

删除第0

M.row_del(0)
M

输出:
[ 5 6 7 8 9 10 11 12 13 14 15 16 ] \left[\begin{matrix}5 & 6 & 7 & 8\\9 & 10 & 11 & 12\\13 & 14 & 15 & 16\end{matrix}\right] 5913610147111581216
再删除最后一列:

M.col_del(-1)
M

[ 5 6 7 9 10 11 13 14 15 ] \left[\begin{matrix}5 & 6 & 7\\9 & 10 & 11\\13 & 14 & 15\end{matrix}\right] 59136101471115

  • 合并

有两个矩阵

from sympy.matrices import eye, zeros
M1 = eye(3)			# 3x3
M2 = zeros(3, 4)	# 3x4

他们具有相同的行数,可以按行把它们拼起来

M1.row_join(M2)

[ 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ] \left[\begin{matrix}1 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 1 & 0 & 0 & 0 & 0\end{matrix}\right] 100010001000000000000

另外可以用.col_join()函数按列聚合矩阵,不再赘述。

基础运算

算数运算符都可以直接使用:+, -, *, /, **

数与矩阵相乘时是数乘运算,矩阵与矩阵相乘时是矩阵乘法;乘方同理。

栗子:

from sympy.matrices import Matrix
import sympy
M = Matrix(2, 2, [1, 2, 3, 4])
x = sympy.symbols('x')
# 数乘
x*M

输出:
[ x 2 x 3 x 4 x ] \left[\begin{matrix}x & 2 x\\3 x & 4 x\end{matrix}\right] [x3x2x4x]

# 矩阵乘法
M*M		# 或M**2

输出:
[ 7 10 15 22 ] \left[\begin{matrix}7 & 10\\15 & 22\end{matrix}\right] [7151022]
如果相对矩阵内的每个元素做三角函数等特殊函数的运算,可以使用.applyfunc(f)的方法

def f(x):
    return sympy.sin(x)

M.applyfunc(f)

输出:
[ sin ⁡ ( 1 ) sin ⁡ ( 2 ) sin ⁡ ( 3 ) sin ⁡ ( 4 ) ] \left[\begin{matrix}\sin{\left(1 \right)} & \sin{\left(2 \right)}\\\sin{\left(3 \right)} & \sin{\left(4 \right)}\end{matrix}\right] [sin(1)sin(3)sin(2)sin(4)]

向量运算

先定义两个列向量v1, v2

from sympy.matrices import Matrix
import sympy
v1 = Matrix([1,2,3])
v2 = Matrix([4,5,6])
  • 叉乘
v3 = v1.cross(v2)
v3

[ − 3 6 − 3 ] \left[\begin{matrix}-3\\6\\-3\end{matrix}\right] 363

  • 点乘
v1.dot(v2)
# 输出: 32
v1.dot(v3)
# 输出: 0

关于Matrix符号运算与线性代数的内容十分丰富,官方文档中也用了大量篇幅进行讲解,后续将继续介绍…


  1. Meurer A, Smith CP, Paprocki M, Čertík O, Kirpichev SB, Rocklin M, Kumar A, Ivanov S, Moore JK, Singh S, Rathnayake T, Vig S, Granger BE, Muller RP, Bonazzi F, Gupta H, Vats S, Johansson F, Pedregosa F, Curry MJ, Terrel AR, Roučka Š, Saboo A, Fernando I, Kulal S, Cimrman R, Scopatz A. (2017) SymPy: symbolic computing in Python. PeerJ Computer Science 3:e103 https://doi.org/10.7717/peerj-cs.103 ↩︎

你可能感兴趣的:(SymPy符号运算系列,矩阵,python,线性代数)