作为引言,我想指出,如果一个矩阵A
由2x2模式的4个子矩阵组成,其中对角矩阵是正方形,那么如果我们将其逆表示为X
子矩阵X22 = (A22-A21(A11^-1)A12)^-1
,这很容易用手显示。
我试图对4x4子矩阵做同样的事情,但是手工起来却很繁琐。所以我认为Sympy会有所帮助。但是我不知道怎么做(我只是尝试重现2x2结果而已。)
我尝试过:
import sympy as s
def blockmatrix(name, sizes, names=None):
if names is None:
names = sizes
ll = []
for i, (s1, n1) in enumerate(zip(sizes, names)):
l = []
for j, (s2, n2) in enumerate(zip(sizes, names)):
l.append(s.MatrixSymbol(name+str(n1)+str(n2), s1, s2))
ll.append(l)
return ll
def eyes(*sizes):
ll = []
for i, s1 in enumerate(sizes):
l = []
for j, s2 in enumerate(sizes):
if i==j:
l.append(s.Identity(s1))
continue
l.append(s.ZeroMatrix(s1, s2))
ll.append(l)
return ll
n1, n2 = s.symbols("n1, n2", integer=True, positive=True, nonzero=True)
M = s.Matrix(blockmatrix("m", (n1, n2)))
X = s.Matrix(blockmatrix("x", (n1, n2)))
I = s.Matrix(eyes(n1, n2))
s.solve(M*X[:, 1:]-I[:, 1:], X[:, 1:])
但是它只返回一个空列表而不是结果。
我也尝试过:
M*X==I
,但仅返回False
(布尔值,而不是表达式)commutative=False
的'普通'符号而不是MatrixSymbols-这给出了GeneratorsError: non-commutative generators: (x12, x22)
的例外情况但没有运气。
您能展示一下如何使用Sympy得出与我作为X22
示例给出的结果类似的结果吗?
关于使用MatrixSymbols求解的最相似的其他问题似乎已经通过使用内部符号数组或类似的符号来解决,从而得以解决。但是由于我要处理具有符号大小的MatrixSymbol,所以这对我来说不是一个选择。
答案 0 :(得分:1)
这是2x2矩阵矩阵的意思吗?
>>> a = [MatrixSymbol(i,2,2) for i in symbols('a1:5')]
>>> A = Matrix(2,2,a)
>>> X = A.inv()
>>> print(X[1,1]) # [1,1] instead of [2,2] because indexing starts at 0
a1*(a1*a3 - a3*a1)**(-1)
[您表示不正确,并指出以上内容不正确-这似乎是一个应解决的问题。]
我不确定为什么不执行此操作,但是我们可以按以下步骤手动解决:
>>> n = 2
>>> v = symbols('b:%s'%n**2,commutative=False)
>>> A = Matrix(n,n,symbols('a:%s'%n**2,commutative=False))
>>> B = Matrix(n,n,v)
>>> eqs = list(A*B - eye(n))
>>> for i in range(n**2):
... s = solve(eqs[i],v[i])[0]
... eqs[i+1:] = [e.subs(v[i],s) for e in eqs[i+1:]]
...
>>> s # solution for v[3] which is B22
(-a2*a0**(-1)*a1 + a3)**(-1)
您可以将n更改为3,然后看到一个适度复杂的表达式。将其更改为4并手动检查结果以对“乏味”一词重新定义;-)
要解决的方程的特殊结构也可以提供更快的解决方案:感兴趣的变量是包含它的每个项中的最后一个因素:
>>> for i in range(n**2):
... c,d = eqs[i].expand().as_independent(v[i])
... assert all(j.args[-1]==v[i] for j in Add.make_args(d))
... s = 1/d.subs(v[i], 1)*-c
... eqs[i+1:] = [e.subs(v[i], s) for e in eqs[i+1:]]