在SymPy中自动填充矩阵元素
有没有办法在SymPy中按照某种规则隐式定义符号矩阵的元素,比如说:矩阵中的符号后面跟着下标(或者一对数字)?
举个例子,我想定义一个3行2列的矩阵,叫做M
,希望SymPy能自动创建并填充这个矩阵,像这样:
M =
[ M_11 M_12]
[ M_21 M_22]
[ M_31 M_32]
如果没有办法隐式做到这一点,那有没有什么简单的方法可以显式地做到呢(比如说用循环)?
2 个回答
19
可以考虑使用 MatrixSymbol
,而不是 Matrix
对象。MatrixSymbol
是一种表示矩阵的方式,它不需要你明确列出矩阵里的每一个元素。
In [1]: M = MatrixSymbol('M', 3, 2)
In [2]: M # Just an expression
Out[2]: M
In [3]: Matrix(M) # Turn it into an explicit matrix if you desire
Out[3]:
⎡M₀₀ M₀₁⎤
⎢ ⎥
⎢M₁₀ M₁₁⎥
⎢ ⎥
⎣M₂₀ M₂₁⎦
In [4]: M.T * M # Still just an expression
Out[4]:
T
M ⋅M
In [5]: Matrix(M.T * M) # Fully evaluate
Out[5]:
⎡ 2 2 2 ⎤
⎢ M₀₀ + M₁₀ + M₂₀ M₀₀⋅M₀₁ + M₁₀⋅M₁₁ + M₂₀⋅M₂₁⎥
⎢ ⎥
⎢ 2 2 2 ⎥
⎣M₀₁⋅M₀₀ + M₁₁⋅M₁₀ + M₂₁⋅M₂₀ M₀₁ + M₁₁ + M₂₁ ⎦
11
这样写怎么样:
import sympy
M = sympy.Matrix(3, 2, lambda i,j:sympy.var('M_%d%d' % (i+1,j+1)))
补充一下小解释。sympy.Matrix()的前两个参数是用来定义一个3行2列的矩阵(就像你要求的那样)。第三个参数是一个lambda函数,这其实是一种简便的方法,可以用一行代码来定义一个函数,而不需要像通常那样用def来正式定义。这个函数接收两个变量i和j作为输入,这两个变量正好是矩阵的索引。对于每一对传入lambda的(i,j)(也就是矩阵中的每个元素),我们会创建一个新的符号变量M_ij。sympy.var()需要一个字符串作为输入,这个字符串定义了新符号变量的名字。我们使用格式字符串'M_%d%d'动态生成这个字符串,并用(i+1,j+1)来填充。我们给i和j加1,是因为你希望矩阵是从1开始计数的,而不是像Python标准那样从0开始。