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 <stdexcept>
33 #include <blaze/math/Forward.h>
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>
48 #include <blaze/util/Assert.h>
55 #include <blaze/util/DisableIf.h>
56 #include <blaze/util/EnableIf.h>
57 #include <blaze/util/mpl/If.h>
59 #include <blaze/util/Template.h>
60 #include <blaze/util/Types.h>
65 
66 
67 namespace blaze {
68 
69 //=================================================================================================
70 //
71 // CLASS DEFINITION
72 //
73 //=================================================================================================
74 
75 //*************************************************************************************************
141 template< typename Type // Data type of the vector
142  , size_t N // Number of elements
143  , bool TF = defaultTransposeFlag > // Transpose flag
144 class StaticVector : public DenseVector< StaticVector<Type,N,TF>, TF >
145  , private AlignedStorage<Type>
146 {
147  private:
148  //**Type definitions****************************************************************************
150  //**********************************************************************************************
151 
152  //**********************************************************************************************
154  enum { NN = N + ( IT::size - ( N % IT::size ) ) % IT::size };
155  //**********************************************************************************************
156 
157  public:
158  //**Type definitions****************************************************************************
160  typedef This ResultType;
162  typedef Type ElementType;
163  typedef typename IT::Type IntrinsicType;
164  typedef const Type& ReturnType;
165  typedef const StaticVector& CompositeType;
166  typedef Type& Reference;
167  typedef const Type& ConstReference;
168  typedef Type* Iterator;
169  typedef const Type* ConstIterator;
170  //**********************************************************************************************
171 
172  //**Compilation flags***************************************************************************
174 
178  enum { vectorizable = IsVectorizable<Type>::value };
179  //**********************************************************************************************
180 
181  //**Constructors********************************************************************************
184  explicit inline StaticVector();
185  explicit inline StaticVector( const Type& init );
186  inline StaticVector( const StaticVector& v );
187  template< typename Other > inline StaticVector( const StaticVector<Other,N,TF>& v );
188  template< typename VT > inline StaticVector( const Vector<VT,TF>& v );
189  template< typename Other > explicit inline StaticVector( const Other (&rhs)[N] );
190 
191  inline StaticVector( const Type& v1, const Type& v2 );
192  inline StaticVector( const Type& v1, const Type& v2, const Type& v3 );
193  inline StaticVector( const Type& v1, const Type& v2, const Type& v3, const Type& v4 );
194  inline StaticVector( const Type& v1, const Type& v2, const Type& v3,
195  const Type& v4, const Type& v5 );
196  inline StaticVector( const Type& v1, const Type& v2, const Type& v3,
197  const Type& v4, const Type& v5, const Type& v6 );
199  //**********************************************************************************************
200 
201  //**Destructor**********************************************************************************
202  // No explicitly declared destructor.
203  //**********************************************************************************************
204 
205  //**Data access functions***********************************************************************
208  inline Reference operator[]( size_t index );
209  inline ConstReference operator[]( size_t index ) const;
210  inline Type* data ();
211  inline const Type* data () const;
212  inline Iterator begin ();
213  inline ConstIterator begin () const;
214  inline ConstIterator cbegin() const;
215  inline Iterator end ();
216  inline ConstIterator end () const;
217  inline ConstIterator cend () const;
219  //**********************************************************************************************
220 
221  //**Assignment operators************************************************************************
224  inline StaticVector& operator= ( Type rhs );
225  inline StaticVector& operator= ( const StaticVector& rhs );
226  template< typename Other > inline StaticVector& operator= ( const StaticVector<Other,N,TF>& rhs );
227  template< typename VT > inline StaticVector& operator= ( const Vector<VT,TF>& rhs );
228  template< typename Other > inline StaticVector& operator= ( const Other (&rhs)[N] );
229  template< typename VT > inline StaticVector& operator+=( const Vector<VT,TF>& rhs );
230  template< typename VT > inline StaticVector& operator-=( const Vector<VT,TF>& rhs );
231  template< typename VT > inline StaticVector& operator*=( const Vector<VT,TF>& rhs );
232 
233  template< typename Other >
234  inline typename EnableIf< IsNumeric<Other>, StaticVector >::Type&
235  operator*=( Other rhs );
236 
237  template< typename Other >
238  inline typename EnableIf< IsNumeric<Other>, StaticVector >::Type&
239  operator/=( Other rhs );
241  //**********************************************************************************************
242 
243  //**Utility functions***************************************************************************
246  inline size_t size() const;
247  inline size_t capacity() const;
248  inline size_t nonZeros() const;
249  inline void reset();
250  template< typename Other > inline StaticVector& scale( Other scalar );
251  inline void swap( StaticVector& v ) /* throw() */;
253  //**********************************************************************************************
254 
255  private:
256  //**********************************************************************************************
258 
259  template< typename VT >
260  struct VectorizedAssign {
261  enum { value = vectorizable && VT::vectorizable &&
263  };
265  //**********************************************************************************************
266 
267  //**********************************************************************************************
269 
270  template< typename VT >
271  struct VectorizedAddAssign {
272  enum { value = vectorizable && VT::vectorizable &&
273  IsSame<Type,typename VT::ElementType>::value &&
274  IntrinsicTrait<Type>::addition };
275  };
277  //**********************************************************************************************
278 
279  //**********************************************************************************************
281 
282  template< typename VT >
283  struct VectorizedSubAssign {
284  enum { value = vectorizable && VT::vectorizable &&
285  IsSame<Type,typename VT::ElementType>::value &&
286  IntrinsicTrait<Type>::subtraction };
287  };
289  //**********************************************************************************************
290 
291  //**********************************************************************************************
293 
294  template< typename VT >
295  struct VectorizedMultAssign {
296  enum { value = vectorizable && VT::vectorizable &&
297  IsSame<Type,typename VT::ElementType>::value &&
298  IntrinsicTrait<Type>::multiplication };
299  };
301  //**********************************************************************************************
302 
303  public:
304  //**Expression template evaluation functions****************************************************
307  template< typename Other > inline bool canAlias ( const Other* alias ) const;
308  template< typename Other > inline bool isAliased( const Other* alias ) const;
309  inline IntrinsicType get ( size_t index ) const;
310 
311  template< typename VT >
312  inline typename DisableIf< VectorizedAssign<VT> >::Type
313  assign( const DenseVector<VT,TF>& rhs );
314 
315  template< typename VT >
316  inline typename EnableIf< VectorizedAssign<VT> >::Type
317  assign( const DenseVector<VT,TF>& rhs );
318 
319  template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
320 
321  template< typename VT >
322  inline typename DisableIf< VectorizedAddAssign<VT> >::Type
323  addAssign( const DenseVector<VT,TF>& rhs );
324 
325  template< typename VT >
326  inline typename EnableIf< VectorizedAddAssign<VT> >::Type
327  addAssign( const DenseVector<VT,TF>& rhs );
328 
329  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
330 
331  template< typename VT >
332  inline typename DisableIf< VectorizedSubAssign<VT> >::Type
333  subAssign( const DenseVector<VT,TF>& rhs );
334 
335  template< typename VT >
336  inline typename EnableIf< VectorizedSubAssign<VT> >::Type
337  subAssign( const DenseVector<VT,TF>& rhs );
338 
339  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
340 
341  template< typename VT >
342  inline typename DisableIf< VectorizedMultAssign<VT> >::Type
343  multAssign( const DenseVector<VT,TF>& rhs );
344 
345  template< typename VT >
346  inline typename EnableIf< VectorizedMultAssign<VT> >::Type
347  multAssign( const DenseVector<VT,TF>& rhs );
348 
349  template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
351  //**********************************************************************************************
352 
353  private:
354  //**Member variables****************************************************************************
357  Type v_[NN];
358 
364  //**********************************************************************************************
365 
366  //**Compile time checks*************************************************************************
372  BLAZE_STATIC_ASSERT( NN % IT::size == 0UL );
373  BLAZE_STATIC_ASSERT( NN >= N );
375  //**********************************************************************************************
376 };
377 //*************************************************************************************************
378 
379 
380 
381 
382 //=================================================================================================
383 //
384 // CONSTRUCTORS
385 //
386 //=================================================================================================
387 
388 //*************************************************************************************************
393 template< typename Type // Data type of the vector
394  , size_t N // Number of elements
395  , bool TF > // Transpose flag
397 {
398  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
399 
400  if( IsNumeric<Type>::value ) {
401  for( size_t i=0UL; i<NN; ++i )
402  v_[i] = Type();
403  }
404 }
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
416 inline StaticVector<Type,N,TF>::StaticVector( const Type& init )
417 {
418  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
419 
420  for( size_t i=0UL; i<N; ++i )
421  v_[i] = init;
422 
423  if( IsNumeric<Type>::value ) {
424  for( size_t i=N; i<NN; ++i )
425  v_[i] = Type();
426  }
427 }
428 //*************************************************************************************************
429 
430 
431 //*************************************************************************************************
438 template< typename Type // Data type of the vector
439  , size_t N // Number of elements
440  , bool TF > // Transpose flag
442 {
443  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
444 
445  for( size_t i=0UL; i<NN; ++i )
446  v_[i] = v.v_[i];
447 }
448 //*************************************************************************************************
449 
450 
451 //*************************************************************************************************
456 template< typename Type // Data type of the vector
457  , size_t N // Number of elements
458  , bool TF > // Transpose flag
459 template< typename Other > // Data type of the foreign vector
461 {
462  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
463 
464  for( size_t i=0UL; i<N; ++i )
465  v_[i] = v[i];
466 
467  if( IsNumeric<Type>::value ) {
468  for( size_t i=N; i<NN; ++i )
469  v_[i] = Type();
470  }
471 }
472 //*************************************************************************************************
473 
474 
475 //*************************************************************************************************
485 template< typename Type // Data type of the vector
486  , size_t N // Number of elements
487  , bool TF > // Transpose flag
488 template< typename VT > // Type of the foreign vector
490 {
491  using blaze::assign;
492 
493  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
494 
495  if( (~v).size() != N )
496  throw std::invalid_argument( "Invalid setup of static vector" );
497 
498  if( IsNumeric<Type>::value ) {
499  for( size_t i=( IsSparseVector<VT>::value )?( 0UL ):( N ); i<NN; ++i )
500  v_[i] = Type();
501  }
502 
503  assign( *this, ~v );
504 }
505 //*************************************************************************************************
506 
507 
508 //*************************************************************************************************
522 template< typename Type // Data type of the vector
523  , size_t N // Number of elements
524  , bool TF > // Transpose flag
525 template< typename Other > // Data type of the initialization array
526 inline StaticVector<Type,N,TF>::StaticVector( const Other (&rhs)[N] )
527 {
528  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
529 
530  for( size_t i=0UL; i<N; ++i )
531  v_[i] = rhs[i];
532 
533  if( IsNumeric<Type>::value ) {
534  for( size_t i=N; i<NN; ++i )
535  v_[i] = Type();
536  }
537 }
538 //*************************************************************************************************
539 
540 
541 //*************************************************************************************************
553 template< typename Type // Data type of the vector
554  , size_t N // Number of elements
555  , bool TF > // Transpose flag
556 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2 )
557 {
558  BLAZE_STATIC_ASSERT( N == 2UL );
559  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
560 
561  v_[0] = v1;
562  v_[1] = v2;
563 
564  if( IsNumeric<Type>::value ) {
565  for( size_t i=N; i<NN; ++i )
566  v_[i] = Type();
567  }
568 }
569 //*************************************************************************************************
570 
571 
572 //*************************************************************************************************
585 template< typename Type // Data type of the vector
586  , size_t N // Number of elements
587  , bool TF > // Transpose flag
588 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3 )
589 {
590  BLAZE_STATIC_ASSERT( N == 3UL );
591  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
592 
593  v_[0] = v1;
594  v_[1] = v2;
595  v_[2] = v3;
596 
597  if( IsNumeric<Type>::value ) {
598  for( size_t i=N; i<NN; ++i )
599  v_[i] = Type();
600  }
601 }
602 //*************************************************************************************************
603 
604 
605 //*************************************************************************************************
619 template< typename Type // Data type of the vector
620  , size_t N // Number of elements
621  , bool TF > // Transpose flag
622 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2,
623  const Type& v3, const Type& v4 )
624 {
625  BLAZE_STATIC_ASSERT( N == 4UL );
626  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
627 
628  v_[0] = v1;
629  v_[1] = v2;
630  v_[2] = v3;
631  v_[3] = v4;
632 
633  if( IsNumeric<Type>::value ) {
634  for( size_t i=N; i<NN; ++i )
635  v_[i] = Type();
636  }
637 }
638 //*************************************************************************************************
639 
640 
641 //*************************************************************************************************
656 template< typename Type // Data type of the vector
657  , size_t N // Number of elements
658  , bool TF > // Transpose flag
659 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3,
660  const Type& v4, const Type& v5 )
661 {
662  BLAZE_STATIC_ASSERT( N == 5UL );
663  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
664 
665  v_[0] = v1;
666  v_[1] = v2;
667  v_[2] = v3;
668  v_[3] = v4;
669  v_[4] = v5;
670 
671  if( IsNumeric<Type>::value ) {
672  for( size_t i=N; i<NN; ++i )
673  v_[i] = Type();
674  }
675 }
676 //*************************************************************************************************
677 
678 
679 //*************************************************************************************************
695 template< typename Type // Data type of the vector
696  , size_t N // Number of elements
697  , bool TF > // Transpose flag
698 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3,
699  const Type& v4, const Type& v5, const Type& v6 )
700 {
701  BLAZE_STATIC_ASSERT( N == 6UL );
702  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
703 
704  v_[0] = v1;
705  v_[1] = v2;
706  v_[2] = v3;
707  v_[3] = v4;
708  v_[4] = v5;
709  v_[5] = v6;
710 
711  if( IsNumeric<Type>::value ) {
712  for( size_t i=N; i<NN; ++i )
713  v_[i] = Type();
714  }
715 }
716 //*************************************************************************************************
717 
718 
719 
720 
721 //=================================================================================================
722 //
723 // DATA ACCESS FUNCTIONS
724 //
725 //=================================================================================================
726 
727 //*************************************************************************************************
735 template< typename Type // Data type of the vector
736  , size_t N // Number of elements
737  , bool TF > // Transpose flag
740 {
741  BLAZE_USER_ASSERT( index < N, "Invalid vector access index" );
742  return v_[index];
743 }
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 //*************************************************************************************************
772 template< typename Type // Data type of the vector
773  , size_t N // Number of elements
774  , bool TF > // Transpose flag
776 {
777  return v_;
778 }
779 //*************************************************************************************************
780 
781 
782 //*************************************************************************************************
787 template< typename Type // Data type of the vector
788  , size_t N // Number of elements
789  , bool TF > // Transpose flag
790 inline const Type* StaticVector<Type,N,TF>::data() const
791 {
792  return v_;
793 }
794 //*************************************************************************************************
795 
796 
797 //*************************************************************************************************
802 template< typename Type // Data type of the vector
803  , size_t N // Number of elements
804  , bool TF > // Transpose flag
806 {
807  return v_;
808 }
809 //*************************************************************************************************
810 
811 
812 //*************************************************************************************************
817 template< typename Type // Data type of the vector
818  , size_t N // Number of elements
819  , bool TF > // Transpose flag
821 {
822  return v_;
823 }
824 //*************************************************************************************************
825 
826 
827 //*************************************************************************************************
832 template< typename Type // Data type of the vector
833  , size_t N // Number of elements
834  , bool TF > // Transpose flag
836 {
837  return v_;
838 }
839 //*************************************************************************************************
840 
841 
842 //*************************************************************************************************
847 template< typename Type // Data type of the vector
848  , size_t N // Number of elements
849  , bool TF > // Transpose flag
851 {
852  return v_ + N;
853 }
854 //*************************************************************************************************
855 
856 
857 //*************************************************************************************************
862 template< typename Type // Data type of the vector
863  , size_t N // Number of elements
864  , bool TF > // Transpose flag
866 {
867  return v_ + N;
868 }
869 //*************************************************************************************************
870 
871 
872 //*************************************************************************************************
877 template< typename Type // Data type of the vector
878  , size_t N // Number of elements
879  , bool TF > // Transpose flag
881 {
882  return v_ + N;
883 }
884 //*************************************************************************************************
885 
886 
887 
888 
889 //=================================================================================================
890 //
891 // ASSIGNMENT OPERATORS
892 //
893 //=================================================================================================
894 
895 //*************************************************************************************************
901 template< typename Type // Data type of the vector
902  , size_t N // Number of elements
903  , bool TF > // Transpose flag
905 {
906  for( size_t i=0UL; i<N; ++i )
907  v_[i] = rhs;
908  return *this;
909 }
910 //*************************************************************************************************
911 
912 
913 //*************************************************************************************************
921 template< typename Type // Data type of the vector
922  , size_t N // Number of elements
923  , bool TF > // Transpose flag
925 {
926  // This implementation was chosen for several reasons:
927  // - it works for all possible element types (even types that could not be copied by 'memcpy')
928  // - it is faster than the synthesized default copy assignment operator
929  // - it is faster than an implementation with the C library function 'memcpy' in combination
930  // with a protection against self-assignment
931  // - it goes without a protection against self-assignment
932  for( size_t i=0UL; i<N; ++i )
933  v_[i] = rhs.v_[i];
934  return *this;
935 }
936 //*************************************************************************************************
937 
938 
939 //*************************************************************************************************
945 template< typename Type // Data type of the vector
946  , size_t N // Number of elements
947  , bool TF > // Transpose flag
948 template< typename Other > // Data type of the foreign vector
950 {
951  // This implementation was chosen for several reasons:
952  // - it works for all possible element types (even types that could not be copied by 'memcpy')
953  // - it is faster than the synthesized default copy assignment operator
954  // - it is faster than an implementation with the C library function 'memcpy' in combination
955  // with a protection against self-assignment
956  // - it goes without a protection against self-assignment
957  for( size_t i=0UL; i<N; ++i )
958  v_[i] = rhs[i];
959  return *this;
960 }
961 //*************************************************************************************************
962 
963 
964 //*************************************************************************************************
974 template< typename Type // Data type of the vector
975  , size_t N // Number of elements
976  , bool TF > // Transpose flag
977 template< typename VT > // Type of the right-hand side vector
979 {
980  using blaze::assign;
981 
982  if( (~rhs).size() != N )
983  throw std::invalid_argument( "Invalid assignment to static vector" );
984 
985  if( (~rhs).canAlias( this ) ) {
986  StaticVector tmp( ~rhs );
987  swap( tmp );
988  }
989  else {
991  reset();
992  assign( *this, ~rhs );
993  }
994 
995  return *this;
996 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1016 template< typename Type // Data type of the vector
1017  , size_t N // Number of elements
1018  , bool TF > // Transpose flag
1019 template< typename Other > // Data type of the initialization array
1021 {
1022  for( size_t i=0UL; i<N; ++i )
1023  v_[i] = rhs[i];
1024  return *this;
1025 }
1026 //*************************************************************************************************
1027 
1028 
1029 //*************************************************************************************************
1039 template< typename Type // Data type of the vector
1040  , size_t N // Number of elements
1041  , bool TF > // Transpose flag
1042 template< typename VT > // Type of the right-hand side vector
1044 {
1045  using blaze::addAssign;
1046 
1047  if( (~rhs).size() != N )
1048  throw std::invalid_argument( "Vector sizes do not match" );
1049 
1050  if( (~rhs).canAlias( this ) ) {
1051  StaticVector tmp( ~rhs );
1052  addAssign( *this, tmp );
1053  }
1054  else {
1055  addAssign( *this, ~rhs );
1056  }
1057 
1058  return *this;
1059 }
1060 //*************************************************************************************************
1061 
1062 
1063 //*************************************************************************************************
1073 template< typename Type // Data type of the vector
1074  , size_t N // Number of elements
1075  , bool TF > // Transpose flag
1076 template< typename VT > // Type of the right-hand side vector
1078 {
1079  using blaze::subAssign;
1080 
1081  if( (~rhs).size() != N )
1082  throw std::invalid_argument( "Vector sizes do not match" );
1083 
1084  if( (~rhs).canAlias( this ) ) {
1085  StaticVector tmp( ~rhs );
1086  subAssign( *this, tmp );
1087  }
1088  else {
1089  subAssign( *this, ~rhs );
1090  }
1091 
1092  return *this;
1093 }
1094 //*************************************************************************************************
1095 
1096 
1097 //*************************************************************************************************
1108 template< typename Type // Data type of the vector
1109  , size_t N // Number of elements
1110  , bool TF > // Transpose flag
1111 template< typename VT > // Type of the right-hand side vector
1113 {
1114  using blaze::assign;
1115 
1116  if( (~rhs).size() != N )
1117  throw std::invalid_argument( "Vector sizes do not match" );
1118 
1119  if( (~rhs).canAlias( this ) || IsSparseVector<VT>::value ) {
1120  StaticVector tmp( *this * (~rhs) );
1121  this->operator=( tmp );
1122  }
1123  else {
1124  assign( *this, *this * (~rhs) );
1125  }
1126 
1127  return *this;
1128 }
1129 //*************************************************************************************************
1130 
1131 
1132 //*************************************************************************************************
1139 template< typename Type // Data type of the vector
1140  , size_t N // Number of elements
1141  , bool TF > // Transpose flag
1142 template< typename Other > // Data type of the right-hand side scalar
1143 inline typename EnableIf< IsNumeric<Other>, StaticVector<Type,N,TF> >::Type&
1145 {
1146  return operator=( (*this) * rhs );
1147 }
1148 //*************************************************************************************************
1149 
1150 
1151 //*************************************************************************************************
1160 template< typename Type // Data type of the vector
1161  , size_t N // Number of elements
1162  , bool TF > // Transpose flag
1163 template< typename Other > // Data type of the right-hand side scalar
1164 inline typename EnableIf< IsNumeric<Other>, StaticVector<Type,N,TF> >::Type&
1166 {
1167  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1168 
1169  return operator=( (*this) / rhs );
1170 }
1171 //*************************************************************************************************
1172 
1173 
1174 
1175 
1176 //=================================================================================================
1177 //
1178 // UTILITY FUNCTIONS
1179 //
1180 //=================================================================================================
1181 
1182 //*************************************************************************************************
1187 template< typename Type // Data type of the vector
1188  , size_t N // Number of elements
1189  , bool TF > // Transpose flag
1190 inline size_t StaticVector<Type,N,TF>::size() const
1191 {
1192  return N;
1193 }
1194 //*************************************************************************************************
1195 
1196 
1197 //*************************************************************************************************
1202 template< typename Type // Data type of the vector
1203  , size_t N // Number of elements
1204  , bool TF > // Transpose flag
1206 {
1207  return NN;
1208 }
1209 //*************************************************************************************************
1210 
1211 
1212 //*************************************************************************************************
1220 template< typename Type // Data type of the vector
1221  , size_t N // Number of elements
1222  , bool TF > // Transpose flag
1224 {
1225  size_t nonzeros( 0 );
1226 
1227  for( size_t i=0UL; i<N; ++i ) {
1228  if( !isDefault( v_[i] ) )
1229  ++nonzeros;
1230  }
1231 
1232  return nonzeros;
1233 }
1234 //*************************************************************************************************
1235 
1236 
1237 //*************************************************************************************************
1242 template< typename Type // Data type of the vector
1243  , size_t N // Number of elements
1244  , bool TF > // Transpose flag
1246 {
1247  using blaze::reset;
1248  for( size_t i=0UL; i<N; ++i )
1249  reset( v_[i] );
1250 }
1251 //*************************************************************************************************
1252 
1253 
1254 //*************************************************************************************************
1260 template< typename Type // Data type of the vector
1261  , size_t N // Number of elements
1262  , bool TF > // Transpose flag
1263 template< typename Other > // Data type of the scalar value
1265 {
1266  for( size_t i=0; i<N; ++i )
1267  v_[i] *= scalar;
1268  return *this;
1269 }
1270 //*************************************************************************************************
1271 
1272 
1273 //*************************************************************************************************
1280 template< typename Type // Data type of the vector
1281  , size_t N // Number of elements
1282  , bool TF > // Transpose flag
1283 inline void StaticVector<Type,N,TF>::swap( StaticVector& v ) /* throw() */
1284 {
1285  using std::swap;
1286 
1287  for( size_t i=0UL; i<N; ++i )
1288  swap( v_[i], v.v_[i] );
1289 }
1290 //*************************************************************************************************
1291 
1292 
1293 
1294 
1295 //=================================================================================================
1296 //
1297 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1298 //
1299 //=================================================================================================
1300 
1301 //*************************************************************************************************
1311 template< typename Type // Data type of the vector
1312  , size_t N // Number of elements
1313  , bool TF > // Transpose flag
1314 template< typename Other > // Data type of the foreign expression
1315 inline bool StaticVector<Type,N,TF>::canAlias( const Other* alias ) const
1316 {
1317  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1318 }
1319 //*************************************************************************************************
1320 
1321 
1322 //*************************************************************************************************
1332 template< typename Type // Data type of the vector
1333  , size_t N // Number of elements
1334  , bool TF > // Transpose flag
1335 template< typename Other > // Data type of the foreign expression
1336 inline bool StaticVector<Type,N,TF>::isAliased( const Other* alias ) const
1337 {
1338  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1339 }
1340 //*************************************************************************************************
1341 
1342 
1343 //*************************************************************************************************
1354 template< typename Type // Data type of the vector
1355  , size_t N // Number of elements
1356  , bool TF > // Transpose flag
1358  StaticVector<Type,N,TF>::get( size_t index ) const
1359 {
1361 
1362  BLAZE_INTERNAL_ASSERT( index < N , "Invalid vector access index" );
1363  BLAZE_INTERNAL_ASSERT( index + IT::size <= NN , "Invalid vector access index" );
1364  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid vector access index" );
1365 
1366  return load( &v_[index] );
1367 }
1368 //*************************************************************************************************
1369 
1370 
1371 //*************************************************************************************************
1382 template< typename Type // Data type of the vector
1383  , size_t N // Number of elements
1384  , bool TF > // Transpose flag
1385 template< typename VT > // Type of the right-hand side dense vector
1386 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAssign<VT> >::Type
1388 {
1389  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1390 
1391  for( size_t i=0UL; i<N; ++i )
1392  v_[i] = (~rhs)[i];
1393 }
1394 //*************************************************************************************************
1395 
1396 
1397 //*************************************************************************************************
1408 template< typename Type // Data type of the vector
1409  , size_t N // Number of elements
1410  , bool TF > // Transpose flag
1411 template< typename VT > // Type of the right-hand side dense vector
1412 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAssign<VT> >::Type
1414 {
1415  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1416 
1418 
1419  for( size_t i=0UL; i<N; i+=IT::size ) {
1420  store( v_+i, (~rhs).get(i) );
1421  }
1422 }
1423 //*************************************************************************************************
1424 
1425 
1426 //*************************************************************************************************
1437 template< typename Type // Data type of the vector
1438  , size_t N // Number of elements
1439  , bool TF > // Transpose flag
1440 template< typename VT > // Type of the right-hand side sparse vector
1442 {
1443  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1444 
1445  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1446  v_[element->index()] = element->value();
1447 }
1448 //*************************************************************************************************
1449 
1450 
1451 //*************************************************************************************************
1462 template< typename Type // Data type of the vector
1463  , size_t N // Number of elements
1464  , bool TF > // Transpose flag
1465 template< typename VT > // Type of the right-hand side dense vector
1466 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >::Type
1468 {
1469  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1470 
1471  for( size_t i=0UL; i<N; ++i )
1472  v_[i] += (~rhs)[i];
1473 }
1474 //*************************************************************************************************
1475 
1476 
1477 //*************************************************************************************************
1488 template< typename Type // Data type of the vector
1489  , size_t N // Number of elements
1490  , bool TF > // Transpose flag
1491 template< typename VT > // Type of the right-hand side dense vector
1492 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >::Type
1494 {
1495  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1496 
1498 
1499  for( size_t i=0UL; i<N; i+=IT::size ) {
1500  store( v_+i, load( v_+i ) + (~rhs).get(i) );
1501  }
1502 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1517 template< typename Type // Data type of the vector
1518  , size_t N // Number of elements
1519  , bool TF > // Transpose flag
1520 template< typename VT > // Type of the right-hand side sparse vector
1522 {
1523  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1524 
1525  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1526  v_[element->index()] += element->value();
1527 }
1528 //*************************************************************************************************
1529 
1530 
1531 //*************************************************************************************************
1542 template< typename Type // Data type of the vector
1543  , size_t N // Number of elements
1544  , bool TF > // Transpose flag
1545 template< typename VT > // Type of the right-hand side dense vector
1546 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >::Type
1548 {
1549  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1550 
1551  for( size_t i=0UL; i<N; ++i )
1552  v_[i] -= (~rhs)[i];
1553 }
1554 //*************************************************************************************************
1555 
1556 
1557 //*************************************************************************************************
1568 template< typename Type // Data type of the vector
1569  , size_t N // Number of elements
1570  , bool TF > // Transpose flag
1571 template< typename VT > // Type of the right-hand side dense vector
1572 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >::Type
1574 {
1575  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1576 
1578 
1579  for( size_t i=0UL; i<N; i+=IT::size ) {
1580  store( v_+i, load( v_+i ) - (~rhs).get(i) );
1581  }
1582 }
1583 //*************************************************************************************************
1584 
1585 
1586 //*************************************************************************************************
1597 template< typename Type // Data type of the vector
1598  , size_t N // Number of elements
1599  , bool TF > // Transpose flag
1600 template< typename VT > // Type of the right-hand side sparse vector
1602 {
1603  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1604 
1605  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1606  v_[element->index()] -= element->value();
1607 }
1608 //*************************************************************************************************
1609 
1610 
1611 //*************************************************************************************************
1622 template< typename Type // Data type of the vector
1623  , size_t N // Number of elements
1624  , bool TF > // Transpose flag
1625 template< typename VT > // Type of the right-hand side dense vector
1626 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >::Type
1628 {
1629  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1630 
1631  for( size_t i=0UL; i<N; ++i )
1632  v_[i] *= (~rhs)[i];
1633 }
1634 //*************************************************************************************************
1635 
1636 
1637 //*************************************************************************************************
1648 template< typename Type // Data type of the vector
1649  , size_t N // Number of elements
1650  , bool TF > // Transpose flag
1651 template< typename VT > // Type of the right-hand side dense vector
1652 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >::Type
1654 {
1655  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1656 
1658 
1659  for( size_t i=0UL; i<N; i+=IT::size ) {
1660  store( v_+i, load( v_+i ) * (~rhs).get(i) );
1661  }
1662 }
1663 //*************************************************************************************************
1664 
1665 
1666 //*************************************************************************************************
1677 template< typename Type // Data type of the vector
1678  , size_t N // Number of elements
1679  , bool TF > // Transpose flag
1680 template< typename VT > // Type of the right-hand side sparse vector
1682 {
1683  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1684 
1685  const StaticVector tmp( *this );
1686 
1687  reset();
1688 
1689  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1690  v_[element->index()] = tmp[element->index()] * element->value();
1691 }
1692 //*************************************************************************************************
1693 
1694 
1695 
1696 
1697 
1698 
1699 
1700 
1701 //=================================================================================================
1702 //
1703 // UNDEFINED CLASS TEMPLATE SPECIALIZATION
1704 //
1705 //=================================================================================================
1706 
1707 //*************************************************************************************************
1715 template< typename Type // Data type of the vector
1716  , bool TF > // Transpose flag
1717 class StaticVector<Type,0UL,TF>;
1719 //*************************************************************************************************
1720 
1721 
1722 
1723 
1724 
1725 
1726 
1727 
1728 //=================================================================================================
1729 //
1730 // STATICVECTOR OPERATORS
1731 //
1732 //=================================================================================================
1733 
1734 //*************************************************************************************************
1737 template< typename Type, size_t N, bool TF >
1738 inline bool isnan( const StaticVector<Type,N,TF>& v );
1739 
1740 template< typename Type, size_t N, bool TF >
1741 inline void reset( StaticVector<Type,N,TF>& v );
1742 
1743 template< typename Type, size_t N, bool TF >
1744 inline void clear( StaticVector<Type,N,TF>& v );
1745 
1746 template< typename Type, size_t N, bool TF >
1747 inline bool isDefault( const StaticVector<Type,N,TF>& v );
1748 
1749 template< typename Type, bool TF >
1751 
1752 template< typename Type, bool TF >
1754 
1755 template< typename Type, size_t N, bool TF >
1756 inline void swap( StaticVector<Type,N,TF>& a, StaticVector<Type,N,TF>& b ) /* throw() */;
1758 //*************************************************************************************************
1759 
1760 
1761 //*************************************************************************************************
1778 template< typename Type // Data type of the vector
1779  , size_t N // Number of elements
1780  , bool TF > // Transpose flag
1781 inline bool isnan( const StaticVector<Type,N,TF>& v )
1782 {
1783  for( size_t i=0UL; i<N; ++i ) {
1784  if( isnan( v[i] ) ) return true;
1785  }
1786  return false;
1787 }
1788 //*************************************************************************************************
1789 
1790 
1791 //*************************************************************************************************
1798 template< typename Type // Data type of the vector
1799  , size_t N // Number of elements
1800  , bool TF > // Transpose flag
1802 {
1803  v.reset();
1804 }
1805 //*************************************************************************************************
1806 
1807 
1808 //*************************************************************************************************
1817 template< typename Type // Data type of the vector
1818  , size_t N // Number of elements
1819  , bool TF > // Transpose flag
1821 {
1822  v.reset();
1823 }
1824 //*************************************************************************************************
1825 
1826 
1827 //*************************************************************************************************
1845 template< typename Type // Data type of the vector
1846  , size_t N // Number of elements
1847  , bool TF > // Transpose flag
1848 inline bool isDefault( const StaticVector<Type,N,TF>& v )
1849 {
1850  for( size_t i=0UL; i<N; ++i )
1851  if( !isDefault( v[i] ) ) return false;
1852  return true;
1853 }
1854 //*************************************************************************************************
1855 
1856 
1857 //*************************************************************************************************
1868 template< typename Type // Data type of the vector
1869  , bool TF > // Transpose flag
1871 {
1872  return StaticVector<Type,2UL,TF>( -v[1UL], v[0UL] );
1873 }
1874 //*************************************************************************************************
1875 
1876 
1877 //*************************************************************************************************
1885 template< typename Type // Data type of the vector
1886  , bool TF > // Transpose flag
1888 {
1889  if( v[0] != Type() || v[1] != Type() )
1890  return StaticVector<Type,3UL,TF>( v[1UL], -v[0UL], Type() );
1891  else
1892  return StaticVector<Type,3UL,TF>( Type(), v[2UL], -v[1UL] );
1893 }
1894 //*************************************************************************************************
1895 
1896 
1897 //*************************************************************************************************
1906 template< typename Type // Data type of the vector
1907  , size_t N // Number of elements
1908  , bool TF > // Transpose flag
1909 inline void swap( StaticVector<Type,N,TF>& a, StaticVector<Type,N,TF>& b ) /* throw() */
1910 {
1911  a.swap( b );
1912 }
1913 //*************************************************************************************************
1914 
1915 
1916 
1917 
1918 //=================================================================================================
1919 //
1920 // ADDTRAIT SPECIALIZATIONS
1921 //
1922 //=================================================================================================
1923 
1924 //*************************************************************************************************
1926 template< typename T1, size_t N, bool TF, typename T2 >
1927 struct AddTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
1928 {
1929  typedef StaticVector< typename AddTrait<T1,T2>::Type, N, TF > Type;
1930 };
1932 //*************************************************************************************************
1933 
1934 
1935 
1936 
1937 //=================================================================================================
1938 //
1939 // SUBTRAIT SPECIALIZATIONS
1940 //
1941 //=================================================================================================
1942 
1943 //*************************************************************************************************
1945 template< typename T1, size_t N, bool TF, typename T2 >
1946 struct SubTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
1947 {
1948  typedef StaticVector< typename SubTrait<T1,T2>::Type, N, TF > Type;
1949 };
1951 //*************************************************************************************************
1952 
1953 
1954 
1955 
1956 //=================================================================================================
1957 //
1958 // MULTTRAIT SPECIALIZATIONS
1959 //
1960 //=================================================================================================
1961 
1962 //*************************************************************************************************
1964 template< typename T1, size_t N, bool TF, typename T2 >
1965 struct MultTrait< StaticVector<T1,N,TF>, T2 >
1966 {
1967  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
1969 };
1970 
1971 template< typename T1, typename T2, size_t N, bool TF >
1972 struct MultTrait< T1, StaticVector<T2,N,TF> >
1973 {
1974  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
1976 };
1977 
1978 template< typename T1, size_t N, bool TF, typename T2 >
1979 struct MultTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
1980 {
1981  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
1982 };
1983 
1984 template< typename T1, size_t M, typename T2, size_t N >
1985 struct MultTrait< StaticVector<T1,M,false>, StaticVector<T2,N,true> >
1986 {
1987  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, false > Type;
1988 };
1989 
1990 template< typename T1, size_t N, typename T2 >
1991 struct MultTrait< StaticVector<T1,N,true>, StaticVector<T2,N,false> >
1992 {
1993  typedef typename MultTrait<T1,T2>::Type Type;
1994 };
1996 //*************************************************************************************************
1997 
1998 
1999 
2000 
2001 //=================================================================================================
2002 //
2003 // CROSSTRAIT SPECIALIZATIONS
2004 //
2005 //=================================================================================================
2006 
2007 //*************************************************************************************************
2009 template< typename T1, typename T2 >
2010 struct CrossTrait< StaticVector<T1,3UL,false>, StaticVector<T2,3UL,false> >
2011 {
2012  private:
2013  typedef typename MultTrait<T1,T2>::Type T;
2014 
2015  public:
2016  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
2017 };
2019 //*************************************************************************************************
2020 
2021 
2022 
2023 
2024 //=================================================================================================
2025 //
2026 // DIVTRAIT SPECIALIZATIONS
2027 //
2028 //=================================================================================================
2029 
2030 //*************************************************************************************************
2032 template< typename T1, size_t N, bool TF, typename T2 >
2033 struct DivTrait< StaticVector<T1,N,TF>, T2 >
2034 {
2035  typedef StaticVector< typename DivTrait<T1,T2>::Type, N, TF > Type;
2037 };
2039 //*************************************************************************************************
2040 
2041 
2042 
2043 
2044 //=================================================================================================
2045 //
2046 // MATHTRAIT SPECIALIZATIONS
2047 //
2048 //=================================================================================================
2049 
2050 //*************************************************************************************************
2052 template< typename T1, size_t N, bool TF, typename T2 >
2053 struct MathTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2054 {
2055  typedef StaticVector< typename MathTrait<T1,T2>::HighType, N, TF > HighType;
2056  typedef StaticVector< typename MathTrait<T1,T2>::LowType , N, TF > LowType;
2057 };
2059 //*************************************************************************************************
2060 
2061 } // namespace blaze
2062 
2063 #endif