web-dev-qa-db-ja.com

行列から線形独立行を見つける方法

行列から線形独立行を識別する方法は?例えば、

enter image description here

4行目は独立しています。

18
SparkAndShine

まず、3行目は1tと2行目で線形従属です。ただし、1列目と4列目は線形従属です。

使用できる2つの方法:

固有値

行列の1つの固有値がゼロの場合、対応する固有ベクトルは線形従属です。ドキュメント 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不等式 を使用できます。基本的に、ベクトルの内積がベクトルのノルムの積に等しい場合、ベクトルは線形従属です。以下は列の例です。

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'

行をテストすることも同様のアプローチです。

次に、これを拡張してベクトルのすべての組み合わせをテストすることもできますが、このソリューションはサイズに応じてうまく拡張できないと思います。

23
hakanc

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]])

これは、(2次行列だけでなく)長方形行列にも有効です。

17
MSeifert

コーシーシュワルツの不等式のコードを編集しました。これは、次元に合わせてスケーリングします。入力は行列とその次元であり、出力は、行に沿って開始行列の線形独立列を含む新しい長方形行列です。これは、最初の列がnullになることはないという前提で機能しますが、この場合も実装するために簡単に一般化できます。私が観察したもう1つのことは、一部の特定の病理学的ベクトルがその場合線形依存であることが判明したため、1e-5は「だらしない」しきい値のように見えることです。1e-4では同じ問題が発生しません。私はこれがいくつかの助けになることを願っています:私がliベクトルを抽出するための本当に機能するルーチンを見つけるのはかなり困難でしたので、私は喜んで私と共有します。バグを発見したら、報告してください!!

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
7

私はこれが少し前に尋ねられたことを知っていますが、これは非常に簡単な解決策です。配列が与えられた場合、次の例では、ベクトルを徐々に追加し、ランクが増加したかどうかをテストすることにより、線形独立のベクトルのセットを見つけます。

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)
3
Couchy311

この問題を、他の行から線形的に独立している行を見つけると解釈します。これは、他の行に線形に依存する行を見つけることと同じです。

ガウス消去法を使用して、しきい値よりも小さい数値をゼロとして処理できるようにします。これは、行列の固有値を見つけ、コーシーシュワルツの不等式、または特異値分解を使用して行のすべての組み合わせをテストするよりも高速です。

参照: 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

1
R zu