Raw File
solve-methods.Rd
\name{solve-methods}
\title{Methods in Package \pkg{Matrix} for Function \code{solve}}
%
\docType{methods}
\keyword{algebra}
\keyword{array}
\keyword{methods}
%
\alias{solve}
\alias{solve-methods}
%
\alias{solve,ANY,ANY-method}
\alias{solve,BunchKaufman,missing-method}
\alias{solve,BunchKaufman,dgeMatrix-method}
\alias{solve,CHMfactor,missing-method}
\alias{solve,CHMfactor,dgeMatrix-method}
\alias{solve,CHMfactor,dgCMatrix-method}
\alias{solve,Cholesky,missing-method}
\alias{solve,Cholesky,dgeMatrix-method}
\alias{solve,CsparseMatrix,ANY-method}
\alias{solve,Matrix,sparseVector-method}
\alias{solve,MatrixFactorization,CsparseMatrix-method}
\alias{solve,MatrixFactorization,RsparseMatrix-method}
\alias{solve,MatrixFactorization,TsparseMatrix-method}
\alias{solve,MatrixFactorization,denseMatrix-method}
\alias{solve,MatrixFactorization,dgCMatrix-method}
\alias{solve,MatrixFactorization,dgeMatrix-method}
\alias{solve,MatrixFactorization,diagonalMatrix-method}
\alias{solve,MatrixFactorization,indMatrix-method}
\alias{solve,MatrixFactorization,matrix-method}
\alias{solve,MatrixFactorization,sparseVector-method}
\alias{solve,MatrixFactorization,vector-method}
\alias{solve,RsparseMatrix,ANY-method}
\alias{solve,Schur,ANY-method}
\alias{solve,TsparseMatrix,ANY-method}
\alias{solve,ddiMatrix,Matrix-method}
\alias{solve,ddiMatrix,matrix-method}
\alias{solve,ddiMatrix,missing-method}
\alias{solve,ddiMatrix,vector-method}
\alias{solve,denseLU,missing-method}
\alias{solve,denseLU,dgeMatrix-method}
\alias{solve,denseMatrix,ANY-method}
\alias{solve,dgCMatrix,denseMatrix-method}
\alias{solve,dgCMatrix,matrix-method}
\alias{solve,dgCMatrix,missing-method}
\alias{solve,dgCMatrix,sparseMatrix-method}
\alias{solve,dgCMatrix,vector-method}
\alias{solve,dgeMatrix,ANY-method}
\alias{solve,diagonalMatrix,ANY-method}
\alias{solve,dpoMatrix,ANY-method}
\alias{solve,dppMatrix,ANY-method}
\alias{solve,dsCMatrix,denseMatrix-method}
\alias{solve,dsCMatrix,matrix-method}
\alias{solve,dsCMatrix,missing-method}
\alias{solve,dsCMatrix,sparseMatrix-method}
\alias{solve,dsCMatrix,vector-method}
\alias{solve,dspMatrix,ANY-method}
\alias{solve,dsyMatrix,ANY-method}
\alias{solve,dtCMatrix,dgCMatrix-method}
\alias{solve,dtCMatrix,dgeMatrix-method}
\alias{solve,dtCMatrix,missing-method}
\alias{solve,dtCMatrix,triangularMatrix-method}
\alias{solve,dtpMatrix,dgeMatrix-method}
\alias{solve,dtpMatrix,missing-method}
\alias{solve,dtpMatrix,triangularMatrix-method}
\alias{solve,dtrMatrix,dgeMatrix-method}
\alias{solve,dtrMatrix,missing-method}
\alias{solve,dtrMatrix,triangularMatrix-method}
\alias{solve,indMatrix,ANY-method}
\alias{solve,matrix,Matrix-method}
\alias{solve,matrix,sparseVector-method}
\alias{solve,pBunchKaufman,missing-method}
\alias{solve,pBunchKaufman,dgeMatrix-method}
\alias{solve,pCholesky,missing-method}
\alias{solve,pCholesky,dgeMatrix-method}
\alias{solve,pMatrix,Matrix-method}
\alias{solve,pMatrix,matrix-method}
\alias{solve,pMatrix,missing-method}
\alias{solve,pMatrix,vector-method}
\alias{solve,sparseLU,missing-method}
\alias{solve,sparseLU,dgeMatrix-method}
\alias{solve,sparseLU,dgCMatrix-method}
\alias{solve,sparseQR,missing-method}
\alias{solve,sparseQR,dgeMatrix-method}
\alias{solve,sparseQR,dgCMatrix-method}
\alias{solve,triangularMatrix,CsparseMatrix-method}
\alias{solve,triangularMatrix,RsparseMatrix-method}
\alias{solve,triangularMatrix,TsparseMatrix-method}
\alias{solve,triangularMatrix,denseMatrix-method}
\alias{solve,triangularMatrix,dgCMatrix-method}
\alias{solve,triangularMatrix,dgeMatrix-method}
\alias{solve,triangularMatrix,diagonalMatrix-method}
\alias{solve,triangularMatrix,indMatrix-method}
\alias{solve,triangularMatrix,matrix-method}
\alias{solve,triangularMatrix,vector-method}
%
\description{
  Methods for generic function \code{\link[base]{solve}} for solving
  linear systems of equations,
  i.e., for \eqn{X} in \eqn{A X = B}{A * X = B},
  where \eqn{A} is a square matrix and \eqn{X} and \eqn{B} are matrices
  with dimensions consistent with \eqn{A}.
}
\usage{
solve(a, b, ...)

\S4method{solve}{dgeMatrix,ANY}(a, b, tol = .Machine$double.eps, \dots)

\S4method{solve}{dgCMatrix,missing}(a, b, sparse = TRUE, \dots)
\S4method{solve}{dgCMatrix,matrix}(a, b, sparse = FALSE, \dots)
\S4method{solve}{dgCMatrix,denseMatrix}(a, b, sparse = FALSE, \dots)
\S4method{solve}{dgCMatrix,sparseMatrix}(a, b, sparse = TRUE, \dots)

\S4method{solve}{denseLU,dgeMatrix}(a, b, \dots)
\S4method{solve}{BunchKaufman,dgeMatrix}(a, b, \dots)
\S4method{solve}{Cholesky,dgeMatrix}(a, b, \dots)
\S4method{solve}{sparseLU,dgCMatrix}(a, b, tol = .Machine$double.eps, \dots)
\S4method{solve}{sparseQR,dgCMatrix}(a, b, \dots)
\S4method{solve}{CHMfactor,dgCMatrix}(a, b, system = c("A", "LDLt", "LD", "DLt", "L", "Lt", "D", "P", "Pt"), \dots)
}
\arguments{
  \item{a}{a \link[=is.finite]{finite} square matrix or
    \code{\linkS4class{Matrix}} containing the coefficients
    of the linear system, or otherwise a
    \code{\linkS4class{MatrixFactorization}},
    in which case methods behave (by default)
    as if the factorized matrix were specified.}
  \item{b}{a vector, \code{\linkS4class{sparseVector}},
    matrix, or \code{\linkS4class{Matrix}} satisfying
    \code{NROW(b) == nrow(a)}, giving the right-hand side(s)
    of the linear system.  Vectors \code{b} are treated as
    \code{length(b)}-by-1 matrices.  If \code{b} is missing,
    then methods take \code{b} to be an identity matrix.}
  \item{tol}{a non-negative number.  For \code{a} inheriting from
    \code{\linkS4class{denseMatrix}}, an error is signaled if the
    reciprocal one-norm condition number (see \code{\link[base]{rcond}})
    of \code{a} is less than \code{tol}, indicating that \code{a} is
    near-singular.  For \code{a} of class \code{\linkS4class{sparseLU}},
    an error is signaled if the ratio \code{min(d)/max(d)} is less
    than \code{tol}, where \code{d = abs(diag(a@U))}.  (Interpret
    with care, as this ratio is a cheap heuristic and \emph{not}
    in general equal to or even proportional to the reciprocal
    one-norm condition number.)  Setting \code{tol = 0} disables
    the test.}
  \item{sparse}{a logical indicating if the result should be formally
    sparse, i.e., if the result should inherit from virtual class
    \code{\linkS4class{sparseMatrix}}.
    Only methods for sparse \code{a} and missing or matrix \code{b}
    have this argument.
    Methods for missing or sparse \code{b} use \code{sparse = TRUE}
    by default.  Methods for dense \code{b} use \code{sparse = FALSE}
    by default.}
  \item{system}{a string specifying a linear system to be solved.
    Only methods for \code{a}
    inheriting from \code{\linkS4class{CHMfactor}} have this argument.
    See \sQuote{Details}.}
  \item{\dots}{further arguments passed to or from methods.}
}
\details{
  Methods for general and symmetric matrices \code{a} compute a
  triangular factorization (LU, Bunch-Kaufman, or Cholesky)
  and call the method for the corresponding factorization class.
  The factorization is sparse if \code{a} is.  Methods for sparse,
  symmetric matrices \code{a} attempt a Cholesky factorization
  and perform an LU factorization only if that fails (typically
  because \code{a} is not positive definite).

  Triangular, diagonal, and permutation matrices do not require
  factorization (they are already \dQuote{factors}), hence methods
  for those are implemented directly.  For triangular \code{a},
  solutions are obtained by forward or backward substitution;
  for diagonal \code{a}, they are obtained by scaling the rows
  of \code{b}; and for permutations \code{a}, they are obtained
  by permuting the rows of \code{b}.

  Methods for dense \code{a} are built on 14 LAPACK routines:
  class \code{d..Matrix}, where \code{..=(ge|tr|tp|sy|sp|po|pp)},
  uses routines \code{d..tri} and \code{d..trs} for missing
  and non-missing \code{b}, respectively.  A corollary is that
  these methods always give a dense result.
  
  Methods for sparse \code{a} are built on CXSparse routines
  \code{cs_lsolve}, \code{cs_usolve}, and \code{cs_spsolve} and
  CHOLMOD routines \code{cholmod_solve} and \code{cholmod_spsolve}.
  By default, these methods give a vector result if \code{b}
  is a vector, a sparse matrix result if \code{b} is missing
  or a sparse matrix, and a dense matrix result if \code{b}
  is a dense matrix.  One can override this behaviour by setting
  the \code{sparse} argument, where available, but that should
  be done with care.  Note that a sparse result may be sparse only
  in the formal sense and not at all in the mathematical sense,
  depending on the nonzero patterns of \code{a} and \code{b}.
  Furthermore, whereas dense results are fully preallocated,
  sparse results must be \dQuote{grown} in a loop over the columns
  of \code{b}.
  
  Methods for \code{a} of class \code{\linkS4class{sparseQR}}
  are simple wrappers around \code{\link{qr.coef}}, giving the
  \emph{least squares} solution in overdetermined cases.
  
  Methods for \code{a} inheriting from \code{\linkS4class{CHMfactor}}
  can solve systems other than the default one \eqn{A X = B}{A * X = B}.
  The correspondence between its \code{system} argument the system
  actually solved is outlined in the table below.
  See \code{\link{CHMfactor-class}} for a definition of notation.
  
  \tabular{rrr}{
    \code{system} \tab \code{\link{isLDL}(a)=TRUE} \tab \code{\link{isLDL}(a)=FALSE}\cr
    \code{"A"} \tab \eqn{A X = B}{A * X = B} \tab \eqn{A X = B}{A * X = B}\cr
    \code{"LDLt"} \tab \eqn{L_{1} D L_{1}' X = B}{L1 * D * L1' * X = B} \tab \eqn{L L' X = B}{L * L' * X = B}\cr
    \code{"LD"} \tab \eqn{L_{1} D X = B}{L1 * D * X = B} \tab \eqn{L X = B}{L * X = B}\cr
    \code{"DLt"} \tab \eqn{D L_{1}' X = B}{D * L1' * X = B} \tab \eqn{L' X = B}{L' * X = B}\cr
    \code{"L"} \tab \eqn{L_{1} X = B}{L1 * X = B} \tab \eqn{L X = B}{L * X = B}\cr
    \code{"Lt"} \tab \eqn{L_{1}' X = B}{L1' * X = B} \tab \eqn{L' X = B}{L' * X = B}\cr
    \code{"D"} \tab \eqn{D X = B}{D * X = B} \tab \eqn{X = B}{X = B}\cr
    \code{"P"} \tab \eqn{X = P_{1} B}{X = P1 * B} \tab \eqn{X = P_{1} B}{X = P1 * B}\cr
    \code{"Pt"} \tab \eqn{X = P_{1}' B}{X = P1' * B} \tab \eqn{X = P_{1}' B}{X = P1' * B}
  }
}
\seealso{
  Virtual class \code{\linkS4class{MatrixFactorization}} and its
  subclasses.

  Generic functions \code{\link{Cholesky}}, \code{\link{BunchKaufman}},
  \code{\link{Schur}}, \code{\link{lu}}, and \code{\link{qr}} for
  \emph{computing} factorizations.

  Generic function \code{\link[base]{solve}} from \pkg{base}.

  Function \code{\link{qr.coef}} from \pkg{base} for computing
  least squares solutions of overdetermined linear systems.
}
\examples{
## A close to symmetric example with "quite sparse" inverse:
n1 <- 7; n2 <- 3
dd <- data.frame(a = gl(n1,n2), b = gl(n2,1,n1*n2))# balanced 2-way
X <- sparse.model.matrix(~ -1+ a + b, dd)# no intercept --> even sparser
XXt <- tcrossprod(X)
diag(XXt) <- rep(c(0,0,1,0), length.out = nrow(XXt))

n <- nrow(ZZ <- kronecker(XXt, Diagonal(x=c(4,1))))
image(a <- 2*Diagonal(n) + ZZ \%*\% Diagonal(x=c(10, rep(1, n-1))))
isSymmetric(a) # FALSE
image(drop0(skewpart(a)))
image(ia0 <- solve(a, tol = 0)) # checker board, dense [but really, a is singular!]
try(solve(a, sparse=TRUE))##-> error [ TODO: assertError ]
ia. <- solve(a, sparse=TRUE, tol = 1e-19)##-> *no* error
if(R.version$arch == "x86_64")
  ## Fails on 32-bit [Fedora 19, R 3.0.2] from Matrix 1.1-0 on [FIXME ??] only
  stopifnot(all.equal(as.matrix(ia.), as.matrix(ia0)))
a <- a + Diagonal(n)
iad <- solve(a)
ias <- solve(a, sparse=FALSE)
stopifnot(all.equal(as(iad,"denseMatrix"), ias, tolerance=1e-14))
I. <- iad \%*\% a          ; image(I.)
I0 <- drop0(zapsmall(I.)); image(I0)
.I <- a \%*\% iad
.I0 <- drop0(zapsmall(.I))
stopifnot( all.equal(as(I0, "diagonalMatrix"), Diagonal(n)),
           all.equal(as(.I0,"diagonalMatrix"), Diagonal(n)) )

}
back to top