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 XlifeppMultiVecTraits.hpp
19   \author Manh Ha NGUYEN
20   \since 05 April 2013
21   \date  12 June 2013
22 
23   \brief Declaration of basic traits for the multivector type
24 
25   xlifepp::MultiVecTraits declares basic traits for the multivector
26   type MV used in xlifepp's orthogonalizations and solvers.  A
27   specialization of xlifepp::MultiVecTraits that defines all the traits must
28   be made for each specific multivector type.  Here, we only provide
29   default definitions that fail at compile time if no specialization
30   of xlifepp::MultiVecTraits exists for the given combination of scalar type
31   (ScalarType) and multivector type (MV).
32 */
33 
34 // This file is adapted from Anasazi, an extensible and interoperable framework
35 // for large-scale eigenvalue algorithms
36 // ***********************************************************************
37 //
38 //                 Block Eigensolvers Package
39 //                 Copyright (2004) Sandia Corporation
40 //
41 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
42 // license for use of this work by or on behalf of the U.S. Government.
43 //
44 // This library is free software; you can redistribute it and/or modify
45 // it under the terms of the GNU Lesser General Public License as
46 // published by the Free Software Foundation; either version 2.1 of the
47 // License, or (at your option) any later version.
48 //
49 // This library is distributed in the hope that it will be useful, but
50 // WITHOUT ANY WARRANTY; without even the implied warranty of
51 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
52 // Lesser General Public License for more details.
53 //
54 // You should have received a copy of the GNU Lesser General Public
55 // License along with this library; if not, write to the Free Software
56 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
57 // USA
58 //
59 // ***********************************************************************
60 
61 
62 #ifndef XLIFEPP_MULTI_VEC_TRAITS_HPP
63 #define XLIFEPP_MULTI_VEC_TRAITS_HPP
64 
65 #include "XlifeppEigenTypes.hpp"
66 
67 namespace xlifepp {
68 
69 /*! \class UndefinedMultiVecTraits
70     \brief Used by MultiVecTraits to report lack of a specialization.
71 
72     MultiVecTraits<ScalarType, MV> uses this struct to produce a
73     compile-time error when no specialization exists for the scalar
74     type ScalarType and multivector type MV.
75 */
76 template< class ScalarType, class MV >
77 struct UndefinedMultiVecTraits
78 {
79   /*! \brief Any attempt to compile this method will result in a compile-time error.
80 
81       If you see compile errors referring to this method, then
82       either no specialization of MultiVecTraits exists for the
83       scalar type ScalarType and multivector type MV, or the
84       specialization for ScalarType and MV is not complete.
85   */
notDefinedxlifepp::UndefinedMultiVecTraits86   static inline ScalarType notDefined() { return MV::this_type_is_missing_a_specialization(); };
87 };
88 
89 
90 /*!
91     \class MultiVecTraits
92     \tparam ScalarType The type of the entries in the multivectors.
93     \tparam MV The type of the multivectors themselves.
94 
95     \brief Traits class which defines basic operations on multivectors.
96 
97     This traits class tells xlifepp's solvers how to perform
98     multivector operations for the multivector type MV.  These
99     operations include creating copies or views, finding the number
100     of rows or columns (i.e., vectors) in a given multivector, and
101     computing inner products, norms, and vector sums.  (xlifepp's
102     solvers use the OperatorTraits traits class to apply operators
103     to multivectors.)
104 
105     xlifepp gives users two different ways to tell its solvers how
106     to compute with multivectors of a given type MV.  The first and
107     preferred way is for users to specialize MultiVecTraits, this
108     traits class, for their given MV type. The second way
109     is for users to make their multivector type (or a wrapper
110     thereof) inherit from MultiVec.  This works because xlifepp
111     provides a specialization of MultiVecTraits for MultiVec.
112     Specializing MultiVecTraits is more flexible because it does not
113     require a multivector type to inherit from MultiVec; this is
114     possible even if you do not have control over the interface of a
115     class.
116 
117     If you have a different multivector type MV that you would like
118     to use with xlifepp, and if that type does not inherit from
119     MultiVec, then you must implement a specialization of
120     MultiVecTraits for MV.  Otherwise, this traits class will report
121     a compile-time error (relating to UndefinedMultiVecTraits).
122     Specializing MultiVecTraits for your MV type is not hard.
123 */
124 template<class ScalarType, class MV>
125 class MultiVecTraits {
126 public:
127   //! @name Creation methods
128   //@{
129 
130   /*! \brief Creates a new empty \c MV containing \c numvecs columns.
131 
132   \return Reference-counted pointer to the new multivector of type \c MV.
133   */
clone(const MV & mv,const int numvecs)134   static SmartPtr<MV> clone(const MV& mv, const int numvecs)
135   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return _smPtrNull; }
136 
137   /*! \brief Creates a new \c MV and copies contents of \c mv into the new vector (deep copy).
138 
139     \return Reference-counted pointer to the new multivector of type \c MV.
140   */
cloneCopy(const MV & mv)141   static SmartPtr<MV> cloneCopy(const MV& mv)
142   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return _smPtrNull; }
143 
144   /*! \brief Creates a new \c MV and copies the selected contents of \c mv into the new vector (deep copy).
145 
146     The copied vectors from \c mv are indicated by the \c index.size() indices in \c index.
147     \return Reference-counted pointer to the new multivector of type \c MV.
148   */
cloneCopy(const MV & mv,const std::vector<int> & index)149   static SmartPtr<MV> cloneCopy(const MV& mv, const std::vector<int>& index)
150   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return _smPtrNull; }
151 
152   /*! \brief Creates a new \c MV that shares the selected contents of \c mv (shallow copy).
153 
154   The index of the \c numvecs vectors shallow copied from \c mv are indicated by the indices given in \c index.
155   \return Reference-counted pointer to the new multivector of type \c MV.
156   */
cloneViewNonConst(MV & mv,const std::vector<int> & index)157   static SmartPtr<MV> cloneViewNonConst(MV& mv, const std::vector<int>& index)
158   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return _smPtrNull; }
159 
160   /*! \brief Creates a new const \c MV that shares the selected contents of \c mv (shallow copy).
161 
162   The index of the \c numvecs vectors shallow copied from \c mv are indicated by the indices given in \c index.
163   \return Reference-counted pointer to the new const multivector of type \c MV.
164   */
cloneView(const MV & mv,const std::vector<int> & index)165   static SmartPtr<const MV> cloneView(const MV& mv, const std::vector<int>& index)
166   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return _smPtrNull; }
167 
168   //@}
169 
170   //! @name Attribute methods
171   //@{
172 
173   //! Obtain the vector length of \c mv.
getVecLength(const MV & mv)174   static int getVecLength(const MV& mv)
175   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return 0; }
176 
177   //! Obtain the number of vectors in \c mv
getNumberVecs(const MV & mv)178   static int getNumberVecs(const MV& mv)
179   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return 0; }
180 
181   //@}
182 
183   //! @name Update methods
184   //@{
185 
186   /*! \brief Update \c mv with \f$ \alpha AB + \beta mv \f$.
187    */
mvTimesMatAddMv(const ScalarType alpha,const MV & A,const MatrixEigenDense<ScalarType> & B,const ScalarType beta,MV & mv)188   static void mvTimesMatAddMv(const ScalarType alpha, const MV& A,
189                                const MatrixEigenDense<ScalarType>& B,
190                                const ScalarType beta, MV& mv)
191   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
192 
193   /*! \brief Replace \c mv with \f$\alpha A + \beta B\f$.
194    */
mvAddMv(const ScalarType alpha,const MV & A,const ScalarType beta,const MV & B,MV & mv)195   static void mvAddMv(const ScalarType alpha, const MV& A, const ScalarType beta, const MV& B, MV& mv)
196   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
197 
198   /*! \brief Scale each element of the vectors in \c mv with \c alpha.
199    */
mvScale(MV & mv,const ScalarType alpha)200   static void mvScale (MV& mv, const ScalarType alpha)
201   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
202 
203   /*! \brief Scale each element of the \c i-th vector in \c mv with \c alpha[i].
204    */
mvScale(MV & mv,const std::vector<ScalarType> & alpha)205   static void mvScale (MV& mv, const std::vector<ScalarType>& alpha)
206   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
207 
208   /*! \brief Compute a dense matrix \c B through the matrix-matrix multiply \f$ \alpha A^Hmv \f$.
209   */
mvTransMv(const ScalarType alpha,const MV & A,const MV & mv,MatrixEigenDense<ScalarType> & B)210   static void mvTransMv(const ScalarType alpha, const MV& A, const MV& mv, MatrixEigenDense<ScalarType>& B)
211   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
212 
213   /*! \brief Compute a vector \c b where the components are the individual dot-products of the \c i-th columns of \c A and \c mv, i.e.\f$b[i] = A[i]^Hmv[i]\f$.
214    */
mvDot(const MV & mv,const MV & A,std::vector<ScalarType> & b)215   static void mvDot (const MV& mv, const MV& A, std::vector<ScalarType>& b)
216   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
217 
218   //@}
219   //! @name Norm method
220   //@{
221 
222   /*! \brief Compute the 2-norm of each individual vector of \c mv.
223     Upon return, \c normvec[i] holds the value of \f$||mv_i||_2\f$, the \c i-th column of \c mv.
224   */
mvNorm(const MV & mv,std::vector<typename NumTraits<ScalarType>::magnitudeType> & normvec)225   static void mvNorm(const MV& mv, std::vector<typename NumTraits<ScalarType>::magnitudeType>& normvec)
226   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
227 
228   //@}
229 
230   //! @name Initialization methods
231   //@{
232   /*! \brief Copy the vectors in \c A to a set of vectors in \c mv indicated by the indices given in \c index.
233 
234   The \c numvecs vectors in \c A are copied to a subset of vectors in \c mv indicated by the indices given in \c index,
235   i.e.<tt> mv[index[i]] = A[i]</tt>.
236   */
setBlock(const MV & A,const std::vector<int> & index,MV & mv)237   static void setBlock(const MV& A, const std::vector<int>& index, MV& mv)
238   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
239 
240   /*!
241     \brief mv := A
242     assign (deep copy) A into mv.
243   */
assign(const MV & A,MV & mv)244   static void assign(const MV& A, MV& mv)
245   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
246 
247   /*! \brief Replace the vectors in \c mv with random vectors.
248    */
mvRandom(MV & mv)249   static void mvRandom(MV& mv)
250   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
251 
252   /*! \brief Replace each element of the vectors in \c mv with \c alpha.
253    */
mvInit(MV & mv,const ScalarType alpha=NumTraits<ScalarType>::zero ())254   static void mvInit(MV& mv, const ScalarType alpha = NumTraits<ScalarType>::zero())
255   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
256   //@}
257 
258   //! @name Print method
259   //@{
260   /*! \brief Print the \c mv multi-vector to the \c os output stream.
261    */
mvPrint(const MV & mv,std::ostream & os)262   static void mvPrint(const MV& mv, std::ostream& os)
263   { UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
264   //@}
265 };
266 
267 } // namespace xlifepp
268 
269 #endif /* XLIFEPP_MULTI_VEC_TRAITS_HPP */
270 
271