在SymPy中自动填充矩阵元素

8 投票
2 回答
3912 浏览
提问于 2025-04-16 22:32

有没有办法在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来正式定义。这个函数接收两个变量ij作为输入,这两个变量正好是矩阵的索引。对于每一对传入lambda(i,j)(也就是矩阵中的每个元素),我们会创建一个新的符号变量M_ijsympy.var()需要一个字符串作为输入,这个字符串定义了新符号变量的名字。我们使用格式字符串'M_%d%d'动态生成这个字符串,并用(i+1,j+1)来填充。我们给ij加1,是因为你希望矩阵是从1开始计数的,而不是像Python标准那样从0开始。

撰写回答