Processing math: 73%

First time here? Check out the FAQ!

Ask Your Question
1

Finding minimal linearly dependent vectors

asked 2 years ago

kevinfat gravatar image

updated 2 years ago

I have a matrix whose rows are linearly dependent. Showing that with sage is straightforward. Is there a reasonably fast algorithm to find a smallest set of rows that form such a linear dependence and would it be simple to implement in sage?

Preview: (hide)

Comments

Over what field is the matrix?

Max Alekseyev gravatar imageMax Alekseyev ( 2 years ago )

These are vectors of real numbers.

kevinfat gravatar imagekevinfat ( 2 years ago )

1 Answer

Sort by » oldest newest most voted
0

answered 2 years ago

Max Alekseyev gravatar image

updated 2 years ago

Let's consider the matrix over Q (a real matrix can be approximated by a rational one). By scaling it by an integer factor, the matrix can be assumed to be over Z, where the corresponding problem is known to be NP-complete. So our best shot would be using Integer Linear Programming.

Let's introduce integer coefficients ci in the linear combination of the rows of a given matrix M giving a zero vector. We want the smallest number but at least one of ci be nonzero. We will need indicator 01-variables pi and ni telling if ci is positive or negative, and assume that ci come from some range (C,C), where C is a large constant of our choice. Then the problem can be formulated as the following MILP:

{ipi+nimin where i,j range over indices of rows and columns of M, respectively.

Here is a sample code:

C = 10000

M = random_matrix(ZZ,10,5)
print(f'Matrix:\n{M}\n')

my_ilp = MixedIntegerLinearProgram(maximization=False)
c = my_ilp.new_variable(integer=True)
p = my_ilp.new_variable(binary=True)
n = my_ilp.new_variable(binary=True)

obj = sum(p[i]+n[i] for i in range(M.nrows()))
my_ilp.set_objective( obj )
my_ilp.add_constraint( obj >= 1 )

for j in range(M.ncols()):
    my_ilp.add_constraint( sum( c[i]*M[i,j] for i in range(M.nrows()) ) == 0 )

for i in range(M.nrows()):
    my_ilp.add_constraint( c[i] <= C*p[i]  )
    my_ilp.add_constraint( c[i] >= -(1-p[i])*C + 1  )
    my_ilp.add_constraint( c[i] >= -C*n[i]  )
    my_ilp.add_constraint( c[i] <= (1-n[i])*C - 1  )
    my_ilp.add_constraint( p[i]+n[i] <= 1 )

my_ilp.solve()
C = my_ilp.get_values(c)
e = vector( C[i] for i in range(M.nrows()) )
assert e * M == 0
print( 'Coefficients of minimal linear combination:', e)
print( 'Indices of linearly dependent rows of M:', [i for i in range(M.nrows()) if e[i]])

and a typical output:

Matrix:
[   5   -9   -1   -3  -10]
[   0   -5   -1    0   -3]
[   0    0   -2   -1   -1]
[   1   -1   -1   -1   -4]
[ -17   11    1    0    3]
[   4    0    0 -206    0]
[   1    4    6   11    3]
[   3    0   -1    2    2]
[   0   -8   -1    3   -2]
[  -4   -5   -1    1    1]

Coefficients of minimal linear combination: (1620.0, -9145.0, 0.0, 2435.0, 0.0, 0.0, -95.0, 0.0, 1910.0, 2610.0)
Indices of linearly dependent rows of M: [0, 1, 3, 6, 8, 9]
Preview: (hide)
link

Comments

Yah I was worried this might fall into the NP-complete issue.

kevinfat gravatar imagekevinfat ( 2 years ago )

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2 years ago

Seen: 638 times

Last updated: Oct 01 '22