我正在尝试编写一个函数,该函数将方形或非方形矩阵作为输入,并返回行的子集,以便返回的矩阵是满秩的。我还需要跟踪哪些线性相关行被删除。尽管我的示例很简单,但矩阵并不总是二进制值。
似乎有很多关于这个主题的线程(例如How to find linearly independent rows from a matrix),这让我尝试了QR分解方法:
def reduce_to_full_rank(A):
Q, R = np.linalg.qr(A)
to_keep = (np.abs(np.diag(R)) > 1e-10)
return A[to_keep]
字符串
我不明白的是,为什么这种方法似乎取决于A中的行的顺序。
例如,给定输入:
A = np.array(
[
[1,1,0],
[1,1,0],
[1,1,1],
]
)
型
下面的代码打印秩为2,这是有意义的,因为[1,1,0]和[1,1,1]是独立的。
Q, R = np.linalg.qr(A)
rank = (np.abs(np.diag(R)) > 1e-10).sum()
print(rank)
型
但是,如果我把A的顺序改为:
A = np.array(
[
[1,1,1],
[1,1,0],
[1,1,0],
]
)
型
同样的代码会输出秩为1的结果,因为R的对角线上只有一个非零元素。
有没有人可以帮助我理解:
1.为什么R中非零对角元素的数量取决于A中行的顺序?
1.如果这是QR分解的某种基本限制,我还能怎么解决这个问题呢?
谢谢你,谢谢
1条答案
按热度按时间pod7payv1#
实际上,这可能取决于硬件。
所以,在我的情况下,
个字符
这是一个正确的Q/R分解,因为Q是正交的
型
基本上是恒等的。所以Q是正交的。
R是三角形。
和
型
基本上是原始的矩阵。
但是你的Q/R也是正确的(有更大的错误,但这可能是因为复制和粘贴numpy的输出,它被截断了)
型
同样
型
接近身份(再次,1 e-10而不是1 e-17是因为论坛中的复制和粘贴)
Q也是正交的
你的R也是三角形,
型
所以两者都是同一矩阵的正确QR分解。毫无疑问。这是数学,而不是numpy(即使我用numpy验证了这一点,但至少,这是相同的numpy,它说两者都是好的。另外,我确信任何其他线性代数,甚至只是纸和笔都会说同样的话)
因此,如果同一矩阵的两个正确的QR分解在对角线上的0元素的数量不相同,这意味着我一开始忽略的假设(假设是真的,没有考虑太多,因为它来自math. stackexchange.)是假的。这不是一个 numpy 问题。只是,如果相同秩矩阵(甚至是相同矩阵)的2个正确QR分解在对角线上的0元素的个数不相同,则证明对角线上的0元素的个数不是一个准则。
如果你仔细想想,这是很合乎逻辑的。
你所知道的是Q是由独立的行和列组成的(至少在正方形的情况下是这样),而R列是如何将Q列合并组合成A=QR列。
所以,在我的例子中,A的第一列只是(对于乘法因子)Q的第一列。
A的第二列是相同的,因为Q的第二列和第一列是相同的。对于我们的两个分解。对角线元素中的0确实证明了我们不会使用“新”向量来创建A的第二列;只有我们已经为第一列使用的向量。因此,秩下降了-1。在我们的两个例子中。
场景不同之处(以及考虑解释变得重要的地方)是第三列。
在我的例子中,R的第3列有3个非零值(因此对角线元素上的非0,但这并不重要)。所以,这意味着我将使用A“新”向量的第3列,这是我第一次有一个非--第二和第三行为零。所以第一次我将合并的第二和第三列Q。所以,这是一个新的维度。没有秩减少。
在你的例子中,R的第三列只有两个非零值。对角元素是0。但这并不重要。重要的是,第二行第一次是非零的。你用Q的第二列来创建A的第三列,这是第一次。你还没有对前两列这样做。所以,这也是一个新的维度。所以,尽管对角线上的值为0,但等级没有降低。
因此,重要的不是对角线值是否为非0,而是新的一行是否为非0,在之前所有列中为0的一行是否为非0。
在满秩的情况下,确实是在对角线值上,但在非满秩的情况下,“新的非0”可能在对角线上,或者可能更高。
因此,对角线唯一相关的情况是证明矩阵是否满秩。如果R的对角线上有0,则矩阵不是满秩的。否则它是满秩的。
所以,简短的回答:R的对角线上的非零元素的数量不是秩。