【发布时间】:2020-09-07 01:56:05
【问题描述】:
我需要在 Python / Numpy 中为 A 和 B 两个矩阵计算 AB⁻¹(当然,B 是正方形)。
我知道np.linalg.inv() 可以让我计算B⁻¹,然后我可以将其与A 相乘。
我也知道B⁻¹A 实际上是better 用np.linalg.solve() 计算的。
受此启发,我决定将AB⁻¹ 改写为np.linalg.solve()。
我得到了一个基于identity (AB)ᵀ = BᵀAᵀ 的公式,它使用np.linalg.solve() 和.transpose():
np.linalg.solve(a.transpose(), b.transpose()).transpose()
这似乎在做这项工作:
import numpy as np
n, m = 4, 2
np.random.seed(0)
a = np.random.random((n, n))
b = np.random.random((m, n))
print(np.matmul(b, np.linalg.inv(a)))
# [[ 2.87169378 -0.04207382 -1.10553758 -0.83200471]
# [-1.08733434 1.00110176 0.79683577 0.67487591]]
print(np.linalg.solve(a.transpose(), b.transpose()).transpose())
# [[ 2.87169378 -0.04207382 -1.10553758 -0.83200471]
# [-1.08733434 1.00110176 0.79683577 0.67487591]]
print(np.all(np.isclose(np.matmul(b, np.linalg.inv(a)), np.linalg.solve(a.transpose(), b.transpose()).transpose())))
# True
并且对于足够大的输入也可以更快地出现:
n, m = 400, 200
np.random.seed(0)
a = np.random.random((n, n))
b = np.random.random((m, n))
print(np.all(np.isclose(np.matmul(b, np.linalg.inv(a)), np.linalg.solve(a.transpose(), b.transpose()).transpose())))
# True
%timeit np.matmul(b, np.linalg.inv(a))
# 100 loops, best of 3: 13.3 ms per loop
%timeit np.linalg.solve(a.transpose(), b.transpose()).transpose()
# 100 loops, best of 3: 7.71 ms per loop
我的问题是:这个身份总是是否正确或我忽略了一些极端情况?
【问题讨论】:
-
只要
a不是单数我看不出问题 -
顺便说一句,您可以做一些事情来使您的代码更简洁和可读:1) 使用
a.T而不是a.transpose(),以及 2) 使用@运算符矩阵乘法而不是np.matmul()。所以你的支票是np.allclose(b @ a.T, np.linalg.solve(a.T, b.T).T)。
标签: python numpy linear-algebra matrix-inverse