numpy:反转上三角矩阵

发布于 2024-11-08 14:37:27 字数 201 浏览 3 评论 0原文

在 numpy/scipy 中,计算上三角矩阵逆的规范方法是什么?

矩阵存储为具有零个下对角线元素的 2D numpy 数组,并且结果也应存储为 2D 数组。

编辑到目前为止我发现的最好的是scipy.linalg.solve_triangle(A, np.identity(n))。是这样吗?

In numpy/scipy, what's the canonical way to compute the inverse of an upper triangular matrix?

The matrix is stored as 2D numpy array with zero sub-diagonal elements, and the result should also be stored as a 2D array.

edit The best I've found so far is scipy.linalg.solve_triangular(A, np.identity(n)). Is that it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

樱花坊 2024-11-15 14:37:27

本身确实不存在反转例程。 scipy.linalg.solve 是求解矩阵向量或矩阵矩阵方程的规范方法,并且可以给出有关矩阵结构的明确信息,它将用于选择正确的例程(在本例中可能相当于 BLAS3 dtrsm)。

LAPACK 确实包含用于此目的的 doptri,并且 scipy.linalg 确实公开了原始 C lapack 接口。如果逆矩阵确实是您想要的,那么您可以尝试使用它。

There really isn't an inversion routine, per se. scipy.linalg.solve is the canonical way of solving a matrix-vector or matrix-matrix equation, and it can be given explicit information about the structure of the matrix which it will use to choose the correct routine (probably the equivalent of BLAS3 dtrsm in this case).

LAPACK does include doptri for this purpose, and scipy.linalg does expose a raw C lapack interface. If the inverse matrix is really what you want, then you could try using that.

清旖 2024-11-15 14:37:27

我同意 dtrtri 应该更明显,所以我写了一个例子。

# Import.
import timeit
import numpy as np
from scipy.linalg.lapack import dtrtri

# Make a random upper triangular matrix.
rng = np.random.default_rng(12345)
n = 15
mat = np.triu(rng.random(size=(n, n)))
# The condition number is high, and grows quickly with n.
print('Condition number: ', np.linalg.cond(mat))

# Time the generic matrix inverse routine and the ad hoc one.
print('Time inv: ',    timeit.timeit(lambda: np.linalg.inv(mat), number=10000))
print('Time dtrtri: ', timeit.timeit(lambda: dtrtri(mat, lower=0), number=10000))

# Check the error.
inv_mat1 = np.linalg.inv(mat)
inv_mat2, _ = dtrtri(mat, lower=0)
print('Error inv: ',    np.max(np.abs(inv_mat1 @ mat - np.eye(n))))
print('Error dtrtri: ', np.max(np.abs(inv_mat2 @ mat - np.eye(n))))

至少对于这个简单的例子,我们得到:

Condition number:  227524.1404212523
Time inv:  0.1151930999999422
Time dtrtri:  0.03039009999974951
Error inv:  7.883022033401421e-12
Error dtrtri:  7.65486099651801e-13

这表明 dtrtri()inv() 更快、更准确。在本例中,inv()dtrtri() 都计算出一个恰好是上三角的矩阵。但是,下三角矩阵的情况并非如此,对角线上方的小条目会污染 inv() 的结果。

I agree that dtrtri should be more visible, so I wrote an example.

# Import.
import timeit
import numpy as np
from scipy.linalg.lapack import dtrtri

# Make a random upper triangular matrix.
rng = np.random.default_rng(12345)
n = 15
mat = np.triu(rng.random(size=(n, n)))
# The condition number is high, and grows quickly with n.
print('Condition number: ', np.linalg.cond(mat))

# Time the generic matrix inverse routine and the ad hoc one.
print('Time inv: ',    timeit.timeit(lambda: np.linalg.inv(mat), number=10000))
print('Time dtrtri: ', timeit.timeit(lambda: dtrtri(mat, lower=0), number=10000))

# Check the error.
inv_mat1 = np.linalg.inv(mat)
inv_mat2, _ = dtrtri(mat, lower=0)
print('Error inv: ',    np.max(np.abs(inv_mat1 @ mat - np.eye(n))))
print('Error dtrtri: ', np.max(np.abs(inv_mat2 @ mat - np.eye(n))))

At least for this simple example we get:

Condition number:  227524.1404212523
Time inv:  0.1151930999999422
Time dtrtri:  0.03039009999974951
Error inv:  7.883022033401421e-12
Error dtrtri:  7.65486099651801e-13

Which shows that dtrtri() is both faster and accurate than inv(). In this case, both inv() and dtrtri() compute a matrix that is exactly upper triangular. However, this is not the case for a lower triangular matrix, where small entries above the diagonal pollute the result of inv().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文