numpy Python中QR分解去除潜在秩亏矩阵的线性无关行的困惑

3phpmpom  于 12个月前  发布在  Python
关注(0)|答案(1)|浏览(146)

我正在尝试编写一个函数,该函数将方形或非方形矩阵作为输入,并返回行的子集,以便返回的矩阵是满秩的。我还需要跟踪哪些线性相关行被删除。尽管我的示例很简单,但矩阵并不总是二进制值。
似乎有很多关于这个主题的线程(例如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分解的某种基本限制,我还能怎么解决这个问题呢?
谢谢你,谢谢

pod7payv

pod7payv1#

实际上,这可能取决于硬件。
所以,在我的情况下,

Qme,Rme=np.linalg.qr([[1,1,1],[1,1,0],[1,1,0]])

个字符
这是一个正确的Q/R分解,因为Q是正交的

[email protected]
array([[ 1.00000000e+00,  7.91376881e-18, -1.76949056e-17],
       [ 7.91376881e-18,  1.00000000e+00,  2.98200950e-18],
       [-1.76949056e-17,  2.98200950e-18,  1.00000000e+00]])


基本上是恒等的。所以Q是正交的。
R是三角形。

Qme@Rme =
array([[ 1.00000000e+00,  1.00000000e+00,  1.00000000e+00],
       [ 1.00000000e+00,  1.00000000e+00,  7.91376881e-18],
       [ 1.00000000e+00,  1.00000000e+00, -1.76949056e-17]])


基本上是原始的矩阵。
但是你的Q/R也是正确的(有更大的错误,但这可能是因为复制和粘贴numpy的输出,它被截断了)

Qyou = 
array([[-5.77350269e-01,  8.16496581e-01, -2.21595527e-16],
       [-5.77350269e-01, -4.08248290e-01, -7.07106781e-01],
       [-5.77350269e-01, -4.08248290e-01,  7.07106781e-01]])

Ryou = 
array([[-1.73205081e+00, -1.73205081e+00, -5.77350269e-01],
       [ 0.00000000e+00, -3.13297402e-17,  8.16496581e-01],
       [ 0.00000000e+00,  0.00000000e+00, -1.69038416e-16]])


同样

[email protected] =
array([[ 1.00000000e+00,  1.30276010e-10,  1.30275697e-10],
       [ 1.30276010e-10,  9.99999999e-01, -3.33885539e-10],
       [ 1.30275697e-10, -3.33885539e-10,  9.99999999e-01]])


接近身份(再次,1 e-10而不是1 e-17是因为论坛中的复制和粘贴)
Q也是正交的
你的R也是三角形,

Qyou@Ryou =
array([[1.00000000e+00, 1.00000000e+00, 1.00000000e+00],
       [1.00000000e+00, 1.00000000e+00, 1.30275973e-10],
       [1.00000000e+00, 1.00000000e+00, 1.30275734e-10]])


所以两者都是同一矩阵的正确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的对角线上的非零元素的数量不是秩。

相关问题