remove \r
[extl.git] / extl / math / vvector_base.h
blob4d1139aa0ca56ac64a8d9333c461d12b67770ce3
1 /* ///////////////////////////////////////////////////////////////////////
2 * File: vvector_base.h
4 * Created: 08.08.07
5 * Updated: 09.01.27
7 * Brief: vvector_base class
9 * [<Home>]
10 * Copyright (c) 2008-2020, Waruqi All rights reserved.
11 * //////////////////////////////////////////////////////////////////// */
13 #ifndef EXTL_MATH_VVECTOR_BASE_H
14 #define EXTL_MATH_VVECTOR_BASE_H
16 /*!\file vvector_base.h
17 * \brief vvector_base class
20 /* ///////////////////////////////////////////////////////////////////////
21 * Includes
23 #include "prefix.h"
24 #include "../utility/operators.h"
25 #include "../container/array_base.h"
26 #include "../error/error.h"
27 #include "../algorithm/stats.h"
28 #include "../math/math.h"
29 #include "vmatrix_selector.h"
30 /* ///////////////////////////////////////////////////////////////////////
31 * ::extl namespace
33 EXTL_BEGIN_NAMESPACE
35 /*!\brief vvector_base
37 * \param Dev The derived type
38 * \param Buf The buffer type
40 * \ingroup extl_group_math
42 template< typename_param_k Dev
43 , typename_param_k Buf
45 class vvector_base
46 : public array_base<Dev, Buf>
47 #if !defined(EXTL_COMPILER_IS_DMC) && \
48 !defined(EXTL_COMPILER_IS_WATCOM)
49 // VC6.0 warning: decorated name length exceeded, name was truncated
50 , private operators_arithmetic_2_noleft_<Dev, typename_type_k Buf::value_type,
51 operators_add_1_<Dev,
52 operators_sub_1_<Dev
53 > > >
54 #endif
56 /// \name Types
57 /// @{
58 public:
59 typedef array_base<Dev, Buf> base_type;
60 typedef vvector_base class_type;
61 typedef typename_type_k base_type::derived_type derived_type;
62 typedef typename_type_k base_type::buffer_type buffer_type;
63 typedef typename_type_k base_type::allocator_type allocator_type;
64 typedef typename_type_k base_type::value_type value_type;
65 typedef typename_type_k base_type::pointer pointer;
66 typedef typename_type_k base_type::const_pointer const_pointer;
67 typedef typename_type_k base_type::reference reference;
68 typedef typename_type_k base_type::const_reference const_reference;
69 typedef typename_type_k base_type::iterator iterator;
70 typedef typename_type_k base_type::const_iterator const_iterator;
71 typedef typename_type_k base_type::reverse_iterator reverse_iterator;
72 typedef typename_type_k base_type::const_reverse_iterator const_reverse_iterator;
73 typedef typename_type_k base_type::size_type size_type;
74 typedef typename_type_k base_type::bool_type bool_type;
75 typedef typename_type_k base_type::difference_type difference_type;
76 typedef typename_type_k base_type::int_type int_type;
77 typedef typename_type_k base_type::index_type index_type;
78 typedef typename_type_k vmatrix_selector<value_type>::vmatrix_type vmatrix_type;
79 /// @}
81 /// \name Members
82 /// @{
83 private:
84 bool_type m_is_col;
85 /// @}
87 private:
88 /*!\brief Prohibit the following case:
90 * \code
91 Dev da, db;
92 Buf &ba = da, &bb = db;
93 ba = bb;
94 Buf b(ba);
95 * \endcode
97 vvector_base(class_type const&);
98 class_type& operator=(class_type const&);
100 /// \name Constructors
101 /// @{
102 public:
103 vvector_base()
104 : base_type()
105 , m_is_col(e_true_v)
108 vvector_base(derived_type const& rhs)
109 : base_type(rhs)
110 , m_is_col(rhs.is_col())
113 vvector_base(const_pointer vv, size_type n, bool_type is_col = e_true_v)
114 : base_type(vv, n)
115 , m_is_col(is_col)
118 vvector_base(const_reference value, size_type n, bool_type is_col = e_true_v)
119 : base_type(value, n)
120 , m_is_col(is_col)
123 explicit_k vvector_base(size_type n, bool_type is_col = e_true_v)
124 : base_type(value_type(), n)
125 , m_is_col(is_col)
128 /// @}
130 /// \name Statistics Algorithms
131 /// @{
132 public:
133 /// min
134 value_type find_min() const { return stats_min(*this); }
135 /// max
136 value_type find_max() const { return stats_max(*this); }
137 /// sum
138 value_type sum() const { return stats_sum(*this); }
139 /// average = (x1 + x2 + ... + xn) / n;
140 value_type avg() const { return stats_avg(*this); }
141 /// variance = ((x1 - avg)^2 + (x2 - avg)^2 + ... + (xn - avg)^2) / (n - 1);
142 value_type var() const { return stats_var(*this); }
143 /// standard deviation = sqrt(((x1 - avg)^2 + (x2 - avg)^2 + ... + (xn - avg)^2) / (n - 1);
144 value_type sd() const { return stats_sd(*this); }
145 /// first-order norm: ||x|| = |x1| + |x2| + ... + |xn|;
146 value_type norm_1() const { return stats_norm_1(*this); }
147 /// second-order norm: ||x|| = sqrt(|x1|^2 + |x2|^2 + ... + |xn|^2);
148 value_type norm_2() const { return stats_norm_2(*this); }
149 /// second-order norm^2: ||x|| = |x1|^2 + |x2|^2 + ... + |xn|^2;
150 value_type norm_22() const { return stats_norm_22(*this); }
151 /// stats_infinite norm: ||x|| = max(|x1|, |x2|, ... , |xn|);
152 value_type norm_i() const { return stats_norm_i(*this); }
153 /// @}
155 /// \name Attributes
156 /// @{
157 public:
158 /// returns \true if the direction of vector is column vector
159 bool_type is_col() const { return m_is_col; }
160 /// sets the direction of vector
161 void is_col(bool_type b) { m_is_col = b; }
162 /// @}
164 /// \name Algebraic operation
165 /// @{
166 public:
167 /// returns vector transpose
168 derived_type const tr() const { derived_type tmp(derive()); tmp.is_col(!tmp.is_col()); return tmp; }
170 /// return inner product of vector
171 /// (x, y) = x1 * y1 + x2 * y2 + ... + xn * yn;
172 value_type const dot(derived_type const& rhs) const;
174 /// return inner product of vector
175 /// (x, x) = x1 * x1 + x2 * x2 + ... + xn * xn;
176 value_type const dot() const { return dot(derive()); }
178 /// return (x1 * y1, x2 * y2, ... , xn * yn)
179 derived_type const dot_mul(derived_type const& rhs) const;
181 /// return (x1 / y1, x2 / y2, ... , xn / yn)
182 derived_type const dot_div(derived_type const& rhs) const;
184 /// return (x1^2, x2^2, ... , xn^2)
185 derived_type const dot_pow2() const { return derive().dot_mul(derive()); }
187 /// returns \true if this vector is orthogonal with rhs
188 bool_type is_orthogonal(derived_type const& rhs) const { return (xtl_abs(dot(rhs) - 1) < 1e-10); }
190 /// returns \true if this vector is orthogonal
191 bool_type is_orthogonal() const { return is_orthogonal(derive()); }
192 /// @}
194 /// \name Operators overload
195 /// @{
196 public:
197 derived_type& operator =(const_reference value);
198 derived_type& operator +=(const_reference value);
199 derived_type& operator -=(const_reference value);
200 derived_type& operator *=(const_reference value);
201 derived_type& operator /=(const_reference value);
203 derived_type& operator =(derived_type const& rhs);
204 derived_type& operator +=(derived_type const& rhs);
205 derived_type& operator -=(derived_type const& rhs);
207 derived_type& operator ++();
208 derived_type const operator ++(int);
209 derived_type& operator --();
210 derived_type const operator --(int);
212 derived_type const operator +() const; // +vv
213 derived_type const operator -() const; // -vv
215 #if defined(EXTL_COMPILER_IS_WATCOM)
216 friend derived_type operator-(const_reference lhs, derived_type const& rhs)
218 derived_type ret(static_cast<derived_type const&>(rhs));
220 pointer p = ret.data();
221 EXTL_ASSERT(NULL != p);
223 size_type n = rhs.size();
224 for (size_type i = 0; i < n; ++i) p[i] = lhs - p[i];
225 return ret;
227 friend derived_type operator/(const_reference lhs, derived_type const& rhs)
229 derived_type ret(static_cast<derived_type const&>(rhs));
231 pointer p = ret.data();
232 EXTL_ASSERT(NULL != p);
234 size_type n = rhs.size();
235 for (size_type i = 0; i < n; ++i) p[i] = lhs / p[i];
236 return ret;
238 #endif
239 // matrix = vector * vector
240 vmatrix_type operator *(derived_type const& rhs) const
242 size_type lhs_n = derive().size();
243 size_type rhs_n = rhs.size();
245 // - * |
246 if (!derive().is_col() && rhs.is_col() && lhs_n == rhs_n)
248 vmatrix_type vm(1, 1);
249 vm.at(0, 0) = value_type();
250 for (index_type i = 0; i < lhs_n; ++i)
251 vm.at(0, 0) += derive().at(i) * rhs.at(i);
253 return vm;
255 // | * -
256 else if (derive().is_col() && !rhs.is_col())
258 vmatrix_type vm(lhs_n, rhs_n);
260 for (index_type i = 0; i < lhs_n; ++i)
261 for (index_type j = 0; j < rhs_n; ++j)
262 vm.at(i, j) = derive().at(i) * rhs.at(j);
264 return vm;
266 else
268 EXTL_MESSAGE_ASSERT(0, "the vectors can be not multiplied");
269 return vmatrix_type();
272 /// @}
274 /// \name Others
275 /// @{
276 protected:
277 derived_type& derive() { return static_cast<derived_type&>(*this); }
278 derived_type const& derive() const { return static_cast<derived_type const&>(*this); }
280 buffer_type& buffer() { return base_type::buffer(); }
281 buffer_type const& buffer() const { return base_type::buffer(); }
282 /// @}
284 /* /////////////////////////////////////////////////////////////////////////
285 * Implemention
287 // =
288 template< typename_param_k Dev
289 , typename_param_k Buf
291 inline typename_type_ret_k vvector_base<Dev, Buf>::
292 derived_type& vvector_base<Dev, Buf>::operator =(derived_type const& rhs)
294 return base_type::operator =(rhs);
296 // =
297 template< typename_param_k Dev
298 , typename_param_k Buf
300 inline typename_type_ret_k vvector_base<Dev, Buf>::
301 derived_type& vvector_base<Dev, Buf>::operator =(const_reference value)
303 return base_type::operator =(value);
305 // +=
306 template< typename_param_k Dev
307 , typename_param_k Buf
309 inline typename_type_ret_k vvector_base<Dev, Buf>::
310 derived_type& vvector_base<Dev, Buf>::operator +=(derived_type const& rhs)
312 pointer pl = buffer().data();
313 const_pointer pr = rhs.data();
314 EXTL_ASSERT(pl != NULL && pr != NULL);
316 size_type n = derive().size();
317 EXTL_ASSERT(n == rhs.size());
319 for (size_type i = 0; i < n; ++i) pl[i] += pr[i];
320 return derive();
322 // +=
323 template< typename_param_k Dev
324 , typename_param_k Buf
326 inline typename_type_ret_k vvector_base<Dev, Buf>::
327 derived_type& vvector_base<Dev, Buf>::operator +=(const_reference value)
329 pointer p = buffer().data();
330 EXTL_ASSERT(p != NULL);
332 size_type n = derive().size();
333 for (size_type i = 0; i < n; ++i) p[i] += value;
334 return derive();
336 // -=
337 template< typename_param_k Dev
338 , typename_param_k Buf
340 inline typename_type_ret_k vvector_base<Dev, Buf>::
341 derived_type& vvector_base<Dev, Buf>::operator -=(derived_type const& rhs)
343 pointer pl = buffer().data();
344 const_pointer pr = rhs.data();
345 EXTL_ASSERT(pl != NULL && pr != NULL);
347 size_type n = derive().size();
348 EXTL_ASSERT(n == rhs.size());
350 for (size_type i = 0; i < n; ++i) pl[i] -= pr[i];
351 return derive();
353 // -=
354 template< typename_param_k Dev
355 , typename_param_k Buf
357 inline typename_type_ret_k vvector_base<Dev, Buf>::
358 derived_type& vvector_base<Dev, Buf>::operator -=(const_reference value)
360 pointer p = buffer().data();
361 EXTL_ASSERT(p != NULL);
363 size_type n = derive().size();
364 for (size_type i = 0; i < n; ++i) p[i] -= value;
365 return derive();
367 // *=
368 template< typename_param_k Dev
369 , typename_param_k Buf
371 inline typename_type_ret_k vvector_base<Dev, Buf>::
372 derived_type& vvector_base<Dev, Buf>::operator *=(const_reference value)
374 pointer p = buffer().data();
375 EXTL_ASSERT(p != NULL);
377 size_type n = derive().size();
378 for (size_type i = 0; i < n; ++i) p[i] *= value;
379 return derive();
381 // /=
382 template< typename_param_k Dev
383 , typename_param_k Buf
385 inline typename_type_ret_k vvector_base<Dev, Buf>::
386 derived_type& vvector_base<Dev, Buf>::operator /=(const_reference value)
388 pointer p = buffer().data();
389 EXTL_ASSERT(p != NULL);
391 size_type n = derive().size();
392 for (size_type i = 0; i < n; ++i) p[i] /= value;
393 return derive();
396 // ++i
397 template< typename_param_k Dev
398 , typename_param_k Buf
400 inline typename_type_ret_k vvector_base<Dev, Buf>::
401 derived_type& vvector_base<Dev, Buf>::operator ++()
403 pointer p = buffer().data();
404 EXTL_ASSERT(p != NULL);
406 size_type n = derive().size();
407 for (size_type i = 0; i < n; ++i) ++p[i];
408 return derive();
410 // i++
411 template< typename_param_k Dev
412 , typename_param_k Buf
414 inline typename_type_ret_k vvector_base<Dev, Buf>::
415 derived_type const vvector_base<Dev, Buf>::operator ++(int)
417 derived_type ret(derive());
419 pointer p = buffer().data();
420 EXTL_ASSERT(p != NULL);
422 size_type n = derive().size();
423 for (size_type i = 0; i < n; ++i) ++p[i];
425 return ret;
427 // --i
428 template< typename_param_k Dev
429 , typename_param_k Buf
431 inline typename_type_ret_k vvector_base<Dev, Buf>::
432 derived_type& vvector_base<Dev, Buf>::operator --()
434 pointer p = buffer().data();
435 EXTL_ASSERT(p != NULL);
437 size_type n = derive().size();
438 for (size_type i = 0; i < n; ++i) --p[i];
439 return derive();
441 // i--
442 template< typename_param_k Dev
443 , typename_param_k Buf
445 inline typename_type_ret_k vvector_base<Dev, Buf>::
446 derived_type const vvector_base<Dev, Buf>::operator --(int)
448 derived_type ret(derive());
450 pointer p = buffer().data();
451 EXTL_ASSERT(p != NULL);
453 size_type n = derive().size();
454 for (size_type i = 0; i < n; ++i) --p[i];
456 return ret;
458 #if !defined(EXTL_COMPILER_IS_WATCOM)
459 // value - class
460 template< typename_param_k T
461 , typename_param_k Dev
462 , typename_param_k Buf
464 inline typename_type_ret_k vvector_base<Dev, Buf>::
465 derived_type operator-(T const& lhs, vvector_base<Dev, Buf> const& rhs)
467 typedef typename_type_k vvector_base<Dev, Buf>::derived_type derived_type;
468 typedef typename_type_k vvector_base<Dev, Buf>::pointer pointer;
469 typedef typename_type_k vvector_base<Dev, Buf>::size_type size_type;
471 derived_type ret(static_cast<derived_type const&>(rhs));
473 pointer p = ret.data();
474 EXTL_ASSERT(NULL != p);
476 size_type n = rhs.size();
477 for (size_type i = 0; i < n; ++i) p[i] = lhs - p[i];
478 return ret;
480 // value / class
481 template< typename_param_k T
482 , typename_param_k Dev
483 , typename_param_k Buf
485 inline typename_type_ret_k vvector_base<Dev, Buf>::
486 derived_type operator/(T const& lhs, vvector_base<Dev, Buf> const& rhs)
488 typedef typename_type_k vvector_base<Dev, Buf>::derived_type derived_type;
489 typedef typename_type_k vvector_base<Dev, Buf>::pointer pointer;
490 typedef typename_type_k vvector_base<Dev, Buf>::size_type size_type;
492 derived_type ret(static_cast<derived_type const&>(rhs));
494 pointer p = ret.data();
495 EXTL_ASSERT(NULL != p);
497 size_type n = rhs.size();
498 for (size_type i = 0; i < n; ++i) p[i] = lhs / p[i];
499 return ret;
502 #endif
503 // +vv
504 template< typename_param_k Dev
505 , typename_param_k Buf
507 inline typename_type_ret_k vvector_base<Dev, Buf>::
508 derived_type const vvector_base<Dev, Buf>::operator +() const
510 derived_type ret(derive());
512 pointer p = ret.data();
513 EXTL_ASSERT(p != NULL);
515 size_type n = ret.size();
516 for (size_type i = 0; i < n; ++i) p[i] = +p[i];
518 return ret;
520 // -vv
521 template< typename_param_k Dev
522 , typename_param_k Buf
524 inline typename_type_ret_k vvector_base<Dev, Buf>::
525 derived_type const vvector_base<Dev, Buf>::operator -() const
527 derived_type ret(derive());
529 pointer p = ret.data();
530 EXTL_ASSERT(p != NULL);
532 size_type n = ret.size();
533 for (size_type i = 0; i < n; ++i) p[i] = -p[i];
535 return ret;
537 /// return inner product of vector
538 template< typename_param_k Dev
539 , typename_param_k Buf
541 inline typename_type_ret_k vvector_base<Dev, Buf>::
542 value_type const vvector_base<Dev, Buf>::dot(derived_type const& rhs) const
544 EXTL_ASSERT(derive().size() == rhs.size());
546 value_type ret = value_type();
547 size_type n = rhs.size();
548 for (size_type i = 0; i < n; ++i) ret += derive()[i] * rhs[i];
549 return ret;
552 /// return (x1 * y1, x2 * y2, ... , xn * yn)
553 template< typename_param_k Dev
554 , typename_param_k Buf
556 inline typename_type_ret_k vvector_base<Dev, Buf>::
557 derived_type const vvector_base<Dev, Buf>::dot_mul(derived_type const& rhs) const
559 EXTL_ASSERT(derive().size() == rhs.size());
561 derived_type ret(derive().size());
562 size_type n = rhs.size();
563 for (size_type i = 0; i < n; ++i) ret[i] = derive()[i] * rhs[i];
564 return ret;
567 /// return (x1 / y1, x2 / y2, ... , xn / yn)
568 template< typename_param_k Dev
569 , typename_param_k Buf
571 inline typename_type_ret_k vvector_base<Dev, Buf>::
572 derived_type const vvector_base<Dev, Buf>::dot_div(derived_type const& rhs) const
574 EXTL_ASSERT(derive().size() == rhs.size());
576 derived_type ret(derive().size());
577 size_type n = rhs.size();
578 for (size_type i = 0; i < n; ++i) ret[i] = derive()[i] / rhs[i];
579 return ret;
581 /* /////////////////////////////////////////////////////////////////////////
582 * swapping
584 template< typename_param_k Dev
585 , typename_param_k Buf
587 EXTL_INLINE void swap(vvector_base<Dev, Buf>& lhs, vvector_base<Dev, Buf>& rhs)
589 static_cast<Dev&>(lhs).swap(static_cast<Dev&>(rhs));
591 /* /////////////////////////////////////////////////////////////////////////
592 * shims
594 template< typename_param_k Dev
595 , typename_param_k Buf
597 EXTL_INLINE typename_type_ret_k vvector_base<Dev, Buf>::
598 const_pointer get_ptr(vvector_base<Dev, Buf> const& vv)
600 return static_cast<Dev const&>(vv).data();
603 template< typename_param_k Dev
604 , typename_param_k Buf
606 EXTL_INLINE typename_type_ret_k vvector_base<Dev, Buf>::
607 size_type get_size(vvector_base<Dev, Buf> const& vv)
609 return static_cast<Dev const&>(vv).size();
612 /* ///////////////////////////////////////////////////////////////////////
613 * ::extl namespace
615 EXTL_END_NAMESPACE
617 /* ///////////////////////////////////////////////////////////////////////
618 * std::swap
620 #if !defined(EXTL_NO_STL) && \
621 !defined(EXTL_NO_NAMESPACE)
622 /* ::std namespace */
623 EXTL_STD_BEGIN_NAMESPACE
625 template< typename_param_k Dev
626 , typename_param_k Buf
628 EXTL_INLINE void swap(EXTL_NS(vvector_base)<Dev, Buf>& lhs,
629 EXTL_NS(vvector_base)<Dev, Buf>& rhs)
631 static_cast<Dev&>(lhs).swap(static_cast<Dev&>(rhs));
633 /* ::std namespace */
634 EXTL_STD_END_NAMESPACE
635 #endif
637 /* //////////////////////////////////////////////////////////////////// */
638 #endif /* EXTL_MATH_VVECTOR_BASE_H */
639 /* //////////////////////////////////////////////////////////////////// */