2

How to solve a homogenous system Ax = 0, when A is any m * n matrix (not necessarily a square one) in R?

# A=[-0.1 0.1]= 1x2 matrix; x=2x1 to be found; 0: 1x1 zero matrix
A <- t(matrix(c(-0.1,0.1))) 

This question seems to be equivalent of finding the kernel (null space) of an Rn -> Rm (can't do superscript; sorry) linear transformation.

Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248
Erdogan CEVHER
  • 1,788
  • 1
  • 21
  • 40

1 Answers1

7

Anyway, the solution for the above specific matrix A will suffice to me.

We can eye-spot it, x = (a, a), where a is an arbitrary value.


A classic / text-book solution

The following function NullSpace finds the null space of A using the above theory. In case 1, the null space is trivially zero; while in cases 2 to 4 a matrix is returned whose columns span the null space.

NullSpace <- function (A) {
  m <- dim(A)[1]; n <- dim(A)[2]
  ## QR factorization and rank detection
  QR <- base::qr.default(A)
  r <- QR$rank
  ## cases 2 to 4
  if ((r < min(m, n)) || (m < n)) {
    R <- QR$qr[1:r, , drop = FALSE]
    P <- QR$pivot
    F <- R[, (r + 1):n, drop = FALSE]
    I <- base::diag(1, n - r)
    B <- -1.0 * base::backsolve(R, F, r)
    Y <- base::rbind(B, I)
    X <- Y[base::order(P), , drop = FALSE]
    return(X)
    }
  ## case 1
  return(base::matrix(0, n, 1))
  }

With your example matrix, it correctly returns the null space.

A1 <- matrix(c(-0.1, 0.1), 1, 2)
NullSpace(A1)
#     [,1]
#[1,]    1
#[2,]    1

We can also try a random example.

set.seed(0)
A2 <- matrix(runif(10), 2, 5)
#          [,1]      [,2]      [,3]      [,4]      [,5]
#[1,] 0.8966972 0.3721239 0.9082078 0.8983897 0.6607978
#[2,] 0.2655087 0.5728534 0.2016819 0.9446753 0.6291140

X <- NullSpace(A2)
#           [,1]      [,2]       [,3]
#[1,] -1.0731435 -0.393154 -0.3481344
#[2,]  0.1453199 -1.466849 -0.9368564
#[3,]  1.0000000  0.000000  0.0000000
#[4,]  0.0000000  1.000000  0.0000000
#[5,]  0.0000000  0.000000  1.0000000

## X indeed solves A2 %*% X = 0
A2 %*% X
#             [,1]          [,2]          [,3]
#[1,] 2.220446e-16 -1.110223e-16 -2.220446e-16
#[2,] 5.551115e-17 -1.110223e-16 -1.110223e-16

Finding orthonormal basis

My function NullSpace returns an non-orthogonal basis for the null space. An alternative is to apply QR factorization to t(A) (transpose of A), get the rank r, and retain the final (n - r) columns of the Q matrix. This gives an orthonormal basis for the null space.

The nullspace function from pracma package is an existing implementation. Let's take matrix A2 above for a demonstration.

library(pracma)
X2 <- nullspace(A2)
#            [,1]        [,2]       [,3]
#[1,] -0.67453687 -0.24622524 -0.2182437
#[2,]  0.27206765 -0.69479881 -0.4260258
#[3,]  0.67857488  0.07429112  0.0200459
#[4,] -0.07098962  0.62990141 -0.2457700
#[5,] -0.07399872 -0.23309397  0.8426547

## it indeed solves A2 %*% X = 0
A2 %*% X2
#             [,1]          [,2]          [,3]
#[1,] 2.567391e-16  1.942890e-16  0.000000e+00
#[2,] 6.938894e-17 -5.551115e-17 -1.110223e-16

## it has orthonormal columns
round(crossprod(X2), 15)
#     [,1] [,2] [,3]
#[1,]    1    0    0
#[2,]    0    1    0
#[3,]    0    0    1

Appendix: Markdown (needs MathJax support) for the pictures

Let $A$ be $m \times n$, then its null space is $\{x: Ax = 0\}$. To find a solution of $Ax = 0$, the conventional method is Gaussian elimination that reduces $A$ into a row echelon form. However, let's consider the QR factorization (with column pivoting) approach, where a sequence of Householder transforms are applied to both sides of $Ax = 0$, reducing the equation to $RP'x = 0$, where $P$ is an $n \times n$ column permutation matrix. What $R$ looks like depends on the relationship of $m$ and $n$, as well as the rank of $A$, denoted by $r$.

 1. If $m \ge n = r$, $R$ is an $n \times n$ full-rank upper triangular matrix, which looks like $$\begin{pmatrix} \times & \times & \times & \times \\ & \times & \times & \times \\ & & \times & \times \\ & & & \times\end{pmatrix}$$
 2. If $m \ge n > r$, $R$ is an $n \times n$ rank-deficient upper triangular matrix, which looks like $$\begin{pmatrix} \times & \times & \times & \times \\ & \times & \times & \times \\ & & \times & \times \\ & & & 0\end{pmatrix}$$
 3. If $r = m < n$, $R$ is an $m \times n$ full-rank matrix which looks like $$\begin{pmatrix} \times & \times & \times & \times & \times & \times & \times \\ & \times & \times & \times & \times & \times & \times\\ & & \times & \times & \times & \times & \times\\ & & & \times & \times & \times & \times\end{pmatrix}$$
 4. If $r < m < n$, $R$ is an $m \times n$ rank-deficient matrix which looks like $$\begin{pmatrix} \times & \times & \times & \times & \times & \times & \times \\ & \times & \times & \times & \times & \times & \times\\ & & \times & \times & \times & \times & \times\\ & & & 0 & 0 & 0 & 0\end{pmatrix}$$.

In all cases, the first $r$ non-zero rows of $R$ can be partiontioned into $\begin{pmatrix} U & F\end{pmatrix}$, where $U$ is an $r \times r$ full-rank upper triangular matrix and $F$ is an $r \times (n - r)$ rectangular matrix. The null space of $A$ has dimension $(n - r)$ and can be characterized by an $ n \times (n - r)$ matrix $X$, such that $RP'X = 0$. In practice, $X$ is obtained in two steps.

 1. Let $Y$ be an $ n \times (n - r)$ matrix and solve $RY = 0$. Clearly $Y$ can not be uniquely determined as the linear system has $(n - r)$ free parameters. A common solution is to find $Y = \left(\begin{smallmatrix} B \\ I \end{smallmatrix}\right)$, where $I$ is an $(n - r) \times (n - r)$ identity matrix. Then $B$ can be uniquely solved from $UB = -F$ using back substitution.
 2. Solve $P'X = Y$ for $X = PY$, which is simply a row permutation of $Y$.
Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248
  • QR factorization with column pivoting is better than Gaussian elimination with row pivoting or LU factorization with row pivoting. Taking the example matrix `A1` in [this question](https://stackoverflow.com/q/52334647/4891738), LU factorization (`Matrix::lu`) fails as the second pivot would be 0. Gaussian elimination (`pracma::rref`) can proceed to reduce the matrix into reduced row echelon form, but the pivot columns are not the first two columns but the 1st and the 3rd column. The column pivoting in QR approach ensures that pivot columns are the first 2 columns. – Zheyuan Li Oct 03 '18 at 21:22