ug4
Loading...
Searching...
No Matches
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
40namespace 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
75template<class A> class TRANSPOSED
76{
77public:
78 TRANSPOSED(const A &a_) : a(a_) {}
80 const A& T() const {return a; }
81private:
82 const A &a;
83};
84
90template<class A> class TE_AMV_X
91{
92public:
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
104template<typename R>
105class AlphaVec_Expression : public TE_AMV_X<AlphaVec_Expression<R> >
106{
107public:
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
116template<typename T>
117double getScaling(const T &t)
118{
119 return 1.0;
120}
121
122template<typename T>
123const T &getVector(const T &t)
124{
125 return t;
126}
127
128
129template<typename T>
131{
132 return t.alpha;
133}
134
135template<typename T>
137{
138 return t.r;
139}
140
141
143
144
150template<typename L, typename R>
151class MatVec_Expression : public TE_AMV_X<MatVec_Expression<L, R> >
152{
153public:
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
176template<typename L, typename operation, typename R>
177class AlphaMatVec_X_Expression : public TE_AMV_X<AlphaMatVec_X_Expression<L, operation, R> >
178{
179public:
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
191template<typename R>
193{
194public:
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
207template<typename L, typename R>
212
214template<typename L, typename R>
219
220
222template<typename L, typename R>
223MatVec_Expression <L, R> operator * (const AlphaMat_Expression<L> &l, const R &r)
224{
226}
227
229
230// use like MAKE_TEMPLATE_OPERATORS_VECTOR(std::vector<double>)
231#define MAKE_TEMPLATE_OPERATORS_VECTOR(VECTOR_TYPE) \
232AlphaVec_Expression<VECTOR_TYPE> operator * (double d, const VECTOR_TYPE &r) \
233{ \
234 return AlphaVec_Expression<VECTOR_TYPE> (d, r); \
235} \
236template<typename L> \
237AlphaMatVec_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} \
241template<typename L> \
242AlphaMatVec_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) \
249template<TEMPLATE_DEFINITION> \
250AlphaVec_Expression<VECTOR_TYPE> operator * (double d, const VECTOR_TYPE &r) \
251{ \
252 return AlphaVec_Expression<VECTOR_TYPE> (d, r); \
253} \
254template<typename L, TEMPLATE_DEFINITION> \
255AlphaMatVec_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} \
259template<typename L, TEMPLATE_DEFINITION> \
260AlphaMatVec_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) \
269AlphaMat_Expression <MATRIX_TYPE> operator * (double d, const MATRIX_TYPE &r) \
270{ \
271 return AlphaMat_Expression <MATRIX_TYPE> (d, r.cast()); \
272} \
273template<typename R> \
274MatVec_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) \
282template<TEMPLATE_DEFINITION> \
283AlphaMat_Expression <MATRIX_TYPE> operator * (double d, const MATRIX_TYPE &r) \
284{ \
285 return AlphaMat_Expression <MATRIX_TYPE> (d, r.cast()); \
286} \
287template<TEMPLATE_DEFINITION, typename R> \
288MatVec_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 A & cast() const
cast this class down to original class A.
Definition template_expressions.h:94
const TRANSPOSED< TE_AMV_X< A > > T() const
Definition template_expressions.h:95
this helper class is a transposed of class A
Definition template_expressions.h:76
const A & T() const
get untransposed original class A.
Definition template_expressions.h:80
TRANSPOSED(const A &a_)
Definition template_expressions.h:78
const A & a
Definition template_expressions.h:82
the ug namespace
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
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
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_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
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