1 /* ///////////////////////////////////////////////////////////////////////
7 * Brief: vvector_base class
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 /* ///////////////////////////////////////////////////////////////////////
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 /* ///////////////////////////////////////////////////////////////////////
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
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
,
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
;
88 /*!\brief Prohibit the following case:
92 Buf &ba = da, &bb = db;
97 vvector_base(class_type
const&);
98 class_type
& operator=(class_type
const&);
100 /// \name Constructors
108 vvector_base(derived_type
const& rhs
)
110 , m_is_col(rhs
.is_col())
113 vvector_base(const_pointer vv
, size_type n
, bool_type is_col
= e_true_v
)
118 vvector_base(const_reference value
, size_type n
, bool_type is_col
= e_true_v
)
119 : base_type(value
, n
)
123 explicit_k
vvector_base(size_type n
, bool_type is_col
= e_true_v
)
124 : base_type(value_type(), n
)
130 /// \name Statistics Algorithms
134 value_type
find_min() const { return stats_min(*this); }
136 value_type
find_max() const { return stats_max(*this); }
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); }
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
; }
164 /// \name Algebraic operation
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()); }
194 /// \name Operators overload
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
];
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
];
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();
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
);
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
);
268 EXTL_MESSAGE_ASSERT(0, "the vectors can be not multiplied");
269 return vmatrix_type();
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(); }
284 /* /////////////////////////////////////////////////////////////////////////
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
);
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
);
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
];
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
;
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
];
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
;
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
;
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
;
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
];
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
];
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
];
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
];
458 #if !defined(EXTL_COMPILER_IS_WATCOM)
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
];
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
];
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
];
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
];
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
];
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
];
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
];
581 /* /////////////////////////////////////////////////////////////////////////
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 /* /////////////////////////////////////////////////////////////////////////
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 /* ///////////////////////////////////////////////////////////////////////
617 /* ///////////////////////////////////////////////////////////////////////
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
637 /* //////////////////////////////////////////////////////////////////// */
638 #endif /* EXTL_MATH_VVECTOR_BASE_H */
639 /* //////////////////////////////////////////////////////////////////// */