OpenVolumeMesh
 All Classes Functions Variables Typedefs Pages
VectorT_inc.hh
1 /*===========================================================================*\
2  * *
3  * OpenVolumeMesh *
4  * Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
5  * www.openvolumemesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenVolumeMesh. *
9  * *
10  * OpenVolumeMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenVolumeMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenVolumeMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision: 93 $ *
38  * $Date: 2012-02-10 11:56:12 +0100 (Fr, 10 Feb 2012) $ *
39  * $LastChangedBy: kremer $ *
40  * *
41 \*===========================================================================*/
42 
43 // Set template keywords and class names properly when
44 // parsing with doxygen. This only seems to work this way since
45 // the scope of preprocessor defines is limited to one file in doxy.
46 #ifdef DOXYGEN
47 
48 // Only used for correct doxygen parsing
49 #define OPENVOLUMEMESH_VECTOR_HH
50 
51 #define DIM N
52 #define TEMPLATE_HEADER template <typename Scalar, int N>
53 #define CLASSNAME VectorT
54 #define DERIVED VectorDataT<Scalar,N>
55 #define unroll(expr) for (int i=0; i<N; ++i) expr(i)
56 
57 #endif
58 
59 #if defined( OPENVOLUMEMESH_VECTOR_HH )
60 
61 // ----------------------------------------------------------------------------
62 
63 TEMPLATE_HEADER
64 class CLASSNAME : public DERIVED
65 {
66 private:
67  typedef DERIVED Base;
68 public:
69 
70  //---------------------------------------------------------------- class info
71 
73  typedef Scalar value_type;
74 
76  typedef VectorT<Scalar,DIM> vector_type;
77 
79  static inline int dim() { return DIM; }
80 
82  static inline size_t size() { return DIM; }
83 
84  static const size_t size_ = DIM;
85 
86 
87  //-------------------------------------------------------------- constructors
88 
90  inline VectorT() {}
91 
93  explicit inline VectorT(const Scalar& v) {
94 // assert(DIM==1);
95 // values_[0] = v0;
96  vectorize(v);
97  }
98 
100  inline VectorT(const Scalar& v0, const Scalar& v1) {
101  assert(DIM==2);
102  Base::values_[0] = v0; Base::values_[1] = v1;
103  }
104 
106  inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2) {
107  assert(DIM==3);
108  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
109  }
110 
112  inline VectorT(const Scalar& v0, const Scalar& v1,
113  const Scalar& v2, const Scalar& v3) {
114  assert(DIM==4);
115  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
116  }
117 
119  inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2,
120  const Scalar& v3, const Scalar& v4) {
121  assert(DIM==5);
122  Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4;
123  }
124 
126  inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2,
127  const Scalar& v3, const Scalar& v4, const Scalar& v5) {
128  assert(DIM==6);
129  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
130  Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
131  }
132 
134  explicit inline VectorT(const Scalar _values[DIM]) {
135  memcpy(Base::values_, _values, DIM*sizeof(Scalar));
136  }
137 
138 
139 #ifdef OM_CC_MIPS
140 
141  // mipspro need this method
142  inline vector_type& operator=(const vector_type& _rhs) {
143  memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar));
144  return *this;
145  }
146 #endif
147 
148 
150  template<typename otherScalarType>
151  explicit inline VectorT(const VectorT<otherScalarType,DIM>& _rhs) {
152  operator=(_rhs);
153  }
154 
155 
156 
157 
158  //--------------------------------------------------------------------- casts
159 
161  template<typename otherScalarType>
162  inline vector_type& operator=(const VectorT<otherScalarType,DIM>& _rhs) {
163 #define expr(i) Base::values_[i] = (Scalar)_rhs[i];
164  unroll(expr);
165 #undef expr
166  return *this;
167  }
168 
169 // /// cast to Scalar array
170 // inline operator Scalar*() { return Base::values_; }
171 
172 // /// cast to const Scalar array
173 // inline operator const Scalar*() const { return Base::values_; }
174 
176  inline Scalar* data() { return Base::values_; }
177 
179  inline const Scalar*data() const { return Base::values_; }
180 
181 
182 
183 
184  //----------------------------------------------------------- element access
185 
186 // /// get i'th element read-write
187 // inline Scalar& operator[](int _i) {
188 // assert(_i>=0 && _i<DIM); return Base::values_[_i];
189 // }
190 
191 // /// get i'th element read-only
192 // inline const Scalar& operator[](int _i) const {
193 // assert(_i>=0 && _i<DIM); return Base::values_[_i];
194 // }
195 
197  inline Scalar& operator[](size_t _i) {
198  assert(_i<DIM); return Base::values_[_i];
199  }
200 
202  inline const Scalar& operator[](size_t _i) const {
203  assert(_i<DIM); return Base::values_[_i];
204  }
205 
206 
207 
208 
209  //---------------------------------------------------------------- comparsion
210 
212  inline bool operator==(const vector_type& _rhs) const {
213 #define expr(i) if(Base::values_[i]!=_rhs.Base::values_[i]) return false;
214  unroll(expr);
215 #undef expr
216  return true;
217  }
218 
220  inline bool operator!=(const vector_type& _rhs) const {
221  return !(*this == _rhs);
222  }
223 
224 
225 
226 
227  //---------------------------------------------------------- scalar operators
228 
230  inline vector_type& operator*=(const Scalar& _s) {
231 #define expr(i) Base::values_[i] *= _s;
232  unroll(expr);
233 #undef expr
234  return *this;
235  }
236 
239  inline vector_type& operator/=(const Scalar& _s) {
240 #define expr(i) Base::values_[i] /= _s;
241  unroll(expr);
242 #undef expr
243  return *this;
244  }
245 
246 
248  inline vector_type operator*(const Scalar& _s) const {
249 #if DIM==N
250  return vector_type(*this) *= _s;
251 #else
252 #define expr(i) Base::values_[i] * _s
253  return vector_type(unroll_csv(expr));
254 #undef expr
255 #endif
256  }
257 
258 
260  inline vector_type operator/(const Scalar& _s) const {
261 #if DIM==N
262  return vector_type(*this) /= _s;
263 #else
264 #define expr(i) Base::values_[i] / _s
265  return vector_type(unroll_csv(expr));
266 #undef expr
267 #endif
268  }
269 
270 
271 
272 
273 
274 
275  //---------------------------------------------------------- vector operators
276 
278  inline vector_type& operator*=(const vector_type& _rhs) {
279 #define expr(i) Base::values_[i] *= _rhs[i];
280  unroll(expr);
281 #undef expr
282  return *this;
283  }
284 
286  inline vector_type& operator/=(const vector_type& _rhs) {
287 #define expr(i) Base::values_[i] /= _rhs[i];
288  unroll(expr);
289 #undef expr
290  return *this;
291  }
292 
294  inline vector_type& operator-=(const vector_type& _rhs) {
295 #define expr(i) Base::values_[i] -= _rhs[i];
296  unroll(expr);
297 #undef expr
298  return *this;
299  }
300 
302  inline vector_type& operator+=(const vector_type& _rhs) {
303 #define expr(i) Base::values_[i] += _rhs[i];
304  unroll(expr);
305 #undef expr
306  return *this;
307  }
308 
309 
311  inline vector_type operator*(const vector_type& _v) const {
312 #if DIM==N
313  return vector_type(*this) *= _v;
314 #else
315 #define expr(i) Base::values_[i] * _v.Base::values_[i]
316  return vector_type(unroll_csv(expr));
317 #undef expr
318 #endif
319  }
320 
321 
323  inline vector_type operator/(const vector_type& _v) const {
324 #if DIM==N
325  return vector_type(*this) /= _v;
326 #else
327 #define expr(i) Base::values_[i] / _v.Base::values_[i]
328  return vector_type(unroll_csv(expr));
329 #undef expr
330 #endif
331  }
332 
333 
335  inline vector_type operator+(const vector_type& _v) const {
336 #if DIM==N
337  return vector_type(*this) += _v;
338 #else
339 #define expr(i) Base::values_[i] + _v.Base::values_[i]
340  return vector_type(unroll_csv(expr));
341 #undef expr
342 #endif
343  }
344 
345 
347  inline vector_type operator-(const vector_type& _v) const {
348 #if DIM==N
349  return vector_type(*this) -= _v;
350 #else
351 #define expr(i) Base::values_[i] - _v.Base::values_[i]
352  return vector_type(unroll_csv(expr));
353 #undef expr
354 #endif
355  }
356 
357 
359  inline vector_type operator-(void) const {
360  vector_type v;
361 #define expr(i) v.Base::values_[i] = -Base::values_[i];
362  unroll(expr);
363 #undef expr
364  return v;
365  }
366 
367 
370  inline VectorT<Scalar,3> operator%(const VectorT<Scalar,3>& _rhs) const
371 #if DIM==3
372  {
373  return
374  VectorT<Scalar,3>(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1],
375  Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2],
376  Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]);
377  }
378 #else
379  ;
380 #endif
381 
382 
385  inline Scalar operator|(const vector_type& _rhs) const {
386  Scalar p(0);
387 #define expr(i) p += Base::values_[i] * _rhs.Base::values_[i];
388  unroll(expr);
389 #undef expr
390  return p;
391  }
392 
393 
394 
395 
396 
397  //------------------------------------------------------------ euclidean norm
398 
400 
401 
402  inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); }
403  inline Scalar length() const { return norm(); } // OpenSG interface
404 
406  inline Scalar sqrnorm() const
407  {
408 #if DIM==N
409  Scalar s(0);
410 #define expr(i) s += Base::values_[i] * Base::values_[i];
411  unroll(expr);
412 #undef expr
413  return s;
414 #else
415 #define expr(i) Base::values_[i]*Base::values_[i]
416  return (unroll_comb(expr, +));
417 #undef expr
418 #endif
419  }
420 
425  {
426  *this /= norm();
427  return *this;
428  }
429 
433  {
434  Scalar n = norm();
435  if (n != (Scalar)0.0)
436  {
437  *this /= n;
438  }
439  return *this;
440  }
441 
443 
444  //------------------------------------------------------------ euclidean norm
445 
447 
448 
450  inline Scalar l1_norm() const
451  {
452 #if DIM==N
453  Scalar s(0);
454 #define expr(i) s += abs(Base::values_[i]);
455  unroll(expr);
456 #undef expr
457  return s;
458 #else
459 #define expr(i) abs(Base::values_[i])
460  return (unroll_comb(expr, +));
461 #undef expr
462 #endif
463  }
464 
466  inline Scalar l8_norm() const
467  {
468  return max_abs();
469  }
470 
472 
473  //------------------------------------------------------------ max, min, mean
474 
476 
477 
479  inline Scalar max() const
480  {
481  Scalar m(Base::values_[0]);
482  for(int i=1; i<DIM; ++i) if(Base::values_[i]>m) m=Base::values_[i];
483  return m;
484  }
485 
487  inline Scalar max_abs() const
488  {
489  Scalar m(abs(Base::values_[0]));
490  for(int i=1; i<DIM; ++i)
491  if(abs(Base::values_[i])>m)
492  m=abs(Base::values_[i]);
493  return m;
494  }
495 
496 
498  inline Scalar min() const
499  {
500  Scalar m(Base::values_[0]);
501  for(int i=1; i<DIM; ++i) if(Base::values_[i]<m) m=Base::values_[i];
502  return m;
503  }
504 
506  inline Scalar min_abs() const
507  {
508  Scalar m(abs(Base::values_[0]));
509  for(int i=1; i<DIM; ++i)
510  if(abs(Base::values_[i])<m)
511  m=abs(Base::values_[i]);
512  return m;
513  }
514 
516  inline Scalar mean() const {
517  Scalar m(Base::values_[0]);
518  for(int i=1; i<DIM; ++i) m+=Base::values_[i];
519  return m/Scalar(DIM);
520  }
521 
523  inline Scalar mean_abs() const {
524  Scalar m(abs(Base::values_[0]));
525  for(int i=1; i<DIM; ++i) m+=abs(Base::values_[i]);
526  return m/Scalar(DIM);
527  }
528 
529 
531  inline vector_type minimize(const vector_type& _rhs) {
532 #define expr(i) if (_rhs[i] < Base::values_[i]) Base::values_[i] = _rhs[i];
533  unroll(expr);
534 #undef expr
535  return *this;
536  }
537 
539  inline bool minimized(const vector_type& _rhs) {
540  bool result(false);
541 #define expr(i) if (_rhs[i] < Base::values_[i]) { Base::values_[i] = _rhs[i]; result = true; }
542  unroll(expr);
543 #undef expr
544  return result;
545  }
546 
548  inline vector_type maximize(const vector_type& _rhs) {
549 #define expr(i) if (_rhs[i] > Base::values_[i]) Base::values_[i] = _rhs[i];
550  unroll(expr);
551 #undef expr
552  return *this;
553  }
554 
556  inline bool maximized(const vector_type& _rhs) {
557  bool result(false);
558 #define expr(i) if (_rhs[i] > Base::values_[i]) { Base::values_[i] =_rhs[i]; result = true; }
559  unroll(expr);
560 #undef expr
561  return result;
562  }
563 
565  inline vector_type min(const vector_type& _rhs) {
566  return vector_type(*this).minimize(_rhs);
567  }
568 
570  inline vector_type max(const vector_type& _rhs) {
571  return vector_type(*this).maximize(_rhs);
572  }
573 
575 
576  //------------------------------------------------------------ misc functions
577 
579  template<typename Functor>
580  inline vector_type apply(const Functor& _func) const {
581  vector_type result;
582 #define expr(i) result[i] = _func(Base::values_[i]);
583  unroll(expr);
584 #undef expr
585  return result;
586  }
587 
589  vector_type& vectorize(const Scalar& _s) {
590 #define expr(i) Base::values_[i] = _s;
591  unroll(expr);
592 #undef expr
593  return *this;
594  }
595 
596 
598  static vector_type vectorized(const Scalar& _s) {
599  return vector_type().vectorize(_s);
600  }
601 
602 
604  bool operator<(const vector_type& _rhs) const {
605 #define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \
606  return (Base::values_[i] < _rhs.Base::values_[i]);
607  unroll(expr);
608 #undef expr
609  return false;
610  }
611 };
612 
613 
614 
616 TEMPLATE_HEADER
617 inline std::istream&
618 operator>>(std::istream& is, VectorT<Scalar,DIM>& vec)
619 {
620 #define expr(i) is >> vec[i];
621  unroll(expr);
622 #undef expr
623  return is;
624 }
625 
626 
628 TEMPLATE_HEADER
629 inline std::ostream&
630 operator<<(std::ostream& os, const VectorT<Scalar,DIM>& vec)
631 {
632 #if DIM==N
633  for(int i=0; i<N-1; ++i) os << vec[i] << " ";
634  os << vec[N-1];
635 #else
636 #define expr(i) vec[i]
637  os << unroll_comb(expr, << " " <<);
638 #undef expr
639 #endif
640 
641  return os;
642 }
643 
644 
645 // ----------------------------------------------------------------------------
646 #endif // included by VectorT.hh
647 //=============================================================================