% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/ScaledMatrix.R
\docType{class}
\name{ScaledMatrix}
\alias{ScaledMatrix}
\alias{ScaledMatrixSeed}
\alias{ScaledMatrixSeed-class}
\alias{dim,ScaledMatrixSeed-method}
\alias{dimnames,ScaledMatrixSeed-method}
\alias{extract_array,ScaledMatrixSeed-method}
\alias{DelayedArray,ScaledMatrixSeed-method}
\alias{show,ScaledMatrixSeed-method}
\alias{ScaledMatrix-class}
\alias{dimnames<-,ScaledMatrix,ANY-method}
\alias{t,ScaledMatrix-method}
\alias{[,ScaledMatrix,ANY,ANY,ANY-method}
\alias{colSums,ScaledMatrix-method}
\alias{rowSums,ScaledMatrix-method}
\alias{colMeans,ScaledMatrix-method}
\alias{rowMeans,ScaledMatrix-method}
\alias{\%*\%,ANY,ScaledMatrix-method}
\alias{\%*\%,ScaledMatrix,ANY-method}
\alias{\%*\%,ScaledMatrix,ScaledMatrix-method}
\alias{crossprod,ScaledMatrix,missing-method}
\alias{crossprod,ScaledMatrix,ANY-method}
\alias{crossprod,ANY,ScaledMatrix-method}
\alias{crossprod,ScaledMatrix,ScaledMatrix-method}
\alias{tcrossprod,ScaledMatrix,missing-method}
\alias{tcrossprod,ScaledMatrix,ANY-method}
\alias{tcrossprod,ANY,ScaledMatrix-method}
\alias{tcrossprod,ScaledMatrix,ScaledMatrix-method}
\title{The ScaledMatrix class}
\usage{
ScaledMatrix(x, center = NULL, scale = NULL)
}
\arguments{
\item{x}{A matrix or any matrix-like object (e.g., from the \pkg{Matrix} package).

This can alternatively be a ScaledMatrixSeed, in which case any values of \code{center} and \code{scale} are ignored.}

\item{center}{A numeric vector of length equal to \code{ncol(x)}, where each element is to be subtracted from the corresponding column of \code{x}.
A \code{NULL} value indicates that no subtraction is to be performed.
Alternatively \code{TRUE}, in which case it is set to the column means of \code{x}.}

\item{scale}{A numeric vector of length equal to \code{ncol(x)}, where each element is to divided from the corresponding column of \code{x} (after subtraction).
A \code{NULL} value indicates that no division is to be performed.
Alternatively \code{TRUE}, in which case it is set to the column-wise root-mean-squared differences from \code{center} 
(interpretable as standard deviations if \code{center} is set to the column means, see \code{\link{scale}} for commentary).}
}
\value{
The \code{ScaledMatrixSeed} constructor will return a ScaledMatrixSeed object.

The \code{ScaledMatrix} constructor will return a ScaledMatrix object equivalent to \code{t((t(x) - center)/scale)}.
}
\description{
Defines the ScaledMatrixSeed and ScaledMatrix classes and their associated methods.
These classes support delayed centering and scaling of the columns in the same manner as \code{\link{scale}},
but preserving the original data structure for more efficient operations like matrix multiplication.
}
\section{Methods for ScaledMatrixSeed objects}{

ScaledMatrixSeed objects are implemented as \linkS4class{DelayedMatrix} backends.
They support standard operations like \code{dim}, \code{dimnames} and \code{extract_array}.

Passing a ScaledMatrixSeed object to the \code{\link{DelayedArray}} constructor will create a ScaledMatrix object.

It is possible for \code{x} to contain a ScaledMatrix, thus nesting one ScaledMatrix inside another.
This can occasionally be useful in combination with transposition to achieve centering/scaling in both dimensions.
}

\section{Methods for ScaledMatrix objects}{

ScaledMatrix objects are derived from \linkS4class{DelayedMatrix} objects and support all of valid operations on the latter.
Several functions are specialized for greater efficiency when operating on ScaledMatrix instances, including:
\itemize{
    \item Subsetting, transposition and replacement of row/column names.
        These will return a new ScaledMatrix rather than a DelayedMatrix.
    \item Matrix multiplication via \code{\%*\%}, \code{crossprod} and \code{tcrossprod}.
        These functions will return a DelayedMatrix.
    \item Calculation of row and column sums and means by \code{colSums}, \code{rowSums}, etc. 
}

All other operations applied to a ScaledMatrix will use the underlying \pkg{DelayedArray} machinery.
Unary or binary operations will generally create a new DelayedMatrix instance containing a ScaledMatrixSeed.

Tranposition can effectively be used to allow centering/scaling on the rows if the input \code{x} is transposed.
}

\section{Efficiency vs precision}{

The raison d'etre of the ScaledMatrix is that it can offer faster matrix multiplication by avoiding the \pkg{DelayedArray} block processing.
This is done by refactoring the scaling/centering operations to use the (hopefully more efficient) multiplication operator of the original matrix \code{x}.
Unfortunately, the speed-up comes at the cost of increasing the risk of catastrophic cancellation.
The procedure requires subtraction of one large intermediate number from another to obtain the values of the final matrix product.
This could result in a loss of numerical precision that compromises the accuracy of downstream algorithms. 
In practice, this does not seem to be a major concern though one should be careful if the input \code{x} contains very large positive/negative values.
}

\examples{
library(Matrix)
y <- ScaledMatrix(rsparsematrix(10, 20, 0.1), 
    center=rnorm(20), scale=1+runif(20))
y

crossprod(y)
tcrossprod(y)
y \%*\% rnorm(20)

}
\author{
Aaron Lun
}
