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 /*!
18 \file DualSkylineStorage.hpp
19 \authors D. Martin, E. Lunéville, NGUYEN Manh Ha, N. Kielbasiewicz
20 \since 24 juin 2011
21 \date 6 Juin 2014
22
23 \brief Definition of the xlifepp::DualSkylineStorage class
24
25 xlifepp::DualSkylineStorage class is the child class of xlifepp::SkylineStorage class dealing with skyline Row/Col Storage
26
27 The diagonal is always first stored, then the lower triangular part in row skyline, then the upper triangular part in col skyline
28 NOTE : the first entry (say (1,1)) is stored at adress 1 in values vector (not at adress 0!)
29
30 - rowPointer_ : for lower part, vector of positions of begining of rows in previous vector
31 - colPointer_ : for upper part, vector of positions of begining of columns in previous vector
32
33
34 Example : The following 5 x 6 non symmetric matrix
35 -------
36 0 d x . x . x
37 1 . d x . . x ndiag = 5
38 2 x x d . . . rowPointer_ = [ 0 0 0 2 3 10 ] (last gives the number of non zeros in the strict lower part)
39 3 . . x d . . colPointer_ = [ 0 0 1 2 5 5 10 ] (last gives the number of non zeros in the strict upper part)
40 4 x . x x d .
41
42 Note : for an empty row, rowPointer_is equal to the previous one : length of row i = rowPointer_[i+1]-rowPointer_[i]
43 for an empty col, colPointer_is equal to the previous one : length of col j = colPointer_[j+1]-colPointer_[j]
44 */
45
46 #ifndef DUAL_SKYLINE_STORAGE_HPP
47 #define DUAL_SKYLINE_STORAGE_HPP
48
49 #include "config.h"
50 #include "SkylineStorage.hpp"
51
52 namespace xlifepp
53 {
54
55 /*!
56 \class DualSkylineStorage
57 child class for dual row/col compressed sparse storage
58 */
59
60 class DualSkylineStorage : public SkylineStorage
61 {
62 protected:
63 std::vector<number_t> rowPointer_; //!< vector of positions of begining of rows
64 std::vector<number_t> colPointer_; //!< vector of positions of begining of cols
65
66 public:
67 // constructor, destructor
68 DualSkylineStorage(number_t nr = 0, number_t nc = 0, string_t id="DualSkylineStorage"); //!< default constructor
69 DualSkylineStorage(const std::vector<number_t>&, const std::vector<number_t>&,
70 string_t id="DualSkylineStorage"); //!< explicit constructor
~DualSkylineStorage()71 ~DualSkylineStorage() {} //!< destructor
72 //! constructor by a pair of global numerotation vectors
73 DualSkylineStorage(number_t, number_t, const std::vector< std::vector<number_t> >&, const std::vector< std::vector<number_t> >&, string_t id="DualSkylineStorage");
74 //! constructor by the list of col index by rows
75 template<class L>
76 DualSkylineStorage(number_t, number_t, const std::vector<L>&, string_t id="DualSkylineStorage");
clone() const77 DualSkylineStorage* clone() const //! create a clone (virtual copy constructor, covariant)
78 {return new DualSkylineStorage(*this);}
79 DualSkylineStorage* toScalar(dimen_t, dimen_t); //!< create a new scalar DualSkyline storage from current DualSkyline storage and submatrix sizes
clear()80 virtual void clear() //! clear storage vectors
81 {rowPointer_.clear();colPointer_.clear();}
82
83 // utilities
size() const84 number_t size() const //! number of non zero elements stored
85 {return std::min(nbRows_, nbCols_) + rowPointer_[nbRows_] + colPointer_[nbCols_];}
lowerPartSize() const86 number_t lowerPartSize() const {return rowPointer_[nbRows_];} //!< returns number of entries of lower triangular part
upperPartSize() const87 number_t upperPartSize() const {return colPointer_[nbCols_];} //!< returns number of entries of upper triangular part
rowPointer() const88 const std::vector<number_t>& rowPointer() const //! returns rowPointer_ (const)
89 {return rowPointer_;}
colPointer() const90 const std::vector<number_t>& colPointer() const //! returns colPointer_ (const)
91 {return colPointer_;}
92 bool sameStorage(const MatrixStorage&) const; //!< check if two storages have the same structures
93
94 // access operator
95 number_t pos(number_t i, number_t j, SymType s = _noSymmetry) const; //!< returns adress of entry (i,j)
96 void positions(const std::vector<number_t>&, const std::vector<number_t>&,
97 std::vector<number_t>&, bool errorOn = true, SymType = _noSymmetry) const; //!< access to submatrix positions
98 std::vector<std::pair<number_t, number_t> > getCol(SymType s, number_t c, number_t r1=1, number_t r2=0) const; //!< get (row indices, adress) of col c in set [r1,r2]
99 std::vector<std::pair<number_t, number_t> > getRow(SymType s, number_t r, number_t c1=1, number_t c2=0) const; //!< get (col indices, adress) of row r in set [c1,c2]
100 void addSubMatrixIndices(const std::vector<number_t>&,const std::vector<number_t>&); //!< add dense submatrix indices to storage
101
102 /* template specializations
103 This rather COMPLICATED implementation of multMatrixVector is made
104 to simulate "template virtual functions" in abstract base class MatrixStorage
105 and thus to avoid "switch...case:" programming and "downcasting" in Matrix*Vector
106 overloaded operator* of class LargeMatrix.
107 Note that the call to template functions above is forced with the "<>" template
108 descriptor in the following specialized virtual functions (this is not recursion) */
109
110 /*------------------------------------------------------------------------------------------------------------------
111 input and output stuff
112 ------------------------------------------------------------------------------------------------------------------*/
113 void print(std::ostream&) const; //!< print storage pointers
114 void printEntries(std::ostream&, const std::vector<real_t>&,
115 number_t vb, const SymType sym) const; //!< print real scalar matrix
116 void printEntries(std::ostream&, const std::vector<complex_t>&,
117 number_t vb, const SymType sym) const; //!< print complex scalar matrix
118 void printEntries(std::ostream&, const std::vector<Matrix<real_t> >&,
119 number_t vb, const SymType sym) const; //!< print matrix of real matrices
120 void printEntries(std::ostream&, const std::vector<Matrix<complex_t> >&,
121 number_t vb, const SymType sym) const; //!< print matrix of complex matrices
122 void printEntries(std::ostream&, const std::vector<Vector<real_t> >&,
123 number_t vb, const SymType sym) const; //!< print matrix of real vectors (not available)
124 void printEntries(std::ostream&, const std::vector<Vector<complex_t> >&,
125 number_t vb, const SymType sym) const; //!< print matrix of complex vectors (not available)
126
127 template<typename MatIterator>
128 void printCooMatrix(MatIterator&, SymType, std::ostream&) const; //!< output matrix of real scalars in coordinate form
129 void printCooMatrix(std::ostream&, const std::vector<real_t>&,
130 SymType s = _noSymmetry) const; //!< output matrix of real scalars in coordinate form
131 void printCooMatrix(std::ostream&, const std::vector<complex_t>&,
132 SymType s = _noSymmetry) const; //!< output matrix of real scalars in coordinate form
133 void printCooMatrix(std::ostream&, const std::vector< Matrix<real_t> >&,
134 SymType s = _noSymmetry) const; //!< output matrix of real scalars in coordinate form
135 void printCooMatrix(std::ostream&, const std::vector< Matrix<complex_t> >&,
136 SymType s = _noSymmetry) const; //!< output matrix of complex scalars in coordinate form
137
print(PrintStream & os) const138 void print(PrintStream& os) const
139 {print(os.currentStream());}
printEntries(PrintStream & os,const std::vector<real_t> & m,number_t vb,const SymType sym) const140 void printEntries(PrintStream& os, const std::vector<real_t>& m, number_t vb, const SymType sym) const
141 {printEntries(os.currentStream(), m, vb, sym);}
printEntries(PrintStream & os,const std::vector<complex_t> & m,number_t vb,const SymType sym) const142 void printEntries(PrintStream& os, const std::vector<complex_t>& m, number_t vb, const SymType sym) const
143 {printEntries(os.currentStream(), m, vb, sym);}
printEntries(PrintStream & os,const std::vector<Matrix<real_t>> & m,number_t vb,const SymType sym) const144 void printEntries(PrintStream& os, const std::vector<Matrix<real_t> >& m, number_t vb, const SymType sym) const
145 {printEntries(os.currentStream(), m, vb, sym);}
printEntries(PrintStream & os,const std::vector<Matrix<complex_t>> & m,number_t vb,const SymType sym) const146 void printEntries(PrintStream& os, const std::vector<Matrix<complex_t> >& m, number_t vb, const SymType sym) const
147 {printEntries(os.currentStream(), m, vb, sym);}
printEntries(PrintStream & os,const std::vector<Vector<real_t>> & m,number_t vb,const SymType sym) const148 void printEntries(PrintStream& os, const std::vector<Vector<real_t> >& m, number_t vb, const SymType sym) const
149 {printEntries(os.currentStream(), m, vb, sym);}
printEntries(PrintStream & os,const std::vector<Vector<complex_t>> & m,number_t vb,const SymType sym) const150 void printEntries(PrintStream& os, const std::vector<Vector<complex_t> >& m, number_t vb, const SymType sym) const
151 {printEntries(os.currentStream(), m, vb, sym);}
printCooMatrix(PrintStream & os,const std::vector<real_t> & m,SymType s=_noSymmetry) const152 void printCooMatrix(PrintStream& os, const std::vector<real_t>& m, SymType s = _noSymmetry) const
153 {printCooMatrix(os.currentStream(), m, s);}
printCooMatrix(PrintStream & os,const std::vector<complex_t> & m,SymType s=_noSymmetry) const154 void printCooMatrix(PrintStream& os, const std::vector<complex_t>& m,SymType s = _noSymmetry) const
155 {printCooMatrix(os.currentStream(), m, s);}
printCooMatrix(PrintStream & os,const std::vector<Matrix<real_t>> & m,SymType s=_noSymmetry) const156 void printCooMatrix(PrintStream& os, const std::vector< Matrix<real_t> >& m, SymType s = _noSymmetry) const
157 {printCooMatrix(os.currentStream(), m, s);}
printCooMatrix(PrintStream & os,const std::vector<Matrix<complex_t>> & m,SymType s=_noSymmetry) const158 void printCooMatrix(PrintStream& os, const std::vector< Matrix<complex_t> >& m, SymType s = _noSymmetry) const
159 {printCooMatrix(os.currentStream(), m, s);}
160
161 // load from file utilities
162 //! load from dense matrix in file
loadFromFileDense(std::istream & ifs,std::vector<real_t> & mat,SymType sym,bool realAsCmplx)163 void loadFromFileDense(std::istream& ifs, std::vector<real_t>& mat, SymType sym, bool realAsCmplx)
164 {loadSkylineFromFileDense(ifs, mat, rowPointer_, colPointer_, sym, realAsCmplx);}
165 //! load from dense matrix in file
loadFromFileDense(std::istream & ifs,std::vector<complex_t> & mat,SymType sym,bool realAsCmplx)166 void loadFromFileDense(std::istream& ifs, std::vector<complex_t>& mat, SymType sym, bool realAsCmplx)
167 {loadSkylineFromFileDense(ifs, mat, rowPointer_, colPointer_, sym, realAsCmplx);}
168 //! load from coordinate matrix in file
loadFromFileCoo(std::istream & ifs,std::vector<real_t> & mat,SymType sym,bool realAsCmplx)169 void loadFromFileCoo(std::istream& ifs, std::vector<real_t>& mat, SymType sym, bool realAsCmplx)
170 {loadSkylineFromFileCoo(ifs, mat, rowPointer_, colPointer_, sym, realAsCmplx);}
171 //! load from coordinate matrix in fire
loadFromFileCoo(std::istream & ifs,std::vector<complex_t> & mat,SymType sym,bool realAsCmplx)172 void loadFromFileCoo(std::istream& ifs, std::vector<complex_t>& mat, SymType sym, bool realAsCmplx)
173 {loadSkylineFromFileCoo(ifs, mat, rowPointer_, colPointer_, sym, realAsCmplx);}
174
175
176 /*------------------------------------------------------------------------------------------------------------------
177 basic algebra stuff
178 ------------------------------------------------------------------------------------------------------------------*/
179 //! Set the Diagonal with a specific value
180 template<typename T>
setDiagValueDualSkyline(std::vector<T> & v,const T m)181 void setDiagValueDualSkyline(std::vector<T>& v, const T m)
182 {
183 typename std::vector<T>::iterator it = v.begin() + 1;
184 number_t diagSize = diagonalSize() + 1;
185 for (number_t k = 1; k < diagSize; k++, it++) {*it = m;}
186 }
187 //@{
188 //! Set value of Diagonal
setDiagValue(std::vector<real_t> & m,const real_t k)189 void setDiagValue(std::vector<real_t>& m, const real_t k)
190 { setDiagValueDualSkyline<>(m, k);}
setDiagValue(std::vector<complex_t> & m,const complex_t k)191 void setDiagValue(std::vector<complex_t>& m, const complex_t k)
192 { setDiagValueDualSkyline<>(m, k);}
193 //@}
194 // template Matrix + Matrix addition and specializations (see below)
195 template<typename M1, typename M2, typename R>
196 void addMatrixMatrix(const std::vector<M1>&, const std::vector<M2>&, std::vector<R>&) const; //!< templated skyline dual Matrix + Matrix
197
198 //@{
199 //! Matrix+Matrix
addMatrixMatrix(const std::vector<real_t> & m,const std::vector<real_t> & v,std::vector<real_t> & rv) const200 void addMatrixMatrix(const std::vector<real_t>& m, const std::vector<real_t>& v, std::vector<real_t>& rv) const
201 { addMatrixMatrix<>(m, v, rv);}
addMatrixMatrix(const std::vector<real_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv) const202 void addMatrixMatrix(const std::vector<real_t>& m, const std::vector<complex_t>& v, std::vector<complex_t>& rv) const
203 { addMatrixMatrix<>(m, v, rv); }
addMatrixMatrix(const std::vector<complex_t> & m,const std::vector<real_t> & v,std::vector<complex_t> & rv) const204 void addMatrixMatrix(const std::vector<complex_t>& m, const std::vector<real_t>& v, std::vector<complex_t>& rv) const
205 { addMatrixMatrix<>(m, v, rv); }
addMatrixMatrix(const std::vector<complex_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv) const206 void addMatrixMatrix(const std::vector<complex_t>& m, const std::vector<complex_t>& v, std::vector<complex_t>& rv) const
207 { addMatrixMatrix<>(m, v, rv); }
208
209 template<typename M1, typename M2>
210 void addTwoMatrixDualSkyline(std::vector<M1>&, SymType, const std::vector<number_t>&, const std::vector<number_t>&, const std::vector<M2>&, SymType);
addTwoMatrix(std::vector<real_t> & m1,SymType st1,const std::vector<number_t> & rowPtr2,const std::vector<number_t> & colPtr2,const std::vector<real_t> & m2,SymType st2)211 void addTwoMatrix(std::vector<real_t>& m1, SymType st1, const std::vector<number_t>& rowPtr2, const std::vector<number_t>& colPtr2, const std::vector<real_t>& m2, SymType st2)
212 { addTwoMatrixDualSkyline<>(m1, st1, rowPtr2, colPtr2, m2, st2); }
addTwoMatrix(std::vector<complex_t> & m1,SymType st1,const std::vector<number_t> & rowPtr2,const std::vector<number_t> & colPtr2,const std::vector<real_t> & m2,SymType st2)213 void addTwoMatrix(std::vector<complex_t>& m1, SymType st1, const std::vector<number_t>& rowPtr2, const std::vector<number_t>& colPtr2, const std::vector<real_t>& m2, SymType st2)
214 { addTwoMatrixDualSkyline<>(m1, st1, rowPtr2, colPtr2, m2, st2); }
addTwoMatrix(std::vector<complex_t> & m1,SymType st1,const std::vector<number_t> & rowPtr2,const std::vector<number_t> & colPtr2,const std::vector<complex_t> & m2,SymType st2)215 void addTwoMatrix(std::vector<complex_t>& m1, SymType st1, const std::vector<number_t>& rowPtr2, const std::vector<number_t>& colPtr2, const std::vector<complex_t>& m2, SymType st2)
216 { addTwoMatrixDualSkyline<>(m1, st1, rowPtr2, colPtr2, m2, st2); }
217 //@}
218
219 /*------------------------------------------------------------------------------------------------------------------
220 template Matrix x Vector & Vector x Matrix multiplications and specializations
221 ------------------------------------------------------------------------------------------------------------------*/
222 template<typename M, typename V, typename R>
223 void multMatrixVector(const std::vector<M>&, const std::vector<V>&, std::vector<R>&) const; //!< templated dual_skyline Matrix x Vector
224 template<typename M, typename V, typename R>
225 void multVectorMatrix(const std::vector<M>&, const std::vector<V>&, std::vector<R>&) const; //!< templated Vector x dual_skyline Matrix
226 template<typename M, typename V, typename R>
227 void multMatrixVector(const std::vector<M>& m, V* vp, R* rp) const; //!< templated dual_skyline Matrix x Vector (pointer form)
228 template<typename M, typename V, typename R>
229 void multVectorMatrix(const std::vector<M>& m, V* vp, R* rp) const; //!< templated Vector x dual_skyline Matrix (pointer form)
230
231 //@{
232 //! Matrix (Scalar) * Vector (Scalar)
multMatrixVector(const std::vector<real_t> & m,const std::vector<real_t> & v,std::vector<real_t> & rv,SymType sym) const233 void multMatrixVector(const std::vector<real_t>& m, const std::vector<real_t>& v, std::vector<real_t>& rv, SymType sym) const
234 { multMatrixVector<>(m, v, rv); }
multMatrixVector(const std::vector<real_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType sym) const235 void multMatrixVector(const std::vector<real_t>& m, const std::vector<complex_t>& v, std::vector<complex_t>& rv, SymType sym) const
236 { multMatrixVector<>(m, v, rv); }
multMatrixVector(const std::vector<complex_t> & m,const std::vector<real_t> & v,std::vector<complex_t> & rv,SymType sym) const237 void multMatrixVector(const std::vector<complex_t>& m, const std::vector<real_t>& v, std::vector<complex_t>& rv, SymType sym) const
238 { multMatrixVector<>(m, v, rv); }
multMatrixVector(const std::vector<complex_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType sym) const239 void multMatrixVector(const std::vector<complex_t>& m, const std::vector<complex_t>& v, std::vector<complex_t>& rv, SymType sym) const
240 { multMatrixVector<>(m, v, rv); }
241 //@}
242
243 //@{
244 //! Matrix (Matrix) * Vector (Vector)
multMatrixVector(const std::vector<Matrix<real_t>> & m,const std::vector<Vector<real_t>> & v,std::vector<Vector<real_t>> & rv,SymType sym) const245 void multMatrixVector(const std::vector< Matrix<real_t> >& m, const std::vector< Vector<real_t> >& v, std::vector< Vector<real_t> >& rv, SymType sym) const
246 { multMatrixVector<>(m, v, rv); }
multMatrixVector(const std::vector<Matrix<real_t>> & m,const std::vector<Vector<complex_t>> & v,std::vector<Vector<complex_t>> & rv,SymType sym) const247 void multMatrixVector(const std::vector< Matrix<real_t> >& m, const std::vector< Vector<complex_t> >& v, std::vector< Vector<complex_t> >& rv, SymType sym) const
248 { multMatrixVector<>(m, v, rv); }
multMatrixVector(const std::vector<Matrix<complex_t>> & m,const std::vector<Vector<real_t>> & v,std::vector<Vector<complex_t>> & rv,SymType sym) const249 void multMatrixVector(const std::vector< Matrix<complex_t> >& m, const std::vector< Vector<real_t> >& v, std::vector< Vector<complex_t> >& rv, SymType sym) const
250 { multMatrixVector<>(m, v, rv); }
multMatrixVector(const std::vector<Matrix<complex_t>> & m,const std::vector<Vector<complex_t>> & v,std::vector<Vector<complex_t>> & rv,SymType sym) const251 void multMatrixVector(const std::vector< Matrix<complex_t> >& m, const std::vector< Vector<complex_t> >& v, std::vector< Vector<complex_t> >& rv, SymType sym) const
252 { multMatrixVector<>(m, v, rv); }
253 //@}
254
255 //@{
256 //! Vector (Scalar) * Matrix (Scalar)
multVectorMatrix(const std::vector<real_t> & m,const std::vector<real_t> & v,std::vector<real_t> & rv,SymType sym) const257 void multVectorMatrix(const std::vector<real_t>& m, const std::vector<real_t>& v, std::vector<real_t>& rv, SymType sym) const
258 { multVectorMatrix<>(m, v, rv); }
multVectorMatrix(const std::vector<real_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType sym) const259 void multVectorMatrix(const std::vector<real_t>& m, const std::vector<complex_t>& v, std::vector<complex_t>& rv, SymType sym) const
260 { multVectorMatrix<>(m, v, rv); }
multVectorMatrix(const std::vector<complex_t> & m,const std::vector<real_t> & v,std::vector<complex_t> & rv,SymType sym) const261 void multVectorMatrix(const std::vector<complex_t>& m, const std::vector<real_t>& v, std::vector<complex_t>& rv, SymType sym) const
262 { multVectorMatrix<>(m, v, rv); }
multVectorMatrix(const std::vector<complex_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType sym) const263 void multVectorMatrix(const std::vector<complex_t>& m, const std::vector<complex_t>& v, std::vector<complex_t>& rv, SymType sym) const
264 { multVectorMatrix<>(m, v, rv); }
265 //@}
266
267 //@{ Matrix (Matrix) * Vector (Vector)
multVectorMatrix(const std::vector<Matrix<real_t>> & m,const std::vector<Vector<real_t>> & v,std::vector<Vector<real_t>> & rv,SymType sym) const268 void multVectorMatrix(const std::vector< Matrix<real_t> >& m, const std::vector< Vector<real_t> >& v, std::vector< Vector<real_t> >& rv, SymType sym) const
269 { multVectorMatrix<>(m, v, rv); }
multVectorMatrix(const std::vector<Matrix<real_t>> & m,const std::vector<Vector<complex_t>> & v,std::vector<Vector<complex_t>> & rv,SymType sym) const270 void multVectorMatrix(const std::vector< Matrix<real_t> >& m, const std::vector< Vector<complex_t> >& v, std::vector< Vector<complex_t> >& rv, SymType sym) const
271 { multVectorMatrix<>(m, v, rv); }
multVectorMatrix(const std::vector<Matrix<complex_t>> & m,const std::vector<Vector<real_t>> & v,std::vector<Vector<complex_t>> & rv,SymType sym) const272 void multVectorMatrix(const std::vector< Matrix<complex_t> >& m, const std::vector< Vector<real_t> >& v, std::vector< Vector<complex_t> >& rv, SymType sym) const
273 { multVectorMatrix<>(m, v, rv); }
multVectorMatrix(const std::vector<Matrix<complex_t>> & m,const std::vector<Vector<complex_t>> & v,std::vector<Vector<complex_t>> & rv,SymType sym) const274 void multVectorMatrix(const std::vector< Matrix<complex_t> >& m, const std::vector< Vector<complex_t> >& v, std::vector< Vector<complex_t> >& rv, SymType sym) const
275 { multVectorMatrix<>(m, v, rv); }
276 //@}
277
278 //@{
279 //! Matrix * Vector (pointer form)
multMatrixVector(const std::vector<real_t> & m,real_t * vp,real_t * rp,SymType sym) const280 void multMatrixVector(const std::vector<real_t>& m, real_t* vp, real_t* rp, SymType sym) const
281 { multMatrixVector<>(m, vp, rp); }
multMatrixVector(const std::vector<real_t> & m,complex_t * vp,complex_t * rp,SymType sym) const282 void multMatrixVector(const std::vector<real_t>& m, complex_t* vp, complex_t* rp, SymType sym) const
283 { multMatrixVector<>(m, vp, rp); }
multMatrixVector(const std::vector<complex_t> & m,real_t * vp,complex_t * rp,SymType sym) const284 void multMatrixVector(const std::vector<complex_t>& m, real_t* vp, complex_t* rp, SymType sym) const
285 { multMatrixVector<>(m, vp, rp); }
multMatrixVector(const std::vector<complex_t> & m,complex_t * vp,complex_t * rp,SymType sym) const286 void multMatrixVector(const std::vector<complex_t>& m, complex_t* vp, complex_t* rp, SymType sym) const
287 { multMatrixVector<>(m, vp, rp); }
288 //@}
289
290 //@{
291 //! Vector * Matrix (pointer form)
multVectorMatrix(const std::vector<real_t> & m,real_t * vp,real_t * rp,SymType sym) const292 void multVectorMatrix(const std::vector<real_t>& m, real_t* vp, real_t* rp, SymType sym) const
293 { multVectorMatrix<>(m, vp, rp); }
multVectorMatrix(const std::vector<real_t> & m,complex_t * vp,complex_t * rp,SymType sym) const294 void multVectorMatrix(const std::vector<real_t>& m, complex_t* vp, complex_t* rp, SymType sym) const
295 { multVectorMatrix<>(m, vp, rp); }
multVectorMatrix(const std::vector<complex_t> & m,real_t * vp,complex_t * rp,SymType sym) const296 void multVectorMatrix(const std::vector<complex_t>& m, real_t* vp, complex_t* rp, SymType sym) const
297 { multVectorMatrix<>(m, vp, rp); }
multVectorMatrix(const std::vector<complex_t> & m,complex_t * vp,complex_t * rp,SymType sym) const298 void multVectorMatrix(const std::vector<complex_t>& m, complex_t* vp, complex_t* rp, SymType sym) const
299 { multVectorMatrix<>(m, vp, rp); }
300 //@}
301
302 /*---------------------------------------------------------------------------------------------------------------------
303 triangular part matrix * vector
304 ------------------------------------------------------------------------------------------------------------------*/
305 template<typename M, typename V, typename R>
306 void lowerMatrixVector(const std::vector<M>&, const std::vector<V>&, std::vector<R>&) const;
307 //@{
308 //! lower Matrix (Scalar) * Vector (Scalar)
lowerMatrixVector(const std::vector<real_t> & m,const std::vector<real_t> & v,std::vector<real_t> & rv,SymType s) const309 virtual void lowerMatrixVector(const std::vector<real_t>&m, const std::vector<real_t>&v, std::vector<real_t>&rv, SymType s) const
310 {lowerMatrixVector<>(m,v,rv);}
lowerMatrixVector(const std::vector<real_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const311 virtual void lowerMatrixVector(const std::vector<real_t>&m, const std::vector<complex_t>&v, std::vector<complex_t>&rv, SymType s) const
312 {lowerMatrixVector<>(m,v,rv);}
lowerMatrixVector(const std::vector<complex_t> & m,const std::vector<real_t> & v,std::vector<complex_t> & rv,SymType s) const313 virtual void lowerMatrixVector(const std::vector<complex_t>&m, const std::vector<real_t>&v, std::vector<complex_t>&rv, SymType s) const
314 {lowerMatrixVector<>(m,v,rv);}
lowerMatrixVector(const std::vector<complex_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const315 virtual void lowerMatrixVector(const std::vector<complex_t>&m, const std::vector<complex_t>&v, std::vector<complex_t>&rv, SymType s) const
316 {lowerMatrixVector<>(m,v,rv);}
317 //@}
318 template<typename M, typename V, typename R>
319 void lowerD1MatrixVector(const std::vector<M>&, const std::vector<V>&, std::vector<R>&) const;
320 //@{
321 //! lower Matrix diag 1 (Scalar) * Vector (Scalar)
lowerD1MatrixVector(const std::vector<real_t> & m,const std::vector<real_t> & v,std::vector<real_t> & rv,SymType s) const322 virtual void lowerD1MatrixVector(const std::vector<real_t>& m, const std::vector<real_t>& v, std::vector<real_t>& rv, SymType s) const
323 {lowerD1MatrixVector<>(m,v,rv);}
lowerD1MatrixVector(const std::vector<real_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const324 virtual void lowerD1MatrixVector(const std::vector<real_t>& m, const std::vector<complex_t>& v, std::vector<complex_t>& rv, SymType s) const
325 {lowerD1MatrixVector<>(m,v,rv);}
lowerD1MatrixVector(const std::vector<complex_t> & m,const std::vector<real_t> & v,std::vector<complex_t> & rv,SymType s) const326 virtual void lowerD1MatrixVector(const std::vector<complex_t>& m, const std::vector<real_t>& v, std::vector<complex_t>& rv, SymType s) const
327 {lowerD1MatrixVector<>(m,v,rv);}
lowerD1MatrixVector(const std::vector<complex_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const328 virtual void lowerD1MatrixVector(const std::vector<complex_t>& m, const std::vector<complex_t>& v, std::vector<complex_t>& rv, SymType s) const
329 {lowerD1MatrixVector<>(m,v,rv);}
330 //@}
331 template<typename M, typename V, typename R>
332 void upperMatrixVector(const std::vector<M>&, const std::vector<V>&, std::vector<R>&) const;
333 //@{
334 //! upper Matrix (Scalar) * Vector (Scalar)
upperMatrixVector(const std::vector<real_t> & m,const std::vector<real_t> & v,std::vector<real_t> & rv,SymType s) const335 virtual void upperMatrixVector(const std::vector<real_t>&m, const std::vector<real_t>&v, std::vector<real_t>&rv, SymType s) const
336 {upperMatrixVector<>(m,v,rv);}
upperMatrixVector(const std::vector<real_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const337 virtual void upperMatrixVector(const std::vector<real_t>&m, const std::vector<complex_t>&v, std::vector<complex_t>&rv, SymType s) const
338 {upperMatrixVector<>(m,v,rv);}
upperMatrixVector(const std::vector<complex_t> & m,const std::vector<real_t> & v,std::vector<complex_t> & rv,SymType s) const339 virtual void upperMatrixVector(const std::vector<complex_t>&m, const std::vector<real_t>&v, std::vector<complex_t>&rv, SymType s) const
340 {upperMatrixVector<>(m,v,rv);}
upperMatrixVector(const std::vector<complex_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const341 virtual void upperMatrixVector(const std::vector<complex_t>&m, const std::vector<complex_t>&v, std::vector<complex_t>&rv, SymType s) const
342 {upperMatrixVector<>(m,v,rv);}
343 //@}
344 template<typename M, typename V, typename R>
345 void upperD1MatrixVector(const std::vector<M>&, const std::vector<V>&, std::vector<R>&) const;
346 //@{
347 //! upper Matrix diag 1 (Scalar) * Vector (Scalar)
upperD1MatrixVector(const std::vector<real_t> & m,const std::vector<real_t> & v,std::vector<real_t> & rv,SymType s) const348 virtual void upperD1MatrixVector(const std::vector<real_t>&m, const std::vector<real_t>&v, std::vector<real_t>&rv, SymType s) const
349 {upperD1MatrixVector<>(m,v,rv);}
upperD1MatrixVector(const std::vector<real_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const350 virtual void upperD1MatrixVector(const std::vector<real_t>&m, const std::vector<complex_t>&v, std::vector<complex_t>&rv, SymType s) const
351 {upperD1MatrixVector<>(m,v,rv);}
upperD1MatrixVector(const std::vector<complex_t> & m,const std::vector<real_t> & v,std::vector<complex_t> & rv,SymType s) const352 virtual void upperD1MatrixVector(const std::vector<complex_t>&m, const std::vector<real_t>&v, std::vector<complex_t>&rv, SymType s) const
353 {upperD1MatrixVector<>(m,v,rv);}
upperD1MatrixVector(const std::vector<complex_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const354 virtual void upperD1MatrixVector(const std::vector<complex_t>&m, const std::vector<complex_t>&v, std::vector<complex_t>&rv, SymType s) const
355 {upperD1MatrixVector<>(m,v,rv);}
356 //@}
357 template<typename M, typename V, typename R>
358 void diagonalMatrixVector(const std::vector<M>&, const std::vector<V>&, std::vector<R>&) const;
359 //@{
360 //! diag Matrix * Vector (Scalar)
diagonalMatrixVector(const std::vector<real_t> & m,const std::vector<real_t> & v,std::vector<real_t> & rv,SymType s) const361 virtual void diagonalMatrixVector(const std::vector<real_t>&m, const std::vector<real_t>&v, std::vector<real_t>&rv, SymType s) const
362 {diagonalMatrixVector<>(m,v,rv);}
diagonalMatrixVector(const std::vector<real_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const363 virtual void diagonalMatrixVector(const std::vector<real_t>&m, const std::vector<complex_t>&v, std::vector<complex_t>&rv, SymType s) const
364 {diagonalMatrixVector<>(m,v,rv);}
diagonalMatrixVector(const std::vector<complex_t> & m,const std::vector<real_t> & v,std::vector<complex_t> & rv,SymType s) const365 virtual void diagonalMatrixVector(const std::vector<complex_t>&m, const std::vector<real_t>&v, std::vector<complex_t>&rv, SymType s) const
366 {diagonalMatrixVector<>(m,v,rv);}
diagonalMatrixVector(const std::vector<complex_t> & m,const std::vector<complex_t> & v,std::vector<complex_t> & rv,SymType s) const367 virtual void diagonalMatrixVector(const std::vector<complex_t>&m, const std::vector<complex_t>&v, std::vector<complex_t>&rv, SymType s) const
368 {diagonalMatrixVector<>(m,v,rv);}
369 //@}
370
371 //----------------------------------------------------------------------------------------------------------------
372 // direct solver stuff
373 //----------------------------------------------------------------------------------------------------------------
374 //! Template LU factorization
375 template<typename M>
376 void lu(std::vector<M>& m, std::vector<M>& fa) const;
377
378 //! Matrix factorization with LU
379 template<typename M>
380 void luParallel(std::vector<M>& m, std::vector<M>& fa) const;
381
382 //@{
383 //! specializations of template LU
lu(std::vector<real_t> & m,std::vector<real_t> & fa,const SymType sym=_noSymmetry) const384 void lu(std::vector<real_t>& m, std::vector<real_t>& fa, const SymType sym = _noSymmetry) const
385 {
386 #ifdef XLIFEPP_WITH_OMP
387 luParallel<>(m, fa);
388 #else
389 lu<>(m, fa);
390 #endif
391 }
392
lu(std::vector<complex_t> & m,std::vector<complex_t> & fa,const SymType sym=_noSymmetry) const393 void lu(std::vector<complex_t>& m, std::vector<complex_t>& fa, const SymType sym = _noSymmetry) const
394 {
395 #ifdef XLIFEPP_WITH_OMP
396 luParallel<>(m, fa);
397 #else
398 lu<>(m, fa);
399 #endif
400 }
401 //@}
402
403 /*!
404 Template diagonal and triangular part solvers (after factorization)
405 Lower triangular with unit diagonal linear system solver : (I+L) x = b
406 */
407 template<typename M, typename V, typename X>
408 void lowerD1Solver(const std::vector<M>& m, std::vector<V>& v, std::vector<X>& x) const;
409 //@{
410 //! Specializations of lower triangular part with unit diagonal linear solvers (I + L) x = v */
lowerD1Solver(const std::vector<real_t> & m,std::vector<real_t> & v,std::vector<real_t> & x) const411 void lowerD1Solver(const std::vector<real_t>& m, std::vector<real_t>& v, std::vector<real_t>& x) const
412 { lowerD1Solver<>(m, v, x); }
lowerD1Solver(const std::vector<real_t> & m,std::vector<complex_t> & v,std::vector<complex_t> & x) const413 void lowerD1Solver(const std::vector<real_t>& m, std::vector<complex_t>& v, std::vector<complex_t>& x) const
414 { lowerD1Solver<>(m, v, x); }
lowerD1Solver(const std::vector<complex_t> & m,std::vector<real_t> & v,std::vector<complex_t> & x) const415 void lowerD1Solver(const std::vector<complex_t>& m, std::vector<real_t>& v, std::vector<complex_t>& x) const
416 { lowerD1Solver<>(m, v, x); }
lowerD1Solver(const std::vector<complex_t> & m,std::vector<complex_t> & v,std::vector<complex_t> & x) const417 void lowerD1Solver(const std::vector<complex_t>& m, std::vector<complex_t>& v, std::vector<complex_t>& x) const
418 { lowerD1Solver<>(m, v, x); }
419 //@}
420
421 //! Diagonal linear system solver : D x = b
422 template<typename M, typename V, typename X>
423 void diagonalSolver(const std::vector<M>& m, std::vector<V>& v, std::vector<X>& x) const;
424 //@{
425 //! Specializations of diagonal linear solvers D x = v
diagonalSolver(const std::vector<real_t> & m,std::vector<real_t> & v,std::vector<real_t> & x) const426 void diagonalSolver(const std::vector<real_t>& m, std::vector<real_t>& v, std::vector<real_t>& x) const
427 { diagonalSolver<>(m, v, x); }
diagonalSolver(const std::vector<real_t> & m,std::vector<complex_t> & v,std::vector<complex_t> & x) const428 void diagonalSolver(const std::vector<real_t>& m, std::vector<complex_t>& v, std::vector<complex_t>& x) const
429 { diagonalSolver<>(m, v, x); }
diagonalSolver(const std::vector<complex_t> & m,std::vector<real_t> & v,std::vector<complex_t> & x) const430 void diagonalSolver(const std::vector<complex_t>& m, std::vector<real_t>& v, std::vector<complex_t>& x) const
431 { diagonalSolver<>(m, v, x); }
diagonalSolver(const std::vector<complex_t> & m,std::vector<complex_t> & v,std::vector<complex_t> & x) const432 void diagonalSolver(const std::vector<complex_t>& m, std::vector<complex_t>& v, std::vector<complex_t>& x) const
433 { diagonalSolver<>(m, v, x); }
434 //@}
435
436 //! Upper triangular with unit diagonal linear system solver : (I+U) x = b
437 template<typename M, typename V, typename X>
438 void upperD1Solver(const std::vector<M>& m, std::vector<V>& v, std::vector<X>& x, const SymType sym) const;
439 //@{
440 //! Specializations of upper triangular part with unit diagonal linear solvers (I + U) x = v
upperD1Solver(const std::vector<real_t> & m,std::vector<real_t> & v,std::vector<real_t> & x,const SymType sym=_noSymmetry) const441 void upperD1Solver(const std::vector<real_t>& m, std::vector<real_t>& v, std::vector<real_t>& x, const SymType sym = _noSymmetry) const
442 { upperD1Solver<>(m, v, x, sym); }
upperD1Solver(const std::vector<real_t> & m,std::vector<complex_t> & v,std::vector<complex_t> & x,const SymType sym=_noSymmetry) const443 void upperD1Solver(const std::vector<real_t>& m, std::vector<complex_t>& v, std::vector<complex_t>& x, const SymType sym = _noSymmetry) const
444 { upperD1Solver<>(m, v, x, sym); }
upperD1Solver(const std::vector<complex_t> & m,std::vector<real_t> & v,std::vector<complex_t> & x,const SymType sym=_noSymmetry) const445 void upperD1Solver(const std::vector<complex_t>& m, std::vector<real_t>& v, std::vector<complex_t>& x, const SymType sym = _noSymmetry) const
446 { upperD1Solver<>(m, v, x, sym); }
upperD1Solver(const std::vector<complex_t> & m,std::vector<complex_t> & v,std::vector<complex_t> & x,const SymType sym=_noSymmetry) const447 void upperD1Solver(const std::vector<complex_t>& m, std::vector<complex_t>& v, std::vector<complex_t>& x, const SymType sym = _noSymmetry) const
448 { upperD1Solver<>(m, v, x, sym); }
449 //@}
450
451 //! upper triangular linear system solver : (D+U) x = b
452 template<typename M, typename V, typename X>
453 void upperSolver(const std::vector<M>& m, std::vector<V>& v, std::vector<X>& x) const;
454 //@{
455 //! specializations of upper triangular part linear solvers (D + U) x = v
upperSolver(const std::vector<real_t> & m,std::vector<real_t> & v,std::vector<real_t> & x,const SymType sym) const456 void upperSolver(const std::vector<real_t>& m, std::vector<real_t>& v, std::vector<real_t>& x, const SymType sym) const
457 { upperSolver<>(m, v, x); }
upperSolver(const std::vector<real_t> & m,std::vector<complex_t> & v,std::vector<complex_t> & x,const SymType) const458 void upperSolver(const std::vector<real_t>& m, std::vector<complex_t>& v, std::vector<complex_t>& x, const SymType) const
459 { upperSolver<>(m, v, x); }
upperSolver(const std::vector<complex_t> & m,std::vector<real_t> & v,std::vector<complex_t> & x,const SymType sym) const460 void upperSolver(const std::vector<complex_t>& m, std::vector<real_t>& v, std::vector<complex_t>& x, const SymType sym) const
461 { upperSolver<>(m, v, x); }
upperSolver(const std::vector<complex_t> & m,std::vector<complex_t> & v,std::vector<complex_t> & x,const SymType sym) const462 void upperSolver(const std::vector<complex_t>& m, std::vector<complex_t>& v, std::vector<complex_t>& x, const SymType sym) const
463 { upperSolver<>(m, v, x); }
464 //@}
465
466 /* ----------------------------------------------------------------------------------------------------------------------------
467 UMFpack stuff
468 ----------------------------------------------------------------------------------------------------------------------------*/
469 //! conversion to umfpack format
470 template<typename M, typename OrdinalType>
471 void toUmfPack(const std::vector<M>& values, std::vector<OrdinalType>& colPointer, std::vector<OrdinalType>& rowIndex, std::vector<M>& mat) const;
472 //@{
473 //! specializations of umfpack conversion
toUmfPack(const std::vector<real_t> & values,std::vector<int_t> & colPointer,std::vector<int_t> & rowIndex,std::vector<real_t> & mat,const SymType sym) const474 void toUmfPack(const std::vector<real_t>& values, std::vector<int_t>& colPointer, std::vector<int_t>& rowIndex, std::vector<real_t>& mat, const SymType sym) const
475 { toUmfPack<>(values,colPointer,rowIndex,mat);}
toUmfPack(const std::vector<complex_t> & values,std::vector<int_t> & colPointer,std::vector<int_t> & rowIndex,std::vector<complex_t> & mat,const SymType sym) const476 void toUmfPack(const std::vector<complex_t>& values, std::vector<int_t>& colPointer, std::vector<int_t>& rowIndex, std::vector<complex_t>& mat, const SymType sym) const
477 { toUmfPack<>(values,colPointer,rowIndex,mat);}
478 //@}
479
480 }; //end of class definition
481
482
483 // constructor from the list of col index of non zero for each row
484 // cols[k] of type L stores the indices of column of non zero element on row k (index starts at 1!)
485 // only requirement on L are the definition of forward const iterator named ::const_iterator
486 // and the size
487 // works for L = vector<number_t>, list<number_t>, set<number_t>
488 template<class L>
DualSkylineStorage(number_t nr,number_t nc,const std::vector<L> & cols,string_t id)489 DualSkylineStorage::DualSkylineStorage(number_t nr, number_t nc, const std::vector<L>& cols, string_t id)
490 : SkylineStorage(nr, nc, _dual, id)
491 {
492 trace_p->push("DualSkylineStorage constructor");
493
494 // construct rowPointer_ for strict lower part
495 typename std::vector<L>::const_iterator itvn;
496 rowPointer_.resize(nbRows_ + 1);
497 colPointer_.resize(nbCols_ + 1);
498 std::vector<number_t>::iterator it = rowPointer_.begin();
499 number_t r = 2, l = 0;
500 *it = 0; it++;
501 for(itvn = cols.begin()+1; itvn != cols.end(); itvn++, r++, it++) {
502 *it = *(it - 1) + l;
503 l=0;
504 if(!itvn->empty()) { // length
505 number_t s = *std::min_element(itvn->begin(), itvn->end());
506 if(s<r) l = r-s;
507 }
508 }
509 *it = *(it - 1) + l;
510
511 //construct colPointer_ for strict upper part
512 number_t c = 1;
513 for(it = colPointer_.begin(); it != colPointer_.end(); it++,c++) { *it = c; }
514 it=colPointer_.begin();
515 typename L::const_iterator its;
516 r=1;
517 for(itvn = cols.begin(); itvn != cols.end(); itvn++, r++)
518 {
519 for(its = itvn->begin(); its != itvn->end(); its++)
520 if(*its > r) //strict upper part
521 {
522 c=*its-1;
523 *(it+c) = std::min(*(it+c), r); // update min row index on col c
524 }
525 }
526
527 *(colPointer_.begin()) = 0;
528 c = 2; l=0;
529 for(it = colPointer_.begin() + 1; it != colPointer_.end(); it++, c++)
530 {
531 r=*it;
532 *it = *(it - 1) + l;
533 l=c-r;
534 }
535
536 trace_p->pop();
537 }
538
539 } // end of namespace xlifepp
540
541 #endif // DUAL_SKYLINE_STORAGE_HPP
542