Как найти линейно независимые строки из матрицы

Как определить линейно независимые строки из матрицы? Например,

enter image description here

4 строки независимы.

Ответы

Ответ 1

Во-первых, ваша 3-я строка линейно зависит от 1t и 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,:]

Неравенство Коши-Шварца

Чтобы проверить линейную зависимость векторов и выяснить, какие из них можно использовать неравенство Коши-Шварца. В принципе, если скалярное произведение векторов равно произведению нормы векторов, то векторы линейно зависимы. Вот пример для столбцов:

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'

Для проверки строк используется аналогичный подход.

Затем вы можете расширить это, чтобы проверить все комбинации векторов, но я думаю, что это решение сильно ухудшает размер.

Ответ 2

С вы можете найти линейные независимые строки, используя: 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]])

Это также хорошо работает для прямоугольных (не только квадратичных) матриц.

Ответ 3

Я отредактировал код неравенства Коши-Шварца, который лучше масштабируется с измерением: входные данные - это матрица и ее размерность, а выходные данные - это новая прямоугольная матрица, которая содержит вдоль своих строк линейно независимые столбцы исходной матрицы. Это работает в предположении, что первый столбец никогда не равен нулю, но может быть легко обобщен для реализации этого случая. Еще одна вещь, которую я заметил, заключается в том, что 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

Ответ 4

Я знаю, что это было задано некоторое время назад, но вот очень простое решение. Для данного массива следующее находит набор линейно независимых векторов путем постепенного добавления вектора и проверки увеличения ранга:

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)

Ответ 5

Я интерпретирую проблему как нахождение строк, которые линейно независимы от других строк. Это эквивалентно нахождению строк, которые линейно зависят от других строк.

Исключение по Гауссу и обработка чисел, меньших порога, поскольку нули могут сделать это. Это быстрее, чем поиск собственных значений матрицы, проверка всех комбинаций строк с неравенством Коши-Шварца или разложение по сингулярным числам.

См.: https://math.stackexchange.com/info/1297437/using-gauss-elidity-to-check-for-linear-dependence

Проблема с числами с плавающей запятой:

http://numpy-discussion.10968.n7.nabble.com/Reduced-row-echelon-form-td16486.html