ug4
template_expressions.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3  * Author: Martin Rupp
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 
34 #ifndef __H__UG__LIB_ALGEBRA__TEMPLATE_EXPRESSIONS__
35 #define __H__UG__LIB_ALGEBRA__TEMPLATE_EXPRESSIONS__
36 
37 //#include "blockMatrix.h"
38 
39 
40 namespace ug{
41 
42 // the problem:
43 // template<typename T> void bla(T &t) { }
44 // can be used for all kinds of T. if we do not want this, we can use CRTP, the Curiously recurring template pattern
45 // (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)
46 // example:
47 // class myVectorClass : public TE_VEC<myVectorClass> { ... }
48 // now one can write functions
49 // template<typename T> void bla(TE_VEC<T> &ttvec) { T &t = ttvec.cast(); // see cast() }
50 // which only work for functions with the "attribute" TE_VEC.
51 
52 // if you want to use the template expression mechanism for your vector class myVectorClass, then write
53 // class myVectorClass : public TE_VEC<myVectorClass> { ... }
54 // and add functions
55 // template<typename T> myVectorClass& operator = (const TE_AMV_X<T> &t) { VectorAssign(&this, t); return *this; }
56 // template<typename T> myVectorClass& operator += (const TE_AMV_X<T> &t) { VectorAdd(&this, t); return *this; }
57 // template<typename T> myVectorClass& operator -= (const TE_AMV_X<T> &t) { VectorSub(&this, t); return *this; }
58 // if your class supports operator [] and int size(), then you can use the standart VecScaleAdd functions of operations_vec.h
59 // otherwise, declare your own
60 // void VecScale(myVectorClass &dest, double alpha1, myVectorClass &v1)
61 // { // dest = alpha1*v1; // .. }
62 // void VecScaleAdd(myVectorClass &dest, double alpha1, myVectorClass &v1, double alpha2, myVectorClass &v2)
63 // { // dest = alpha1*v1 + alpha2*v2; // .. }
64 // void VecScaleAdd(myVectorClass &dest, double alpha1, myVectorClass &v1, double alpha2, myVectorClass &v2, double alpha3, myVectorClass &v3)
65 // { // dest = alpha1*v1 + alpha2*v2 + alpha3*v3; // .. }
66 // and you are ready to go. an expression like x += 0.6*y - z; is then transformed to VecScaleAdd(x, 0.6, y, -1.0, z, 1.0, x);
67 
68 
71 
73 
75 template<class A> class TRANSPOSED
76 {
77 public:
78  TRANSPOSED(const A &a_) : a(a_) {}
80  const A& T() const {return a; }
81 private:
82  const A &a;
83 };
84 
90 template<class A> class TE_AMV_X
91 {
92 public:
94  const A& cast() const {return static_cast<const A&>(*this); }
95  const TRANSPOSED<TE_AMV_X<A> > T() const { return TRANSPOSED<TE_AMV_X<A> > (*this); }
96 };
97 
98 
104 template<typename R>
105 class AlphaVec_Expression : public TE_AMV_X<AlphaVec_Expression<R> >
106 {
107 public:
108  double alpha;
109  const R& r;
110  inline AlphaVec_Expression(double alpha_, const R & r_) : alpha(alpha_), r(r_)
111  { }
112 };
113 
114 // a normal vector is a vector which is scaled by 1.0.
115 
116 template<typename T>
117 double getScaling(const T &t)
118 {
119  return 1.0;
120 }
121 
122 template<typename T>
123 const T &getVector(const T &t)
124 {
125  return t;
126 }
127 
128 
129 template<typename T>
131 {
132  return t.alpha;
133 }
134 
135 template<typename T>
137 {
138  return t.r;
139 }
140 
141 
143 
144 
150 template<typename L, typename R>
151 class MatVec_Expression : public TE_AMV_X<MatVec_Expression<L, R> >
152 {
153 public:
154  double alpha;
155  const L& l;
156  const R& r;
157  inline MatVec_Expression(double alpha_, const L & l_, const R & r_) : alpha(alpha_), l(l_),r(r_)
158  { }
159 };
160 
163 {
164  static inline bool is_add() { return true; }
165 };
166 
168 {
169  static bool inline is_add() { return false; }
170 };
171 
176 template<typename L, typename operation, typename R>
177 class AlphaMatVec_X_Expression : public TE_AMV_X<AlphaMatVec_X_Expression<L, operation, R> >
178 {
179 public:
180  const L& l;
181  const R& r;
182  inline AlphaMatVec_X_Expression(const L& l_, const R& r_) : l(l_),r(r_) {}
183  //{ UG_ASSERT(l.size() == r.size(), l << " has different length as " << r); }
184 
185  static inline bool is_add() { return operation::is_add(); }
186 };
187 
191 template<typename R>
193 {
194 public:
195  double alpha;
196  const R& r;
197  inline AlphaMat_Expression(double d, const R & r_) : alpha(d), r(r_)
198  { }
199 };
200 
201 //#pragma mark operator x -> X_Operator
203 // operators
204 
205 
207 template<typename L, typename R>
209 {
211 }
212 
214 template<typename L, typename R>
216 {
218 }
219 
220 
222 template<typename L, typename R>
224 {
225  return MatVec_Expression<L, R> (l.alpha*getScaling(r), l.r, getVector(r));
226 }
227 
229 
230 // use like MAKE_TEMPLATE_OPERATORS_VECTOR(std::vector<double>)
231 #define MAKE_TEMPLATE_OPERATORS_VECTOR(VECTOR_TYPE) \
232 AlphaVec_Expression<VECTOR_TYPE> operator * (double d, const VECTOR_TYPE &r) \
233 { \
234  return AlphaVec_Expression<VECTOR_TYPE> (d, r); \
235 } \
236 template<typename L> \
237 AlphaMatVec_X_Expression<L, operation_add, VECTOR_TYPE> operator + (const L &l, const VECTOR_TYPE &r) \
238 { \
239  return AlphaMatVec_X_Expression<L, operation_add, VECTOR_TYPE > (l, r); \
240 } \
241 template<typename L> \
242 AlphaMatVec_X_Expression<L, operation_sub, VECTOR_TYPE> operator - (const L &l, const VECTOR_TYPE &r) \
243 { \
244  return AlphaMatVec_X_Expression<L, operation_sub, VECTOR_TYPE > (l, r); \
245 }
246 
247 // use like MAKE_TEMPLATE_OPERATORS_VECTOR2(typename TStorage, DenseVector<TStorage>)
248 #define MAKE_TEMPLATE_OPERATORS_VECTOR2(TEMPLATE_DEFINITION, VECTOR_TYPE) \
249 template<TEMPLATE_DEFINITION> \
250 AlphaVec_Expression<VECTOR_TYPE> operator * (double d, const VECTOR_TYPE &r) \
251 { \
252  return AlphaVec_Expression<VECTOR_TYPE> (d, r); \
253 } \
254 template<typename L, TEMPLATE_DEFINITION> \
255 AlphaMatVec_X_Expression<L, operation_add, VECTOR_TYPE> operator + (const L &l, const VECTOR_TYPE &r) \
256 { \
257  return AlphaMatVec_X_Expression<L, operation_add, VECTOR_TYPE > (l, r); \
258 } \
259 template<typename L, TEMPLATE_DEFINITION> \
260 AlphaMatVec_X_Expression<L, operation_sub, VECTOR_TYPE> operator - (const L &l, const VECTOR_TYPE &r) \
261 { \
262  return AlphaMatVec_X_Expression<L, operation_sub, VECTOR_TYPE > (l, r); \
263 }
264 
265 
267 // use like MAKE_TEMPLATE_OPERATORS_MATRIX(SparseMatrix<double>)
268 #define MAKE_TEMPLATE_OPERATORS_MATRIX(MATRIX_TYPE) \
269 AlphaMat_Expression <MATRIX_TYPE> operator * (double d, const MATRIX_TYPE &r) \
270 { \
271  return AlphaMat_Expression <MATRIX_TYPE> (d, r.cast()); \
272 } \
273 template<typename R> \
274 MatVec_Expression<MATRIX_TYPE, R> operator * (const MATRIX_TYPE &l, const R &r) \
275 { \
276  return MatVec_Expression<MATRIX_TYPE, R> (1.0, l, r); \
277 }
278 
279 
280 // use like MAKE_TEMPLATE_OPERATORS_MATRIX2(typename T, SparseMatrix<T>)
281 #define MAKE_TEMPLATE_OPERATORS_MATRIX2(TEMPLATE_DEFINITION, MATRIX_TYPE) \
282 template<TEMPLATE_DEFINITION> \
283 AlphaMat_Expression <MATRIX_TYPE> operator * (double d, const MATRIX_TYPE &r) \
284 { \
285  return AlphaMat_Expression <MATRIX_TYPE> (d, r.cast()); \
286 } \
287 template<TEMPLATE_DEFINITION, typename R> \
288 MatVec_Expression<MATRIX_TYPE, R> operator * (const MATRIX_TYPE &l, const R &r) \
289 { \
290  return MatVec_Expression<MATRIX_TYPE, R> (1.0, l, r); \
291 }
292 
293 
294 } // namespace ug
295 
296 #endif
Definition: template_expressions.h:193
AlphaMat_Expression(double d, const R &r_)
Definition: template_expressions.h:197
const R & r
Definition: template_expressions.h:196
double alpha
Definition: template_expressions.h:195
Definition: template_expressions.h:178
static bool is_add()
Definition: template_expressions.h:185
const R & r
Definition: template_expressions.h:181
const L & l
Definition: template_expressions.h:180
AlphaMatVec_X_Expression(const L &l_, const R &r_)
Definition: template_expressions.h:182
Definition: template_expressions.h:106
double alpha
Definition: template_expressions.h:108
const R & r
Definition: template_expressions.h:109
AlphaVec_Expression(double alpha_, const R &r_)
Definition: template_expressions.h:110
Definition: template_expressions.h:152
const R & r
Definition: template_expressions.h:156
const L & l
Definition: template_expressions.h:155
MatVec_Expression(double alpha_, const L &l_, const R &r_)
Definition: template_expressions.h:157
double alpha
Definition: template_expressions.h:154
Definition: template_expressions.h:91
const TRANSPOSED< TE_AMV_X< A > > T() const
Definition: template_expressions.h:95
const A & cast() const
cast this class down to original class A.
Definition: template_expressions.h:94
this helper class is a transposed of class A
Definition: template_expressions.h:76
TRANSPOSED(const A &a_)
Definition: template_expressions.h:78
const A & a
Definition: template_expressions.h:82
const A & T() const
get untransposed original class A.
Definition: template_expressions.h:80
the ug namespace
MatVec_Expression< L, R > operator*(const AlphaMat_Expression< L > &l, const R &r)
create a MatVec_Expression by (alpha*MATRIX) * VECTOR
Definition: template_expressions.h:223
AlphaMatVec_X_Expression< L, operation_sub, R > operator-(const TE_AMV_X< L > &l, const TE_AMV_X< R > &r)
create AlphaMatVec_X_Expression<L, operation_minus, R> by conjunction of TE_AMV_X<L> + TE_AMV_X<R>
Definition: template_expressions.h:215
const T & getVector(const T &t)
Definition: template_expressions.h:123
double getScaling(const T &t)
Definition: template_expressions.h:117
AlphaMatVec_X_Expression< L, operation_add, R > operator+(const TE_AMV_X< L > &l, const TE_AMV_X< R > &r)
create AlphaMatVec_X_Expression<L, operation_add, R> by conjunction of TE_AMV_X<L> + TE_AMV_X<R>
Definition: template_expressions.h:208
Definition: template_expressions.h:163
static bool is_add()
Definition: template_expressions.h:164
Definition: template_expressions.h:168
static bool is_add()
Definition: template_expressions.h:169