\chapter{Introduction}\label{ch:introduction} \section{Purpose} \LA{} is a C++ class library for numerical linear algebra and related tasks. Its core are the class templates \code{NRVec} (vector), \code{NRMat} (dense matrix) and \code{NRSMat} (symmetric or hermitian matrix in packed storage), which provide a convenient and efficient interface to the BLAS and LAPACK libraries. Around them a number of further classes and algorithms has grown, mostly motivated by the needs of quantum chemistry: sparse matrices, tensors with arbitrary index symmetry, four-index quantities (two-electron integrals), iterative eigensolvers and linear solvers working with matrices that are never stored explicitly, convergence acceleration, numerical optimization, permutations and the symmetric group, polynomials, quaternions and others. The design follows a few principles, which are explained in detail in chapter~\ref{ch:concepts}: \begin{itemize} \item \emph{Reference counting with copy on demand.} Copying and assigning objects is cheap, data are shared until they are modified. Objects can therefore be passed and returned by value. The price is that writing to individual elements requires an explicit \code{copyonwrite()} call (section~\ref{sec:concepts:refcount}). \item \emph{No expression templates.} The library does not optimize matrix expressions. Operators like \code{A*x+y} are available for convenience, but performance critical code should call the BLAS-like member functions (\code{gemv}, \code{gemm}, \code{axpy}, \dots) directly, which avoid temporaries. \item \emph{Generic algorithms.} Iterative methods (Davidson, Lanczos, conjugate gradients, GMRES, the matrix exponential, \dots) are templates which only need a few operations of the matrix class (typically \code{nrows()}, \code{ncols()}, \code{diagonalof()} and \code{gemv()}), so that they work with user classes which compute the matrix--vector product on the fly (``direct'' methods). \item \emph{Nesting.} The element type of the containers can itself be a container, e.g.\ \code{NRVec >}; copy on demand and I/O work recursively (section~\ref{sec:concepts:traits}). \end{itemize} The manual is written for users who know both C++ and linear algebra. It explains the concepts and gives a compact but complete reference of the public interface. Many further usage examples are in the test programs \header{t.cc}, \header{t2.cc} and \header{test.cc} of the distribution; the regression test of the optimization module is \header{testoptimize.cc}. The class names \code{NRVec}, \code{NRMat} etc.\ are historical: the classes were first used together with the Numerical Recipes library. They can be used with it, but are completely independent of it. \section{Overview} \begin{longtable}{@{}p{0.33\linewidth}p{0.62\linewidth}@{}} \toprule \textbf{Header} & \textbf{Content} \\ \midrule \endhead \header{la.h} & the single include file for the user \\ \header{vec.h} & \code{NRVec}, \code{NRVec_from1} (chapter~\ref{ch:vec}) \\ \header{mat.h} & \code{NRMat}, \code{NRMat_from1} (chapter~\ref{ch:mat}) \\ \header{smat.h} & \code{NRSMat}, \code{NRSMat_from1} (chapter~\ref{ch:smat}) \\ \header{sparsemat.h}, \header{sparsesmat.h} & sparse matrices \code{SparseMat}, \code{SparseSMat} (chapter~\ref{ch:sparse}) \\ \header{csrmat.h} & compressed row storage sparse matrix (unfinished) \\ \header{nonclass.h}, \header{matexp.h} & linear systems, eigenvalue problems, SVD, matrix functions (chapter~\ref{ch:nonclass}) \\ \header{davidson.h}, \header{lanczos.h}, \header{conjgrad.h}, \header{gmres.h}, \header{diis.h}, \header{bisection.h} & iterative methods, DIIS convergence acceleration (chapter~\ref{ch:iterative}) \\ \header{optimize.h} & numerical optimization (chapter~\ref{ch:optimize}) \\ \header{tensor.h} & tensors with index symmetries (chapter~\ref{ch:tensor}) \\ \header{fourindex.h} & four-index quantities, two-electron integrals (chapter~\ref{ch:fourindex}) \\ \header{permutation.h}, \header{qsort.h} & permutations, partitions, Young tableaux, sorting (chapter~\ref{ch:permutation}) \\ \header{polynomial.h}, \header{contfrac.h} & polynomials, rationals and continued fractions (chapter~\ref{ch:polynomial}) \\ \header{vecmat3.h} & 3D vectors and matrices (chapter~\ref{ch:vecmat3}) \\ \header{quaternion.h} & quaternions (chapter~\ref{ch:quaternion}) \\ \header{bitvector.h} & bit vectors, polynomials over GF(2) (chapter~\ref{ch:bitvector}) \\ \header{numbers.h}, \header{graph.h} & number theory, graph algorithms (chapter~\ref{ch:utilities}) \\ \header{reg.h}, \header{regsurf.h} & regression (chapter~\ref{ch:regression}) \\ \header{auxstorage.h}, \header{la_random.h}, \header{miscfunc.h}, \header{simple.h}, \header{laerror.h} & utilities (chapter~\ref{ch:utilities}) \\ \header{la_traits.h} & traits classes, the basis of the generic programming (section~\ref{sec:concepts:traits}) \\ \bottomrule \end{longtable} Everything is declared in the namespace \code{LA}, with the exception of a few headers designed to be usable also without the rest of the library (\header{vecmat3.h}: namespace \code{LA_Vecmat3}, \header{quaternion.h}: namespace \code{LA_Quaternion}, \header{simple.h}). \header{la.h} includes all headers and contains \code{using namespace LA;} together with a few typedefs (\code{NRDVec}, \code{NRCVec}, \code{NRIVec}, \code{NRDMat}, \code{NRCMat}, \code{NRIMat} for \code{double}, \code{std::complex} and \code{int} elements). \section{A minimal example} \begin{lstlisting} #include "la.h" using namespace LA; using namespace std; int main() { const int n=4; NRSMat h(n); h.randomize(1.); //symmetric matrix with random elements NRSMat hsave; hsave |= h; //deep copy, diagonalize() destroys its argument NRVec e(n); NRMat v(n,n); diagonalize(h,e,&v); //eigenvalues e (ascending), eigenvectors in columns of v NRMat r = hsave*v; //residual H V - V diag(e) r.copyonwrite(); //always before writing via operator() or [] for(int i=0; i