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