【问题标题】:Computing `AB⁻¹` with `np.linalg.solve()`使用 `np.linalg.solve()` 计算 `AB⁻¹`
【发布时间】:2020-09-07 01:56:05
【问题描述】:

我需要在 Python / Numpy 中为 AB 两个矩阵计算 AB⁻¹(当然,B 是正方形)。

我知道np.linalg.inv() 可以让我计算B⁻¹,然后我可以将其与A 相乘。 我也知道B⁻¹A 实际上是betternp.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


【解决方案1】:

一般来说,np.linalg.solve(B, A) 等价于B<sup>-1</sup>A。剩下的只是数学。

在所有情况下,(AB)<sup>T</sup> = B<sup>T</sup>A<sup>T</sup>: https://math.stackexchange.com/q/1440305/295281

在这种情况下不需要,但对于可逆矩阵,(AB)<sup>-1</sup> = B<sup>-1</sup>A<sup>-1</sup>: https://math.stackexchange.com/q/688339/295281

对于可逆矩阵,(A<sup>-1</sup>)<sup>T</sup> = (A<sup>T</sup>)<sup>-1</sup>:https://math.stackexchange.com/q/340233/295281也是如此。

由此得出(AB<sup>-1</sup>)<sup>T</sup> = (B<sup>-1</sup>)<sup>T</sup>A<sup>T</sup> = (B<sup>T</sup>)<sup>-1</sup>A<sup>T</sup>。只要B 是可逆的,您在任何情况下都应该对您提出的转换没有任何问题。

【讨论】:

  • 我不确定我们为什么需要(AB)⁻¹ = B⁻¹A⁻¹。其余的,这正是我的想法。
  • @norok2。为了好的措施:)。我在意识到我不会使用它之前添加了它。我把它留在里面是因为它不疼。我现在在它前面加上了一个注释。
猜你喜欢
  • 2015-03-18
  • 2011-11-22
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 2012-04-19
相关资源
最近更新 更多