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/Forward.h>
35 #include <blaze/math/Functions.h>
36 #include <blaze/math/Intrinsics.h>
38 #include <blaze/math/shims/IsNaN.h>
39 #include <blaze/math/shims/Reset.h>
50 #include <blaze/util/Assert.h>
59 #include <blaze/util/DisableIf.h>
60 #include <blaze/util/EnableIf.h>
61 #include <blaze/util/mpl/If.h>
63 #include <blaze/util/Template.h>
64 #include <blaze/util/Types.h>
70 
71 
72 namespace blaze {
73 
74 //=================================================================================================
75 //
76 // CLASS DEFINITION
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
146 template< typename Type // Data type of the vector
147  , size_t N // Number of elements
148  , bool TF = defaultTransposeFlag > // Transpose flag
149 class StaticVector : public DenseVector< StaticVector<Type,N,TF>, TF >
150  , private AlignedStorage<Type>
151 {
152  private:
153  //**Type definitions****************************************************************************
155  //**********************************************************************************************
156 
157  //**********************************************************************************************
159  enum { NN = N + ( IT::size - ( N % IT::size ) ) % IT::size };
160  //**********************************************************************************************
161 
162  public:
163  //**Type definitions****************************************************************************
165  typedef This ResultType;
167  typedef Type ElementType;
168  typedef typename IT::Type IntrinsicType;
169  typedef const Type& ReturnType;
170  typedef const StaticVector& CompositeType;
171  typedef Type& Reference;
172  typedef const Type& ConstReference;
173  typedef Type* Iterator;
174  typedef const Type* ConstIterator;
175 
177 
179  //**********************************************************************************************
180 
181  //**Compilation flags***************************************************************************
183 
187  enum { vectorizable = IsVectorizable<Type>::value };
188  //**********************************************************************************************
189 
190  //**Constructors********************************************************************************
193  explicit inline StaticVector();
194  explicit inline StaticVector( const Type& init );
195  inline StaticVector( const StaticVector& v );
196  template< typename Other > inline StaticVector( const StaticVector<Other,N,TF>& v );
197  template< typename VT > inline StaticVector( const Vector<VT,TF>& v );
198  template< typename Other > explicit inline StaticVector( const Other (&rhs)[N] );
199 
200  inline StaticVector( const Type& v1, const Type& v2 );
201  inline StaticVector( const Type& v1, const Type& v2, const Type& v3 );
202  inline StaticVector( const Type& v1, const Type& v2, const Type& v3, const Type& v4 );
203  inline StaticVector( const Type& v1, const Type& v2, const Type& v3,
204  const Type& v4, const Type& v5 );
205  inline StaticVector( const Type& v1, const Type& v2, const Type& v3,
206  const Type& v4, const Type& v5, const Type& v6 );
208  //**********************************************************************************************
209 
210  //**Destructor**********************************************************************************
211  // No explicitly declared destructor.
212  //**********************************************************************************************
213 
214  //**Data access functions***********************************************************************
217  inline Reference operator[]( size_t index );
218  inline ConstReference operator[]( size_t index ) const;
219  inline Type* data ();
220  inline const Type* data () const;
221  inline Iterator begin ();
222  inline ConstIterator begin () const;
223  inline ConstIterator cbegin() const;
224  inline Iterator end ();
225  inline ConstIterator end () const;
226  inline ConstIterator cend () const;
228  //**********************************************************************************************
229 
230  //**Assignment operators************************************************************************
233  inline StaticVector& operator= ( Type rhs );
234  inline StaticVector& operator= ( const StaticVector& rhs );
235  template< typename Other > inline StaticVector& operator= ( const StaticVector<Other,N,TF>& rhs );
236  template< typename VT > inline StaticVector& operator= ( const Vector<VT,TF>& rhs );
237  template< typename Other > inline StaticVector& operator= ( const Other (&rhs)[N] );
238  template< typename VT > inline StaticVector& operator+=( const Vector<VT,TF>& rhs );
239  template< typename VT > inline StaticVector& operator-=( const Vector<VT,TF>& rhs );
240  template< typename VT > inline StaticVector& operator*=( const Vector<VT,TF>& rhs );
241 
242  template< typename Other >
243  inline typename EnableIf< IsNumeric<Other>, StaticVector >::Type&
244  operator*=( Other rhs );
245 
246  template< typename Other >
247  inline typename EnableIf< IsNumeric<Other>, StaticVector >::Type&
248  operator/=( Other rhs );
250  //**********************************************************************************************
251 
252  //**Utility functions***************************************************************************
255  inline size_t size() const;
256  inline size_t capacity() const;
257  inline size_t nonZeros() const;
258  inline void reset();
259  inline LengthType length() const;
260  inline Type sqrLength() const;
261  inline StaticVector& normalize();
262  inline const StaticVector getNormalized() const;
263  template< typename Other > inline StaticVector& scale( Other scalar );
264  inline void swap( StaticVector& v ) /* throw() */;
266  //**********************************************************************************************
267 
268  private:
269  //**********************************************************************************************
271 
272  template< typename VT >
273  struct VectorizedAssign {
274  enum { value = vectorizable && VT::vectorizable &&
276  };
278  //**********************************************************************************************
279 
280  //**********************************************************************************************
282 
283  template< typename VT >
284  struct VectorizedAddAssign {
285  enum { value = vectorizable && VT::vectorizable &&
286  IsSame<Type,typename VT::ElementType>::value &&
287  IntrinsicTrait<Type>::addition };
288  };
290  //**********************************************************************************************
291 
292  //**********************************************************************************************
294 
295  template< typename VT >
296  struct VectorizedSubAssign {
297  enum { value = vectorizable && VT::vectorizable &&
298  IsSame<Type,typename VT::ElementType>::value &&
299  IntrinsicTrait<Type>::subtraction };
300  };
302  //**********************************************************************************************
303 
304  //**********************************************************************************************
306 
307  template< typename VT >
308  struct VectorizedMultAssign {
309  enum { value = vectorizable && VT::vectorizable &&
310  IsSame<Type,typename VT::ElementType>::value &&
311  IntrinsicTrait<Type>::multiplication };
312  };
314  //**********************************************************************************************
315 
316  public:
317  //**Expression template evaluation functions****************************************************
320  template< typename Other > inline bool canAlias ( const Other* alias ) const;
321  template< typename Other > inline bool isAliased( const Other* alias ) const;
322  inline IntrinsicType get ( size_t index ) const;
323 
324  template< typename VT >
325  inline typename DisableIf< VectorizedAssign<VT> >::Type
326  assign( const DenseVector<VT,TF>& rhs );
327 
328  template< typename VT >
329  inline typename EnableIf< VectorizedAssign<VT> >::Type
330  assign( const DenseVector<VT,TF>& rhs );
331 
332  template< typename VT > inline void assign( const SparseVector<VT,TF>& rhs );
333 
334  template< typename VT >
335  inline typename DisableIf< VectorizedAddAssign<VT> >::Type
336  addAssign( const DenseVector<VT,TF>& rhs );
337 
338  template< typename VT >
339  inline typename EnableIf< VectorizedAddAssign<VT> >::Type
340  addAssign( const DenseVector<VT,TF>& rhs );
341 
342  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
343 
344  template< typename VT >
345  inline typename DisableIf< VectorizedSubAssign<VT> >::Type
346  subAssign( const DenseVector<VT,TF>& rhs );
347 
348  template< typename VT >
349  inline typename EnableIf< VectorizedSubAssign<VT> >::Type
350  subAssign( const DenseVector<VT,TF>& rhs );
351 
352  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
353 
354  template< typename VT >
355  inline typename DisableIf< VectorizedMultAssign<VT> >::Type
356  multAssign( const DenseVector<VT,TF>& rhs );
357 
358  template< typename VT >
359  inline typename EnableIf< VectorizedMultAssign<VT> >::Type
360  multAssign( const DenseVector<VT,TF>& rhs );
361 
362  template< typename VT > inline void multAssign( const SparseVector<VT,TF>& rhs );
364  //**********************************************************************************************
365 
366  private:
367  //**Member variables****************************************************************************
370  Type v_[NN];
371 
377  //**********************************************************************************************
378 
379  //**Compile time checks*************************************************************************
385  BLAZE_STATIC_ASSERT( NN % IT::size == 0UL );
386  BLAZE_STATIC_ASSERT( NN >= N );
388  //**********************************************************************************************
389 };
390 //*************************************************************************************************
391 
392 
393 
394 
395 //=================================================================================================
396 //
397 // CONSTRUCTORS
398 //
399 //=================================================================================================
400 
401 //*************************************************************************************************
406 template< typename Type // Data type of the vector
407  , size_t N // Number of elements
408  , bool TF > // Transpose flag
410 {
411  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
412 
413  if( IsBuiltin<Type>::value ) {
414  for( size_t i=0UL; i<NN; ++i )
415  v_[i] = Type();
416  }
417 }
418 //*************************************************************************************************
419 
420 
421 //*************************************************************************************************
426 template< typename Type // Data type of the vector
427  , size_t N // Number of elements
428  , bool TF > // Transpose flag
429 inline StaticVector<Type,N,TF>::StaticVector( const Type& init )
430 {
431  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
432 
433  for( size_t i=0UL; i<N; ++i )
434  v_[i] = init;
435 
436  if( IsBuiltin<Type>::value ) {
437  for( size_t i=N; i<NN; ++i )
438  v_[i] = Type();
439  }
440 }
441 //*************************************************************************************************
442 
443 
444 //*************************************************************************************************
451 template< typename Type // Data type of the vector
452  , size_t N // Number of elements
453  , bool TF > // Transpose flag
455 {
456  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
457 
458  for( size_t i=0UL; i<NN; ++i )
459  v_[i] = v.v_[i];
460 }
461 //*************************************************************************************************
462 
463 
464 //*************************************************************************************************
469 template< typename Type // Data type of the vector
470  , size_t N // Number of elements
471  , bool TF > // Transpose flag
472 template< typename Other > // Data type of the foreign vector
474 {
475  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
476 
477  for( size_t i=0UL; i<N; ++i )
478  v_[i] = v[i];
479 
480  if( IsBuiltin<Type>::value ) {
481  for( size_t i=N; i<NN; ++i )
482  v_[i] = Type();
483  }
484 }
485 //*************************************************************************************************
486 
487 
488 //*************************************************************************************************
498 template< typename Type // Data type of the vector
499  , size_t N // Number of elements
500  , bool TF > // Transpose flag
501 template< typename VT > // Type of the foreign vector
503 {
504  using blaze::assign;
505 
506  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
507 
508  if( (~v).size() != N )
509  throw std::invalid_argument( "Invalid setup of static vector" );
510 
511  if( IsBuiltin<Type>::value ) {
512  for( size_t i=( IsSparseVector<VT>::value )?( 0UL ):( N ); i<NN; ++i )
513  v_[i] = Type();
514  }
515 
516  assign( *this, ~v );
517 }
518 //*************************************************************************************************
519 
520 
521 //*************************************************************************************************
535 template< typename Type // Data type of the vector
536  , size_t N // Number of elements
537  , bool TF > // Transpose flag
538 template< typename Other > // Data type of the initialization array
539 inline StaticVector<Type,N,TF>::StaticVector( const Other (&rhs)[N] )
540 {
541  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
542 
543  for( size_t i=0UL; i<N; ++i )
544  v_[i] = rhs[i];
545 
546  if( IsBuiltin<Type>::value ) {
547  for( size_t i=N; i<NN; ++i )
548  v_[i] = Type();
549  }
550 }
551 //*************************************************************************************************
552 
553 
554 //*************************************************************************************************
566 template< typename Type // Data type of the vector
567  , size_t N // Number of elements
568  , bool TF > // Transpose flag
569 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2 )
570 {
571  BLAZE_STATIC_ASSERT( N == 2UL );
572  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
573 
574  v_[0] = v1;
575  v_[1] = v2;
576 
577  if( IsBuiltin<Type>::value ) {
578  for( size_t i=N; i<NN; ++i )
579  v_[i] = Type();
580  }
581 }
582 //*************************************************************************************************
583 
584 
585 //*************************************************************************************************
598 template< typename Type // Data type of the vector
599  , size_t N // Number of elements
600  , bool TF > // Transpose flag
601 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3 )
602 {
603  BLAZE_STATIC_ASSERT( N == 3UL );
604  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
605 
606  v_[0] = v1;
607  v_[1] = v2;
608  v_[2] = v3;
609 
610  if( IsBuiltin<Type>::value ) {
611  for( size_t i=N; i<NN; ++i )
612  v_[i] = Type();
613  }
614 }
615 //*************************************************************************************************
616 
617 
618 //*************************************************************************************************
632 template< typename Type // Data type of the vector
633  , size_t N // Number of elements
634  , bool TF > // Transpose flag
635 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2,
636  const Type& v3, const Type& v4 )
637 {
638  BLAZE_STATIC_ASSERT( N == 4UL );
639  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
640 
641  v_[0] = v1;
642  v_[1] = v2;
643  v_[2] = v3;
644  v_[3] = v4;
645 
646  if( IsBuiltin<Type>::value ) {
647  for( size_t i=N; i<NN; ++i )
648  v_[i] = Type();
649  }
650 }
651 //*************************************************************************************************
652 
653 
654 //*************************************************************************************************
669 template< typename Type // Data type of the vector
670  , size_t N // Number of elements
671  , bool TF > // Transpose flag
672 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3,
673  const Type& v4, const Type& v5 )
674 {
675  BLAZE_STATIC_ASSERT( N == 5UL );
676  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
677 
678  v_[0] = v1;
679  v_[1] = v2;
680  v_[2] = v3;
681  v_[3] = v4;
682  v_[4] = v5;
683 
684  if( IsBuiltin<Type>::value ) {
685  for( size_t i=N; i<NN; ++i )
686  v_[i] = Type();
687  }
688 }
689 //*************************************************************************************************
690 
691 
692 //*************************************************************************************************
708 template< typename Type // Data type of the vector
709  , size_t N // Number of elements
710  , bool TF > // Transpose flag
711 inline StaticVector<Type,N,TF>::StaticVector( const Type& v1, const Type& v2, const Type& v3,
712  const Type& v4, const Type& v5, const Type& v6 )
713 {
714  BLAZE_STATIC_ASSERT( N == 6UL );
715  BLAZE_INTERNAL_ASSERT( !( reinterpret_cast<size_t>( v_ ) % IT::alignment ), "Invalid alignment detected" );
716 
717  v_[0] = v1;
718  v_[1] = v2;
719  v_[2] = v3;
720  v_[3] = v4;
721  v_[4] = v5;
722  v_[5] = v6;
723 
724  if( IsBuiltin<Type>::value ) {
725  for( size_t i=N; i<NN; ++i )
726  v_[i] = Type();
727  }
728 }
729 //*************************************************************************************************
730 
731 
732 
733 
734 //=================================================================================================
735 //
736 // DATA ACCESS FUNCTIONS
737 //
738 //=================================================================================================
739 
740 //*************************************************************************************************
748 template< typename Type // Data type of the vector
749  , size_t N // Number of elements
750  , bool TF > // Transpose flag
753 {
754  BLAZE_USER_ASSERT( index < N, "Invalid vector access index" );
755  return v_[index];
756 }
757 //*************************************************************************************************
758 
759 
760 //*************************************************************************************************
768 template< typename Type // Data type of the vector
769  , size_t N // Number of elements
770  , bool TF > // Transpose flag
773 {
774  BLAZE_USER_ASSERT( index < N, "Invalid vector access index" );
775  return v_[index];
776 }
777 //*************************************************************************************************
778 
779 
780 //*************************************************************************************************
785 template< typename Type // Data type of the vector
786  , size_t N // Number of elements
787  , bool TF > // Transpose flag
789 {
790  return v_;
791 }
792 //*************************************************************************************************
793 
794 
795 //*************************************************************************************************
800 template< typename Type // Data type of the vector
801  , size_t N // Number of elements
802  , bool TF > // Transpose flag
803 inline const Type* StaticVector<Type,N,TF>::data() const
804 {
805  return v_;
806 }
807 //*************************************************************************************************
808 
809 
810 //*************************************************************************************************
815 template< typename Type // Data type of the vector
816  , size_t N // Number of elements
817  , bool TF > // Transpose flag
819 {
820  return v_;
821 }
822 //*************************************************************************************************
823 
824 
825 //*************************************************************************************************
830 template< typename Type // Data type of the vector
831  , size_t N // Number of elements
832  , bool TF > // Transpose flag
834 {
835  return v_;
836 }
837 //*************************************************************************************************
838 
839 
840 //*************************************************************************************************
845 template< typename Type // Data type of the vector
846  , size_t N // Number of elements
847  , bool TF > // Transpose flag
849 {
850  return v_;
851 }
852 //*************************************************************************************************
853 
854 
855 //*************************************************************************************************
860 template< typename Type // Data type of the vector
861  , size_t N // Number of elements
862  , bool TF > // Transpose flag
864 {
865  return v_ + N;
866 }
867 //*************************************************************************************************
868 
869 
870 //*************************************************************************************************
875 template< typename Type // Data type of the vector
876  , size_t N // Number of elements
877  , bool TF > // Transpose flag
879 {
880  return v_ + N;
881 }
882 //*************************************************************************************************
883 
884 
885 //*************************************************************************************************
890 template< typename Type // Data type of the vector
891  , size_t N // Number of elements
892  , bool TF > // Transpose flag
894 {
895  return v_ + N;
896 }
897 //*************************************************************************************************
898 
899 
900 
901 
902 //=================================================================================================
903 //
904 // ASSIGNMENT OPERATORS
905 //
906 //=================================================================================================
907 
908 //*************************************************************************************************
914 template< typename Type // Data type of the vector
915  , size_t N // Number of elements
916  , bool TF > // Transpose flag
918 {
919  for( size_t i=0UL; i<N; ++i )
920  v_[i] = rhs;
921  return *this;
922 }
923 //*************************************************************************************************
924 
925 
926 //*************************************************************************************************
934 template< typename Type // Data type of the vector
935  , size_t N // Number of elements
936  , bool TF > // Transpose flag
938 {
939  // This implementation was chosen for several reasons:
940  // - it works for all possible element types (even types that could not be copied by 'memcpy')
941  // - it is faster than the synthesized default copy assignment operator
942  // - it is faster than an implementation with the C library function 'memcpy' in combination
943  // with a protection against self-assignment
944  // - it goes without a protection against self-assignment
945  for( size_t i=0UL; i<N; ++i )
946  v_[i] = rhs.v_[i];
947  return *this;
948 }
949 //*************************************************************************************************
950 
951 
952 //*************************************************************************************************
958 template< typename Type // Data type of the vector
959  , size_t N // Number of elements
960  , bool TF > // Transpose flag
961 template< typename Other > // Data type of the foreign vector
963 {
964  // This implementation was chosen for several reasons:
965  // - it works for all possible element types (even types that could not be copied by 'memcpy')
966  // - it is faster than the synthesized default copy assignment operator
967  // - it is faster than an implementation with the C library function 'memcpy' in combination
968  // with a protection against self-assignment
969  // - it goes without a protection against self-assignment
970  for( size_t i=0UL; i<N; ++i )
971  v_[i] = rhs[i];
972  return *this;
973 }
974 //*************************************************************************************************
975 
976 
977 //*************************************************************************************************
987 template< typename Type // Data type of the vector
988  , size_t N // Number of elements
989  , bool TF > // Transpose flag
990 template< typename VT > // Type of the right-hand side vector
992 {
993  using blaze::assign;
994 
995  if( (~rhs).size() != N )
996  throw std::invalid_argument( "Invalid assignment to static vector" );
997 
998  if( (~rhs).canAlias( this ) ) {
999  StaticVector tmp( ~rhs );
1000  swap( tmp );
1001  }
1002  else {
1004  reset();
1005  assign( *this, ~rhs );
1006  }
1007 
1008  return *this;
1009 }
1010 //*************************************************************************************************
1011 
1012 
1013 //*************************************************************************************************
1029 template< typename Type // Data type of the vector
1030  , size_t N // Number of elements
1031  , bool TF > // Transpose flag
1032 template< typename Other > // Data type of the initialization array
1034 {
1035  for( size_t i=0UL; i<N; ++i )
1036  v_[i] = rhs[i];
1037  return *this;
1038 }
1039 //*************************************************************************************************
1040 
1041 
1042 //*************************************************************************************************
1052 template< typename Type // Data type of the vector
1053  , size_t N // Number of elements
1054  , bool TF > // Transpose flag
1055 template< typename VT > // Type of the right-hand side vector
1057 {
1058  using blaze::addAssign;
1059 
1060  if( (~rhs).size() != N )
1061  throw std::invalid_argument( "Vector sizes do not match" );
1062 
1063  if( (~rhs).canAlias( this ) ) {
1064  StaticVector tmp( ~rhs );
1065  addAssign( *this, tmp );
1066  }
1067  else {
1068  addAssign( *this, ~rhs );
1069  }
1070 
1071  return *this;
1072 }
1073 //*************************************************************************************************
1074 
1075 
1076 //*************************************************************************************************
1086 template< typename Type // Data type of the vector
1087  , size_t N // Number of elements
1088  , bool TF > // Transpose flag
1089 template< typename VT > // Type of the right-hand side vector
1091 {
1092  using blaze::subAssign;
1093 
1094  if( (~rhs).size() != N )
1095  throw std::invalid_argument( "Vector sizes do not match" );
1096 
1097  if( (~rhs).canAlias( this ) ) {
1098  StaticVector tmp( ~rhs );
1099  subAssign( *this, tmp );
1100  }
1101  else {
1102  subAssign( *this, ~rhs );
1103  }
1104 
1105  return *this;
1106 }
1107 //*************************************************************************************************
1108 
1109 
1110 //*************************************************************************************************
1121 template< typename Type // Data type of the vector
1122  , size_t N // Number of elements
1123  , bool TF > // Transpose flag
1124 template< typename VT > // Type of the right-hand side vector
1126 {
1127  using blaze::assign;
1128 
1129  if( (~rhs).size() != N )
1130  throw std::invalid_argument( "Vector sizes do not match" );
1131 
1132  if( (~rhs).canAlias( this ) || IsSparseVector<VT>::value ) {
1133  StaticVector tmp( *this * (~rhs) );
1134  this->operator=( tmp );
1135  }
1136  else {
1137  assign( *this, *this * (~rhs) );
1138  }
1139 
1140  return *this;
1141 }
1142 //*************************************************************************************************
1143 
1144 
1145 //*************************************************************************************************
1152 template< typename Type // Data type of the vector
1153  , size_t N // Number of elements
1154  , bool TF > // Transpose flag
1155 template< typename Other > // Data type of the right-hand side scalar
1156 inline typename EnableIf< IsNumeric<Other>, StaticVector<Type,N,TF> >::Type&
1158 {
1159  return operator=( (*this) * rhs );
1160 }
1161 //*************************************************************************************************
1162 
1163 
1164 //*************************************************************************************************
1173 template< typename Type // Data type of the vector
1174  , size_t N // Number of elements
1175  , bool TF > // Transpose flag
1176 template< typename Other > // Data type of the right-hand side scalar
1177 inline typename EnableIf< IsNumeric<Other>, StaticVector<Type,N,TF> >::Type&
1179 {
1180  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1181 
1182  return operator=( (*this) / rhs );
1183 }
1184 //*************************************************************************************************
1185 
1186 
1187 
1188 
1189 //=================================================================================================
1190 //
1191 // UTILITY FUNCTIONS
1192 //
1193 //=================================================================================================
1194 
1195 //*************************************************************************************************
1200 template< typename Type // Data type of the vector
1201  , size_t N // Number of elements
1202  , bool TF > // Transpose flag
1203 inline size_t StaticVector<Type,N,TF>::size() const
1204 {
1205  return N;
1206 }
1207 //*************************************************************************************************
1208 
1209 
1210 //*************************************************************************************************
1215 template< typename Type // Data type of the vector
1216  , size_t N // Number of elements
1217  , bool TF > // Transpose flag
1219 {
1220  return NN;
1221 }
1222 //*************************************************************************************************
1223 
1224 
1225 //*************************************************************************************************
1233 template< typename Type // Data type of the vector
1234  , size_t N // Number of elements
1235  , bool TF > // Transpose flag
1237 {
1238  size_t nonzeros( 0 );
1239 
1240  for( size_t i=0UL; i<N; ++i ) {
1241  if( !isDefault( v_[i] ) )
1242  ++nonzeros;
1243  }
1244 
1245  return nonzeros;
1246 }
1247 //*************************************************************************************************
1248 
1249 
1250 //*************************************************************************************************
1255 template< typename Type // Data type of the vector
1256  , size_t N // Number of elements
1257  , bool TF > // Transpose flag
1259 {
1260  using blaze::reset;
1261  for( size_t i=0UL; i<N; ++i )
1262  reset( v_[i] );
1263 }
1264 //*************************************************************************************************
1265 
1266 
1267 //*************************************************************************************************
1297 template< typename Type // Data type of the vector
1298  , size_t N // Number of elements
1299  , bool TF > // Transpose flag
1300 #ifndef WIN32
1302 #else
1304 #endif
1305 {
1307 
1308  LengthType sum( 0 );
1309  for( size_t i=0UL; i<N; ++i )
1310  sum += v_[i] * v_[i];
1311  return std::sqrt( sum );
1312 }
1313 //*************************************************************************************************
1314 
1315 
1316 //*************************************************************************************************
1326 template< typename Type // Data type of the vector
1327  , size_t N // Number of elements
1328  , bool TF > // Transpose flag
1330 {
1332 
1333  Type sum( 0 );
1334  for( size_t i=0UL; i<N; ++i )
1335  sum += v_[i] * v_[i];
1336  return sum;
1337 }
1338 //*************************************************************************************************
1339 
1340 
1341 //*************************************************************************************************
1350 template< typename Type // Data type of the vector
1351  , size_t N // Number of elements
1352  , bool TF > // Transpose flag
1354 {
1356 
1357  const Type len( length() );
1358 
1359  if( len == Type(0) )
1360  return *this;
1361 
1362  const Type ilen( Type(1) / len );
1363 
1364  for( size_t i=0UL; i<N; ++i )
1365  v_[i] *= ilen;
1366 
1367  return *this;
1368 }
1369 //*************************************************************************************************
1370 
1371 
1372 //*************************************************************************************************
1381 template< typename Type // Data type of the vector
1382  , size_t N // Number of elements
1383  , bool TF > // Transpose flag
1385 {
1387 
1388  const Type len( length() );
1389 
1390  if( len == Type(0) )
1391  return *this;
1392 
1393  const Type ilen( Type(1) / len );
1394  StaticVector tmp;
1395 
1396  for( size_t i=0UL; i<N; ++i )
1397  tmp[i] = v_[i] * ilen;
1398 
1399  return tmp;
1400 }
1401 //*************************************************************************************************
1402 
1403 
1404 //*************************************************************************************************
1410 template< typename Type // Data type of the vector
1411  , size_t N // Number of elements
1412  , bool TF > // Transpose flag
1413 template< typename Other > // Data type of the scalar value
1415 {
1416  for( size_t i=0; i<N; ++i )
1417  v_[i] *= scalar;
1418  return *this;
1419 }
1420 //*************************************************************************************************
1421 
1422 
1423 //*************************************************************************************************
1430 template< typename Type // Data type of the vector
1431  , size_t N // Number of elements
1432  , bool TF > // Transpose flag
1433 inline void StaticVector<Type,N,TF>::swap( StaticVector& v ) /* throw() */
1434 {
1435  using std::swap;
1436 
1437  for( size_t i=0UL; i<N; ++i )
1438  swap( v_[i], v.v_[i] );
1439 }
1440 //*************************************************************************************************
1441 
1442 
1443 
1444 
1445 //=================================================================================================
1446 //
1447 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1448 //
1449 //=================================================================================================
1450 
1451 //*************************************************************************************************
1461 template< typename Type // Data type of the vector
1462  , size_t N // Number of elements
1463  , bool TF > // Transpose flag
1464 template< typename Other > // Data type of the foreign expression
1465 inline bool StaticVector<Type,N,TF>::canAlias( const Other* alias ) const
1466 {
1467  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1468 }
1469 //*************************************************************************************************
1470 
1471 
1472 //*************************************************************************************************
1482 template< typename Type // Data type of the vector
1483  , size_t N // Number of elements
1484  , bool TF > // Transpose flag
1485 template< typename Other > // Data type of the foreign expression
1486 inline bool StaticVector<Type,N,TF>::isAliased( const Other* alias ) const
1487 {
1488  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1489 }
1490 //*************************************************************************************************
1491 
1492 
1493 //*************************************************************************************************
1504 template< typename Type // Data type of the vector
1505  , size_t N // Number of elements
1506  , bool TF > // Transpose flag
1508  StaticVector<Type,N,TF>::get( size_t index ) const
1509 {
1511 
1512  BLAZE_INTERNAL_ASSERT( index < N , "Invalid vector access index" );
1513  BLAZE_INTERNAL_ASSERT( index + IT::size <= NN , "Invalid vector access index" );
1514  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid vector access index" );
1515 
1516  return load( &v_[index] );
1517 }
1518 //*************************************************************************************************
1519 
1520 
1521 //*************************************************************************************************
1532 template< typename Type // Data type of the vector
1533  , size_t N // Number of elements
1534  , bool TF > // Transpose flag
1535 template< typename VT > // Type of the right-hand side dense vector
1536 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAssign<VT> >::Type
1538 {
1539  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1540 
1541  for( size_t i=0UL; i<N; ++i )
1542  v_[i] = (~rhs)[i];
1543 }
1544 //*************************************************************************************************
1545 
1546 
1547 //*************************************************************************************************
1558 template< typename Type // Data type of the vector
1559  , size_t N // Number of elements
1560  , bool TF > // Transpose flag
1561 template< typename VT > // Type of the right-hand side dense vector
1562 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAssign<VT> >::Type
1564 {
1565  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1566 
1568 
1569  for( size_t i=0UL; i<N; i+=IT::size ) {
1570  store( v_+i, (~rhs).get(i) );
1571  }
1572 }
1573 //*************************************************************************************************
1574 
1575 
1576 //*************************************************************************************************
1587 template< typename Type // Data type of the vector
1588  , size_t N // Number of elements
1589  , bool TF > // Transpose flag
1590 template< typename VT > // Type of the right-hand side sparse vector
1592 {
1593  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1594 
1595  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1596  v_[element->index()] = element->value();
1597 }
1598 //*************************************************************************************************
1599 
1600 
1601 //*************************************************************************************************
1612 template< typename Type // Data type of the vector
1613  , size_t N // Number of elements
1614  , bool TF > // Transpose flag
1615 template< typename VT > // Type of the right-hand side dense vector
1616 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >::Type
1618 {
1619  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1620 
1621  for( size_t i=0UL; i<N; ++i )
1622  v_[i] += (~rhs)[i];
1623 }
1624 //*************************************************************************************************
1625 
1626 
1627 //*************************************************************************************************
1638 template< typename Type // Data type of the vector
1639  , size_t N // Number of elements
1640  , bool TF > // Transpose flag
1641 template< typename VT > // Type of the right-hand side dense vector
1642 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >::Type
1644 {
1645  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1646 
1648 
1649  for( size_t i=0UL; i<N; i+=IT::size ) {
1650  store( v_+i, load( v_+i ) + (~rhs).get(i) );
1651  }
1652 }
1653 //*************************************************************************************************
1654 
1655 
1656 //*************************************************************************************************
1667 template< typename Type // Data type of the vector
1668  , size_t N // Number of elements
1669  , bool TF > // Transpose flag
1670 template< typename VT > // Type of the right-hand side sparse vector
1672 {
1673  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1674 
1675  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1676  v_[element->index()] += element->value();
1677 }
1678 //*************************************************************************************************
1679 
1680 
1681 //*************************************************************************************************
1692 template< typename Type // Data type of the vector
1693  , size_t N // Number of elements
1694  , bool TF > // Transpose flag
1695 template< typename VT > // Type of the right-hand side dense vector
1696 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >::Type
1698 {
1699  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1700 
1701  for( size_t i=0UL; i<N; ++i )
1702  v_[i] -= (~rhs)[i];
1703 }
1704 //*************************************************************************************************
1705 
1706 
1707 //*************************************************************************************************
1718 template< typename Type // Data type of the vector
1719  , size_t N // Number of elements
1720  , bool TF > // Transpose flag
1721 template< typename VT > // Type of the right-hand side dense vector
1722 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >::Type
1724 {
1725  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1726 
1728 
1729  for( size_t i=0UL; i<N; i+=IT::size ) {
1730  store( v_+i, load( v_+i ) - (~rhs).get(i) );
1731  }
1732 }
1733 //*************************************************************************************************
1734 
1735 
1736 //*************************************************************************************************
1747 template< typename Type // Data type of the vector
1748  , size_t N // Number of elements
1749  , bool TF > // Transpose flag
1750 template< typename VT > // Type of the right-hand side sparse vector
1752 {
1753  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1754 
1755  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1756  v_[element->index()] -= element->value();
1757 }
1758 //*************************************************************************************************
1759 
1760 
1761 //*************************************************************************************************
1772 template< typename Type // Data type of the vector
1773  , size_t N // Number of elements
1774  , bool TF > // Transpose flag
1775 template< typename VT > // Type of the right-hand side dense vector
1776 inline typename DisableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >::Type
1778 {
1779  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1780 
1781  for( size_t i=0UL; i<N; ++i )
1782  v_[i] *= (~rhs)[i];
1783 }
1784 //*************************************************************************************************
1785 
1786 
1787 //*************************************************************************************************
1798 template< typename Type // Data type of the vector
1799  , size_t N // Number of elements
1800  , bool TF > // Transpose flag
1801 template< typename VT > // Type of the right-hand side dense vector
1802 inline typename EnableIf< typename StaticVector<Type,N,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >::Type
1804 {
1805  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1806 
1808 
1809  for( size_t i=0UL; i<N; i+=IT::size ) {
1810  store( v_+i, load( v_+i ) * (~rhs).get(i) );
1811  }
1812 }
1813 //*************************************************************************************************
1814 
1815 
1816 //*************************************************************************************************
1827 template< typename Type // Data type of the vector
1828  , size_t N // Number of elements
1829  , bool TF > // Transpose flag
1830 template< typename VT > // Type of the right-hand side sparse vector
1832 {
1833  BLAZE_INTERNAL_ASSERT( (~rhs).size() == N, "Invalid vector sizes" );
1834 
1835  const StaticVector tmp( *this );
1836 
1837  reset();
1838 
1839  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1840  v_[element->index()] = tmp[element->index()] * element->value();
1841 }
1842 //*************************************************************************************************
1843 
1844 
1845 
1846 
1847 
1848 
1849 
1850 
1851 //=================================================================================================
1852 //
1853 // UNDEFINED CLASS TEMPLATE SPECIALIZATION
1854 //
1855 //=================================================================================================
1856 
1857 //*************************************************************************************************
1865 template< typename Type // Data type of the vector
1866  , bool TF > // Transpose flag
1867 class StaticVector<Type,0UL,TF>;
1869 //*************************************************************************************************
1870 
1871 
1872 
1873 
1874 
1875 
1876 
1877 
1878 //=================================================================================================
1879 //
1880 // STATICVECTOR OPERATORS
1881 //
1882 //=================================================================================================
1883 
1884 //*************************************************************************************************
1887 template< typename Type, size_t N, bool TF >
1888 inline bool isnan( const StaticVector<Type,N,TF>& v );
1889 
1890 template< typename Type, size_t N, bool TF >
1891 inline void reset( StaticVector<Type,N,TF>& v );
1892 
1893 template< typename Type, size_t N, bool TF >
1894 inline void clear( StaticVector<Type,N,TF>& v );
1895 
1896 template< typename Type, size_t N, bool TF >
1897 inline bool isDefault( const StaticVector<Type,N,TF>& v );
1898 
1899 template< typename Type, bool TF >
1901 
1902 template< typename Type, bool TF >
1904 
1905 template< typename Type, size_t N, bool TF >
1906 inline void swap( StaticVector<Type,N,TF>& a, StaticVector<Type,N,TF>& b ) /* throw() */;
1908 //*************************************************************************************************
1909 
1910 
1911 //*************************************************************************************************
1928 template< typename Type // Data type of the vector
1929  , size_t N // Number of elements
1930  , bool TF > // Transpose flag
1931 inline bool isnan( const StaticVector<Type,N,TF>& v )
1932 {
1933  for( size_t i=0UL; i<N; ++i ) {
1934  if( isnan( v[i] ) ) return true;
1935  }
1936  return false;
1937 }
1938 //*************************************************************************************************
1939 
1940 
1941 //*************************************************************************************************
1948 template< typename Type // Data type of the vector
1949  , size_t N // Number of elements
1950  , bool TF > // Transpose flag
1952 {
1953  v.reset();
1954 }
1955 //*************************************************************************************************
1956 
1957 
1958 //*************************************************************************************************
1967 template< typename Type // Data type of the vector
1968  , size_t N // Number of elements
1969  , bool TF > // Transpose flag
1971 {
1972  v.reset();
1973 }
1974 //*************************************************************************************************
1975 
1976 
1977 //*************************************************************************************************
1995 template< typename Type // Data type of the vector
1996  , size_t N // Number of elements
1997  , bool TF > // Transpose flag
1998 inline bool isDefault( const StaticVector<Type,N,TF>& v )
1999 {
2000  for( size_t i=0UL; i<N; ++i )
2001  if( !isDefault( v[i] ) ) return false;
2002  return true;
2003 }
2004 //*************************************************************************************************
2005 
2006 
2007 //*************************************************************************************************
2018 template< typename Type // Data type of the vector
2019  , bool TF > // Transpose flag
2021 {
2022  return StaticVector<Type,2UL,TF>( -v[1UL], v[0UL] );
2023 }
2024 //*************************************************************************************************
2025 
2026 
2027 //*************************************************************************************************
2035 template< typename Type // Data type of the vector
2036  , bool TF > // Transpose flag
2038 {
2039  if( v[0] != Type() || v[1] != Type() )
2040  return StaticVector<Type,3UL,TF>( v[1UL], -v[0UL], Type() );
2041  else
2042  return StaticVector<Type,3UL,TF>( Type(), v[2UL], -v[1UL] );
2043 }
2044 //*************************************************************************************************
2045 
2046 
2047 //*************************************************************************************************
2056 template< typename Type // Data type of the vector
2057  , size_t N // Number of elements
2058  , bool TF > // Transpose flag
2059 inline void swap( StaticVector<Type,N,TF>& a, StaticVector<Type,N,TF>& b ) /* throw() */
2060 {
2061  a.swap( b );
2062 }
2063 //*************************************************************************************************
2064 
2065 
2066 
2067 
2068 //=================================================================================================
2069 //
2070 // ADDTRAIT SPECIALIZATIONS
2071 //
2072 //=================================================================================================
2073 
2074 //*************************************************************************************************
2076 template< typename T1, size_t N, bool TF, typename T2 >
2077 struct AddTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2078 {
2079  typedef StaticVector< typename AddTrait<T1,T2>::Type, N, TF > Type;
2080 };
2082 //*************************************************************************************************
2083 
2084 
2085 
2086 
2087 //=================================================================================================
2088 //
2089 // SUBTRAIT SPECIALIZATIONS
2090 //
2091 //=================================================================================================
2092 
2093 //*************************************************************************************************
2095 template< typename T1, size_t N, bool TF, typename T2 >
2096 struct SubTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2097 {
2098  typedef StaticVector< typename SubTrait<T1,T2>::Type, N, TF > Type;
2099 };
2101 //*************************************************************************************************
2102 
2103 
2104 
2105 
2106 //=================================================================================================
2107 //
2108 // MULTTRAIT SPECIALIZATIONS
2109 //
2110 //=================================================================================================
2111 
2112 //*************************************************************************************************
2114 template< typename T1, size_t N, bool TF, typename T2 >
2115 struct MultTrait< StaticVector<T1,N,TF>, T2 >
2116 {
2117  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
2119 };
2120 
2121 template< typename T1, typename T2, size_t N, bool TF >
2122 struct MultTrait< T1, StaticVector<T2,N,TF> >
2123 {
2124  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
2126 };
2127 
2128 template< typename T1, size_t N, bool TF, typename T2 >
2129 struct MultTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2130 {
2131  typedef StaticVector< typename MultTrait<T1,T2>::Type, N, TF > Type;
2132 };
2133 
2134 template< typename T1, size_t M, typename T2, size_t N >
2135 struct MultTrait< StaticVector<T1,M,false>, StaticVector<T2,N,true> >
2136 {
2137  typedef StaticMatrix< typename MultTrait<T1,T2>::Type, M, N, false > Type;
2138 };
2139 
2140 template< typename T1, size_t N, typename T2 >
2141 struct MultTrait< StaticVector<T1,N,true>, StaticVector<T2,N,false> >
2142 {
2143  typedef typename MultTrait<T1,T2>::Type Type;
2144 };
2146 //*************************************************************************************************
2147 
2148 
2149 
2150 
2151 //=================================================================================================
2152 //
2153 // CROSSTRAIT SPECIALIZATIONS
2154 //
2155 //=================================================================================================
2156 
2157 //*************************************************************************************************
2159 template< typename T1, typename T2 >
2160 struct CrossTrait< StaticVector<T1,3UL,false>, StaticVector<T2,3UL,false> >
2161 {
2162  private:
2163  typedef typename MultTrait<T1,T2>::Type T;
2164 
2165  public:
2166  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
2167 };
2169 //*************************************************************************************************
2170 
2171 
2172 
2173 
2174 //=================================================================================================
2175 //
2176 // DIVTRAIT SPECIALIZATIONS
2177 //
2178 //=================================================================================================
2179 
2180 //*************************************************************************************************
2182 template< typename T1, size_t N, bool TF, typename T2 >
2183 struct DivTrait< StaticVector<T1,N,TF>, T2 >
2184 {
2185  typedef StaticVector< typename DivTrait<T1,T2>::Type, N, TF > Type;
2187 };
2189 //*************************************************************************************************
2190 
2191 
2192 
2193 
2194 //=================================================================================================
2195 //
2196 // MATHTRAIT SPECIALIZATIONS
2197 //
2198 //=================================================================================================
2199 
2200 //*************************************************************************************************
2202 template< typename T1, size_t N, bool TF, typename T2 >
2203 struct MathTrait< StaticVector<T1,N,TF>, StaticVector<T2,N,TF> >
2204 {
2205  typedef StaticVector< typename MathTrait<T1,T2>::HighType, N, TF > HighType;
2206  typedef StaticVector< typename MathTrait<T1,T2>::LowType , N, TF > LowType;
2207 };
2209 //*************************************************************************************************
2210 
2211 } // namespace blaze
2212 
2213 #endif