# Confusing NullSpace Method behaviour

The background of this question is that I'm trying to get the bottom of when the output of NullSpace outputs a list of pairwise orthogonal vectors. On my route to answering this question, I came upon the following weirdness:

The documentation of NullSpace makes the claim (M10)

Possible settings for the Method option include "CofactorExpansion", "DivisionFreeRowReduction", and "OneStepRowReduction". The default setting of Automatic switches among these methods depending on the matrix given.

but the example which follows seems to demonstrate that this is at least partially false.

First, we make functions that output matrices with null spaces of specified dimensions, just by changing the basis of some trivial projectors:

randMat[dim_,dimNull_] := With[{A=RandomReal[{-1,1},{dim,dim}]}, A.DiagonalMatrix[Array[If[#>dimNull,1,0]&,dim]].Inverse[A]]
randIntMat[dim_,dimNull_] := With[{A=RandomInteger[{-1,1},{dim,dim}]}, A.DiagonalMatrix[Array[If[#>dimNull,1,0]&,dim]].Inverse[A]]


Next, we try NullSpace with all four method options, and output the pairwise dot product of the resulting null space vectors in each case:

MatrixForm /@ Chop /@ Module[{mat = randMat[5, 3]},
With[{null = NullSpace[mat, Method -> #]},
Outer[#1.#2 &, null, null, 1]] & /@ {"CofactorExpansion",
"DivisionFreeRowReduction", "OneStepRowReduction", Automatic}
]


In the case of the RandomReal random matrix version, we get answers like

$$\left\{\{\},\left( \begin{array}{ccc} 6.48185 & 1.67163 & 4.27561 \\ 1.67163 & 4.29849 & 0.35762 \\ 4.27561 & 0.35762 & 4.65582 \\ \end{array} \right),\left( \begin{array}{ccc} 6.48185 & 1.67163 & 4.27561 \\ 1.67163 & 4.29849 & 0.35762 \\ 4.27561 & 0.35762 & 4.65582 \\ \end{array} \right),\left( \begin{array}{ccc} 1. & 0 & 0 \\ 0 & 1. & 0 \\ 0 & 0 & 1. \\ \end{array} \right)\right\}$$

In the case of the RandomInteger random matrix, we get answers like

$$\left\{ \left( \begin{array}{ccc} 2 & 0 & -1 \\ 0 & 2 & -1 \\ -1 & -1 & 3 \\ \end{array} \right),\left( \begin{array}{ccc} 2 & 0 & -1 \\ 0 & 2 & -1 \\ -1 & -1 & 3 \\ \end{array} \right),\left( \begin{array}{ccc} 2 & 0 & -1 \\ 0 & 2 & -1 \\ -1 & -1 & 3 \\ \end{array} \right),\left( \begin{array}{ccc} 2 & 0 & -1 \\ 0 & 2 & -1 \\ -1 & -1 & 3 \\ \end{array} \right) \right\}$$

And if we call N on the integer matrix before invoking NullSpace, we get answers like

$$\left\{\{\},\left( \begin{array}{ccc} 1.55556 & 0.222222 & 0.444444 \\ 0.222222 & 1.88889 & -0.222222 \\ 0.444444 & -0.222222 & 1.55556 \\ \end{array} \right),\left( \begin{array}{ccc} 1.55556 & 0.222222 & 0.444444 \\ 0.222222 & 1.88889 & -0.222222 \\ 0.444444 & -0.222222 & 1.55556 \\ \end{array} \right),\left( \begin{array}{ccc} 1. & 0 & 0 \\ 0 & 1. & 0 \\ 0 & 0 & 1. \\ \end{array} \right)\right\}$$

So clearly in the _Real case, Automatic is doing something different than simply choosing one of the other three options. Most likely it is choosing one of the three and then orthonormalizing the result? Does anyone know what's actually going on here? Thanks!

• The documentation is really not correct for matrices of approximate numbers. In those cases Automatic will use a method based on SVD. This will give orthonormal vectors since the nulls come from vectors in an orthogonal matrix produced by SVD. – Daniel Lichtblau Jan 21 '15 at 20:27
• @DanielLichtblau That makes sense, I guess, based on how stable SVD algorithms are. Is this a guess on your part? – Ian Hincks Jan 21 '15 at 20:39
• No, not a guess. – Daniel Lichtblau Jan 21 '15 at 21:46