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{Dense storages}
18
19Dense storages are proposed as childs of {\class MatrixStorage} class in order to be consistent with other storages. Contrary to the {\class Matrix} class (see {\lib utils} lib) which is a row dense storage, several dense storages are offered for a $m\times n$ matrix (say $A$) :
20\begin{itemize}
21\item the row dense storage ({\class RowDenseStorage} class)
22$$(A_{11}, A_{12}, ..., A_{1n},A_{21}, A_{22}, ..., A_{2n}, ..., A_{m1}, A_{m2}, ..., A_{mn})$$
23\item the column dense strorage ({\class ColDenseStorage} class)
24$$(A_{11}, A_{21}, ..., A_{2m},A_{12}, A_{22}, ..., A_{m2}, ..., A_{1n}, A_{2n}, ..., A_{mn})$$
25\item the dual dense storage ({\class DualDenseStorage} class), diagonal part is first stored, then strict lower triangular part and strict upper triangular part :
26$$(A_{11}, A_{22}, ..., A_{mm}, A_{21}, ...,A_{i1},...A_{i,i-1}, ..., A_{12}, ...,A_{1j},...A_{j-1,j}, ...) \ \text{case }m=n$$
27\item the symmetric dense storage ({\class SymDenseStorage} class), diagonal part is first stored, then strict lower triangular part :
28$$(A_{11}, A_{22}, ..., A_{mm}, A_{21}, ...,A_{i1},...A_{i,i-1}, ...) \ \text{case }m=n$$
29\end{itemize}
30Dual storage works also for non square matrices. Obviously, symmetric storage works only for square matrices! \\ \\
31All dense storages inherit from the {\class DenseStorage} abstract class which inherits from  {\class MatrixStorage} abstract class.
32
33\subsection{The {\classtitle DenseStorage} class}
34
35The {\class DenseStorage} class has no member attribute.There are some basic constructors just calling {\class MatrixStorage} constructors:
36\vspace{.1cm}
37\begin{lstlisting}[]
38class DenseStorage : public MatrixStorage
39{public :
40  DenseStorage();
41  DenseStorage(AccessType);
42  DenseStorage(AccessType, Number);
43  DenseStorage(AccessType, Number, Number);
44  virtual ~DenseStorage() {}
45  ...
46\end{lstlisting}
47\vspace{.1cm}
48{\class DenseStorage} objects do not have to be instantiated. This class acts as an interface to particular dense storages and gathers all common functionalities of dense storages, some being virtuals:
49\begin{itemize}
50\item pubic size functions:
51\vspace{.1cm}
52\begin{lstlisting}[]
53Number size() const;
54virtual Number lowerPartSize() const;
55virtual Number upperPartSize() const;
56\end{lstlisting}
57\vspace{.1cm}
58\item protected input/output functions (template line is written once):
59\vspace{.1cm}
60\begin{lstlisting}[]
61template<typename Iterator>
62void printScalarEntries(Iterator&, Number, Number, Number, Number, Number,
63                        const String&, Number, std::ostream&) const;
64void printScalarEntriesTriangularPart(Iterator& , Iterator&, Number, Number,
65                                      Number, Number, Number, const String&,
66                                      Number, std::ostream&) const;
67void printMatrixEntries(Iterator&, Number, Number, const String&, Number,
68                        std::ostream&) const;
69void printMatrixEntriesTriangularPart(Iterator&, Iterator&, Number, Number,
70                                      const String&, Number, std::ostream&) const;
71void loadFromFileDense(std::istream&, std::vector<Real>&, SymType, bool);
72void loadFromFileDense(std::istream&, std::vector<Complex>&, SymType, bool);
73void loadFromFileCoo(std::istream&, std::vector<Real>&, SymType, bool);
74void loadFromFileCoo(std::istream&, std::vector<Complex>&, SymType, bool);
75\end{lstlisting}
76\vspace{.1cm}
77\item product of matrix and vector (template line is written once):
78\vspace{.1cm}
79\begin{lstlisting}[]
80template<typename MatIterator, typename VecIterator, typename ResIterator>
81  void diagonalMatrixVector(MatIterator&, VecIterator&, ResIterator&,
82                            ResIterator&) const;
83  void diagonalVectorMatrix(MatIterator&, VecIterator&, ResIterator&,
84                            ResIterator&) const;
85  void lowerMatrixVector(MatIterator&, VecIterator&, VecIterator&,
86                         ResIterator&, ResIterator&, SymType) const;
87  void lowerVectorMatrix(MatIterator&, VecIterator&, VecIterator&,
88                         ResIterator&, ResIterator&, SymType) const;
89  void upperMatrixVector(MatIterator&, VecIterator&, VecIterator&,
90                         ResIterator&, ResIterator&, SymType) const;
91  void upperVectorMatrix(MatIterator&, VecIterator&, VecIterator&,
92                         ResIterator&, ResIterator&, SymType) const;
93  void rowMatrixVector(MatIterator&, VecIterator&, VecIterator&,
94                       ResIterator&, ResIterator&)  const;
95  void rowVectorMatrix(MatIterator&, VecIterator&, VecIterator&,
96                       ResIterator&, ResIterator&)  const;
97  void columnMatrixVector(MatIterator&, VecIterator&, VecIterator&,
98                          ResIterator&, ResIterator&)  const;
99  void columnVectorMatrix(MatIterator&, VecIterator&, VecIterator&,
100                          ResIterator&, ResIterator&)  const;
101\end{lstlisting}
102Note that the product of matrix and vector are performed either by row or column access, for diagonal part, lower part or upper part. They use iterators to by-pass the templated matrix values vector! With this trick, product algorithms are all located in {\class DenseStorage} class.
103\item addition of two matrices:
104\vspace{.1cm}
105\begin{lstlisting}[]
106template<typename Mat1Iterator, typename Mat2Iterator, typename ResIterator>
107void sumMatrixMatrix(Mat1Iterator&, Mat2Iterator&, ResIterator&, ResIterator&) const;
108\end{lstlisting}
109\vspace{.1cm}
110\end{itemize}
111\displayInfos{library=largeMatrix, header=DenseStorage.hpp, implementation=DenseStorage.cpp, test={test\_LargeMatrixDenseStorage.cpp}, header dep={MatrixStorage.hpp, config.h, utils.h}}
112
113\subsection{{\classtitle RowDenseStorage}, {\classtitle ColDenseStorage}, {\classtitle DualDenseStorage} and {\classtitle SymDenseStorage} classes}
114
115All child classes ({\class RowDenseStorage}, {\class ColDenseStorage}, {\class DualDenseStorage} and {\class SymDenseStorage}) of {\class DenseStorage} class have the same structure. We give here only the description of {\class RowDenseStorage} class. \\
116{\class RowDenseStorage} class manages dense storage where matrix values are stored row by row in values vector. It has no member attribute and has constructors just calling {\class DenseStorage} constructors:
117\vspace{.1cm}
118\begin{lstlisting}
119class RowDenseStorage : public DenseStorage
120{public :
121  RowDenseStorage();
122  RowDenseStorage(Number);
123  RowDenseStorage(Number, Number);
124  virtual ~RowDenseStorage() {}
125  ...
126\end{lstlisting}
127\vspace{.2cm}
128The class provides all the virtual methods declared in {\class MatrixStorage} class :
129\vspace{.1cm}
130\begin{lstlisting}[]
131Number pos(Number i, Number j, SymType s=_noSymmetry) const;
132void positions(const std::vector<Number>&, const std::vector<Number>&,
133               std::vector<Number>&, bool errorOn=true, SymType=_noSymmetry ) const;
134void printEntries(std::ostream&, const std::vector<Real>&,
135                  Number vb = 0, SymType sym = _noSymmetry) const;
136template<typename M, typename V, typename R>
137  void multMatrixVector(const std::vector<M>&, const std::vector<V>&,
138                        std::vector<R>&) const;
139  void multVectorMatrix(const std::vector<M>&, const std::vector<V>&,
140                        std::vector<R>&) const;
141template<typename T>
142  void setDiagValueColDense(std::vector<T>& m, const T k);
143template<typename M1, typename M2, typename R>
144  void addMatrixMatrix(const std::vector<M1>&, const std::vector<M2>&, std::vector<R>&) const;
145  ...
146\end{lstlisting}
147\vspace{.1cm}
148Only version of {\cmd multMatrixVector} and {\cmd multVectorMatrix} are written here for \verb?Real? type but versions for \verb?Complex?, \verb?Matrix<Real>?, \verb?Matrix<Complex>? and mixed types are also provided. \\
149\\
150{\class DualDenseStorage} and {\class SymDenseStorage} classes provides also the size of strict lower and strict upper triangular part:
151\vspace{.1cm}
152\begin{lstlisting}[]
153Number lowerPartSize() const;
154Number upperPartSize() const;
155\end{lstlisting}
156\vspace{.3cm}
157XXX=Row, Col, Dual or Sym
158\displayInfos{library=largeMatrix, header=XXXDenseStorage.hpp, implementation=XXXDenseStorage.cpp, test={test\_LargeMatrixDenseStorage.cpp}, header dep={DenseStorage.hpp, MatrixStorage.hpp, config.h, utils.h}}
159
160
161