\HeaderA{rankMatrix}{Rank of a Matrix}{rankMatrix}
\keyword{algebra}{rankMatrix}
\keyword{array}{rankMatrix}
\begin{Description}\relax
Compute the rank of matrix, a well-defined functional in theory,
somewhat ambigous in practice.  We provide several methods, the
default corresponding to Matlab's definition.
\end{Description}
\begin{Usage}
\begin{verbatim}
rankMatrix(x, tol = NULL,
           method = c("tolNorm2", "qrLINPACK", "useGrad", "maybeGrad"),
           sval = svd(x, 0, 0)$d)
\end{verbatim}
\end{Usage}
\begin{Arguments}
\begin{ldescription}
\item[\code{x}] numeric matrix, of dimension \eqn{n \times m}{}, say.
\item[\code{tol}] nonnegative number specifying a tolerance for
\dQuote{practically zero} with specific meaning depending on
\code{method}; by default, \code{max(dim(x)) *
      \LinkA{.Machine}{.Machine}\$double.eps * abs(max(sval))} is according to
Matlab's default (for its only \code{method} "tolNorm2").
\item[\code{method}] a character string specifying the computational method,
can be abbreviated:
\describe{
\item[tolNorm2] the number of singular values \code{>= tol};
\item[qrLINPACK] = \code{\LinkA{qr}{qr}(x, tol, LAPACK=FALSE)\$rank};
this used to be \emph{the} recommended way to compute a matrix
rank for a while in the past.  For this method, \code{sval} are
not used (nor computed).
\item[useGrad] considering the \dQuote{gradient} of the
(decreasing) singular values, the index of the \emph{smallest} gap.
\item[maybeGrad] choosing method \code{"useGrad"} only when that
seems \emph{reasonable}; otherwise using \code{"tolNorm2"}.
}

\item[\code{sval}] numeric vector of non-increasing singular values of
\code{x}; typically unspecified and computed from \code{x}.
\end{ldescription}
\end{Arguments}
\begin{Value}
positive integer in \code{1:min(dim(x))}, with attributes detailing
the method used.
\end{Value}
\begin{Author}\relax
Martin Maechler; for the "*Grad" methods, building on
suggestions by Ravi Varadhan.
\end{Author}
\begin{SeeAlso}\relax
\code{\LinkA{qr}{qr}}, \code{\LinkA{svd}{svd}}.
\end{SeeAlso}
\begin{Examples}
\begin{ExampleCode}
rankMatrix(cbind(1, 0, 1:3)) # 2

(meths <- eval(formals(rankMatrix)$method))

## a "border" case:
H12 <- Hilbert(12)
rankMatrix(H12, tol = 1e-20) # 12;  but  11  with default method & tol.
sapply(meths, function(.m.) rankMatrix(H12, method = .m.))
## tolNorm2 qrLINPACK   useGrad maybeGrad
##       11        12        11        11
\end{ExampleCode}
\end{Examples}

