#keep
import numpy as np
import numpy.linalg as la
#keep
n = 5
np.random.seed(25)
A = np.random.randn(n, n)
# Decrease the rank
A[4] = A[0] + 5 * A[2]
A[1] = 3 * A[0] -2 * A[3]
#keep
from m_echelon import m_echelon
#keep
M, U = m_echelon(A.T)
#keep
la.norm(
M.dot(A.T) - U)
#keep
U.round(3)
Now define NUT
as vectors spanning the nullspace of $N(U^T)$.
NUT = np.eye(n)[:, 3:]
NUT
Check that it's actually a nullspace:
U.T.dot(NUT)
Now define NA
as some vectors spanning $N(A)$:
NA = M.T.dot(NUT)
And check:
A.dot(NA)