All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StaticVector.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_DENSE_STATICVECTOR_H_
23 #define _BLAZE_MATH_DENSE_STATICVECTOR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <algorithm>
31 #include <cmath>
32 #include <stdexcept>
34 #include <blaze/math/Functions.h>
35 #include <blaze/math/Intrinsics.h>
37 #include <blaze/math/shims/IsNaN.h>
38 #include <blaze/math/shims/Reset.h>
46 #include <blaze/math/Types.h>
51 #include <blaze/util/Assert.h>
60 #include <blaze/util/DisableIf.h>
61 #include <blaze/util/EnableIf.h>
62 #include <blaze/util/mpl/If.h>
64 #include <blaze/util/Template.h>
65 #include <blaze/util/Types.h>
71 
72 
73 namespace blaze {
74 
75 //=================================================================================================
76 //
77 // CLASS DEFINITION
78 //
79 //=================================================================================================
80 
81 //*************************************************************************************************
147 template< typename Type // Data type of the vector
148  , size_t N // Number of elements
149  , bool TF = defaultTransposeFlag > // Transpose flag
150 class StaticVector : public DenseVector< StaticVector<Type,N,TF>, TF >
151  , private AlignedStorage<Type>
152 {
153  private:
154  //**Type definitions****************************************************************************
156  //**********************************************************************************************
157 
158  //**********************************************************************************************
160  enum { NN = N + ( IT::size - ( N % IT::size ) ) % IT::size };
161  //**********************************************************************************************
162 
163  public:
164  //**Type definitions****************************************************************************
166  typedef This ResultType;
168  typedef Type ElementType;
169  typedef typename IT::Type IntrinsicType;
170  typedef const Type& ReturnType;
171  typedef const StaticVector& CompositeType;
172  typedef Type& Reference;
173  typedef const Type& ConstReference;
174  typedef Type* Iterator;
175  typedef const Type* ConstIterator;
176 
178 
180  //**********************************************************************************************
181 
182  //**Compilation flags***************************************************************************
184 
188  enum { vectorizable = IsVectorizable<Type>::value };
189 
191 
194  enum { canAlias = 0 };
195  //**********************************************************************************************
196 
197  //**Constructors********************************************************************************
200  explicit inline StaticVector();
201  explicit inline StaticVector( const Type& init );
202  inline StaticVector( const StaticVector& v );
203  template< typename Other > inline StaticVector( const StaticVector<Other,N,TF>& v );
204  template< typename VT > inline StaticVector( const Vector<VT,TF>& v );
205  template< typename Other > explicit inline StaticVector( const Other (&rhs)[N] );
206 
207  inline StaticVector( const Type& v1, const Type& v2 );
208  inline StaticVector( const Type& v1, const Type& v2, const Type& v3 );
209  inline StaticVector( const Type& v1, const Type& v2, const Type& v3, const Type& v4 );
210  inline StaticVector( const Type& v1, const Type& v2, const Type& v3,
211  const Type& v4, const Type& v5 );
212  inline StaticVector( const Type& v1, const Type& v2, const Type& v3,
213  const Type& v4, const Type& v5, const Type& v6 );
215  //**********************************************************************************************
216 
217  //**Destructor**********************************************************************************
218  // No explicitly declared destructor.
219  //**********************************************************************************************
220 
221  //**Data access functions***********************************************************************
224  inline Reference operator[]( size_t index );
225  inline ConstReference operator[]( size_t index ) const;
226  inline Type* data ();
227  inline const Type* data () const;
228  inline Iterator begin ();
229  inline ConstIterator begin () const;
230  inline ConstIterator cbegin() const;
231  inline Iterator end ();
232  inline ConstIterator end () const;
233  inline ConstIterator cend () const;
235  //**********************************************************************************************
236 
237  //**Assignment operators************************************************************************
240  inline StaticVector& operator= ( Type rhs );
241  inline StaticVector& operator= ( const StaticVector& rhs );
242  template< typename Other > inline StaticVector& operator= ( const StaticVector<Other,N,TF>& rhs );
243  template< typename VT > inline StaticVector& operator= ( const Vector<VT,TF>& rhs );
244  template< typename Other > inline StaticVector& operator= ( const Other (&rhs)[N] );
245  template< typename VT > inline StaticVector& operator+=( const Vector<VT,TF>& rhs );
246  template< typename VT > inline StaticVector& operator-=( const Vector<VT,TF>& rhs );
247  template< typename VT > inline StaticVector& operator*=( const Vector<VT,TF>& rhs );
248 
249  template< typename Other >
250  inline typename EnableIf< IsNumeric<Other>, StaticVector >::Type&
251  operator*=( Other rhs );
252 
253  template< typename Other >
254  inline typename EnableIf< IsNumeric<Other>, StaticVector >::Type&
255  operator/=( Other rhs );
257  //**********************************************************************************************
258 
259  //**Utility functions***************************************************************************
262  inline size_t size() const;
263  inline size_t nonZeros() const;
264  inline void reset();
265  inline LengthType length() const;
266  inline Type sqrLength() const;
267  inline StaticVector& normalize();
268  inline const StaticVector getNormalized() const;
269  template< typename Other > inline StaticVector& scale( Other scalar );
270  inline Type min() const;
271  inline Type max() const;
272  inline void swap( StaticVector& v ) /* throw() */;
274  //**********************************************************************************************
275 
276  private:
277  //**********************************************************************************************
279 
280  template< typename VT >
281  struct VectorizedAssign {
282  enum { value = vectorizable && VT::vectorizable &&
283  IsSame<Type,typename VT::ElementType>::value };
284  };
286  //**********************************************************************************************
287 
288  //**********************************************************************************************
290 
291  template< typename VT >
292  struct VectorizedAddAssign {
293  enum { value = vectorizable && VT::vectorizable &&
294  IsSame<Type,typename VT::ElementType>::value &&
295  IntrinsicTrait<Type>::addition };
296  };
298  //**********************************************************************************************
299 
300  //**********************************************************************************************
302 
303  template< typename VT >
304  struct VectorizedSubAssign {
305  enum { value = vectorizable && VT::vectorizable &&
306  IsSame<Type,typename VT::ElementType>::value &&
307  IntrinsicTrait<Type>::subtraction };
308  };
310  //**********************************************************************************************
311 
312  //**********************************************************************************************
314 
315  template< typename VT >
316  struct VectorizedMultAssign {
317  enum { value = vectorizable && VT::vectorizable &&
318  IsSame<Type,typename VT::ElementType>::value &&
319  IntrinsicTrait<Type>::multiplication };
320  };
322  //**********************************************************************************************
323 
324  public:
325  //**Expression template evaluation functions****************************************************
328  template< typename Other > inline bool isAliased( const Other* alias ) const;
329  inline IntrinsicType get ( size_t index ) const;
330 
331  template< typename VT >
332  inline typename DisableIf< VectorizedAssign<VT> >::Type
333  assign( const DenseVector<VT,TF>& rhs );
334 
335  template< typename VT >
336  inline typename EnableIf< VectorizedAssign<VT> >::Type
337  assign( const DenseVector<VT,TF>& rhs );
338 
339  template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
340 
341  template< typename VT >
342  inline typename DisableIf< VectorizedAddAssign<VT> >::Type
343  addAssign( const DenseVector<VT,TF>& rhs );
344 
345  template< typename VT >
346  inline typename EnableIf< VectorizedAddAssign<VT> >::Type
347  addAssign( const DenseVector<VT,TF>& rhs );
348 
349  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
350 
351  template< typename VT >
352  inline typename DisableIf< VectorizedSubAssign<VT> >::Type
353  subAssign( const DenseVector<VT,TF>& rhs );
354 
355  template< typename VT >
356  inline typename EnableIf< VectorizedSubAssign<VT> >::Type
357  subAssign( const DenseVector<VT,TF>& rhs );
358 
359  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
360 
361  template< typename VT >
362  inline typename DisableIf< VectorizedMultAssign<VT> >::Type
363  multAssign( const DenseVector<VT,TF>& rhs );
364 
365  template< typename VT >
366  inline typename EnableIf< VectorizedMultAssign<VT> >::Type
367  multAssign( const DenseVector<VT,TF>& rhs );
368 
369  template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
371  //**********************************************************************************************
372 
373  private:
374  //**Member variables****************************************************************************
377  Type v_[NN];
378 
384  //**********************************************************************************************
385 
386  //**Compile time checks*************************************************************************
392  BLAZE_STATIC_ASSERT( NN % IT::size == 0UL );
393  BLAZE_STATIC_ASSERT( NN >= N );
395  //**********************************************************************************************
396 };
397 //*************************************************************************************************
398 
399 
400 
401 
402 //=================================================================================================
403 //
404 // CONSTRUCTORS
405 //
406 //=================================================================================================
407 
408 //*************************************************************************************************
413 template< typename Type // Data type of the vector
414  , size_t N // Number of elements
415  , bool TF > // Transpose flag
417 {
418  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
419 
420  if( IsBuiltin<Type>::value ) {
421  for( size_t i=0UL; i<NN; ++i )
422  v_[i] = Type();
423  }
424 }
425 //*************************************************************************************************
426 
427 
428 //*************************************************************************************************
433 template< typename Type // Data type of the vector
434  , size_t N // Number of elements
435  , bool TF > // Transpose flag
436 inline StaticVector<Type,N,TF>::StaticVector( const Type& init )
437 {
438  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
439 
440  for( size_t i=0UL; i<N; ++i )
441  v_[i] = init;
442 
443  if( IsBuiltin<Type>::value ) {
444  for( size_t i=N; i<NN; ++i )
445  v_[i] = Type();
446  }
447 }
448 //*************************************************************************************************
449 
450 
451 //*************************************************************************************************
458 template< typename Type // Data type of the vector
459  , size_t N // Number of elements
460  , bool TF > // Transpose flag
462 {
463  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
464 
465  for( size_t i=0UL; i<NN; ++i )
466  v_[i] = v.v_[i];
467 }
468 //*************************************************************************************************
469 
470 
471 //*************************************************************************************************
476 template< typename Type // Data type of the vector
477  , size_t N // Number of elements
478  , bool TF > // Transpose flag
479 template< typename Other > // Data type of the foreign vector
481 {
482  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
483 
484  for( size_t i=0UL; i<N; ++i )
485  v_[i] = v[i];
486 
487  if( IsBuiltin<Type>::value ) {
488  for( size_t i=N; i<NN; ++i )
489  v_[i] = Type();
490  }
491 }
492 //*************************************************************************************************
493 
494 
495 //*************************************************************************************************
505 template< typename Type // Data type of the vector
506  , size_t N // Number of elements
507  , bool TF > // Transpose flag
508 template< typename VT > // Type of the foreign vector
510 {
511  using blaze::assign;
512 
513  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
514 
515  if( (~v).size() != N )
516  throw std::invalid_argument( "Invalid setup of static vector" );
517 
518  if( IsBuiltin<Type>::value ) {
519  for( size_t i=( IsSparseVector<VT>::value )?( 0UL ):( N ); i<NN; ++i )
520  v_[i] = Type();
521  }
522 
523  assign( *this, ~v );
524 }
525 //*************************************************************************************************
526 
527 
528 //*************************************************************************************************
542 template< typename Type // Data type of the vector
543  , size_t N // Number of elements
544  , bool TF > // Transpose flag
545 template< typename Other > // Data type of the initialization array
546 inline StaticVector<Type,N,TF>::StaticVector( const Other (&rhs)[N] )
547 {
548  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
549 
550  for( size_t i=0UL; i<N; ++i )
551  v_[i] = rhs[i];
552 
553  if( IsBuiltin<Type>::value ) {
554  for( size_t i=N; i<NN; ++i )
555  v_[i] = Type();
556  }
557 }
558 //*************************************************************************************************
559 
560 
561 //*************************************************************************************************
573 template< typename Type // Data type of the vector
574  , size_t N // Number of elements
575  , bool TF > // Transpose flag
576 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2 )
577 {
578  BLAZE_STATIC_ASSERT( N == 2UL );
579  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
580 
581  v_[0] = v1;
582  v_[1] = v2;
583 
584  if( IsBuiltin<Type>::value ) {
585  for( size_t i=N; i<NN; ++i )
586  v_[i] = Type();
587  }
588 }
589 //*************************************************************************************************
590 
591 
592 //*************************************************************************************************
605 template< typename Type // Data type of the vector
606  , size_t N // Number of elements
607  , bool TF > // Transpose flag
608 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3 )
609 {
610  BLAZE_STATIC_ASSERT( N == 3UL );
611  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
612 
613  v_[0] = v1;
614  v_[1] = v2;
615  v_[2] = v3;
616 
617  if( IsBuiltin<Type>::value ) {
618  for( size_t i=N; i<NN; ++i )
619  v_[i] = Type();
620  }
621 }
622 //*************************************************************************************************
623 
624 
625 //*************************************************************************************************
639 template< typename Type // Data type of the vector
640  , size_t N // Number of elements
641  , bool TF > // Transpose flag
642 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2,
643  const Type& v3, const Type& v4 )
644 {
645  BLAZE_STATIC_ASSERT( N == 4UL );
646  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
647 
648  v_[0] = v1;
649  v_[1] = v2;
650  v_[2] = v3;
651  v_[3] = v4;
652 
653  if( IsBuiltin<Type>::value ) {
654  for( size_t i=N; i<NN; ++i )
655  v_[i] = Type();
656  }
657 }
658 //*************************************************************************************************
659 
660 
661 //*************************************************************************************************
676 template< typename Type // Data type of the vector
677  , size_t N // Number of elements
678  , bool TF > // Transpose flag
679 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3,
680  const Type& v4, const Type& v5 )
681 {
682  BLAZE_STATIC_ASSERT( N == 5UL );
683  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
684 
685  v_[0] = v1;
686  v_[1] = v2;
687  v_[2] = v3;
688  v_[3] = v4;
689  v_[4] = v5;
690 
691  if( IsBuiltin<Type>::value ) {
692  for( size_t i=N; i<NN; ++i )
693  v_[i] = Type();
694  }
695 }
696 //*************************************************************************************************
697 
698 
699 //*************************************************************************************************
715 template< typename Type // Data type of the vector
716  , size_t N // Number of elements
717  , bool TF > // Transpose flag
718 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3,
719  const Type& v4, const Type& v5, const Type& v6 )
720 {
721  BLAZE_STATIC_ASSERT( N == 6UL );
722  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
723 
724  v_[0] = v1;
725  v_[1] = v2;
726  v_[2] = v3;
727  v_[3] = v4;
728  v_[4] = v5;
729  v_[5] = v6;
730 
731  if( IsBuiltin<Type>::value ) {
732  for( size_t i=N; i<NN; ++i )
733  v_[i] = Type();
734  }
735 }
736 //*************************************************************************************************
737 
738 
739 
740 
741 //=================================================================================================
742 //
743 // DATA ACCESS FUNCTIONS
744 //
745 //=================================================================================================
746 
747 //*************************************************************************************************
755 template< typename Type // Data type of the vector
756  , size_t N // Number of elements
757  , bool TF > // Transpose flag
760 {
761  BLAZE_USER_ASSERT( index < N, "Invalid vector access index" );
762  return v_[index];
763 }
764 //*************************************************************************************************
765 
766 
767 //*************************************************************************************************
775 template< typename Type // Data type of the vector
776  , size_t N // Number of elements
777  , bool TF > // Transpose flag
780 {
781  BLAZE_USER_ASSERT( index < N, "Invalid vector access index" );
782  return v_[index];
783 }
784 //*************************************************************************************************
785 
786 
787 //*************************************************************************************************
792 template< typename Type // Data type of the vector
793  , size_t N // Number of elements
794  , bool TF > // Transpose flag
796 {
797  return v_;
798 }
799 //*************************************************************************************************
800 
801 
802 //*************************************************************************************************
807 template< typename Type // Data type of the vector
808  , size_t N // Number of elements
809  , bool TF > // Transpose flag
810 inline const Type* StaticVector<Type,N,TF>::data() const
811 {
812  return v_;
813 }
814 //*************************************************************************************************
815 
816 
817 //*************************************************************************************************
822 template< typename Type // Data type of the vector
823  , size_t N // Number of elements
824  , bool TF > // Transpose flag
826 {
827  return v_;
828 }
829 //*************************************************************************************************
830 
831 
832 //*************************************************************************************************
837 template< typename Type // Data type of the vector
838  , size_t N // Number of elements
839  , bool TF > // Transpose flag
841 {
842  return v_;
843 }
844 //*************************************************************************************************
845 
846 
847 //*************************************************************************************************
852 template< typename Type // Data type of the vector
853  , size_t N // Number of elements
854  , bool TF > // Transpose flag
856 {
857  return v_;
858 }
859 //*************************************************************************************************
860 
861 
862 //*************************************************************************************************
867 template< typename Type // Data type of the vector
868  , size_t N // Number of elements
869  , bool TF > // Transpose flag
871 {
872  return v_ + N;
873 }
874 //*************************************************************************************************
875 
876 
877 //*************************************************************************************************
882 template< typename Type // Data type of the vector
883  , size_t N // Number of elements
884  , bool TF > // Transpose flag
886 {
887  return v_ + N;
888 }
889 //*************************************************************************************************
890 
891 
892 //*************************************************************************************************
897 template< typename Type // Data type of the vector
898  , size_t N // Number of elements
899  , bool TF > // Transpose flag
901 {
902  return v_ + N;
903 }
904 //*************************************************************************************************
905 
906 
907 
908 
909 //=================================================================================================
910 //
911 // ASSIGNMENT OPERATORS
912 //
913 //=================================================================================================
914 
915 //*************************************************************************************************
921 template< typename Type // Data type of the vector
922  , size_t N // Number of elements
923  , bool TF > // Transpose flag
925 {
926  for( size_t i=0UL; i<N; ++i )
927  v_[i] = rhs;
928  return *this;
929 }
930 //*************************************************************************************************
931 
932 
933 //*************************************************************************************************
941 template< typename Type // Data type of the vector
942  , size_t N // Number of elements
943  , bool TF > // Transpose flag
945 {
946  // This implementation was chosen for several reasons:
947  // - it works for all possible element types (even types that could not be copied by 'memcpy')
948  // - it is faster than the synthesized default copy assignment operator
949  // - it is faster than an implementation with the C library function 'memcpy' in combination
950  // with a protection against self-assignment
951  // - it goes without a protection against self-assignment
952  for( size_t i=0UL; i<N; ++i )
953  v_[i] = rhs.v_[i];
954  return *this;
955 }
956 //*************************************************************************************************
957 
958 
959 //*************************************************************************************************
965 template< typename Type // Data type of the vector
966  , size_t N // Number of elements
967  , bool TF > // Transpose flag
968 template< typename Other > // Data type of the foreign vector
970 {
971  // This implementation was chosen for several reasons:
972  // - it works for all possible element types (even types that could not be copied by 'memcpy')
973  // - it is faster than the synthesized default copy assignment operator
974  // - it is faster than an implementation with the C library function 'memcpy' in combination
975  // with a protection against self-assignment
976  // - it goes without a protection against self-assignment
977  for( size_t i=0UL; i<N; ++i )
978  v_[i] = rhs[i];
979  return *this;
980 }
981 //*************************************************************************************************
982 
983 
984 //*************************************************************************************************
994 template< typename Type // Data type of the vector
995  , size_t N // Number of elements
996  , bool TF > // Transpose flag
997 template< typename VT > // Type of the right-hand side vector
999 {
1000  using blaze::assign;
1001 
1002  if( (~rhs).size() != N )
1003  throw std::invalid_argument( "Invalid assignment to static vector" );
1004 
1005  if( CanAlias<VT>::value && (~rhs).isAliased( this ) ) {
1006  StaticVector tmp( ~rhs );
1007  swap( tmp );
1008  }
1009  else {
1011  reset();
1012  assign( *this, ~rhs );
1013  }
1014 
1015  return *this;
1016 }
1017 //*************************************************************************************************
1018 
1019 
1020 //*************************************************************************************************
1036 template< typename Type // Data type of the vector
1037  , size_t N // Number of elements
1038  , bool TF > // Transpose flag
1039 template< typename Other > // Data type of the initialization array
1041 {
1042  for( size_t i=0UL; i<N; ++i )
1043  v_[i] = rhs[i];
1044  return *this;
1045 }
1046 //*************************************************************************************************
1047 
1048 
1049 //*************************************************************************************************
1059 template< typename Type // Data type of the vector
1060  , size_t N // Number of elements
1061  , bool TF > // Transpose flag
1062 template< typename VT > // Type of the right-hand side vector
1064 {
1065  using blaze::addAssign;
1066 
1067  if( (~rhs).size() != N )
1068  throw std::invalid_argument( "Vector sizes do not match" );
1069 
1070  if( CanAlias<VT>::value && (~rhs).isAliased( this ) ) {
1071  StaticVector tmp( ~rhs );
1072  addAssign( *this, tmp );
1073  }
1074  else {
1075  addAssign( *this, ~rhs );
1076  }
1077 
1078  return *this;
1079 }
1080 //*************************************************************************************************
1081 
1082 
1083 //*************************************************************************************************
1093 template< typename Type // Data type of the vector
1094  , size_t N // Number of elements
1095  , bool TF > // Transpose flag
1096 template< typename VT > // Type of the right-hand side vector
1098 {
1099  using blaze::subAssign;
1100 
1101  if( (~rhs).size() != N )
1102  throw std::invalid_argument( "Vector sizes do not match" );
1103 
1104  if( CanAlias<VT>::value && (~rhs).isAliased( this ) ) {
1105  StaticVector tmp( ~rhs );
1106  subAssign( *this, tmp );
1107  }
1108  else {
1109  subAssign( *this, ~rhs );
1110  }
1111 
1112  return *this;
1113 }
1114 //*************************************************************************************************
1115 
1116 
1117 //*************************************************************************************************
1128 template< typename Type // Data type of the vector
1129  , size_t N // Number of elements
1130  , bool TF > // Transpose flag
1131 template< typename VT > // Type of the right-hand side vector
1133 {
1134  using blaze::assign;
1135 
1136  if( (~rhs).size() != N )
1137  throw std::invalid_argument( "Vector sizes do not match" );
1138 
1139  if( CanAlias<VT>::value && (~rhs).isAliased( this ) ) {
1140  StaticVector tmp( *this * (~rhs) );
1141  this->operator=( tmp );
1142  }
1143  else {
1144  assign( *this, *this * (~rhs) );
1145  }
1146 
1147  return *this;
1148 }
1149 //*************************************************************************************************
1150 
1151 
1152 //*************************************************************************************************
1159 template< typename Type // Data type of the vector
1160  , size_t N // Number of elements
1161  , bool TF > // Transpose flag
1162 template< typename Other > // Data type of the right-hand side scalar
1163 inline typename EnableIf< IsNumeric<Other>, StaticVector<Type,N,TF> >::Type&
1165 {
1166  return operator=( (*this) * rhs );
1167 }
1168 //*************************************************************************************************
1169 
1170 
1171 //*************************************************************************************************
1180 template< typename Type // Data type of the vector
1181  , size_t N // Number of elements
1182  , bool TF > // Transpose flag
1183 template< typename Other > // Data type of the right-hand side scalar
1184 inline typename EnableIf< IsNumeric<Other>, StaticVector<Type,N,TF> >::Type&
1186 {
1187  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1188 
1189  return operator=( (*this) / rhs );
1190 }
1191 //*************************************************************************************************
1192 
1193 
1194 
1195 
1196 //=================================================================================================
1197 //
1198 // UTILITY FUNCTIONS
1199 //
1200 //=================================================================================================
1201 
1202 //*************************************************************************************************
1207 template< typename Type // Data type of the vector
1208  , size_t N // Number of elements
1209  , bool TF > // Transpose flag
1210 inline size_t StaticVector<Type,N,TF>::size() const
1211 {
1212  return N;
1213 }
1214 //*************************************************************************************************
1215 
1216 
1217 //*************************************************************************************************
1225 template< typename Type // Data type of the vector
1226  , size_t N // Number of elements
1227  , bool TF > // Transpose flag
1229 {
1230  size_t nonzeros( 0 );
1231 
1232  for( size_t i=0UL; i<N; ++i ) {
1233  if( !isDefault( v_[i] ) )
1234  ++nonzeros;
1235  }
1236 
1237  return nonzeros;
1238 }
1239 //*************************************************************************************************
1240 
1241 
1242 //*************************************************************************************************
1247 template< typename Type // Data type of the vector
1248  , size_t N // Number of elements
1249  , bool TF > // Transpose flag
1251 {
1252  using blaze::reset;
1253  for( size_t i=0UL; i<N; ++i )
1254  reset( v_[i] );
1255 }
1256 //*************************************************************************************************
1257 
1258 
1259 //*************************************************************************************************
1289 template< typename Type // Data type of the vector
1290  , size_t N // Number of elements
1291  , bool TF > // Transpose flag
1292 #ifndef WIN32
1294 #else
1296 #endif
1297 {
1299 
1300  LengthType sum( 0 );
1301  for( size_t i=0UL; i<N; ++i )
1302  sum += v_[i] * v_[i];
1303  return std::sqrt( sum );
1304 }
1305 //*************************************************************************************************
1306 
1307 
1308 //*************************************************************************************************
1318 template< typename Type // Data type of the vector
1319  , size_t N // Number of elements
1320  , bool TF > // Transpose flag
1322 {
1324 
1325  Type sum( 0 );
1326  for( size_t i=0UL; i<N; ++i )
1327  sum += v_[i] * v_[i];
1328  return sum;
1329 }
1330 //*************************************************************************************************
1331 
1332 
1333 //*************************************************************************************************
1342 template< typename Type // Data type of the vector
1343  , size_t N // Number of elements
1344  , bool TF > // Transpose flag
1346 {
1348 
1349  const Type len( length() );
1350 
1351  if( len == Type(0) )
1352  return *this;
1353 
1354  const Type ilen( Type(1) / len );
1355 
1356  for( size_t i=0UL; i<N; ++i )
1357  v_[i] *= ilen;
1358 
1359  return *this;
1360 }
1361 //*************************************************************************************************
1362 
1363 
1364 //*************************************************************************************************
1373 template< typename Type // Data type of the vector
1374  , size_t N // Number of elements
1375  , bool TF > // Transpose flag
1377 {
1379 
1380  const Type len( length() );
1381 
1382  if( len == Type(0) )
1383  return *this;
1384 
1385  const Type ilen( Type(1) / len );
1386  StaticVector tmp;
1387 
1388  for( size_t i=0UL; i<N; ++i )
1389  tmp[i] = v_[i] * ilen;
1390 
1391  return tmp;
1392 }
1393 //*************************************************************************************************
1394 
1395 
1396 //*************************************************************************************************
1402 template< typename Type // Data type of the vector
1403  , size_t N // Number of elements
1404  , bool TF > // Transpose flag
1405 template< typename Other > // Data type of the scalar value
1407 {
1408  for( size_t i=0; i<N; ++i )
1409  v_[i] *= scalar;
1410  return *this;
1411 }
1412 //*************************************************************************************************
1413 
1414 
1415 //*************************************************************************************************
1420 template< typename Type // Data type of the vector
1421  , size_t N // Number of elements
1422  , bool TF > // Transpose flag
1423 inline Type StaticVector<Type,N,TF>::min() const
1424 {
1425  using blaze::min;
1426 
1427  Type minimum( v_[0] );
1428  for( size_t i=1UL; i<N; ++i )
1429  minimum = min( minimum, v_[i] );
1430  return minimum;
1431 }
1432 //*************************************************************************************************
1433 
1434 
1435 //*************************************************************************************************
1440 template< typename Type // Data type of the vector
1441  , size_t N // Number of elements
1442  , bool TF > // Transpose flag
1443 inline Type StaticVector<Type,N,TF>::max() const
1444 {
1445  using blaze::max;
1446 
1447  Type maximum( v_[0] );
1448  for( size_t i=1UL; i<N; ++i )
1449  maximum = max( maximum, v_[i] );
1450  return maximum;
1451 }
1452 //*************************************************************************************************
1453 
1454 
1455 //*************************************************************************************************
1462 template< typename Type // Data type of the vector
1463  , size_t N // Number of elements
1464  , bool TF > // Transpose flag
1465 inline void StaticVector<Type,N,TF>::swap( StaticVector& v ) /* throw() */
1466 {
1467  using std::swap;
1468 
1469  for( size_t i=0UL; i<N; ++i )
1470  swap( v_[i], v.v_[i] );
1471 }
1472 //*************************************************************************************************
1473 
1474 
1475 
1476 
1477 //=================================================================================================
1478 //
1479 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1480 //
1481 //=================================================================================================
1482 
1483 //*************************************************************************************************
1489 template< typename Type // Data type of the vector
1490  , size_t N // Number of elements
1491  , bool TF > // Transpose flag
1492 template< typename Other > // Data type of the foreign expression
1493 inline bool StaticVector<Type,N,TF>::isAliased( const Other* alias ) const
1494 {
1495  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1496 }
1497 //*************************************************************************************************
1498 
1499 
1500 //*************************************************************************************************
1511 template< typename Type // Data type of the vector
1512  , size_t N // Number of elements
1513  , bool TF > // Transpose flag
1515  StaticVector<Type,N,TF>::get( size_t index ) const
1516 {
1518 
1519  BLAZE_INTERNAL_ASSERT( index < N , "Invalid vector access index" );
1520  BLAZE_INTERNAL_ASSERT( index + IT::size <= NN , "Invalid vector access index" );
1521  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid vector access index" );
1522 
1523  return load( &v_[index] );
1524 }
1525 //*************************************************************************************************
1526 
1527 
1528 //*************************************************************************************************
1539 template< typename Type // Data type of the vector
1540  , size_t N // Number of elements
1541  , bool TF > // Transpose flag
1542 template< typename VT > // Type of the right-hand side dense vector
1543 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAssign<VT> >::Type
1545 {
1546  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1547 
1548  for( size_t i=0UL; i<N; ++i )
1549  v_[i] = (~rhs)[i];
1550 }
1551 //*************************************************************************************************
1552 
1553 
1554 //*************************************************************************************************
1565 template< typename Type // Data type of the vector
1566  , size_t N // Number of elements
1567  , bool TF > // Transpose flag
1568 template< typename VT > // Type of the right-hand side dense vector
1569 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAssign<VT> >::Type
1571 {
1572  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1573 
1575 
1576  for( size_t i=0UL; i<N; i+=IT::size ) {
1577  store( v_+i, (~rhs).get(i) );
1578  }
1579 }
1580 //*************************************************************************************************
1581 
1582 
1583 //*************************************************************************************************
1594 template< typename Type // Data type of the vector
1595  , size_t N // Number of elements
1596  , bool TF > // Transpose flag
1597 template< typename VT > // Type of the right-hand side sparse vector
1599 {
1600  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1601 
1602  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1603  v_[element->index()] = element->value();
1604 }
1605 //*************************************************************************************************
1606 
1607 
1608 //*************************************************************************************************
1619 template< typename Type // Data type of the vector
1620  , size_t N // Number of elements
1621  , bool TF > // Transpose flag
1622 template< typename VT > // Type of the right-hand side dense vector
1623 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >::Type
1625 {
1626  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1627 
1628  for( size_t i=0UL; i<N; ++i )
1629  v_[i] += (~rhs)[i];
1630 }
1631 //*************************************************************************************************
1632 
1633 
1634 //*************************************************************************************************
1645 template< typename Type // Data type of the vector
1646  , size_t N // Number of elements
1647  , bool TF > // Transpose flag
1648 template< typename VT > // Type of the right-hand side dense vector
1649 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >::Type
1651 {
1652  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1653 
1655 
1656  for( size_t i=0UL; i<N; i+=IT::size ) {
1657  store( v_+i, load( v_+i ) + (~rhs).get(i) );
1658  }
1659 }
1660 //*************************************************************************************************
1661 
1662 
1663 //*************************************************************************************************
1674 template< typename Type // Data type of the vector
1675  , size_t N // Number of elements
1676  , bool TF > // Transpose flag
1677 template< typename VT > // Type of the right-hand side sparse vector
1679 {
1680  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1681 
1682  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1683  v_[element->index()] += element->value();
1684 }
1685 //*************************************************************************************************
1686 
1687 
1688 //*************************************************************************************************
1699 template< typename Type // Data type of the vector
1700  , size_t N // Number of elements
1701  , bool TF > // Transpose flag
1702 template< typename VT > // Type of the right-hand side dense vector
1703 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >::Type
1705 {
1706  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1707 
1708  for( size_t i=0UL; i<N; ++i )
1709  v_[i] -= (~rhs)[i];
1710 }
1711 //*************************************************************************************************
1712 
1713 
1714 //*************************************************************************************************
1725 template< typename Type // Data type of the vector
1726  , size_t N // Number of elements
1727  , bool TF > // Transpose flag
1728 template< typename VT > // Type of the right-hand side dense vector
1729 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >::Type
1731 {
1732  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1733 
1735 
1736  for( size_t i=0UL; i<N; i+=IT::size ) {
1737  store( v_+i, load( v_+i ) - (~rhs).get(i) );
1738  }
1739 }
1740 //*************************************************************************************************
1741 
1742 
1743 //*************************************************************************************************
1754 template< typename Type // Data type of the vector
1755  , size_t N // Number of elements
1756  , bool TF > // Transpose flag
1757 template< typename VT > // Type of the right-hand side sparse vector
1759 {
1760  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1761 
1762  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1763  v_[element->index()] -= element->value();
1764 }
1765 //*************************************************************************************************
1766 
1767 
1768 //*************************************************************************************************
1779 template< typename Type // Data type of the vector
1780  , size_t N // Number of elements
1781  , bool TF > // Transpose flag
1782 template< typename VT > // Type of the right-hand side dense vector
1783 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >::Type
1785 {
1786  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1787 
1788  for( size_t i=0UL; i<N; ++i )
1789  v_[i] *= (~rhs)[i];
1790 }
1791 //*************************************************************************************************
1792 
1793 
1794 //*************************************************************************************************
1805 template< typename Type // Data type of the vector
1806  , size_t N // Number of elements
1807  , bool TF > // Transpose flag
1808 template< typename VT > // Type of the right-hand side dense vector
1809 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >::Type
1811 {
1812  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1813 
1815 
1816  for( size_t i=0UL; i<N; i+=IT::size ) {
1817  store( v_+i, load( v_+i ) * (~rhs).get(i) );
1818  }
1819 }
1820 //*************************************************************************************************
1821 
1822 
1823 //*************************************************************************************************
1834 template< typename Type // Data type of the vector
1835  , size_t N // Number of elements
1836  , bool TF > // Transpose flag
1837 template< typename VT > // Type of the right-hand side sparse vector
1839 {
1840  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1841 
1842  const StaticVector tmp( *this );
1843 
1844  reset();
1845 
1846  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1847  v_[element->index()] = tmp[element->index()] * element->value();
1848 }
1849 //*************************************************************************************************
1850 
1851 
1852 
1853 
1854 
1855 
1856 
1857 
1858 //=================================================================================================
1859 //
1860 // UNDEFINED CLASS TEMPLATE SPECIALIZATION
1861 //
1862 //=================================================================================================
1863 
1864 //*************************************************************************************************
1872 template< typename Type // Data type of the vector
1873  , bool TF > // Transpose flag
1874 class StaticVector<Type,0UL,TF>;
1876 //*************************************************************************************************
1877 
1878 
1879 
1880 
1881 
1882 
1883 
1884 
1885 //=================================================================================================
1886 //
1887 // GLOBAL OPERATORS
1888 //
1889 //=================================================================================================
1890 
1891 //*************************************************************************************************
1894 template< typename Type, size_t N, bool TF >
1895 inline bool isnan( const StaticVector<Type,N,TF>& v );
1896 
1897 template< typename Type, size_t N, bool TF >
1898 inline void reset( StaticVector<Type,N,TF>& v );
1899 
1900 template< typename Type, size_t N, bool TF >
1901 inline void clear( StaticVector<Type,N,TF>& v );
1902 
1903 template< typename Type, size_t N, bool TF >
1904 inline bool isDefault( const StaticVector<Type,N,TF>& v );
1905 
1906 template< typename Type, bool TF >
1908 
1909 template< typename Type, bool TF >
1911 
1912 template< typename Type, size_t N, bool TF >
1913 inline void swap( StaticVector<Type,N,TF>& a, StaticVector<Type,N,TF>& b ) /* throw() */;
1915 //*************************************************************************************************
1916 
1917 
1918 //*************************************************************************************************
1935 template< typename Type // Data type of the vector
1936  , size_t N // Number of elements
1937  , bool TF > // Transpose flag
1938 inline bool isnan( const StaticVector<Type,N,TF>& v )
1939 {
1940  for( size_t i=0UL; i<N; ++i ) {
1941  if( isnan( v[i] ) ) return true;
1942  }
1943  return false;
1944 }
1945 //*************************************************************************************************
1946 
1947 
1948 //*************************************************************************************************
1955 template< typename Type // Data type of the vector
1956  , size_t N // Number of elements
1957  , bool TF > // Transpose flag
1959 {
1960  v.reset();
1961 }
1962 //*************************************************************************************************
1963 
1964 
1965 //*************************************************************************************************
1974 template< typename Type // Data type of the vector
1975  , size_t N // Number of elements
1976  , bool TF > // Transpose flag
1978 {
1979  v.reset();
1980 }
1981 //*************************************************************************************************
1982 
1983 
1984 //*************************************************************************************************
2002 template< typename Type // Data type of the vector
2003  , size_t N // Number of elements
2004  , bool TF > // Transpose flag
2005 inline bool isDefault( const StaticVector<Type,N,TF>& v )
2006 {
2007  for( size_t i=0UL; i<N; ++i )
2008  if( !isDefault( v[i] ) ) return false;
2009  return true;
2010 }
2011 //*************************************************************************************************
2012 
2013 
2014 //*************************************************************************************************
2025 template< typename Type // Data type of the vector
2026  , bool TF > // Transpose flag
2028 {
2029  return StaticVector<Type,2UL,TF>( -v[1UL], v[0UL] );
2030 }
2031 //*************************************************************************************************
2032 
2033 
2034 //*************************************************************************************************
2042 template< typename Type // Data type of the vector
2043  , bool TF > // Transpose flag
2045 {
2046  if( v[0] != Type() || v[1] != Type() )
2047  return StaticVector<Type,3UL,TF>( v[1UL], -v[0UL], Type() );
2048  else
2049  return StaticVector<Type,3UL,TF>( Type(), v[2UL], -v[1UL] );
2050 }
2051 //*************************************************************************************************
2052 
2053 
2054 //*************************************************************************************************
2063 template< typename Type // Data type of the vector
2064  , size_t N // Number of elements
2065  , bool TF > // Transpose flag
2066 inline void swap( StaticVector<Type,N,TF>& a, StaticVector<Type,N,TF>& b ) /* throw() */
2067 {
2068  a.swap( b );
2069 }
2070 //*************************************************************************************************
2071 
2072 
2073 
2074 
2075 //=================================================================================================
2076 //
2077 // ADDTRAIT SPECIALIZATIONS
2078 //
2079 //=================================================================================================
2080 
2081 //*************************************************************************************************
2083 template< typename T1, size_t N, bool TF, typename T2 >
2084 struct AddTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2085 {
2086  typedef StaticVector< typename AddTrait<T1,T2>::Type, N, TF > Type;
2087 };
2089 //*************************************************************************************************
2090 
2091 
2092 
2093 
2094 //=================================================================================================
2095 //
2096 // SUBTRAIT SPECIALIZATIONS
2097 //
2098 //=================================================================================================
2099 
2100 //*************************************************************************************************
2102 template< typename T1, size_t N, bool TF, typename T2 >
2103 struct SubTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2104 {
2105  typedef StaticVector< typename SubTrait<T1,T2>::Type, N, TF > Type;
2106 };
2108 //*************************************************************************************************
2109 
2110 
2111 
2112 
2113 //=================================================================================================
2114 //
2115 // MULTTRAIT SPECIALIZATIONS
2116 //
2117 //=================================================================================================
2118 
2119 //*************************************************************************************************
2121 template< typename T1, size_t N, bool TF, typename T2 >
2122 struct MultTrait< StaticVector<T1,N,TF>, T2 >
2123 {
2124  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
2126 };
2127 
2128 template< typename T1, typename T2, size_t N, bool TF >
2129 struct MultTrait< T1, StaticVector<T2,N,TF> >
2130 {
2131  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
2133 };
2134 
2135 template< typename T1, size_t N, bool TF, typename T2 >
2136 struct MultTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2137 {
2138  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
2139 };
2140 
2141 template< typename T1, size_t M, typename T2, size_t N >
2142 struct MultTrait< StaticVector<T1,M,false>, StaticVector<T2,N,true> >
2143 {
2144  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, false > Type;
2145 };
2146 
2147 template< typename T1, size_t N, typename T2 >
2148 struct MultTrait< StaticVector<T1,N,true>, StaticVector<T2,N,false> >
2149 {
2150  typedef typename MultTrait<T1,T2>::Type Type;
2151 };
2153 //*************************************************************************************************
2154 
2155 
2156 
2157 
2158 //=================================================================================================
2159 //
2160 // CROSSTRAIT SPECIALIZATIONS
2161 //
2162 //=================================================================================================
2163 
2164 //*************************************************************************************************
2166 template< typename T1, typename T2 >
2167 struct CrossTrait< StaticVector<T1,3UL,false>, StaticVector<T2,3UL,false> >
2168 {
2169  private:
2170  typedef typename MultTrait<T1,T2>::Type T;
2171 
2172  public:
2173  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
2174 };
2176 //*************************************************************************************************
2177 
2178 
2179 
2180 
2181 //=================================================================================================
2182 //
2183 // DIVTRAIT SPECIALIZATIONS
2184 //
2185 //=================================================================================================
2186 
2187 //*************************************************************************************************
2189 template< typename T1, size_t N, bool TF, typename T2 >
2190 struct DivTrait< StaticVector<T1,N,TF>, T2 >
2191 {
2192  typedef StaticVector< typename DivTrait<T1,T2>::Type, N, TF > Type;
2194 };
2196 //*************************************************************************************************
2197 
2198 
2199 
2200 
2201 //=================================================================================================
2202 //
2203 // MATHTRAIT SPECIALIZATIONS
2204 //
2205 //=================================================================================================
2206 
2207 //*************************************************************************************************
2209 template< typename T1, size_t N, bool TF, typename T2 >
2210 struct MathTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2211 {
2212  typedef StaticVector< typename MathTrait<T1,T2>::HighType, N, TF > HighType;
2213  typedef StaticVector< typename MathTrait<T1,T2>::LowType , N, TF > LowType;
2214 };
2216 //*************************************************************************************************
2217 
2218 } // namespace blaze
2219 
2220 #endif