Library of Assembled Shared Sources
vector.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_VECTOR_INL
46#define LASS_GUARDIAN_OF_INCLUSION_NUM_VECTOR_INL
47
48#include "num_common.h"
49#include "vector.h"
50#include "../meta/is_integral.h"
51
52#define LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(a, b)\
53 *LASS_UTIL_IMPL_MAKE_ENFORCER(\
54 ::lass::util::impl::EqualPredicate,\
55 ::lass::util::impl::DefaultRaiser,\
56 (a).size(), \
57 (b).size(), \
58 "Vectors '" LASS_STRINGIFY(a) "' and '" LASS_STRINGIFY(b) "' have different dimensions in '" LASS_HERE "'.")
59
60namespace lass
61{
62namespace num
63{
64
65// --- public --------------------------------------------------------------------------------------
66
67/** constructs an empty vector
68 *
69 * @par Exception safety:
70 * strong guarentee.
71 */
72template <typename T, typename S>
73Vector<T, S>::Vector():
74 storage_()
75{
76 LASS_ASSERT(size() == 0);
77}
78
79
80
81/** Construct a vector of dimension @a iDimension.
82 * @param iDimension the dimension of the vector to be created. You can pass zero, but you
83 * shouldn't pass negative dimensions though.
84 * @param iInitialValue the initial value of all vector components, zero by default.
85 *
86 * @par Complexity:
87 * O(iDimension)
88 *
89 * @par Exception safety:
90 * strong guarentee.
91 */
92template <typename T, typename S>
93Vector<T, S>::Vector(TSize iDimension, TParam iInitialValue):
94 storage_(iDimension, iInitialValue)
96}
98
100/** construct vector from storage type
102 * @par Complexity:
103 * O(iStorage.size())
105 * @par Exception safety:
106 * strong guarentee.
107 */
108template <typename T, typename S>
109Vector<T, S>::Vector(const TStorage& iStorage):
110 storage_(iStorage)
114
116/** contruct by any particular type supporting [] and size().
117 * Should only be used with writable storage type (like std::vector which is the default).
119 * @par Complexity:
120 * O(iVector.size())
122 * @par Exception safety:
123 * strong guarentee.
124 */
125template <typename T, typename S>
126template <typename VectorType>
127Vector<T, S>::Vector(const VectorType& iVector)
129 init(iVector, meta::Wrap<typename meta::IsIntegral<VectorType>::Type>());
130}
131
133
134/** construct storage/expression vector to this (this should be a storage vector).
135 *
136 * @pre @c this must be an l-value.
137 *
138 * @par Complexity:
139 * O(iOther.size())
140 *
141 * @par Exception safety:
142 * strong guarentee.
143 */
144template <typename T, typename S>
145template <typename T2, typename S2>
146Vector<T, S>::Vector(const Vector<T2, S2>& iOther)
147{
148 TSize n = iOther.storage_.size();
149 storage_.resize(n);
150 for (TSize i = 0; i < n; ++i)
151 {
152 storage_[i] = iOther.storage_[i];
153 }
154}
155
156
157
158/** assign storage/expression vector to this (this should be a storage vector).
159 *
160 * @pre @c this must be an l-value.
161 *
162 * @par Complexity:
163 * O(iOther.size())
164 *
165 * @par Exception safety:
166 * basic guarentee.
167 */
168template <typename T, typename S>
169template <typename T2, typename S2>
170Vector<T, S>& Vector<T, S>::operator=(const Vector<T2, S2>& iOther)
171{
172 TSize n = iOther.storage_.size();
173 storage_.resize(n);
174 for (TSize i = 0; i < n; ++i)
175 {
176 storage_[i] = iOther.storage_[i];
177 }
178 return *this;
179}
180
181
182
183/** return dimension of vector.
184 * this should never be a negative value.
185 *
186 * @par Exception safety:
187 * nofail.
188 */
189template <typename T, typename S> inline
190typename Vector<T, S>::TSize
192{
193 return storage_.size();
194}
195
196
197
198/** return the iIndex'th component value.
199 *
200 * @pre @a iIndex must be in [0, this->size()), unless you're asking for trouble.
201 *
202 * @par Exception safety:
203 * strong guarentee.
204 */
205template <typename T, typename S> inline
206const typename Vector<T, S>::TValue
207Vector<T, S>::operator[](TSize iIndex) const
208{
209 LASS_ASSERT(iIndex < size());
210 return storage_[iIndex];
211}
212
213
214
215/** access the iIndex'th component value.
216 *
217 * @pre
218 * @arg @a iIndex must be in [0, this->size()), unless you're asking for trouble.
219 * @arg @c this must be an l-value.
220 *
221 * @par Exception safety:
222 * strong guarentee.
223 */
224template <typename T, typename S> inline
225typename Vector<T, S>::TReference
227{
228 LASS_ASSERT(iIndex < size());
229 return storage_[iIndex];
230}
231
232
233/** return the iIndex'th component value and wrap index if necessary.
234 * if iIndex is out of the range [0, this->size()), it will be wrapped to map in this range.
235 * This is simply a modulus operation: mod(iIndex, this->size()).
236 *
237 * @par Exception safety:
238 * strong guarentee.
239 */
240template <typename T, typename S> inline
241const typename Vector<T, S>::TValue
242Vector<T, S>::at(TSize iIndex) const
243{
244 return storage_[mod(iIndex, storage_.size())];
245}
246
247
248
249/** access the iIndex'th component value and wrap index if necessary.
250 * if iIndex is out of the range [0, this->size()), it will be wrapped to map in this range.
251 * This is simply a modulus operation: mod(iIndex, this->size()).
252 *
253 * @pre @c this must be an l-value.
254 *
255 * @par Exception safety:
256 * strong guarentee.
257 */
258template <typename T, typename S> inline
259typename Vector<T, S>::TReference
260Vector<T, S>::at(TSize iIndex)
261{
262 return storage_[num::mod(iIndex, storage_.size())];
263}
264
265
266
267/** A weird way to get back the same object
268 *
269 * @par Complexity:
270 * O(1)
271 *
272 * @par Exception safety:
273 * nofail guarentee.
274 */
275template <typename T, typename S> inline
276const Vector<T, S>&
278{
279 return *this;
280}
281
282
283
284/** return a vector with all components negated
285 * (-v)[i] == -(v[i]).
286 *
287 * @par Complexity:
288 * O(1)
289 *
290 * @par Exception safety:
291 * nofail.
292 */
293template <typename T, typename S>
296{
297 typedef impl::VNeg<T, S> TExpression;
298 return Vector<T, TExpression>(TExpression(storage_));
299}
300
301
302
303/** add storage/expression vector to this (this should be a storage vector).
304 *
305 * @pre
306 * @arg this->size() == iB.size()
307 * @arg @c this must be an l-value.
308 *
309 * @par Complexity:
310 * O(this->size())
311 *
312 * @par Exception safety:
313 * basic guarentee.
314 */
315template <typename T, typename S>
316template <typename T2, typename S2>
317Vector<T, S>& Vector<T, S>::operator+=(const Vector<T2, S2>& iB)
318{
319 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
320 const TSize n = storage_.size();
321 for (TSize i = 0; i < n; ++i)
322 {
323 storage_[i] += iB[i];
324 }
325 return *this;
326}
327
328
329
330/** subtract storage/expression vector from this (this should be a storage vector).
331 *
332 * @pre
333 * @arg this->size() == iB.size()
334 * @arg @c this must be an l-value.
335 *
336 * @par Complexity:
337 * O(this->size())
338 *
339 * @par Exception safety:
340 * basic guarentee.
341 */
342template <typename T, typename S>
343template <typename T2, typename S2>
344Vector<T, S>& Vector<T, S>::operator-=(const Vector<T2, S2>& iB)
345{
346 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
347 const TSize n = storage_.size();
348 for (TSize i = 0; i < n; ++i)
349 {
350 storage_[i] -= iB[i];
351 }
352 return *this;
353}
354
355
356
357/** multiply storage/expression vector with this (this should be a storage vector).
358 *
359 * @pre
360 * @arg this->size() == iB.size()
361 * @arg @c this must be an l-value.
362 *
363 * @par Complexity:
364 * O(this->size())
365 *
366 * @par Exception safety:
367 * basic guarentee.
368 */
369template <typename T, typename S>
370template <typename T2, typename S2>
371Vector<T, S>& Vector<T, S>::operator*=(const Vector<T2, S2>& iB)
372{
373 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
374 const TSize n = storage_.size();
375 for (TSize i = 0; i < n; ++i)
376 {
377 storage_[i] *= iB[i];
378 }
379 return *this;
380}
381
382
383
384/** divide this by storage/expression vector (this should be a storage vector).
385 *
386 * @pre
387 * @arg this->size() == iB.size()
388 * @arg @c this must be an l-value.
389 *
390 * @par Complexity:
391 * O(this->size())
392 *
393 * @par Exception safety:
394 * basic guarentee.
395 */
396template <typename T, typename S>
397template <typename T2, typename S2>
398Vector<T, S>& Vector<T, S>::operator/=(const Vector<T2, S2>& iB)
399{
400 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
401 const TSize n = storage_.size();
402 for (TSize i = 0; i < n; ++i)
403 {
404 storage_[i] /= iB[i];
405 }
406 return *this;
407}
408
409
410
411/** add @a iB to all components
412 *
413 * @pre @c this must be an l-value.
414 *
415 * @par Complexity:
416 * O(this->size())
417 */
418template <typename T, typename S>
419template <typename T2>
420Vector<T, S>& Vector<T, S>::operator+=(const T2& iB)
421{
422 const TSize n = storage_.size();
423 for (TSize i = 0; i < n; ++i)
424 {
425 storage_[i] += iB;
426 }
427 return *this;
428}
429
430
431
432/** subtract @a iB from all components
433 *
434 * @pre @c this must be an l-value.
435 *
436 * @par Complexity:
437 * O(this->size())
438 */
439template <typename T, typename S>
440template <typename T2>
441Vector<T, S>& Vector<T, S>::operator-=(const T2& iB)
442{
443 const TSize n = storage_.size();
444 for (TSize i = 0; i < n; ++i)
445 {
446 storage_[i] -= iB;
447 }
448 return *this;
449}
450
451
452
453/** multiply all components with @a iB.
454 *
455 * @pre @c this must be an l-value.
456 *
457 * @par Complexity:
458 * O(this->size())
459 */
460template <typename T, typename S>
461template <typename T2>
462Vector<T, S>& Vector<T, S>::operator*=(const T2& iB)
463{
464 const TSize n = storage_.size();
465 for (TSize i = 0; i < n; ++i)
466 {
467 storage_[i] *= iB;
468 }
469 return *this;
470}
471
472
473
474/** divide all components by @a iB.
475 *
476 * @pre @c this must be an l-value.
477 *
478 * @par Complexity:
479 * O(this->size())
480 */
481template <typename T, typename S>
482template <typename T2>
483Vector<T, S>& Vector<T, S>::operator/=(const T2& iB)
484{
485 const TSize n = storage_.size();
486 for (TSize i = 0; i < n; ++i)
487 {
488 storage_[i] /= iB;
489 }
490 return *this;
491}
492
493
494/** return true if vector contains no dataa at all
495 *
496 * @par Complexity:
497 * O(1)
498 *
499 * @par Exception safety:
500 * nofail.
501 */
502template <typename T, typename S> inline
504{
505 return storage_.size() == 0;
506}
507
508
509
510/** Return true if all the components are (exactly!) zero
511 *
512 * @par Complexity:
513 * O(this->size())
514 */
515template <typename T, typename S>
517{
518 const TSize n = storage_.size();
519 for (TSize i = 0; i < n; ++i)
520 {
521 // if you get your compiler error here, you'll be using a broken STLport version. Ask [Bramz].
522 //
523 if (storage_[i] != TNumTraits::zero)
524 {
525 return false;
526 }
527 }
528 return true;
529}
530
531
532
533/** Return sum of all components of vector.
534 *
535 * @par Complexity:
536 * O(this->size())
537 */
538template <typename T, typename S>
539const typename Vector<T, S>::TValue
541{
542 const TSize n = storage_.size();
543 TValue result = TNumTraits::zero;
544 for (TSize i = 0; i < n; ++i)
545 {
546 result += storage_[i];
547 }
548 return result;
549}
550
551
552
553/** Return minimum of all components of vector.
554 *
555 * @par Complexity:
556 * O(this->size())
557 */
558template <typename T, typename S>
559const typename Vector<T, S>::TValue
561{
562 const TSize n = storage_.size();
563 if (n == 0)
564 {
565 return TNumTraits::zero;
566 }
567 TValue result = storage_[0];
568 for (TSize i = 1; i < n; ++i)
569 {
570 result = std::min(result, storage_[i]);
571 }
572 return result;
573}
574
575
576
577/** Return maximum of all components of vector.
578 *
579 * @par Complexity:
580 * O(this->size())
581 */
582template <typename T, typename S>
583const typename Vector<T, S>::TValue
585{
586 const TSize n = storage_.size();
587 if (n == 0)
588 {
589 return TNumTraits::zero;
590 }
591 TValue result = storage_[0];
592 for (TSize i = 1; i < n; ++i)
593 {
594 result = std::max(result, storage_[i]);
595 }
596 return result;
597}
598
599
600
601/** Return squared norm of vector.
602 * @return dot(*this, *this)
603 *
604 * @par Complexity:
605 * O(this->size())
606 */
607template <typename T, typename S>
608const typename Vector<T, S>::TValue
610{
611 const TSize n = storage_.size();
612 TValue result = TNumTraits::zero;
613 for (TSize i = 0; i < n; ++i)
614 {
615 result += num::sqr(storage_[i]);
616 }
617 return result;
618}
619
620
621
622/** Return norm of vector.
623 * @return sqrt(this->squaredNorm())
624 *
625 * @par Complexity:
626 * O(this->size())
627 */
628template <typename T, typename S>
629const typename Vector<T, S>::TValue
631{
632 return num::sqrt(squaredNorm());
633}
634
635
636
637/** return a unit vector with same direction/sense as this vector.
638 *
639 * <i>The normalized vector of <b>X</b> is a vector in the same direction but with norm (length) 1.
640 * It is denoted <b>X^</b> and given by <b>X^</b> = <b>X</b> / |<b>X</b>|</i>,
641 * http://mathworld.wolfram.com/dimension_ormalizedVector.html.
642 *
643 * @return *this / this->norm()
644 *
645 * @par Complexity:
646 * O(this->size())
647 */
648template <typename T, typename S>
651{
652 const TValue scale = TNumTraits::one / norm();
653 typedef impl::VMul<T, S, impl::VScalar<T> > TExpression;
654 return Vector<T, TExpression>(TExpression(storage_, impl::VScalar<T>(storage_.size(), scale)));
655}
656
657
658
659/** return a vector with each component being the reciprocal value of this vector.
660 *
661 * @par Complexity:
662 * O(1)
663 */
664template <typename T, typename S>
667{
668 typedef impl::VRec<T, S> TExpression;
669 return Vector<T, TExpression>(TExpression(storage_));
670}
671
672
673
674/** Project vector on this one
675 *
676 * @pre this->size() == iB.size()
677 *
678 * @par Complexity:
679 * O(this->size())
680 */
681template <typename T, typename S>
682template <typename S2>
684Vector<T, S>::project(const Vector<T, S2>& iB) const
685{
686 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
687 const TValue scale = dot(iB, *this) / squaredNorm();
688 typedef impl::VMul<T, S, impl::VScalar<T> > TExpression;
689 return Vector<T, TExpression>(TExpression(storage_, impl::VScalar<T>(storage_.size(), scale)));
690}
691
692
693
694/** Project vector on this one
695 *
696 * @pre this->size() == iB.size()
697 *
698 * @par Complexity:
699 * O(this->size())
700 */
701template <typename T, typename S>
702template <typename S2>
704Vector<T, S>::reject(const Vector<T, S2>& iB) const
705{
706 return iB - project(iB);
707}
708
709
710
711/** Normalize vector.
712 *
713 * @pre @c this must be an l-value.
714 *
715 * @par Complexity:
716 * O(this->size())
717 */
718template <typename T, typename S>
720{
721 *this /= norm();
722}
723
724
725
726template <typename T, typename S> inline
727const typename Vector<T, S>::TStorage&
728Vector<T, S>::storage() const
729{
730 return storage_;
731}
732
733
734
735template <typename T, typename S> inline
736typename Vector<T, S>::TStorage&
737Vector<T, S>::storage()
738{
739 return storage_;
740}
741
742
743
744/** swap storage of two vectors
745 *
746 * @pre @c this and @ a iOther must be l-values
747 *
748 * @par Complexity:
749 * O(1)
750 *
751 * @par Exception safety:
752 * no-fail
753 */
754template <typename T, typename S>
755void Vector<T, S>::swap(Vector<T, S>& iOther)
756{
757 storage_.swap(iOther.storage_);
758}
759
760
761
762// --- private -------------------------------------------------------------------------------------
763
764template <typename T, typename S>
765template <typename IntegralType>
766void Vector<T, S>::init(IntegralType iDimension, meta::Wrap<meta::True>)
767{
768 TStorage temp(iDimension, T());
769 storage_.swap(temp);
770}
771
772
773
774template <typename T, typename S>
775template <typename VectorType>
776void Vector<T, S>::init(const VectorType& iVector, meta::Wrap<meta::False>)
777{
778 TSize n = iVector.size();
779 TStorage temp(n, T());
780 for (TSize i = 0; i < n; ++i)
781 {
782 temp[i] = iVector[i];
783 }
784 storage_.swap(temp);
785}
786
787
788
789// --- free ----------------------------------------------------------------------------------------
790
791
792
793/** @relates lass::prim::Vector
794 *
795 * @par Complexity:
796 * O(iA->size())
797 */
798template <typename T, typename S1, typename S2>
799bool operator==(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
800{
801 typedef typename Vector<T, S1>::TSize TSize;
802 const TSize n = iA.size();
803
804 if (n != iB.size())
805 {
806 return false;
807 }
808 for (TSize i = 0; i < n; ++i)
809 {
810 if (iA[i] != iB[i])
811 {
812 return false;
813 }
814 }
815 return true;
816}
817
818
819
820/** @relates lass::prim::Vector
821 *
822 * @par Complexity:
823 * O(iA.size())
824 */
825template <typename T, typename S1, typename S2>
826bool operator!=(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
827{
828 return !(iA == iB);
829}
830
831
832
833/** dot product.
834 * @relates lass::num::Vector
835 *
836 * @pre iA.size() == iB.size()
837 *
838 * @par Complexity:
839 * O(iA.size())
840 */
841template <typename T, typename S1, typename S2>
842const T dot(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
843{
844 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
845 typedef typename Vector<T, S1>::TSize TSize;
846 const TSize n = iA.size();
847
848 T result = NumTraits<T>::zero;
849 for (TSize i = 0; i < n; ++i)
850 {
851 result += iA[i] * iB[i];
852 }
853 return result;
854}
855
856
857
858/** componentwise addition
859 * @relates lass::num::Vector
860 *
861 * @pre iA.size() == iB.size()
862 *
863 * @par Complexity:
864 * O(1)
865 */
866template <typename T, typename S1, typename S2>
868operator+(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
869{
870 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
871 typedef impl::VAdd<T, S1, S2> TExpression;
872 return Vector<T, TExpression>(TExpression(iA.storage(), iB.storage()));
873}
874
875
876
877/** componentwise subtraction
878 * @relates lass::num::Vector
879 *
880 * @pre iA.size() == iB.size()
881 *
882 * @par Complexity:
883 * O(1)
884 */
885template <typename T, typename S1, typename S2>
887operator-(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
888{
889 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
890 typedef impl::VSub<T, S1, S2> TExpression;
891 return Vector<T, TExpression>(TExpression(iA.storage(), iB.storage()));
892}
893
894
895
896/** componentwise multiplication
897 * @relates lass::num::Vector
898 *
899 * @pre iA.size() == iB.size()
900 *
901 * @par Complexity:
902 * O(1)
903 */
904template <typename T, typename S1, typename S2>
906operator*(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
907{
908 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
909 typedef impl::VMul<T, S1, S2> TExpression;
910 return Vector<T, TExpression>(TExpression(iA.storage(), iB.storage()));
911}
912
913
914
915/** componentwise division
916 * @relates lass::num::Vector
917 *
918 * @pre iA.size() == iB.size()
919 *
920 * @par Complexity:
921 * O(1)
922 */
923template <typename T, typename S1, typename S2>
925operator/(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
926{
927 LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
928 typedef impl::VDiv<T, S1, S2> TExpression;
929 return Vector<T, TExpression>(TExpression(iA.storage(), iB.storage()));
930}
931
932
933
934/** add @a iA to all components of @a iB
935 * @relates lass::num::Vector
936 *
937 * @par Complexity:
938 * O(1)
939 */
940template <typename T, typename S>
942operator+(const T& iA, const Vector<T, S>& iB)
943{
944 typedef impl::VAdd<T, impl::VScalar<T>, S> TExpression;
945 return Vector<T, TExpression>(TExpression(impl::VScalar<T>(iB.size(), iA), iB.storage()));
946}
947
948
949
950/** add @a iA to all negated components of @a iB
951 * @relates lass::num::Vector
952 *
953 * @par Complexity:
954 * O(1)
955 */
956template <typename T, typename S>
958operator-(const T& iA, const Vector<T, S>& iB)
959{
960 typedef impl::VSub<T, impl::VScalar<T>, S> TExpression;
961 return Vector<T, TExpression>(TExpression(impl::VScalar<T>(iB.size(), iA), iB.storage()));
962}
963
964
965
966/** multiply @a iA with all components of @a iB
967 * @relates lass::num::Vector
968 *
969 * @par Complexity:
970 * O(1)
971 */
972template <typename T, typename S>
974operator*(const T& iA, const Vector<T, S>& iB)
975{
976 typedef impl::VMul<T, impl::VScalar<T>, S> TExpression;
977 return Vector<T, TExpression>(TExpression(impl::VScalar<T>(iB.size(), iA), iB.storage()));
978}
979
980
981
982/** multiply @a iA with all reciprocal components of @a iB
983 * @relates lass::num::Vector
984 *
985 * @par Complexity:
986 * O(1)
987 */
988template <typename T, typename S>
990operator/(const T& iA, const Vector<T, S>& iB)
991{
992 typedef impl::VDiv<T, impl::VScalar<T>, S> TExpression;
993 return Vector<T, TExpression>(TExpression(impl::VScalar<T>(iB.size(), iA), iB.storage()));
994}
995
996
997
998/** add @a iB to all components of @a iA
999 * @relates lass::num::Vector
1000 *
1001 * @par Complexity:
1002 * O(1)
1003 */
1004template <typename T, typename S>
1006operator+(const Vector<T, S>& iA, const T& iB)
1007{
1008 typedef impl::VAdd<T, S, impl::VScalar<T> > TExpression;
1009 return Vector<T, TExpression>(TExpression(iA.storage(), impl::VScalar<T>(iA.size(), iB)));
1010}
1011
1012
1013
1014/** subtract @a iB from all components of @a iA
1015 * @relates lass::num::Vector
1016 *
1017 * @par Complexity:
1018 * O(1)
1019 */
1020template <typename T, typename S>
1022operator-(const Vector<T, S>& iA, const T& iB)
1023{
1024 typedef impl::VSub<T, S, impl::VScalar<T> > TExpression;
1025 return Vector<T, TExpression>(TExpression(iA.storage(), impl::VScalar<T>(iA.size(), iB)));
1026}
1027
1028
1029
1030/** multiply all components of @a iA with @a iB.
1031 * @relates lass::num::Vector
1032 *
1033 * @par Complexity:
1034 * O(1)
1035 */
1036template <typename T, typename S>
1038operator*(const Vector<T, S>& iA, const T& iB)
1039{
1040 typedef impl::VMul<T, S, impl::VScalar<T> > TExpression;
1041 return Vector<T, TExpression>(TExpression(iA.storage(), impl::VScalar<T>(iA.size(), iB)));
1042}
1043
1044
1045
1046/** multiply all components of @a iA with @a iB.
1047 * @relates lass::num::Vector
1048 *
1049 * @par Complexity:
1050 * O(1)
1051 */
1052template <typename T, typename S>
1054operator/(const Vector<T, S>& iA, const T& iB)
1055{
1056 typedef impl::VDiv<T, S, impl::VScalar<T> > TExpression;
1057 return Vector<T, TExpression>(TExpression(iA.storage(), impl::VScalar<T>(iA.size(), iB)));
1058}
1059
1060
1061
1062/** @relates lass::prim::Vector
1063 *
1064 * @par Complexity:
1065 * O(iB.size())
1066 */
1067template <typename T, typename S, typename Char, typename Traits>
1068std::basic_ostream<Char, Traits>&
1069operator<<(std::basic_ostream<Char, Traits>& oOStream, const Vector<T, S>& iB)
1070{
1071 typedef typename Vector<T, S>::TSize TSize;
1072 const TSize n = iB.size();
1073
1074 LASS_ENFORCE_STREAM(oOStream) << "(";
1075 if (n > 0)
1076 {
1077 LASS_ENFORCE_STREAM(oOStream) << iB[0];
1078 }
1079 for (TSize i = 1; i < n; ++i)
1080 {
1081 LASS_ENFORCE_STREAM(oOStream) << ", " << iB[i];
1082 }
1083 LASS_ENFORCE_STREAM(oOStream) << ")";
1084 return oOStream;
1085}
1086
1087
1088
1089/** @relates lass::prim::Vector
1090 */
1091template <typename T, typename Char, typename Traits>
1092std::basic_istream<Char, Traits>&
1093operator>>(std::basic_istream<Char, Traits>& ioIStream, Vector<T>& oB)
1094{
1095 typedef typename Vector<T>::TValue TValue;
1096 typedef typename Vector<T>::TSize TSize;
1097 typedef typename Vector<T>::TStorage TStorage;
1098
1099 TStorage buffer;
1100 TValue value;
1101 TSize size = 0;
1102
1103 char c = 0;
1104 LASS_ENFORCE_STREAM(ioIStream) >> c;
1105 if (c != '(')
1106 {
1107 ioIStream.clear(std::ios::failbit);
1108 return ioIStream;
1109 }
1110
1111 // TODO peek for empty vectors '()'
1112
1113 // assume no empty vector here
1114 do
1115 {
1116 c = 0;
1117 LASS_ENFORCE_STREAM(ioIStream) >> value >> c;
1118 buffer.push_back(value);
1119 ++size;
1120 if (c != ',' && c != ')')
1121 {
1122 ioIStream.clear(std::ios::failbit);
1123 return ioIStream;
1124 }
1125 }
1126 while (c != ')');
1127
1128 oB.storage().swap(buffer);
1129 return ioIStream;
1130}
1131
1132
1133
1134}
1135
1136}
1137
1138#endif
1139
1140// EOF
a dynamic sized n-dimensional vector with vector expression templates
Definition vector.h:71
bool isZero() const
Return true if all the components are (exactly!) zero.
Definition vector.inl:516
const TValue sum() const
Return sum of all components of vector.
Definition vector.inl:540
const Vector< T, impl::VMul< T, S, impl::VScalar< T > > > operator*(const Vector< T, S > &iA, const T &iB)
multiply all components of iA with iB.
Definition vector.inl:1038
const TValue operator[](TSize iIndex) const
return the iIndex'th component value.
Definition vector.inl:207
const TValue squaredNorm() const
Return squared norm of vector.
Definition vector.inl:609
const Vector< T, impl::VAdd< T, S1, S2 > > operator+(const Vector< T, S1 > &iA, const Vector< T, S2 > &iB)
componentwise addition
Definition vector.inl:868
const Vector< T, impl::VMul< T, S1, S2 > > operator*(const Vector< T, S1 > &iA, const Vector< T, S2 > &iB)
componentwise multiplication
Definition vector.inl:906
const Vector< T, impl::VMul< T, S, impl::VScalar< T > > > project(const Vector< T, S2 > &iB) const
Project vector on this one.
Definition vector.inl:684
const Vector< T, impl::VMul< T, S, impl::VScalar< T > > > normal() const
return a unit vector with same direction/sense as this vector.
Definition vector.inl:650
const Vector< T, impl::VNeg< T, S > > operator-() const
return a vector with all components negated (-v)[i] == -(v[i]).
Definition vector.inl:295
const Vector< T, impl::VDiv< T, impl::VScalar< T >, S > > operator/(const T &iA, const Vector< T, S > &iB)
multiply iA with all reciprocal components of iB
Definition vector.inl:990
void swap(Vector< T, S > &iOther)
swap storage of two vectors
Definition vector.inl:755
const TValue min() const
Return minimum of all components of vector.
Definition vector.inl:560
Vector< T, S > & operator*=(const Vector< T2, S2 > &iB)
multiply storage/expression vector with this (this should be a storage vector).
Definition vector.inl:371
const TValue norm() const
Return norm of vector.
Definition vector.inl:630
Vector< T, S > & operator=(const Vector< T2, S2 > &iOther)
assign storage/expression vector to this (this should be a storage vector).
Definition vector.inl:170
Vector< T, S > & operator/=(const Vector< T2, S2 > &iB)
divide this by storage/expression vector (this should be a storage vector).
Definition vector.inl:398
const Vector< T, impl::VSub< T, S, impl::VScalar< T > > > operator-(const Vector< T, S > &iA, const T &iB)
subtract iB from all components of iA
Definition vector.inl:1022
const Vector< T, impl::VRec< T, S > > reciprocal() const
return a vector with each component being the reciprocal value of this vector.
Definition vector.inl:666
bool isEmpty() const
return true if vector contains no dataa at all
Definition vector.inl:503
const Vector< T, impl::VSub< T, impl::VScalar< T >, S > > operator-(const T &iA, const Vector< T, S > &iB)
add iA to all negated components of iB
Definition vector.inl:958
const Vector< T, impl::VSub< T, S1, S2 > > operator-(const Vector< T, S1 > &iA, const Vector< T, S2 > &iB)
componentwise subtraction
Definition vector.inl:887
const Vector< T, impl::VDiv< T, S, impl::VScalar< T > > > operator/(const Vector< T, S > &iA, const T &iB)
multiply all components of iA with iB.
Definition vector.inl:1054
const Vector< T, impl::VAdd< T, S, impl::VScalar< T > > > operator+(const Vector< T, S > &iA, const T &iB)
add iB to all components of iA
Definition vector.inl:1006
const Vector< T, impl::VSub< T, S2, impl::VMul< T, S, impl::VScalar< T > > > > reject(const Vector< T, S2 > &iB) const
Project vector on this one.
Definition vector.inl:704
const Vector< T, impl::VMul< T, impl::VScalar< T >, S > > operator*(const T &iA, const Vector< T, S > &iB)
multiply iA with all components of iB
Definition vector.inl:974
TSize size() const
return dimension of vector.
Definition vector.inl:191
const Vector< T, impl::VAdd< T, impl::VScalar< T >, S > > operator+(const T &iA, const Vector< T, S > &iB)
add iA to all components of iB
Definition vector.inl:942
const Vector< T, S > & operator+() const
A weird way to get back the same object.
Definition vector.inl:277
Vector< T, S > & operator+=(const Vector< T2, S2 > &iB)
add storage/expression vector to this (this should be a storage vector).
Definition vector.inl:317
const TValue at(TSize iIndex) const
return the iIndex'th component value and wrap index if necessary.
Definition vector.inl:242
Vector< T, S > & operator-=(const Vector< T2, S2 > &iB)
subtract storage/expression vector from this (this should be a storage vector).
Definition vector.inl:344
const TValue max() const
Return maximum of all components of vector.
Definition vector.inl:584
const T dot(const Vector< T, S1 > &iA, const Vector< T, S2 > &iB)
dot product.
Definition vector.inl:842
void normalize()
Normalize vector.
Definition vector.inl:719
const Vector< T, impl::VDiv< T, S1, S2 > > operator/(const Vector< T, S1 > &iA, const Vector< T, S2 > &iB)
componentwise division
Definition vector.inl:925
T sqr(const T &x)
return x * x
Definition basic_ops.h:162
T norm(const T &x)
return norm of x as if x is real part of complex number: sqr(x)
Definition basic_ops.h:211
numeric types and traits.
Definition basic_ops.h:70
Library for Assembled Shared Sources.
Definition config.h:53