Sympy:提取矩阵的下三角部分

发布于 2025-01-17 23:10:05 字数 360 浏览 1 评论 0原文

我正在尝试提取Sympy矩阵的下部三角形部分。由于我找不到Sympy中的tril方法,因此我定义了:

def tril (M):
    m = M.copy()
    for row_index in range (m.rows):
        for col_index in range (row_index + 1, m.cols):
            m[row_index, col_index] = 0
    return (m)

它似乎有效:

“>

.copy()确保原始矩阵完整性的推荐方法吗?

I am trying to extract the lower triangular part of a SymPy matrix. Since I could not find a tril method in SymPy, I defined:

def tril (M):
    m = M.copy()
    for row_index in range (m.rows):
        for col_index in range (row_index + 1, m.cols):
            m[row_index, col_index] = 0
    return (m)

It seems to work:

enter image description here

Is there a more elegant way to extract the lower triangular part of a SymPy matrix?

Is .copy() the recommended way to ensure the integrity of the original matrix?

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

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

发布评论

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

评论(3

何时共饮酒 2025-01-24 23:10:05

在 SymPy 中,M.lower_triangle(k) 将给出第 k 个对角线下方的下三角元素。默认值为 k=0

In SymPy, M.lower_triangular(k) will give the lower triangular elements below the kth diagonal. The default is k=0.

毁梦 2025-01-24 23:10:05
In [99]: M
Out[99]: 
⎡a  b  c⎤
⎢       ⎥
⎢d  e  f⎥
⎢       ⎥
⎣g  h  i⎦

另一个答案建议使用 np.tril 函数:

In [100]: np.tril(M)
Out[100]: 
array([[a, 0, 0],
       [d, e, 0],
       [g, h, i]], dtype=object)

由于符号的原因,它将 M 转换为 numpy 数组 - 对象数据类型。结果也是一个 numpy 数组。

您的函数返回一个 sympy.Matrix

In [101]: def tril (M):
     ...:     m = M.copy()
     ...:     for row_index in range (m.rows):
     ...:         for col_index in range (row_index + 1, m.cols):
     ...:             m[row_index, col_index] = 0
     ...:     return (m)
     ...: 

In [102]: tril(M)
Out[102]: 
⎡a  0  0⎤
⎢       ⎥
⎢d  e  0⎥
⎢       ⎥
⎣g  h  i⎦

作为一般规则,混合 sympynumpy 会导致混乱,甚至错误。 numpy 最适合数字工作。它可以处理诸如符号之类的非数字对象,但数学运算却是偶然的。

np.tri... 函数基于 np.tri 函数构建:

In [114]: np.tri(3).astype(int)
Out[114]: 
array([[1, 0, 0],
       [1, 1, 0],
       [1, 1, 1]])

我们可以由此创建一个符号矩阵:

In [115]: m1 = Matrix(np.tri(3).astype(int))

In [116]: m1
Out[116]: 
⎡1  0  0⎤
⎢       ⎥
⎢1  1  0⎥
⎢       ⎥
⎣1  1  1⎦

并进行逐元素乘法:

In [117]: M.multiply_elementwise(m1)
Out[117]: 
⎡a  0  0⎤
⎢       ⎥
⎢d  e  0⎥
⎢       ⎥
⎣g  h  i⎦

np.tri 的工作原理是将列数组与行进行比较:

In [123]: np.arange(3)[:,None]>=np.arange(3)
Out[123]: 
array([[ True, False, False],
       [ True,  True, False],
       [ True,  True,  True]])

In [124]: _.astype(int)
Out[124]: 
array([[1, 0, 0],
       [1, 1, 0],
       [1, 1, 1]])

另一个答案建议 lower_triangle。查看它的代码很有趣:

    def entry(i, j):
        return self[i, j] if i + k >= j else self.zero

    return self._new(self.rows, self.cols, entry)

它对每个元素应用 i>=j 测试。 _new 必须迭代行和列。

In [99]: M
Out[99]: 
⎡a  b  c⎤
⎢       ⎥
⎢d  e  f⎥
⎢       ⎥
⎣g  h  i⎦

The other answer suggest using the np.tril function:

In [100]: np.tril(M)
Out[100]: 
array([[a, 0, 0],
       [d, e, 0],
       [g, h, i]], dtype=object)

That converts M into a numpy array - object dtype because of the symbols. And the result is also a numpy array.

Your function returns a sympy.Matrix.

In [101]: def tril (M):
     ...:     m = M.copy()
     ...:     for row_index in range (m.rows):
     ...:         for col_index in range (row_index + 1, m.cols):
     ...:             m[row_index, col_index] = 0
     ...:     return (m)
     ...: 

In [102]: tril(M)
Out[102]: 
⎡a  0  0⎤
⎢       ⎥
⎢d  e  0⎥
⎢       ⎥
⎣g  h  i⎦

As a general rule mixing sympy and numpy leads to confusion, if not errors. numpy is best for numeric work. It can handle non-numeric objects like symbols, but the math is hit-or-miss.

The np.tri... functions are built on the np.tri function:

In [114]: np.tri(3).astype(int)
Out[114]: 
array([[1, 0, 0],
       [1, 1, 0],
       [1, 1, 1]])

We can make a symbolic Matrix from this:

In [115]: m1 = Matrix(np.tri(3).astype(int))

In [116]: m1
Out[116]: 
⎡1  0  0⎤
⎢       ⎥
⎢1  1  0⎥
⎢       ⎥
⎣1  1  1⎦

and do element-wise multiplication:

In [117]: M.multiply_elementwise(m1)
Out[117]: 
⎡a  0  0⎤
⎢       ⎥
⎢d  e  0⎥
⎢       ⎥
⎣g  h  i⎦

np.tri works by comparing a column array with a row:

In [123]: np.arange(3)[:,None]>=np.arange(3)
Out[123]: 
array([[ True, False, False],
       [ True,  True, False],
       [ True,  True,  True]])

In [124]: _.astype(int)
Out[124]: 
array([[1, 0, 0],
       [1, 1, 0],
       [1, 1, 1]])

Another answer suggests lower_triangular. It's interesting to look at its code:

    def entry(i, j):
        return self[i, j] if i + k >= j else self.zero

    return self._new(self.rows, self.cols, entry)

It applies an i>=j test to each element. _new must be iterating on the rows and columns.

呢古 2025-01-24 23:10:05

您可以简单地使用 numpy 函数:

import numpy as np    
np.tril(M)

*当然,如下所述,您应该转换回 sympy.Matrix(np.tril(M)) 。但这取决于你接下来要做什么。

You can simply use numpy function:

import numpy as np    
np.tril(M)

*of course, as noted below, you should convert back to sympy.Matrix(np.tril(M)). But it depends on what you're going to do next.

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