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