numpy 如何从矩阵中查找线性无关的行

5m1hhzi4  于 2023-03-18  发布在  其他
关注(0)|答案(8)|浏览(298)

如何识别矩阵中线性无关的行?例如,

第4行是独立的。

1yjd4xko

1yjd4xko1#

首先,第3行与第1行和第2行呈线性相关,而第1列和第4列也呈线性相关。
您可以使用两种方法:

特征值

如果矩阵的一个特征值为零,则其对应的特征向量线性相关。eig文档指出,返回的特征值根据其多重性重复,并且不一定按顺序排列。但是,假设特征值与行向量对应,一种方法是:

import numpy as np

matrix = np.array(
    [
        [0, 1 ,0 ,0],
        [0, 0, 1, 0],
        [0, 1, 1, 0],
        [1, 0, 0, 1]
    ])

lambdas, V =  np.linalg.eig(matrix.T)
# The linearly dependent row vectors 
print matrix[lambdas == 0,:]

柯西-施瓦兹不等式

要测试向量的线性相关性并找出哪些向量是线性相关的,可以使用Cauchy-Schwarz inequality。基本上,如果向量的内积等于向量范数的乘积,则向量是线性相关的。以下是列的示例:

import numpy as np

matrix = np.array(
    [
        [0, 1 ,0 ,0],
        [0, 0, 1, 0],
        [0, 1, 1, 0],
        [1, 0, 0, 1]
    ])

print np.linalg.det(matrix)

for i in range(matrix.shape[0]):
    for j in range(matrix.shape[0]):
        if i != j:
            inner_product = np.inner(
                matrix[:,i],
                matrix[:,j]
            )
            norm_i = np.linalg.norm(matrix[:,i])
            norm_j = np.linalg.norm(matrix[:,j])

            print 'I: ', matrix[:,i]
            print 'J: ', matrix[:,j]
            print 'Prod: ', inner_product
            print 'Norm i: ', norm_i
            print 'Norm j: ', norm_j
            if np.abs(inner_product - norm_j * norm_i) < 1E-5:
                print 'Dependent'
            else:
                print 'Independent'

测试行的方法与此类似。
然后你可以扩展它来测试向量的所有组合,但是我想这个解决方案的规模很大。

093gszye

093gszye2#

对于sympy,您可以使用以下公式查找线性独立行:sympy.Matrix.rref

>>> import sympy 
>>> import numpy as np
>>> mat = np.array([[0,1,0,0],[0,0,1,0],[0,1,1,0],[1,0,0,1]])  # your matrix
>>> _, inds = sympy.Matrix(mat).T.rref()   # to check the rows you need to transpose!
>>> inds
[0, 1, 3]

这基本上说明第0、1和3行是线性独立的,而第2行不是(它是第0和1行的线性组合)。
然后,您可以使用切片删除这些行:

>>> mat[inds]
array([[0, 1, 0, 0],
       [0, 0, 1, 0],
       [1, 0, 0, 1]])

这对于矩形矩阵(不仅仅是二次矩阵)也很有效。

u0njafvf

u0njafvf3#

我编辑了柯西-施瓦茨不等式的代码,它可以更好地随维度变化:输入是矩阵及其维数,而输出是一个新的矩形矩阵,该矩阵的行沿着包含初始矩阵的线性独立列。这在第一列从不为空的假设下有效,但也可以容易地推广以实现这种情况。我观察到的另一件事是1 e-5似乎是一个“草率”阈值,因为在这种情况下发现一些特定的病理向量是线性相关的:1 e-4没有给我带来同样的问题。我希望这能有所帮助:我很难找到一个真正有效的程序来提取li向量,所以我愿意分享我的。如果你发现了一些bug,请报告他们!!

from numpy import dot, zeros
from numpy.linalg import matrix_rank, norm

def find_li_vectors(dim, R):

    r = matrix_rank(R) 
    index = zeros( r ) #this will save the positions of the li columns in the matrix
    counter = 0
    index[0] = 0 #without loss of generality we pick the first column as linearly independent
    j = 0 #therefore the second index is simply 0

    for i in range(R.shape[0]): #loop over the columns
        if i != j: #if the two columns are not the same
            inner_product = dot( R[:,i], R[:,j] ) #compute the scalar product
            norm_i = norm(R[:,i]) #compute norms
            norm_j = norm(R[:,j])

            #inner product and the product of the norms are equal only if the two vectors are parallel
            #therefore we are looking for the ones which exhibit a difference which is bigger than a threshold
            if absolute(inner_product - norm_j * norm_i) > 1e-4:
                counter += 1 #counter is incremented
                index[counter] = i #index is saved
                j = i #j is refreshed
            #do not forget to refresh j: otherwise you would compute only the vectors li with the first column!!

    R_independent = zeros((r, dim))

    i = 0
    #now save everything in a new matrix
    while( i < r ):
        R_independent[i,:] = R[index[i],:] 
        i += 1

    return R_independent
flvlnr44

flvlnr444#

我知道不久前有人问过这个问题,但这里有一个非常简单(虽然可能效率不高)的解决方案,给定一个数组,下面的方法通过逐步增加一个向量并测试秩是否增加来找到一组线性无关的向量:

from numpy.linalg import matrix_rank

def LI_vecs(dim,M):
    LI=[M[0]]
    for i in range(dim):
        tmp=[]
        for r in LI:
            tmp.append(r)
        tmp.append(M[i])                #set tmp=LI+[M[i]]
        if matrix_rank(tmp)>len(LI):    #test if M[i] is linearly independent from all (row) vectors in LI
            LI.append(M[i])             #note that matrix_rank does not need to take in a square matrix
    return LI                           #return set of linearly independent (row) vectors

#Example
mat=[[1,2,3,4],[4,5,6,7],[5,7,9,11],[2,4,6,8]]
LI_vecs(4,mat)
qni6mghb

qni6mghb5#

我把这个问题解释为寻找与其他行线性无关的行,这相当于寻找与其他行线性相关的行。
高斯消去法并将小于阈值的数字视为零就可以实现这一点。它比查找矩阵的特征值、使用柯西-施瓦茨不等式测试行的所有组合或奇异值分解更快。
参见:https://math.stackexchange.com/questions/1297437/using-gauss-elimination-to-check-for-linear-dependence
浮点数问题:
http://numpy-discussion.10968.n7.nabble.com/Reduced-row-echelon-form-td16486.html

tjjdgumg

tjjdgumg6#

关于以下讨论:
Find dependent rows/columns of a matrix using Matlab?

from sympy import *
A = Matrix([[1,1,1],[2,2,2],[1,7,5]])
print(A.nullspace())

很明显,第一行和第二行是彼此相乘的。如果我们执行上面的代码,我们会得到[-1/3, -2/3, 1]。零元素在零空间中的索引显示了独立性。但是为什么这里的第三个元素不是零?如果我们将A矩阵乘以零空间,我们会得到零列向量。那么,出了什么问题?
我们要寻找的答案是A的转置的零空间。

B = A.T
print(B.nullspace())

现在我们得到了[-2, 1, 0],它表明第三行是独立的。
这里有两个重要注意事项:
1.考虑我们是要检查行依赖关系还是列依赖关系。
1.注意,矩阵的零空间不等于该矩阵转置的零空间,除非它是对称的。

jjhzyzn0

jjhzyzn07#

通过使用SymPy库的Matrix对象的columnspace()方法,基本上可以找到跨越矩阵列空间的向量,它们自动地成为矩阵的线性独立列。

import sympy as sp 
import numpy as np 

M  = sp.Matrix([[0, 1, 0, 0],
                [0, 0, 1, 0],
                [1, 0, 0, 1]])

for i in M.columnspace():
    print(np.array(i))
    print()

# The output is following.

# [[0]
#  [0]
#  [1]]

# [[1]
#  [0]
#  [0]]

# [[0]
#  [1]
#  [0]]
3okqufwl

3okqufwl8#

(可能)更短的解决方案:

def cartesian_product(vec1, vec2):
    return np.transpose(np.array([np.repeat(vec1, len(vec2)), np.tile(vec2, len(vec1))]))

def check_dependencies(matrix_):
    def rows_are_dependent(indices):
        if indices[0] == indices[1]:
            return False
        return np.unique(matrix_[indices[0],] / matrix_[indices[1],]).shape[0] == 1

    return np.any(np.apply_along_axis(rows_are_dependent, 1, cartesian_product(np.arange(matrix_.shape[0]), np.arange(matrix_.shape[0]))))

相关问题