1%%%%%%%%%%%%%%%%%%%
2% XLiFE++ is an extended library of finite elements written in C++
3%     Copyright (C) 2014  Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin
4%
5%     This program is free software: you can redistribute it and/or modify
6%     it under the terms of the GNU General Public License as published by
7%     the Free Software Foundation, either version 3 of the License, or
8%     (at your option) any later version.
9%     This program is distributed in the hope that it will be useful,
10%     but WITHOUT ANY WARRANTY; without even the implied warranty of
11%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12%     GNU General Public License for more details.
13%     You should have received a copy of the GNU General Public License
14%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
15%%%%%%%%%%%%%%%%%%%
16
17\section{Compressed sparse storages}
18
19Compressed sparse storages are designed to store only non zero values of a matrix. It exists several methods to do it. The well known CSR/CSC storage being the most common one, we chose it. It consists in storing non zero values of a row (resp. column) in a compressed vector and their column indices (resp. row indices) in a compressed vector. A vector of addresses where begin rows (resp. columns) is also required. More precisely, for a $m\times n$ matrix
20\begin{itemize}
21\item row compressed storage is defined by the three vectors : \\
22\mbox{}\hspace{10 mm}values = (0,$A_{1\mathcal{C}_1}$, ..., $A_{i\mathcal{C}_i}$, ..., $A_{m\mathcal{C}_m}$)\\
23\mbox{}\hspace{10 mm}colIndex = ($\mathcal{C}_1$, ..., $\mathcal{C}_i$, ..., $\mathcal{C}_m$)\\
24\mbox{}\hspace{10 mm}rowPointer = ($p_1$,...,$p_i$,...$,p_m$, $p_{m+1}$)\\
25where $\mathcal{C}_i$ is the set of index $j$ where $A_{ij}\ne 0$ and $p_i$ is the position in vector colIndex of the first entry of row $i\le m$; $p_{m+1}$ gives the number of non zero values. By convention, all the indices begins at 0 and first entry of values vector is always 0! \\
26For instance, the following $5\times 6$ non symmetric matrix
27\[
28A=\left[
29\begin{array}{cccccc}
3011 & 12 & 0 & 14 & 0 & 16\\
310 & 22 & 23 & 0 & 0 & 26 \\
3231 & 32 & 33 & 0 & 0 & 0 \\
330 & 0 & 43 & 44 & 0 & 0 \\
3451 & 0 & 53 & 54 & 55 & 0
35\end{array}
36\right]
37\]
38has the row compressed storage vectors: \\ \\
39\mbox{}\hspace{10 mm}values     = ( 0 11 12 14 16\ \ 22 23 26\ \ 31 32 33\ \ 43 44\ \ 51 53 54 55 ) \\
40\mbox{}\hspace{10 mm}colIndex   = ( 0 1 3 5\ \ 1 2 5\ \ 0 1 2\ \ 2 3\ \ 0 2 3 4 )\\
41\mbox{}\hspace{10 mm}rowPointer = ( 0 4 7 10 12 16) \\
42\item row compressed storage is defined by the three vectors : \\
43\mbox{}\hspace{10 mm}values = (0,$A_{\mathcal{R}_11}$, ..., $A_{\mathcal{R}_jj}$, ..., $A_{\mathcal{R}_nn}$)\\
44\mbox{}\hspace{10 mm}rowIndex = ($\mathcal{R}_1$, ..., $\mathcal{R}_j$, ..., $\mathcal{R}_n$)\\
45\mbox{}\hspace{10 mm}colPointer = ($p_1$,...,$p_j$,...$,p_n$, $p_{n+1}$)\\
46where $\mathcal{R}_j$ is the set of index $i$ where $A_{ij}\ne 0$ and $p_j$ is the position in rowIndex vector of the first entry of column $j\le n$; $p_{n+1}$ gives the number of non zero values. By convention, all the indices begins at 0 and first entry of values vector is always 0! \\
47For instance, the previous  $5\times 6$ non symmetric matrix  $A$  has the column compress storage vectors: \\
48\mbox{}\hspace{10 mm}values     = ( 0 11 31 51\ \ 12 22 32\ \ 23 33 43 53\ \ 55\ \ 16 26 ) \\
49\mbox{}\hspace{10 mm}rowIndex   = ( 0 2 4\ \ 0 1 2\ \ 1 2 3 4\ \ 0 3 4\ \ 4\ \ 0 1)\\
50\mbox{}\hspace{10 mm}colPointer = ( 0 4 7 10 12 16) \\
51\item dual compressed storage is defined by the five vectors : \\
52\mbox{}\hspace{10 mm}values = (0,\text{diag}(A), $A_{\mathcal{C}_11}$, ..., $A_{\mathcal{C}_ii}$, ..., $A_{\mathcal{C}_mm}$, $A_{\mathcal{R}_11}$, ..., $A_{\mathcal{R}_jj}$, ..., $A_{\mathcal{R}_nn}$)\\
53\mbox{}\hspace{10 mm}colIndex = ($\mathcal{C}_1$, ..., $\mathcal{C}_i$, ..., $\mathcal{C}_m$)\\
54\mbox{}\hspace{10 mm}rowPointer = ($p_1$,...,$p_i$,...$,p_m$, $p_{m+1}$)\\
55\mbox{}\hspace{10 mm}rowIndex = ($\mathcal{R}_1$, ..., $\mathcal{R}_j$, ..., $\mathcal{R}_n$)\\
56\mbox{}\hspace{10 mm}colPointer = ($q_1$,...,$q_j$,...$,q_n$, $q_{n+1}$)\\
57where $\mathcal{C}_i$ is the set of index $j$ where $A_{ij}\ne 0$ and $j\le\min(i-1,n)$,
58$\mathcal{R}_j$ is the set of index $i$ where $A_{ij}\ne 0$ and $i\le\min(j-1,m)$,  $p_i$ (resp. $q_j$) is the position in colIndex (resp. rowIndex) vector of the first entry of row $i\le m$ (resp. column $j\le n$). The colIndex and rowPointer vectors describes the row compressed storage of the strict lower part of matrix while the rowIndex and colPointer vectors describes the column compressed storage of the strict upper part of matrix. In this storage, all the diagonal entries of matrix are always first stored even the null entries!\\
59For instance, the previous  $5\times 6$ non symmetric matrix  $A$  has the column compress storage vectors: \\
60\mbox{}\hspace{10 mm}values     = ( 0 11 22 33 44 55\ \ 31 32\ \ 43\ \ 51 53 54 \ \ 23 \ \ 14 44 \ \ 16 26 ) \\
61\mbox{}\hspace{10 mm}colIndex = (0 1\ \ 2\ \ 0 2 3)\\
62\mbox{}\hspace{10 mm}rowPointer = (0 0 0 2 3 6)\\
63\mbox{}\hspace{10 mm}rowIndex   = (0\ \ 1\ \ 0\ \ 0 1)\\
64\mbox{}\hspace{10 mm}colPointer = ( 0 0 1 2 2 3 5) \\
65Note that for an empty row $i$ (resp. column $j$), rowPointer($i$)=rowPointer($i-1$) (resp. colPointer($j$)=colPointer($j-1$)). By the way, rowPointer($i$)-rowPointer($i-1$) gives the number of stored entries on row $i-1$.
66\item symmetric compressed storage is devoted to square matrix with symmetric storage, the matrix may be not symmetric.. In that case, only the storage of lower triangular part of matrix is described by the three vectors (those of row part of dual storage): \\
67\mbox{}\hspace{10 mm}values = (0,\text{diag}(A), $A_{\mathcal{C}_11}$, ..., $A_{\mathcal{C}_ii}$, ..., $A_{\mathcal{C}_mm}$) if $A$ has a symmetry property\\
68\mbox{}\hspace{10 mm}values = (0,\text{diag}(A), $A_{\mathcal{C}_11}$, ..., $A_{\mathcal{C}_ii}$, ..., $A_{\mathcal{C}_mm}$,$A_{\mathcal{C}_11}$, ..., $A_{\mathcal{C}_jj}$, ..., $A_{\mathcal{C}_mm}$) if $A$ has no symmetry property\\
69\mbox{}\hspace{10 mm}colIndex = ($\mathcal{C}_1$, ..., $\mathcal{C}_i$, ..., $\mathcal{C}_m$)\\
70\mbox{}\hspace{10 mm}rowPointer = ($p_1$,...,$p_i$,...$,p_m$, $p_{m+1}$)\\
71where the meaning of $\mathcal{C}_i$ and $p_i$ is the same as dual storage.\\
72For instance, the $5\times 5$ non symmetric matrix with symmetric storage
73\[
74B=\left[
75\begin{array}{ccccc}
7611 & 0 & 13 & 0 & 15 \\
770 & 22 & 23 & 0 & 0 \\
7831 & 32 & 33 & 34 & 35\\
790 & 0 & 43 & 44 & 45 \\
8051 & 0 & 53 & 54 & 55
81\end{array}
82\right]
83\]
84has the symmetric compressed storage vectors: \\
85\mbox{}\hspace{10 mm}values     = ( 0 11 22 33 44 55\ \ 31 32\ \ 43\ \ 51 53 54\ \ 13 23\ \ 34\ \ 15 35 45) \\
86\mbox{}\hspace{10 mm}colIndex = (0 1\ \ 2\ \ 0 2 3)\\
87\mbox{}\hspace{10 mm}rowPointer = (0 0 0 2 3 6)\\
88\end{itemize}
89\textdbend \ \  Be care with the fact that actual matrix values begins at adress 1 in values vector defined outside the storage stuff.
90
91\subsection{The {\classtitle CsStorage} class}
92
93The {\class CsStorage} class has no member attribute. There are some basic constructors just calling {\class MatrixStorage} constructors:
94\vspace{.1cm}
95\begin{lstlisting}[]
96class CsStorage : public MatrixStorage
97{public :
98  CsStorage(AccessType = _dual);
99  CsStorage(Number, AccessType = _dual);
100  CsStorage(Number, Number, AccessType = _dual);
101  virtual ~CsStorage() {}
102 protected :
103  void buildCsStorage(const std::vector<std::vector<Number> >&,
104                      std::vector<Number>&, std::vector<Number>&);
105\end{lstlisting}
106\vspace{.1cm}
107The \verb?buildCsStorage? is a general member function building storage vectors from lists of column indices by row. It is used by any child class of {\class CsStorage} class.
108{\class CsStorage} objects do not have to be instantiated. This class acts as an interface to particular compressed storages and gathers all common functionalities of dense storages, some being virtuals (some template line declaration are omitted):
109\vspace{.1cm}
110\begin{lstlisting}[]
111virtual Number size() const = 0;
112virtual Number lowerPartSize() const;
113virtual Number upperPartSize() const;
114template<typename Iterator>
115  void printEntriesAll(StrucType, Iterator& , const std::vector<Number>&,
116                       const std::vector<Number>&, Number, Number, Number,
117                       const String&, Number, std::ostream&) const;
118  void printEntriesTriangularPart(StrucType, Iterator&, Iterator&,
119                       const std::vector<Number>&, const std::vector<Number>&,
120                       Number, Number, Number, const String&, Number,
121                       std::ostream&) const;
122  void printCooTriangularPart(std::ostream&, Iterator&, const std::vector<Number>&,
123                              const std::vector<Number>&, bool,
124                              SymType sym = _noSymmetry) const;
125  void printCooDiagonalPart(std::ostream&, Iterator&, Number) const;
126
127template <typename T>
128    void loadCsFromFileDense(std::istream&, std::vector<T>&, std::vector<Number>&,
129                             std::vector<Number>&, SymType, bool);
130    void loadCsFromFileCoo(std::istream&, std::vector<T>&, std::vector<Number>&,
131                           std::vector<Number>&, SymType, bool);
132    void loadCsFromFileDense(std::istream&, std::vector<T>&, std::vector<Number>&,
133                             std::vector<Number>&, std::vector<Number>&,
134                             std::vector<Number>&, SymType, bool);
135    void loadCsFromFileCoo(std::istream&, std::vector<T>&, std::vector<Number>&,
136                           std::vector<Number>&, std::vector<Number>&,
137                           std::vector<Number>&, SymType, bool);
138\end{lstlisting}
139\vspace{.2cm}
140The {\class CsStorage} class provides the real code of product of matrix and vector, using iterators as arguments to by-pass the template type of matrix values. For dual and symmetric storage, the computation is performed by splitting the matrix in its diagonal, lower and upper part (template line are omitted):
141\vspace{.1cm}
142\begin{lstlisting}[]
143template<typename MatIterator, typename VecIterator, typename ResIterator>
144  void diagonalMatrixVector(MatIterator&, VecIterator&, ResIterator&,
145                            ResIterator&) const;
146  void lowerMatrixVector(const std::vector<Number>&, const std::vector<Number>&,
147                         MatIterator&, VecIterator&, ResIterator&, SymType sym) const;
148  void upperMatrixVector(const std::vector<Number>&, const std::vector<Number>&,
149                         MatIterator&, VecIterator&, ResIterator&, SymType) const;
150  void rowMatrixVector(const std::vector<Number>&, const std::vector<Number>&,
151                       MatIterator&, VecIterator&, ResIterator&)  const;
152  void columnMatrixVector(const std::vector<Number>&, const std::vector<Number>&,
153                          MatIterator&, VecIterator&, ResIterator&)  const;
154  void diagonalVectorMatrix(MatIterator&, VecIterator&, ResIterator&,
155                            ResIterator&) const;
156  void lowerVectorMatrix(const std::vector<Number>&, const std::vector<Number>&,
157                         MatIterator&, VecIterator&, ResIterator&, SymType sym) const;
158  void upperVectorMatrix(const std::vector<Number>&, const std::vector<Number>&,
159                         MatIterator&, VecIterator&, ResIterator&, SymType) const;
160  void rowVectorMatrix(const std::vector<Number>&, const std::vector<Number>&,
161                       MatIterator&, VecIterator&, ResIterator&)  const;
162  void columnVectorMatrix(const std::vector<Number>&, const std::vector<Number>&,
163                          MatIterator&, VecIterator&, ResIterator&)  const;
164\end{lstlisting}
165\vspace{.1cm}
166Besides the product of matrix and vector, the  {\class CsStorage} provides solvers for matrix in its diagonal, lower and upper part
167\vspace{.1cm}
168\begin{lstlisting}[]
169    template<typename MatIterator, typename VecIterator, typename ResIterator>
170    void bzSorDiagonalMatrixVector(MatIterator& itd, const VecIterator& itvb,
171                                   ResIterator& itrb, const Real w) const;
172
173    template<typename MatIterator, typename VecIterator, typename XIterator>
174    void bzSorLowerSolver(const MatIterator&, const MatIterator&,
175                          VecIterator&, XIterator&, XIterator&,
176                          const std::vector<Number>&, const std::vector<Number>&, const Real) const;
177
178    template<typename MatIterator, typename VecIterator, typename XIterator>
179    void bzSorDiagonalSolver(const MatIterator& itdb, VecIterator& itbb,
180                             XIterator& itxb, XIterator& itxe, const Real w) const;
181
182    template<typename MatRevIterator, typename VecRevIterator, typename XRevIterator>
183    void bzSorUpperSolver(const MatRevIterator&, const MatRevIterator&,
184                          VecRevIterator&, XRevIterator&, XRevIterator&,
185                          const std::vector<Number>&, const std::vector<Number>&, const Real) const;
186\end{lstlisting}
187\vspace{.1cm}
188Addition of two matrices are implemented by
189\vspace{.1cm}
190\begin{lstlisting}[]
191    template<typename Mat1Iterator, typename Mat2Iterator, typename ResIterator>
192    void sumMatrixMatrix(Mat1Iterator&, Mat2Iterator&, ResIterator&, ResIterator&) const;
193\end{lstlisting}
194\vspace{.1cm}
195\displayInfos{library=largeMatrix, header=CsStorage.hpp, implementation=CsStorage.cpp, test={test\_LargeMatrixCstorage.cpp}, header dep={MatrixStorage.hpp, config.h, utils.h}}
196
197\subsection{{\classtitle RowCsStorage} and {\classtitle ColCsStorage} classes}
198
199As mentioned before, row compressed storage are based on the column indices vector and the row pointers vector. So the {\class RowCsStorage} class carries this two vectors:
200\vspace{.1cm}
201\begin{lstlisting}
202class RowCsStorage : public CsStorage
203{protected :
204  std::vector<Number> colIndex_;   //vector of column index of non zero value
205  std::vector<Number> rowPointer_; //vector of positions of begining of rows
206  ...
207\end{lstlisting}
208\vspace{.2cm}
209The class provides a default constructor with no construction of storage vectors and constructors from a list of $(i,j)$ index (coordinates) or a lists of column indices by row, constructing the compressed storage vectors:
210\vspace{.1cm}
211\begin{lstlisting}[]
212RowCsStorage(Number nr=0, Number nc=0);
213RowCsStorage(Number, Number, const std::vector< std::vector<Number> >&,
214             const std::vector< std::vector<Number> >&);
215RowCsStorage(Number, Number, const std::vector< std::vector<Number> >&);
216~RowCsStorage() {};
217\end{lstlisting}
218\vspace{.2cm}
219The class provides most of the virtual methods declared in {\class MatrixStorage} class. For sake of simplicity, we report here only function with \verb?Real? type but versions with \verb?Complex?, \verb?Matrix<Real>?, \verb?Matrix<Complex>? and mixed types are also provided. Some template line declarations are also omitted.
220\vspace{.1cm}
221\begin{lstlisting}[]
222Number size() const;
223Number pos(Number i, Number j, SymType s=_noSymmetry) const;
224void positions(const std::vector<Number>&, const std::vector<Number>&,
225               std::vector<Number>&, bool errorOn=true,
226               SymType s=_noSymmetry) const;
227void printEntries(std::ostream&, const std::vector<Real>&, Number, SymType) const;
228void printCooMatrix(std::ostream&, const std::vector<Real>&,
229                    SymType s=_noSymmetry) const;
230void loadFromFileDense(std::istream&, std::vector<Real>&, SymType, bool );
231void loadFromFileCoo(std::istream& , std::vector<Real>&, SymType, bool);
232template<typename M, typename V, typename R>
233  void multMatrixVector(const std::vector<M>&, const std::vector<V>&,
234                        std::vector<R>&) const;
235  void multVectorMatrix(const std::vector<M>&, const std::vector<V>&,
236                        std::vector<R>&) const;
237  void multMatrixVector(const std::vector<Real>&, const std::vector<Real>&,
238                        std::vector<Real>&, SymType) const;
239  void multVectorMatrix(const std::vector<Real>&, const std::vector<Real>&,
240                        std::vector<Real>&, SymType) const;
241template<typename M1, typename M2, typename R>
242  void addMatrixMatrix(const std::vector<M1>&, const std::vector<M2>&, std::vector<R>&) const; //!< templated row dense Matrix + Matrix
243  void addMatrixMatrix(const std::vector<Real>& m, const std::vector<Real>& v, std::vector<Real>& rv) const
244    { addMatrixMatrix<>(m, v, rv);}
245\end{lstlisting}
246\vspace{.1cm}
247There is no \verb?printDenseMatrix? function because the general one defined in {\class MatrixStorage} class is sufficiently efficient. \\
248\\
249The {\class ColCsStorage} class is very similar to the {\class RowCsStorage} class, except that it manages a row indices vector and a column pointers vector:
250\vspace{.1cm}
251\begin{lstlisting}
252class ColCsStorage : public CsStorage
253{protected :
254  std::vector<Number> rowIndex_;   //!< vector of row index of non zero value
255  std::vector<Number> colPointer_; //!< vector of positions of begining of cols
256  ...
257\end{lstlisting}
258\vspace{.2cm}
259Its constructors have a similar structure (same arguments) and all prototypes of member functions are the same as {\class ColCsStorage} member functions. We do not repeat them.
260\vspace{.1cm}
261XXX=Row or Col
262\displayInfos{library=largeMatrix, header=XXXCsStorage.hpp, implementation=XXXCsStorage.cpp, test={test\_LargeMatrixCsStorage.cpp}, header dep={CsStorage.hpp, MatrixStorage.hpp, config.h, utils.h}}
263
264\subsection{{\classtitle DualCsStorage} and {\classtitle SymCsStorage} classes}
265
266Dual compressed storage travels the matrix as diagonal, strict lower and upper parts. Column indices and row pointers vectors are attached to strict lower part and row indices and column pointers vectors are attached to strict upper part:
267\vspace{.1cm}
268\begin{lstlisting}
269class DualCsStorage : public CsStorage
270{protected :
271  std::vector<Number> colIndex_;   //vector of column index of non zero value
272  std::vector<Number> rowPointer_; //vector of positions of begining of rows
273  std::vector<Number> rowIndex_;   //vector of row index of non zero value
274  std::vector<Number> colPointer_; //vector of positions of begining of cols
275  ...
276\end{lstlisting}
277\vspace{.2cm}
278{\class DualCsStorage} class provides basic constructor (no construction of storage vectors), constructor from a pair of global numbering vectors or list of column indices by rows.
279Both of them create the compressed storage vector using the auxiliary function \verb?buildStorage?:
280\vspace{.1cm}
281\begin{lstlisting}
282DualCsStorage(Number nr=0, Number nc=0);
283DualCsStorage(Number, Number, const std::vector< std::vector<Number> >&,
284              const std::vector< std::vector<Number> >&);
285DualCsStorage(Number, Number, const std::vector<std::vector<Number> >&);
286void buildStorage(const std::vector<std::vector<Number> >&);
287~DualCsStorage() {};
288\end{lstlisting}
289\vspace{.2cm}
290The class provides most of the virtual methods declared in {\class MatrixStorage} class. For sake of simplicity, we report here only function with \verb?Real? type but versions with \verb?Complex?, \verb?Matrix<Real>?, \verb?Matrix<Complex>? and mixed types are also provided. Some template line declarations are also omitted.
291\vspace{.1cm}
292\begin{lstlisting}[]
293Number size() const;
294Number lowerPartSize() const ;
295    Number upperPartSize() const;
296Number pos(Number i, Number j, SymType s=_noSymmetry) const;
297void positions(const std::vector<Number>&, const std::vector<Number>&,
298               std::vector<Number>&, bool errorOn=true,
299               SymType s=_noSymmetry) const;
300void printEntries(std::ostream&, const std::vector<Real>&, Number, SymType) const;
301void printCooMatrix(std::ostream&, const std::vector<Real>&,
302                    SymType s=_noSymmetry) const;
303void loadFromFileDense(std::istream&, std::vector<Real>&, SymType, bool );
304void loadFromFileCoo(std::istream& , std::vector<Real>&, SymType, bool);
305template<typename M, typename V, typename R>
306  void multMatrixVector(const std::vector<M>&, const std::vector<V>&,
307                        std::vector<R>&) const;
308  void multVectorMatrix(const std::vector<M>&, const std::vector<V>&,
309                        std::vector<R>&) const;
310  void multMatrixVector(const std::vector<Real>&, const std::vector<Real>&,
311                        std::vector<Real>&, SymType) const;
312  void multVectorMatrix(const std::vector<Real>&, const std::vector<Real>&,
313                        std::vector<Real>&, SymType) const;
314template<typename M1, typename M2, typename R>
315  void addMatrixMatrix(const std::vector<M1>&, const std::vector<M2>&, std::vector<R>&) const;
316  void addMatrixMatrix(const std::vector<Real>& m, const std::vector<Real>& v, std::vector<Real>& rv) const
317    { addMatrixMatrix<>(m, v, rv);}
318\end{lstlisting}
319\vspace{.2cm}
320
321The {\class SymCsStorage} class is very similar to the {\class DualCsStorage} class, except that it addresses only square matrix with symmetric storage and,
322thus, does not manage row indices vector and column pointers vectors because the upper part has same storage as lower part (transposed). Note that matrix may be have no symmetry property but a symmetric storage. In that case, the upper part is stored.
323\vspace{.1cm}
324\begin{lstlisting}
325class SymCsStorage : public CsStorage
326{protected :
327  std::vector<Number> colndex_;   //!< vector of row index of non zero value
328  std::vector<Number> rowPointer_; //!< vector of positions of begining of cols
329  ...
330\end{lstlisting}
331\vspace{.1cm}
332Contrary to the row compressed storage, in the SymCsStorage, the diagonal is first stored then the lower part of the matrix. \\
333Its constructors have a similar structure (same arguments) to the {\class DualCsStorage} constructors and all prototypes of member functions are the same as {\class DualCsStorage} member functions. We do not repeat them.
334
335Different from other {\class CsStorage} classes, the {\class SymCsStorage} class provides some functions to deal with the {\class SorSolver} class and {\class SsorSolver} class. Only specialized functions with \verb?Real? are listed in the following
336\vspace{.1cm}
337\begin{lstlisting}[deletekeywords={[3] x}]
338void sorDiagonalMatrixVector(const std::vector<Real>& m, const std::vector<Real>& v, std::vector<Real>& rv, const Real w) const
339{ sorDiagonalMatrixVector<>(m, v, rv, w); }
340void sorLowerMatrixVector(const std::vector<Real>& m, const std::vector<Real>& v, std::vector<Real>& rv, const Real w, const SymType sym) const
341{ sorLowerMatrixVector<>(m, v, rv, w, sym); }
342void sorUpperMatrixVector(const std::vector<Real>& m, const std::vector<Real>& v, std::vector<Real>& rv, const Real w, const SymType sym) const
343{ sorUpperMatrixVector<>(m, v, rv, w, sym); }
344void sorDiagonalSolve(const std::vector<Real>& m, const std::vector<Real>& b, std::vector<Real>& x, const Real w) const
345{ sorDiagonalSolve<>(m, b, x, w); }
346void sorLowerSolve(const std::vector<Real>& m, const std::vector<Real>& b, std::vector<Real>& x, const Real w) const
347{ sorLowerSolve<>(m, b, x, w); }
348void sorUpperSolve(const std::vector<Real>& m, const std::vector<Real>& b, std::vector<Real>& x, const Real w, const SymType sym) const
349{ sorUpperSolve<>(m, b, x, w, sym); }
350\end{lstlisting}
351\vspace{.1cm}
352XXX=Dual or Sym
353
354\displayInfos{library=largeMatrix, header=XXXCsStorage.hpp, implementation=XXXCsStorage.cpp, test={test\_LargeMatrixCsStorage.cpp}, header dep={CsStorage.hpp, MatrixStorage.hpp, config.h, utils.h}}
355