Search code examples
pythonnumpymatrixscipyalgebra

How to find linearly independent vectors belonging to the null space of a non-square matrix? (Python)


I have a non-square matrix, and a method to determine the null space of the matrix (found from this thread: How to find the Null Space of a matrix in Python using numpy? ), but I have a few problems with taking this solution.

For one, I'm not sure if the values I have are correct, since I'm not too sure what I'm looking for.

Secondly, I need to find two linearly independent vectors from this null space, but I do not know the next step from here to determine this.

Finally, I need to determine whether any of the columns of the matrix are linearly independent in R3 and R4.

Any help would be greatly appreciated.

Code:

import numpy as np
import scipy as sp
from scipy import linalg

a = np.matrix(
[
    [ 3,  2, -1,  4],
    [ 1,  0,  2,  3],
    [-2, -2,  3, -1]
])


def null(A, eps=1e-15):
    u, s, vh = linalg.svd(A)
    null_mask = (s <= eps)
    null_space = sp.compress(null_mask, vh, axis=0)
    return sp.transpose(null_space)

print(null(a))

Output:

 [[ 0.8290113 ]
 [-0.2330726 ]
 [ 0.24969281]
 [-0.44279897]]

I'm assuming since the output is anything other than an empty matrix [] that there's something special about this matrix, I just don't know what it means.


Solution

  • I would recommend using sympy in this case:

    from sympy import Matrix
    a  = Matrix([
        [ 3,  2, -1,  4],
        [ 1,  0,  2,  3],
        [-2, -2,  3, -1]
    ])
    print(a.nullspace())
    

    Output:

    [Matrix([
    [ -2],
    [7/2],
    [  1],
    [  0]]),
    Matrix([
    [ -3],
    [5/2],
    [  0],
    [  1]])]
    

    You can easily check that the result indeed belongs to the nullspace by explicitly checking that it is mapped to 0 when multiplying with your matrix a:

    n1, n2 = a.nullspace()
    print(a*n1, a*n2) 
    

    results in:

    Matrix([[0], [0], [0]]) Matrix([[0], [0], [0]])
    

    Finally, to get the linearly independent columns of your matrix in R3 you can use the function columnspace, which returns a list of column vectors that span the columnspace of the matrix

    print(a.columnspace())
    

    results in

    [Matrix([
    [ 3],
    [ 1],
    [-2]]), Matrix([
    [ 2],
    [ 0],
    [-2]])]
    

    which are the first two columns of the matrix.