Line data Source code
1 : /*
2 : * Copyright (c) 2009-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
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 : ////////////////////////////////////////////////////////////////////////
35 : // This header defines common vector-types.
36 : // It is possible to completely avoid these vectors and to use your own.
37 : // Have a look at lgmath.h to see which typedefs have to be replaced.
38 : // You have to make sure that your vector-types specialize the
39 : // template methods defined in lgmath_vector_descriptor.
40 :
41 : #ifndef __H__COMMON__MATH_VECTOR__
42 : #define __H__COMMON__MATH_VECTOR__
43 :
44 : #include <cstddef>
45 : #include <iostream>
46 : #include <algorithm>
47 : #include "../../ug_config.h"
48 : #include "../../types.h"
49 : #include "common/math/misc/math_constants.h"
50 :
51 :
52 : namespace ug
53 : {
54 :
55 : /**
56 : * \defgroup vectors Vectors
57 : * Abbreviations of small vectors
58 : * \ingroup ugbase_math
59 : * \{
60 : */
61 :
62 : ////////////////////////////////////////////////////////////////////////
63 : // MathMathVector
64 : /// a mathematical Vector with N entries.
65 : template <std::size_t N, typename T = number> class MathVector;
66 :
67 : /// helper method which creates a vector from another vector of different dimensionality
68 : /** Typically, the method isn't invoked directly but serves as an implementation
69 : * helper for MathVector<toN, T>::from(v).
70 : * \{ */
71 : template <std::size_t fromN, std::size_t toN, typename T>
72 : MathVector<toN, T> MathVectorFrom (const MathVector<fromN, T>& v)
73 : {
74 : MathVector<toN, T> r;
75 : static const size_t minN = std::min(toN, fromN);
76 : static const size_t maxN = std::max(toN, fromN);
77 : for(size_t i = 0; i < minN; ++i)
78 : r[i] = v[i];
79 : for(size_t i = minN; i < maxN; ++i)
80 : r[i] = 0;
81 : return r;
82 : }
83 :
84 : template <std::size_t N, typename T>
85 : MathVector<N, T> MathVectorFrom (const MathVector<N, T>& v)
86 : {
87 : return v;
88 : }
89 : /** \} */
90 :
91 :
92 : /**
93 : * A mathematical Vector with N entries and static storage
94 : */
95 : template <std::size_t N, typename T>
96 : class MathVector
97 : {
98 : public:
99 : typedef T value_type;
100 : typedef std::size_t size_type;
101 : static const std::size_t Size = N;
102 :
103 : public:
104 : MathVector() {for(std::size_t i = 0; i < N; ++i) m_data[i] = 0.0;}
105 : MathVector(const value_type& val) {for(std::size_t i = 0; i < N; ++i) m_data[i] = val;}
106 : MathVector(const MathVector& v) {assign(v);}
107 :
108 : template <std::size_t fromN>
109 : static inline MathVector from(const MathVector<fromN, T>& v)
110 : {
111 : return MathVectorFrom<fromN, N, T>(v);
112 : }
113 :
114 : // operations with other vectors
115 : MathVector& operator= (const MathVector& v)
116 : {
117 : if(this != &v)
118 : {
119 : assign(v);
120 : }
121 : return *this;
122 : }
123 : MathVector& operator+= (const MathVector& v) {for(std::size_t i = 0; i < N; ++i) m_data[i] += v.coord(i);return *this;}
124 : MathVector& operator-= (const MathVector& v) {for(std::size_t i = 0; i < N; ++i) m_data[i] -= v.coord(i);return *this;}
125 :
126 : // operations with scalar
127 : MathVector& operator= (const value_type& val) {for(std::size_t i = 0; i < N; ++i) m_data[i] = val;return *this;}
128 : MathVector& operator+= (const value_type& val) {for(std::size_t i = 0; i < N; ++i) m_data[i] += val;return *this;}
129 : MathVector& operator-= (const value_type& val) {for(std::size_t i = 0; i < N; ++i) m_data[i] -= val;return *this;}
130 : MathVector& operator*= (const value_type& val) {for(std::size_t i = 0; i < N; ++i) m_data[i] *= val;return *this;}
131 : MathVector& operator/= (const value_type& val) {for(std::size_t i = 0; i < N; ++i) m_data[i] /= val;return *this;}
132 :
133 : // negation
134 : MathVector operator- () const { MathVector<N, T> v; for (std::size_t i = 0; i < N; ++i) v.set_coord(i, -m_data[i]); return v; }
135 :
136 : // scalar product
137 : value_type operator* (const MathVector& v) const {value_type res = 0.0; for(std::size_t i = 0; i < N; ++i) res += m_data[i] * v.coord(i);return res;}
138 :
139 : inline std::size_t size() const {return N;}
140 :
141 : inline value_type& coord(size_t index) {return m_data[index];}
142 : inline value_type coord(size_t index) const {return m_data[index];}
143 :
144 : inline value_type& operator[](size_t index) {return m_data[index];}
145 : inline const value_type& operator[](size_t index) const {return m_data[index];}
146 :
147 : inline void set_coord(std::size_t index, value_type v) {m_data[index] = v;}
148 :
149 : protected:
150 : value_type m_data[N];
151 :
152 : protected:
153 : inline void assign(const MathVector<N>& v) {for(std::size_t i = 0; i < N; ++i) m_data[i] = v.coord(i);}
154 :
155 : };
156 :
157 : /** THIS IS A TEMPORARY STUB. Some discretization routines use MathVector<0>, requiring
158 : * a single coordinate.
159 : * A mathematical Vector with 1 entry and static storage
160 : */
161 : template <typename T>
162 : class MathVector<0, T>
163 : {
164 : public:
165 : typedef std::size_t size_type;
166 : typedef T value_type;
167 : static const std::size_t Size = 1;
168 :
169 : public:
170 0 : MathVector() {}
171 0 : MathVector(value_type x)
172 : {
173 0 : m_data[0] = x;
174 : }
175 0 : MathVector(const MathVector<0, T>& v) {assign(v);}
176 :
177 : static inline MathVector from(const MathVector<0, T>& v) {return v;}
178 : static inline MathVector from(const MathVector<1, T>& v) {return MathVector();}
179 : static inline MathVector from(const MathVector<2, T>& v) {return MathVector();}
180 : static inline MathVector from(const MathVector<3, T>& v) {return MathVector();}
181 : static inline MathVector from(const MathVector<4, T>& v) {return MathVector();}
182 : template <std::size_t fromN>
183 : static inline MathVector from(const MathVector<fromN, T>& v)
184 : {
185 : return MathVectorFrom<0, fromN, T>(v);
186 : }
187 :
188 : // operations with other vectors
189 : MathVector& operator= (const MathVector& v) {assign(v); return *this;}
190 : MathVector& operator+= (const MathVector& v) {m_data[0] += v.x(); return *this;}
191 : MathVector& operator-= (const MathVector& v) {m_data[0] -= v.x(); return *this;}
192 :
193 : // operations with scalar
194 : MathVector& operator= (const value_type& val) {m_data[0] = val;return *this;}
195 : MathVector& operator+= (const value_type& val) {m_data[0] += val;return *this;}
196 : MathVector& operator-= (const value_type& val) {m_data[0] -= val;return *this;}
197 : MathVector& operator*= (const value_type& val) {m_data[0] *= val;return *this;}
198 : MathVector& operator/= (const value_type& val) {m_data[0] /= val;return *this;}
199 :
200 : // negation
201 : MathVector& operator- () { return MathVector<0, T>(-m_data[0]); }
202 :
203 : // scalar product
204 : value_type operator* (const MathVector& v) const {return m_data[0] * v.x();}
205 :
206 : inline std::size_t size() const {return 1;}
207 :
208 : inline value_type& coord(std::size_t index) {return m_data[0];}
209 : inline value_type coord(std::size_t index) const {return m_data[0];}
210 :
211 : inline value_type& operator[](std::size_t index) {return m_data[0];}
212 : inline const value_type& operator[](std::size_t index) const {return m_data[0];}
213 :
214 : inline void set_coord(std::size_t index, value_type v) {m_data[0] = v;}
215 :
216 : inline value_type& x() {return m_data[0];}
217 : inline const value_type& x() const {return m_data[0];}
218 :
219 : value_type m_data[1];
220 : protected:
221 0 : inline void assign(const MathVector<0, T>& v) {m_data[0] = v.m_data[0];}
222 :
223 : };
224 :
225 : /**
226 : * A mathematical Vector with 1 entry and static storage
227 : */
228 : template <typename T>
229 : class MathVector<1, T>
230 : {
231 : public:
232 : typedef std::size_t size_type;
233 : typedef T value_type;
234 : static const std::size_t Size = 1;
235 :
236 : public:
237 261 : MathVector() {m_data[0] = 0.0;}
238 0 : MathVector(value_type x) { m_data[0] = x; }
239 9 : MathVector(const MathVector<1, T>& v) {assign(v);}
240 :
241 : static inline MathVector from(const MathVector<0, T>& v) {return MathVector(0);}
242 : static inline MathVector from(const MathVector<1, T>& v) {return v;}
243 : static inline MathVector from(const MathVector<2, T>& v) {return MathVector(v[0]);}
244 0 : static inline MathVector from(const MathVector<3, T>& v) {return MathVector(v[0]);}
245 : static inline MathVector from(const MathVector<4, T>& v) {return MathVector(v[0]);}
246 : template <std::size_t fromN>
247 : static inline MathVector from(const MathVector<fromN, T>& v)
248 : {
249 : return MathVectorFrom<1, fromN, T>(v);
250 : }
251 :
252 : // operations with other vectors
253 0 : MathVector& operator= (const MathVector& v) {assign(v); return *this;}
254 0 : MathVector& operator+= (const MathVector& v) {m_data[0] += v.x(); return *this;}
255 0 : MathVector& operator-= (const MathVector& v) {m_data[0] -= v.x(); return *this;}
256 :
257 : // operations with scalar
258 9 : MathVector& operator= (const value_type& val) {m_data[0] = val;return *this;}
259 : MathVector& operator+= (const value_type& val) {m_data[0] += val;return *this;}
260 : MathVector& operator-= (const value_type& val) {m_data[0] -= val;return *this;}
261 0 : MathVector& operator*= (const value_type& val) {m_data[0] *= val;return *this;}
262 0 : MathVector& operator/= (const value_type& val) {m_data[0] /= val;return *this;}
263 :
264 : // negation
265 : MathVector operator- () const { return MathVector<1, T>(-m_data[0]); }
266 :
267 : // scalar product
268 0 : value_type operator* (const MathVector& v) const {return m_data[0] * v.x();}
269 :
270 : inline std::size_t size() const {return 1;}
271 :
272 0 : inline value_type& coord(std::size_t index) {return m_data[0];}
273 129 : inline value_type coord(std::size_t index) const {return m_data[0];}
274 :
275 0 : inline value_type& operator[](std::size_t index) {return m_data[0];}
276 0 : inline const value_type& operator[](std::size_t index) const {return m_data[0];}
277 :
278 0 : inline void set_coord(std::size_t index, value_type v) {m_data[0] = v;}
279 :
280 : inline value_type& x() {return m_data[0];}
281 : inline const value_type& x() const {return m_data[0];}
282 :
283 : value_type m_data[1];
284 : protected:
285 9 : inline void assign(const MathVector<1, T>& v) {m_data[0] = v.m_data[0];}
286 :
287 : };
288 :
289 : /**
290 : * A mathematical Vector with 2 entries and static storage
291 : */
292 : template <typename T>
293 : class MathVector<2, T>
294 : {
295 : public:
296 : typedef std::size_t size_type;
297 : typedef T value_type;
298 : static const std::size_t Size = 2;
299 :
300 : public:
301 640276337 : MathVector() {m_data[0] = m_data[1] = 0.0;}
302 0 : MathVector(const value_type& val) {m_data[0] = m_data[1] = val;}
303 0 : MathVector(value_type x, value_type y)
304 : {
305 0 : m_data[0] = x;
306 0 : m_data[1] = y;
307 0 : }
308 2092 : MathVector(const MathVector<2,T>& v) {assign(v);}
309 :
310 : static inline MathVector from(const MathVector<0, T>& v) {return MathVector(0, 0);}
311 : static inline MathVector from(const MathVector<1, T>& v) {return MathVector(v[0], 0);}
312 : static inline MathVector from(const MathVector<2, T>& v) {return v;}
313 0 : static inline MathVector from(const MathVector<3, T>& v) {return MathVector(v[0], v[1]);}
314 : static inline MathVector from(const MathVector<4, T>& v) {return MathVector(v[0], v[1]);}
315 : template <std::size_t fromN>
316 : static inline MathVector from(const MathVector<fromN, T>& v)
317 : {
318 : return MathVectorFrom<2, fromN, T>(v);
319 : }
320 :
321 : // operations with other vectors
322 0 : MathVector& operator= (const MathVector& v) {assign(v); return *this;}
323 0 : MathVector& operator+= (const MathVector& v) {for(std::size_t i = 0; i < 2; ++i) m_data[i] += v.coord(i);return *this;}
324 0 : MathVector& operator-= (const MathVector& v) {for(std::size_t i = 0; i < 2; ++i) m_data[i] -= v.coord(i);return *this;}
325 :
326 : // operations with scalar
327 0 : MathVector& operator= (const value_type& val) {for(std::size_t i = 0; i < 2; ++i) m_data[i] = val;return *this;}
328 : MathVector& operator+= (const value_type& val) {for(std::size_t i = 0; i < 2; ++i) m_data[i] += val;return *this;}
329 : MathVector& operator-= (const value_type& val) {for(std::size_t i = 0; i < 2; ++i) m_data[i] -= val;return *this;}
330 18 : MathVector& operator*= (const value_type& val) {for(std::size_t i = 0; i < 2; ++i) m_data[i] *= val;return *this;}
331 0 : MathVector& operator/= (const value_type& val) {for(std::size_t i = 0; i < 2; ++i) m_data[i] /= val;return *this;}
332 :
333 : // negation
334 : MathVector operator- () const { return MathVector<2, T>(-m_data[0], -m_data[1]); }
335 :
336 : // scalar product
337 0 : value_type operator* (const MathVector& v) const {value_type res = 0.0; for(std::size_t i = 0; i < 2; ++i) res += m_data[i] * v.coord(i);return res;}
338 :
339 : inline std::size_t size() const {return 2;}
340 :
341 0 : inline value_type& coord(std::size_t index) {return m_data[index];}
342 524 : inline value_type coord(std::size_t index) const {return m_data[index];}
343 :
344 0 : inline value_type& operator[](std::size_t index) {return m_data[index];}
345 0 : inline const value_type& operator[](std::size_t index) const {return m_data[index];}
346 :
347 0 : inline void set_coord(std::size_t index, value_type v) {m_data[index] = v;}
348 :
349 0 : inline value_type& x() {return m_data[0];}
350 : inline const value_type& x() const {return m_data[0];}
351 :
352 0 : inline value_type& y() {return m_data[1];}
353 : inline const value_type& y() const {return m_data[1];}
354 :
355 : value_type m_data[2];
356 : protected:
357 139470 : inline void assign(const MathVector<2,T>& v) {m_data[0] = v.m_data[0];
358 139470 : m_data[1] = v.m_data[1];}
359 : };
360 :
361 : /**
362 : * A mathematical Vector with 3 entries and static storage
363 : */
364 : template <typename T>
365 : class MathVector<3, T>
366 : {
367 : public:
368 : typedef std::size_t size_type;
369 : typedef T value_type;
370 : static const std::size_t Size = 3;
371 :
372 : public:
373 320005215 : MathVector() {m_data[0] = m_data[1] = m_data[2] = 0.0;}
374 0 : MathVector(const value_type& val) {m_data[0] = m_data[1] = m_data[2] = val;}
375 0 : MathVector(value_type x, value_type y, value_type z)
376 : {
377 0 : m_data[0] = x;
378 0 : m_data[1] = y;
379 0 : m_data[2] = z;
380 0 : }
381 8431 : MathVector(const MathVector<3,T>& v) {assign(v);}
382 :
383 : static inline MathVector from(const MathVector<0, T>& v) {return MathVector(0, 0, 0);}
384 0 : static inline MathVector from(const MathVector<1, T>& v) {return MathVector(v[0], 0, 0);}
385 0 : static inline MathVector from(const MathVector<2, T>& v) {return MathVector(v[0], v[1], 0);}
386 : static inline MathVector from(const MathVector<3, T>& v) {return v;}
387 : static inline MathVector from(const MathVector<4, T>& v) {return MathVector(v[0], v[1], v[2]);}
388 : template <std::size_t fromN>
389 : static inline MathVector from(const MathVector<fromN, T>& v)
390 : {
391 : return MathVectorFrom<3, fromN, T>(v);
392 : }
393 :
394 : // operations with other vectors
395 0 : MathVector& operator= (const MathVector& v) {assign(v); return *this;}
396 0 : MathVector& operator+= (const MathVector& v) {for(std::size_t i = 0; i < 3; ++i) m_data[i] += v.coord(i);return *this;}
397 0 : MathVector& operator-= (const MathVector& v) {for(std::size_t i = 0; i < 3; ++i) m_data[i] -= v.coord(i);return *this;}
398 :
399 : // operations with scalar
400 0 : MathVector& operator= (const value_type& val) {for(std::size_t i = 0; i < 3; ++i) m_data[i] = val;return *this;}
401 : MathVector& operator+= (const value_type& val) {for(std::size_t i = 0; i < 3; ++i) m_data[i] += val;return *this;}
402 : MathVector& operator-= (const value_type& val) {for(std::size_t i = 0; i < 3; ++i) m_data[i] -= val;return *this;}
403 204 : MathVector& operator*= (const value_type& val) {for(std::size_t i = 0; i < 3; ++i) m_data[i] *= val;return *this;}
404 0 : MathVector& operator/= (const value_type& val) {for(std::size_t i = 0; i < 3; ++i) m_data[i] /= val;return *this;}
405 :
406 : // negation
407 : MathVector operator- () const { return MathVector<3, T>(-m_data[0], -m_data[1], -m_data[2]); }
408 :
409 : // scalar product
410 0 : value_type operator* (const MathVector& v) const {value_type res = 0.0; for(std::size_t i = 0; i < 3; ++i) res += m_data[i] * v.coord(i);return res;}
411 :
412 : inline std::size_t size() const {return 3;}
413 :
414 0 : inline value_type& coord(std::size_t index) {return m_data[index];}
415 1269 : inline value_type coord(std::size_t index) const {return m_data[index];}
416 :
417 0 : inline value_type& operator[](std::size_t index) {return m_data[index];}
418 0 : inline const value_type& operator[](std::size_t index) const {return m_data[index];}
419 :
420 0 : inline void set_coord(std::size_t index, value_type v) {m_data[index] = v;}
421 :
422 0 : inline value_type& x() {return m_data[0];}
423 : inline const value_type& x() const {return m_data[0];}
424 :
425 0 : inline value_type& y() {return m_data[1];}
426 : inline const value_type& y() const {return m_data[1];}
427 :
428 0 : inline value_type& z() {return m_data[2];}
429 : inline const value_type& z() const {return m_data[2];}
430 :
431 : value_type m_data[3];
432 : protected:
433 8570 : inline void assign(const MathVector<3,T>& v) {m_data[0] = v.m_data[0];
434 8570 : m_data[1] = v.m_data[1];
435 8569 : m_data[2] = v.m_data[2];}
436 :
437 : };
438 :
439 : /**
440 : * A mathematical Vector with 4 entries and static storage
441 : */
442 : template <typename T>
443 : class MathVector<4, T>
444 : {
445 : public:
446 : typedef std::size_t size_type;
447 : typedef T value_type;
448 : static const std::size_t Size = 4;
449 :
450 : public:
451 0 : MathVector() {m_data[0] = m_data[1] = m_data[2] = m_data[3] = 0.0;}
452 : MathVector(const value_type& val) {m_data[0] = m_data[1] = m_data[2] = m_data[3] =val;}
453 0 : MathVector(value_type x, value_type y, value_type z, value_type w)
454 : {
455 0 : m_data[0] = x;
456 0 : m_data[1] = y;
457 0 : m_data[2] = z;
458 0 : m_data[3] = w;
459 0 : }
460 0 : MathVector(const MathVector<4,T>& v) {assign(v);}
461 :
462 : static inline MathVector from(const MathVector<0, T>& v) {return MathVector(0, 0, 0, 0);}
463 : static inline MathVector from(const MathVector<1, T>& v) {return MathVector(v[0], 0, 0, 0);}
464 : static inline MathVector from(const MathVector<2, T>& v) {return MathVector(v[0], v[1], 0, 0);}
465 : static inline MathVector from(const MathVector<3, T>& v) {return MathVector(v[0], v[1], v[2], 0);}
466 : static inline MathVector from(const MathVector<4, T>& v) {return v;}
467 : template <std::size_t fromN>
468 : static inline MathVector from(const MathVector<fromN, T>& v)
469 : {
470 : return MathVectorFrom<4, fromN, T>(v);
471 : }
472 :
473 : // operations with other vectors
474 0 : MathVector& operator= (const MathVector& v) {assign(v); return *this;}
475 : MathVector& operator+= (const MathVector& v) {for(std::size_t i = 0; i < 4; ++i) m_data[i] += v.coord(i);return *this;}
476 : MathVector& operator-= (const MathVector& v) {for(std::size_t i = 0; i < 4; ++i) m_data[i] -= v.coord(i);return *this;}
477 :
478 : // operations with scalar
479 : MathVector& operator= (const value_type& val) {for(std::size_t i = 0; i < 4; ++i) m_data[i] = val;return *this;}
480 : MathVector& operator+= (const value_type& val) {for(std::size_t i = 0; i < 4; ++i) m_data[i] += val;return *this;}
481 : MathVector& operator-= (const value_type& val) {for(std::size_t i = 0; i < 4; ++i) m_data[i] -= val;return *this;}
482 : MathVector& operator*= (const value_type& val) {for(std::size_t i = 0; i < 4; ++i) m_data[i] *= val;return *this;}
483 : MathVector& operator/= (const value_type& val) {for(std::size_t i = 0; i < 4; ++i) m_data[i] /= val;return *this;}
484 :
485 : // negation
486 : MathVector operator- () const { return MathVector<4, T>(-m_data[0], -m_data[1], -m_data[2], -m_data[3]); }
487 :
488 : // scalar product
489 : value_type operator* (const MathVector& v) const {value_type res = 0.0; for(std::size_t i = 0; i < 4; ++i) res += m_data[i] * v.coord(i);return res;}
490 :
491 : inline std::size_t size() const {return 4;}
492 :
493 0 : inline value_type& coord(std::size_t index) {return m_data[index];}
494 0 : inline value_type coord(std::size_t index) const {return m_data[index];}
495 :
496 0 : inline value_type& operator[](std::size_t index) {return m_data[index];}
497 : inline const value_type& operator[](std::size_t index) const {return m_data[index];}
498 :
499 0 : inline void set_coord(std::size_t index, value_type v) {m_data[index] = v;}
500 :
501 : inline value_type& x() {return m_data[0];}
502 : inline const value_type& x() const {return m_data[0];}
503 :
504 : inline value_type& y() {return m_data[1];}
505 : inline const value_type& y() const {return m_data[1];}
506 :
507 : inline value_type& z() {return m_data[2];}
508 : inline const value_type& z() const {return m_data[2];}
509 :
510 : inline value_type& w() {return m_data[3];}
511 : inline const value_type& w() const {return m_data[3];}
512 :
513 : value_type m_data[4];
514 : protected:
515 0 : inline void assign(const MathVector<4,T>& v) {m_data[0] = v.m_data[0];
516 0 : m_data[1] = v.m_data[1];
517 0 : m_data[2] = v.m_data[2];
518 0 : m_data[3] = v.m_data[3];}
519 :
520 : };
521 :
522 : template <std::size_t N, typename T>
523 : bool operator== (const MathVector<N,T>& v, const MathVector<N,T>& w)
524 : {
525 6020 : for(std::size_t i = 0; i < N; ++i)
526 : {
527 5789 : if(v[i] != w[i]) return false;
528 : }
529 : return true;
530 : }
531 :
532 : template <typename T>
533 : bool operator== (const MathVector<0,T>& v, const MathVector<0,T>& w)
534 : {
535 : return true;
536 : }
537 :
538 : // NOTE: this implementation determines the state of the relation '<'
539 : // by considering the FIRST vector-entry, which is not equal
540 : template <std::size_t N, typename T>
541 : bool operator< (const MathVector<N,T>& v, const MathVector<N,T>& w)
542 : {
543 : for(std::size_t i = 0; i < N; ++i)
544 : {
545 : if(v[i] < w[i] - SMALL) return true;
546 : else if(v[i] > w[i] + SMALL) return false;
547 : }
548 : return false;
549 : }
550 :
551 : template <std::size_t N, typename T>
552 : bool operator!= (const MathVector<N,T>& v, const MathVector<N,T>& w)
553 : {
554 : return !(v == w);
555 : }
556 :
557 : template <std::size_t N, typename T>
558 : std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<N,T>& v)
559 : {
560 : for(std::size_t i = 0; i < N; ++i)
561 : outStream << "[" << i << "]: " << v.coord(i) << std::endl;
562 : return outStream;
563 : }
564 :
565 : template <typename T>
566 : std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<0,T>& v)
567 : {
568 0 : outStream << "(empty)";
569 : return outStream;
570 : }
571 :
572 : template <typename T>
573 18 : std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<1,T>& v)
574 : {
575 18 : outStream << "(" << v[0] << ")";
576 18 : return outStream;
577 : }
578 : template <typename T>
579 70 : std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<2,T>& v)
580 : {
581 140 : outStream << "("<<v[0]<<", "<<v[1]<<")";
582 70 : return outStream;
583 : }
584 : template <typename T>
585 225 : std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<3,T>& v)
586 : {
587 675 : outStream << "("<<v[0]<<", "<<v[1]<<", "<<v[2]<<")";
588 225 : return outStream;
589 : }
590 : template <typename T>
591 : std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<4,T>& v)
592 : {
593 : outStream << "("<<v[0]<<", "<<v[1]<<", "<<v[2]<<", "<<v[3]<<")";
594 : return outStream;
595 : }
596 :
597 : UG_API std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<1>& v);
598 : UG_API std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<2>& v);
599 : UG_API std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<3>& v);
600 : UG_API std::ostream& operator<< (std::ostream& outStream, const ug::MathVector<4>& v);
601 :
602 : UG_API std::ostream& write_plain_txt (std::ostream& outStream, const ug::MathVector<1>& v);
603 : UG_API std::ostream& write_plain_txt (std::ostream& outStream, const ug::MathVector<2>& v);
604 : UG_API std::ostream& write_plain_txt (std::ostream& outStream, const ug::MathVector<3>& v);
605 : UG_API std::ostream& write_plain_txt (std::ostream& outStream, const ug::MathVector<4>& v);
606 :
607 : UG_API std::istream& read_plain_txt (std::istream& inStream, ug::MathVector<1>& v);
608 : UG_API std::istream& read_plain_txt (std::istream& inStream, ug::MathVector<2>& v);
609 : UG_API std::istream& read_plain_txt (std::istream& inStream, ug::MathVector<3>& v);
610 : UG_API std::istream& read_plain_txt (std::istream& inStream, ug::MathVector<4>& v);
611 :
612 : template <class TStream, std::size_t N, class T>
613 : void Serialize(TStream& out, const MathVector<N, T>& val)
614 : {
615 0 : out.write((char*)val.m_data, sizeof(T) * N);
616 : }
617 :
618 : template <class TStream, std::size_t N, class T>
619 : void Deserialize(TStream& out, MathVector<N, T>& valOut)
620 : {
621 0 : out.read((char*)valOut.m_data, sizeof(T) * N);
622 : }
623 :
624 : // end group vectors
625 : /// \}
626 :
627 : }// end of namespace
628 :
629 :
630 : #endif /* __H__COMMON__MATH_MathVector__ */
|