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