\documentclass{article} % \usepackage{myVignette} \usepackage[authoryear,round]{natbib} \bibliographystyle{plainnat} \newcommand{\noFootnote}[1]{{\small (\textit{#1})}} \newcommand{\myOp}[1]{{$\left\langle\ensuremath{#1}\right\rangle$}} %% vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv %%\VignetteIndexEntry{Design Issues in Matrix package Development} %%\VignetteDepends{Matrix} \SweaveOpts{engine=R,eps=FALSE,pdf=TRUE,width=5,height=3,strip.white=TRUE,keep.source=TRUE} % ^^^^^^^^^^^^^^^^ \title{Design Issues in Matrix package Development} \author{Martin Maechler and Douglas Bates\\R Core Development Team \\\email{maechler@stat.math.ethz.ch}, \email{bates@r-project.org}} \date{Spring 2008 ({\tiny typeset on \tiny\today})} % \begin{document} \maketitle \begin{abstract} This is a (\textbf{currently very incomplete}) write-up of the many smaller and larger design decisions we have made in organizing functionalities in the Matrix package. Classes: There's a rich hierarchy of matrix classes, which you can visualize as a set of trees whose inner (and ``upper'') nodes are \emph{virtual} classes and only the leaves are non-virtual ``actual'' classes. Functions and Methods: - setAs() - others \end{abstract} %% Note: These are explained in '?RweaveLatex' : <>= options(width=75) @ \section{The Matrix class structures} \label{sec:classes} Take Martin's DSC 2007 talk to depict class hierarchy. \\ --- --- --- %% \hrule[1pt]{\textwidth} \subsection{Diagonal Matrices} \label{ssec:diagMat} The class of diagonal matrices is worth mentioning for several reasons. First, we have wanted such a class, because \emph{multiplication} methods are particularly simple with diagonal matrices. The typical constructor is \Rfun{Diagonal} whereas the accessor (as for traditional matrices), \Rfun{diag} simply returns the \emph{vector} of diagonal entries: <>= (D4 <- Diagonal(4, 10*(1:4))) str(D4) diag(D4) @ We can \emph{modify} the diagonal in the traditional way (via method definition for \Rfun{diag<-}): <>= diag(D4) <- diag(D4) + 1:4 D4 @ Note that \textbf{unit-diagonal} matrices (the identity matrices of linear algebra) with slot \code{diag = "U"} can have an empty \code{x} slot, very analogously to the unit-diagonal triangular matrices: <>= str(I3 <- Diagonal(3)) ## empty 'x' slot getClass("diagonalMatrix") ## extending "denseMatrix" @ We have implemented diagonal matrices as \emph{dense} rather than sparse matrices, for the following reasons: \begin{enumerate} \item The \code{diag()}onal (vector) is the basic part of such a matrix, and this is simply the \code{x} slot unless the \code{diag} slot is \code{"U"}, the unit-diagonal case, which is the identity matrix. \item given '1)', it does not make much sense to store \emph{where} the matrix is non-zero. This contrasts with all sparse matrix implementations, and hence we did not want to call a diagonal matrix ``sparse''. \end{enumerate} \section{Matrix Transformations} \label{sec:trafos} \subsection{Coercions between Matrix classes} \label{ssec:coerce} You may need to transform Matrix objects into specific shape (triangular, symmetric), content type (double, logical, \dots) or storage structure (dense or sparse). Every useR should use \code{as(x, )} to this end, where \code{} is a \emph{virtual} Matrix super class, such as \code{"triangularMatrix"} \code{"dMatrix"}, or \code{"sparseMatrix"}. In other words, the user should \emph{not} coerce directly to a specific desired class such as \code{"dtCMatrix"}, even though that may occasionally work as well. Here is a set of rules to which the Matrix developers and the users should typically adhere: \begin{description} \item[Rule~1]: \code{as(M, "matrix")} should work for \textbf{all} Matrix objects \code{M}. \item[Rule~2]: \code{Matrix(x)} should also work for matrix like objects \code{x} and always return a ``classed'' Matrix. Applied to a \code{"matrix"} object \code{m}, \code{M <- Matrix(m)} can be considered a kind of inverse of \code{m <- as(M, "matrix")}. \item[Rule~3]: All the following coercions to \emph{virtual} matrix classes should work:\\ \begin{enumerate} \item \code{as(m, "dMatrix")} \item \code{as(m, "lMatrix")} \item \code{as(m, "nMatrix")} \item \code{as(m, "denseMatrix")} \item \code{as(m, "sparseMatrix")} \item \code{as(m, "generalMatrix")} \end{enumerate} whereas the next ones should work under some assumptions: \begin{enumerate} \item \code{as(m1, "triangularMatrix")} \\ should work when \code{m1} is a triangular matrix, i.e. the upper or lower triangle of \code{m1} contains only zeros. \item \code{as(m2, "symmetricMatrix")} should work when \code{m2} is a symmetric matrix in the sense of \code{isSymmetric(m2)} returning \code{TRUE}. Note that this is typically equivalent to something like \code{isTRUE(all.equal(m2, t(m2)))}, i.e., the lower and upper triangle of the matrix have to be equal \emph{up to small numeric fuzz}. \end{enumerate} \end{description} \section{Session Info} <>= toLatex(sessionInfo()) @ %not yet %\bibliography{Matrix} \end{document}