All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSVecDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSVECDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSVECDMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
53 #include <blaze/math/Intrinsics.h>
54 #include <blaze/math/shims/Reset.h>
66 #include <blaze/util/Assert.h>
68 #include <blaze/util/DisableIf.h>
69 #include <blaze/util/EnableIf.h>
71 #include <blaze/util/SelectType.h>
72 #include <blaze/util/Types.h>
75 
76 
77 namespace blaze {
78 
79 //=================================================================================================
80 //
81 // CLASS TSVECDMATMULTEXPR
82 //
83 //=================================================================================================
84 
85 //*************************************************************************************************
92 template< typename VT // Type of the left-hand side sparse vector
93  , typename MT > // Type of the right-hand side dense matrix
94 class TSVecDMatMultExpr : public DenseVector< TSVecDMatMultExpr<VT,MT>, true >
95  , private TVecMatMultExpr
96  , private Computation
97 {
98  private:
99  //**Type definitions****************************************************************************
100  typedef typename VT::ResultType VRT;
101  typedef typename MT::ResultType MRT;
102  typedef typename VRT::ElementType VET;
103  typedef typename MRT::ElementType MET;
104  typedef typename VT::CompositeType VCT;
105  typedef typename MT::CompositeType MCT;
106  //**********************************************************************************************
107 
108  //**********************************************************************************************
110  enum { evaluateVector = IsComputation<VT>::value || RequiresEvaluation<VT>::value };
111  //**********************************************************************************************
112 
113  //**********************************************************************************************
115  enum { evaluateMatrix = ( IsComputation<MT>::value && IsSame<MET,VET>::value &&
117  //**********************************************************************************************
118 
119  //**********************************************************************************************
121 
125  template< typename T1 >
126  struct UseSMPAssign {
127  enum { value = ( evaluateVector || evaluateMatrix ) };
128  };
130  //**********************************************************************************************
131 
132  //**********************************************************************************************
134 
138  template< typename T1, typename T2, typename T3 >
139  struct UseVectorizedKernel {
140  enum { value = T1::vectorizable && T3::vectorizable &&
141  IsSame<typename T1::ElementType,typename T2::ElementType>::value &&
142  IsSame<typename T1::ElementType,typename T3::ElementType>::value &&
143  IntrinsicTrait<typename T1::ElementType>::addition &&
144  IntrinsicTrait<typename T1::ElementType>::multiplication };
145  };
147  //**********************************************************************************************
148 
149  //**********************************************************************************************
151 
155  template< typename T1, typename T2, typename T3 >
156  struct UseOptimizedKernel {
157  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
158  !IsResizable<typename T1::ElementType>::value &&
159  !IsResizable<VET>::value };
160  };
162  //**********************************************************************************************
163 
164  //**********************************************************************************************
166 
169  template< typename T1, typename T2, typename T3 >
170  struct UseDefaultKernel {
171  enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
172  !UseOptimizedKernel<T1,T2,T3>::value };
173  };
175  //**********************************************************************************************
176 
177  public:
178  //**Type definitions****************************************************************************
184  typedef const ElementType ReturnType;
185  typedef const ResultType CompositeType;
186 
188  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
189 
191  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type RightOperand;
192 
195 
198  //**********************************************************************************************
199 
200  //**Compilation flags***************************************************************************
202  enum { vectorizable = MT::vectorizable &&
206 
208  enum { smpAssignable = !evaluateVector && VT::smpAssignable &&
209  !evaluateMatrix && MT::smpAssignable };
210  //**********************************************************************************************
211 
212  //**Constructor*********************************************************************************
218  explicit inline TSVecDMatMultExpr( const VT& vec, const MT& mat )
219  : vec_( vec ) // Left-hand side sparse vector of the multiplication expression
220  , mat_( mat ) // Right-hand side dense matrix of the multiplication expression
221  {
222  BLAZE_INTERNAL_ASSERT( vec_.size() == mat_.rows(), "Invalid vector and matrix sizes" );
223  }
224  //**********************************************************************************************
225 
226  //**Subscript operator**************************************************************************
232  inline ReturnType operator[]( size_t index ) const {
233  BLAZE_INTERNAL_ASSERT( index < mat_.columns(), "Invalid vector access index" );
234 
236 
237  LT x( vec_ ); // Evaluation of the left-hand side sparse vector operand
238 
239  BLAZE_INTERNAL_ASSERT( x.size() == vec_.size(), "Invalid vector size" );
240 
241  const ConstIterator end( x.end() );
242  ConstIterator element( x.begin() );
243  ElementType res;
244 
245  if( element != end ) {
246  res = element->value() * mat_( element->index(), index );
247  ++element;
248  for( ; element!=end; ++element )
249  res += element->value() * mat_( element->index(), index );
250  }
251  else {
252  reset( res );
253  }
254 
255  return res;
256  }
257  //**********************************************************************************************
258 
259  //**Size function*******************************************************************************
264  inline size_t size() const {
265  return mat_.columns();
266  }
267  //**********************************************************************************************
268 
269  //**Left operand access*************************************************************************
274  inline LeftOperand leftOperand() const {
275  return vec_;
276  }
277  //**********************************************************************************************
278 
279  //**Right operand access************************************************************************
284  inline RightOperand rightOperand() const {
285  return mat_;
286  }
287  //**********************************************************************************************
288 
289  //**********************************************************************************************
295  template< typename T >
296  inline bool canAlias( const T* alias ) const {
297  return vec_.isAliased( alias ) || mat_.isAliased( alias );
298  }
299  //**********************************************************************************************
300 
301  //**********************************************************************************************
307  template< typename T >
308  inline bool isAliased( const T* alias ) const {
309  return vec_.isAliased( alias ) || mat_.isAliased( alias );
310  }
311  //**********************************************************************************************
312 
313  //**********************************************************************************************
318  inline bool isAligned() const {
319  return mat_.isAligned();
320  }
321  //**********************************************************************************************
322 
323  //**********************************************************************************************
328  inline bool canSMPAssign() const {
329  return ( size() > SMP_TSVECDMATMULT_THRESHOLD );
330  }
331  //**********************************************************************************************
332 
333  private:
334  //**Member variables****************************************************************************
337  //**********************************************************************************************
338 
339  //**Assignment to dense vectors*****************************************************************
352  template< typename VT2 > // Type of the target dense vector
353  friend inline void assign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
354  {
356 
357  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
358 
359  // Evaluation of the left-hand side sparse vector operand
360  LT x( serial( rhs.vec_ ) );
361  if( x.nonZeros() == 0UL ) {
362  reset( ~lhs );
363  return;
364  }
365 
366  // Evaluation of the right-hand side dense matrix operand
367  RT A( serial( rhs.mat_ ) );
368 
369  // Checking the evaluated operands
370  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
371  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
372  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
373  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
374 
375  // Performing the sparse vector-dense matrix multiplication
376  TSVecDMatMultExpr::selectAssignKernel( ~lhs, x, A );
377  }
379  //**********************************************************************************************
380 
381  //**Default assignment to dense vectors*********************************************************
395  template< typename VT1 // Type of the left-hand side target vector
396  , typename VT2 // Type of the left-hand side vector operand
397  , typename MT1 > // Type of the right-hand side matrix operand
398  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
399  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
400  {
402 
403  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
404 
405  const size_t N( A.columns() );
406 
407  ConstIterator element( x.begin() );
408  const ConstIterator end( x.end() );
409 
410  for( size_t j=0UL; j<N; ++j ) {
411  y[j] = element->value() * A(element->index(),j);
412  }
413 
414  ++element;
415 
416  for( ; element!=end; ++element ) {
417  for( size_t j=0UL; j<N; ++j ) {
418  y[j] += element->value() * A(element->index(),j);
419  }
420  }
421  }
423  //**********************************************************************************************
424 
425  //**Optimized assignment to dense vectors*******************************************************
439  template< typename VT1 // Type of the left-hand side target vector
440  , typename VT2 // Type of the left-hand side vector operand
441  , typename MT1 > // Type of the right-hand side matrix operand
442  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
443  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
444  {
446 
447  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
448 
449  const size_t N( A.columns() );
450 
451  ConstIterator element( x.begin() );
452  const ConstIterator end( x.end() );
453 
454  const size_t iend( x.nonZeros() & size_t(-4) );
455  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
456 
457  if( iend > 3UL )
458  {
459  const size_t i1( element->index() );
460  const VET v1( element->value() );
461  ++element;
462  const size_t i2( element->index() );
463  const VET v2( element->value() );
464  ++element;
465  const size_t i3( element->index() );
466  const VET v3( element->value() );
467  ++element;
468  const size_t i4( element->index() );
469  const VET v4( element->value() );
470  ++element;
471 
472  for( size_t j=0UL; j<N; ++j ) {
473  y[j] = v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
474  }
475  }
476  else
477  {
478  const size_t i1( element->index() );
479  const VET v1( element->value() );
480  ++element;
481 
482  for( size_t j=0UL; j<N; ++j ) {
483  y[j] = v1 * A(i1,j);
484  }
485  }
486 
487  for( size_t i=(iend>3UL)?(4UL):(1UL); (i+4UL)<=iend; i+=4UL )
488  {
489  const size_t i1( element->index() );
490  const VET v1( element->value() );
491  ++element;
492  const size_t i2( element->index() );
493  const VET v2( element->value() );
494  ++element;
495  const size_t i3( element->index() );
496  const VET v3( element->value() );
497  ++element;
498  const size_t i4( element->index() );
499  const VET v4( element->value() );
500  ++element;
501 
502  for( size_t j=0UL; j<N; ++j ) {
503  y[j] += v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
504  }
505  }
506  for( ; element!=end; ++element )
507  {
508  const size_t i1( element->index() );
509  const VET v1( element->value() );
510 
511  for( size_t j=0UL; j<N; ++j ) {
512  y[j] += v1 * A(i1,j);
513  }
514  }
515  }
517  //**********************************************************************************************
518 
519  //**Vectorized assignment to dense vectors******************************************************
533  template< typename VT1 // Type of the left-hand side target vector
534  , typename VT2 // Type of the left-hand side vector operand
535  , typename MT1 > // Type of the right-hand side matrix operand
536  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
537  selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
538  {
539  typedef IntrinsicTrait<ElementType> IT;
541 
542  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
543 
544  const size_t N( A.columns() );
545 
546  ConstIterator element( x.begin() );
547  const ConstIterator end( x.end() );
548 
549  const size_t iend( x.nonZeros() & size_t(-4) );
550  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
551 
552  if( iend > 3UL )
553  {
554  const size_t i1( element->index() );
555  const IntrinsicType v1( set( element->value() ) );
556  ++element;
557  const size_t i2( element->index() );
558  const IntrinsicType v2( set( element->value() ) );
559  ++element;
560  const size_t i3( element->index() );
561  const IntrinsicType v3( set( element->value() ) );
562  ++element;
563  const size_t i4( element->index() );
564  const IntrinsicType v4( set( element->value() ) );
565  ++element;
566 
567  for( size_t j=0UL; j<N; j+=IT::size ) {
568  y.store( j, v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
569  }
570  }
571  else
572  {
573  const size_t i1( element->index() );
574  const IntrinsicType v1( set( element->value() ) );
575  ++element;
576 
577  for( size_t j=0UL; j<N; j+=IT::size ) {
578  y.store( j, v1 * A.load(i1,j) );
579  }
580  }
581 
582  for( size_t i=(iend>3UL)?(4UL):(1UL); (i+4UL)<=iend; i+=4UL )
583  {
584  const size_t i1( element->index() );
585  const IntrinsicType v1( set( element->value() ) );
586  ++element;
587  const size_t i2( element->index() );
588  const IntrinsicType v2( set( element->value() ) );
589  ++element;
590  const size_t i3( element->index() );
591  const IntrinsicType v3( set( element->value() ) );
592  ++element;
593  const size_t i4( element->index() );
594  const IntrinsicType v4( set( element->value() ) );
595  ++element;
596 
597  for( size_t j=0UL; j<N; j+=IT::size ) {
598  y.store( j, y.load(j) + v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
599  }
600  }
601  for( ; element!=end; ++element )
602  {
603  const size_t i1( element->index() );
604  const IntrinsicType v1( set( element->value() ) );
605 
606  for( size_t j=0UL; j<N; j+=IT::size ) {
607  y.store( j, y.load(j) + v1 * A.load(i1,j) );
608  }
609  }
610  }
612  //**********************************************************************************************
613 
614  //**Assignment to sparse vectors****************************************************************
627  template< typename VT2 > // Type of the target sparse vector
628  friend inline void assign( SparseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
629  {
631 
635 
636  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
637 
638  const ResultType tmp( serial( rhs ) );
639  assign( ~lhs, tmp );
640  }
642  //**********************************************************************************************
643 
644  //**Addition assignment to dense vectors********************************************************
656  template< typename VT2 > // Type of the target dense vector
657  friend inline void addAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
658  {
660 
661  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
662 
663  // Evaluation of the left-hand side sparse vector operand
664  LT x( serial( rhs.vec_ ) );
665  if( x.nonZeros() == 0UL ) return;
666 
667  // Evaluation of the right-hand side dense matrix operand
668  RT A( serial( rhs.mat_ ) );
669 
670  // Checking the evaluated operands
671  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
672  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
673  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
674  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
675 
676  // Performing the sparse vector-dense matrix multiplication
677  TSVecDMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
678  }
679  //**********************************************************************************************
680 
681  //**Default addition assignment to dense vectors************************************************
695  template< typename VT1 // Type of the left-hand side target vector
696  , typename VT2 // Type of the left-hand side vector operand
697  , typename MT1 > // Type of the right-hand side matrix operand
698  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
699  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
700  {
702 
703  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
704 
705  const size_t N( A.columns() );
706 
707  ConstIterator element( x.begin() );
708  const ConstIterator end( x.end() );
709 
710  for( ; element!=end; ++element ) {
711  for( size_t j=0UL; j<N; ++j ) {
712  y[j] += element->value() * A(element->index(),j);
713  }
714  }
715  }
717  //**********************************************************************************************
718 
719  //**Optimized addition assignment to dense vectors**********************************************
733  template< typename VT1 // Type of the left-hand side target vector
734  , typename VT2 // Type of the left-hand side vector operand
735  , typename MT1 > // Type of the right-hand side matrix operand
736  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
737  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
738  {
740 
741  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
742 
743  const size_t N( A.columns() );
744 
745  ConstIterator element( x.begin() );
746  const ConstIterator end( x.end() );
747 
748  const size_t iend( x.nonZeros() & size_t(-4) );
749  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
750 
751  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
752  {
753  const size_t i1( element->index() );
754  const VET v1( element->value() );
755  ++element;
756  const size_t i2( element->index() );
757  const VET v2( element->value() );
758  ++element;
759  const size_t i3( element->index() );
760  const VET v3( element->value() );
761  ++element;
762  const size_t i4( element->index() );
763  const VET v4( element->value() );
764  ++element;
765 
766  for( size_t j=0UL; j<N; ++j ) {
767  y[j] += v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
768  }
769  }
770  for( ; element!=end; ++element )
771  {
772  const size_t i1( element->index() );
773  const VET v1( element->value() );
774 
775  for( size_t j=0UL; j<N; ++j ) {
776  y[j] += v1 * A(i1,j);
777  }
778  }
779  }
781  //**********************************************************************************************
782 
783  //**Vectorized addition assignment to dense vectors*********************************************
797  template< typename VT1 // Type of the left-hand side target vector
798  , typename VT2 // Type of the left-hand side vector operand
799  , typename MT1 > // Type of the right-hand side matrix operand
800  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
801  selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
802  {
803  typedef IntrinsicTrait<ElementType> IT;
805 
806  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
807 
808  const size_t N( A.columns() );
809 
810  ConstIterator element( x.begin() );
811  const ConstIterator end( x.end() );
812 
813  const size_t iend( x.nonZeros() & size_t(-4) );
814  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
815 
816  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
817  {
818  const size_t i1( element->index() );
819  const IntrinsicType v1( set( element->value() ) );
820  ++element;
821  const size_t i2( element->index() );
822  const IntrinsicType v2( set( element->value() ) );
823  ++element;
824  const size_t i3( element->index() );
825  const IntrinsicType v3( set( element->value() ) );
826  ++element;
827  const size_t i4( element->index() );
828  const IntrinsicType v4( set( element->value() ) );
829  ++element;
830 
831  for( size_t j=0UL; j<N; j+=IT::size ) {
832  y.store( j, y.load(j) + v1 * A.load(i1,j) + v2 * A.load(i2,j) + v3 * A.load(i3,j) + v4 * A.load(i4,j) );
833  }
834  }
835  for( ; element!=end; ++element )
836  {
837  const size_t i1( element->index() );
838  const IntrinsicType v1( set( element->value() ) );
839 
840  for( size_t j=0UL; j<N; j+=IT::size ) {
841  y.store( j, y.load(j) + v1 * A.load(i1,j) );
842  }
843  }
844  }
846  //**********************************************************************************************
847 
848  //**Addition assignment to sparse vectors*******************************************************
849  // No special implementation for the addition assignment to sparse vectors.
850  //**********************************************************************************************
851 
852  //**Subtraction assignment to dense vectors*****************************************************
864  template< typename VT2 > // Type of the target dense vector
865  friend inline void subAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
866  {
868 
869  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
870 
872 
873  // Evaluation of the left-hand side sparse vector operand
874  LT x( serial( rhs.vec_ ) );
875  if( x.nonZeros() == 0UL ) return;
876 
877  // Evaluation of the right-hand side dense matrix operand
878  RT A( serial( rhs.mat_ ) );
879 
880  // Checking the evaluated operands
881  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
882  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
883  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
884  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
885 
886  // Performing the sparse vector-dense matrix multiplication
887  TSVecDMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
888  }
889  //**********************************************************************************************
890 
891  //**Default subtraction assignment to dense vectors*********************************************
905  template< typename VT1 // Type of the left-hand side target vector
906  , typename VT2 // Type of the left-hand side vector operand
907  , typename MT1 > // Type of the right-hand side matrix operand
908  static inline typename EnableIf< UseDefaultKernel<VT1,VT2,MT1> >::Type
909  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
910  {
912 
913  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
914 
915  const size_t N( A.columns() );
916 
917  ConstIterator element( x.begin() );
918  const ConstIterator end( x.end() );
919 
920  for( ; element!=end; ++element ) {
921  for( size_t j=0UL; j<N; ++j ) {
922  y[j] -= element->value() * A(element->index(),j);
923  }
924  }
925  }
927  //**********************************************************************************************
928 
929  //**Optimized subtraction assignment to dense vectors*******************************************
943  template< typename VT1 // Type of the left-hand side target vector
944  , typename VT2 // Type of the left-hand side vector operand
945  , typename MT1 > // Type of the right-hand side matrix operand
946  static inline typename EnableIf< UseOptimizedKernel<VT1,VT2,MT1> >::Type
947  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
948  {
950 
951  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
952 
953  const size_t N( A.columns() );
954 
955  ConstIterator element( x.begin() );
956  const ConstIterator end( x.end() );
957 
958  const size_t iend( x.nonZeros() & size_t(-4) );
959  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
960 
961  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
962  {
963  const size_t i1( element->index() );
964  const VET v1( element->value() );
965  ++element;
966  const size_t i2( element->index() );
967  const VET v2( element->value() );
968  ++element;
969  const size_t i3( element->index() );
970  const VET v3( element->value() );
971  ++element;
972  const size_t i4( element->index() );
973  const VET v4( element->value() );
974  ++element;
975 
976  for( size_t j=0UL; j<N; ++j ) {
977  y[j] -= v1 * A(i1,j) + v2 * A(i2,j) + v3 * A(i3,j) + v4 * A(i4,j);
978  }
979  }
980  for( ; element!=end; ++element )
981  {
982  const size_t i1( element->index() );
983  const VET v1( element->value() );
984 
985  for( size_t j=0UL; j<N; ++j ) {
986  y[j] -= v1 * A(i1,j);
987  }
988  }
989  }
991  //**********************************************************************************************
992 
993  //**Vectorized subtraction assignment to dense vectors******************************************
1007  template< typename VT1 // Type of the left-hand side target vector
1008  , typename VT2 // Type of the left-hand side vector operand
1009  , typename MT1 > // Type of the right-hand side matrix operand
1010  static inline typename EnableIf< UseVectorizedKernel<VT1,VT2,MT1> >::Type
1011  selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
1012  {
1013  typedef IntrinsicTrait<ElementType> IT;
1015 
1016  BLAZE_INTERNAL_ASSERT( x.nonZeros() != 0UL, "Invalid number of non-zero elements" );
1017 
1018  const size_t N( A.columns() );
1019 
1020  ConstIterator element( x.begin() );
1021  const ConstIterator end( x.end() );
1022 
1023  const size_t iend( x.nonZeros() & size_t(-4) );
1024  BLAZE_INTERNAL_ASSERT( ( x.nonZeros() - ( x.nonZeros() % 4UL ) ) == iend, "Invalid end calculation" );
1025 
1026  for( size_t i=0UL; (i+4UL)<=iend; i+=4UL )
1027  {
1028  const size_t i1( element->index() );
1029  const IntrinsicType v1( set( element->value() ) );
1030  ++element;
1031  const size_t i2( element->index() );
1032  const IntrinsicType v2( set( element->value() ) );
1033  ++element;
1034  const size_t i3( element->index() );
1035  const IntrinsicType v3( set( element->value() ) );
1036  ++element;
1037  const size_t i4( element->index() );
1038  const IntrinsicType v4( set( element->value() ) );
1039  ++element;
1040 
1041  for( size_t j=0UL; j<N; j+=IT::size ) {
1042  y.store( j, y.load(j) - v1 * A.load(i1,j) - v2 * A.load(i2,j) - v3 * A.load(i3,j) - v4 * A.load(i4,j) );
1043  }
1044  }
1045  for( ; element!=x.end(); ++element )
1046  {
1047  const size_t i1( element->index() );
1048  const IntrinsicType v1( set( element->value() ) );
1049 
1050  for( size_t j=0UL; j<N; j+=IT::size ) {
1051  y.store( j, y.load(j) - v1 * A.load(i1,j) );
1052  }
1053  }
1054  }
1056  //**********************************************************************************************
1057 
1058  //**Subtraction assignment to sparse vectors****************************************************
1059  // No special implementation for the subtraction assignment to sparse vectors.
1060  //**********************************************************************************************
1061 
1062  //**Multiplication assignment to dense vectors**************************************************
1074  template< typename VT2 > // Type of the target dense vector
1075  friend inline void multAssign( DenseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
1076  {
1078 
1082 
1083  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1084 
1085  const ResultType tmp( serial( rhs ) );
1086  multAssign( ~lhs, tmp );
1087  }
1088  //**********************************************************************************************
1089 
1090  //**Multiplication assignment to sparse vectors*************************************************
1091  // No special implementation for the multiplication assignment to sparse vectors.
1092  //**********************************************************************************************
1093 
1094  //**SMP assignment to dense vectors*************************************************************
1109  template< typename VT2 > // Type of the target dense vector
1110  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1112  {
1114 
1115  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1116 
1117  // Evaluation of the left-hand side sparse vector operand
1118  LT x( rhs.vec_ );
1119  if( x.nonZeros() == 0UL ) {
1120  reset( ~lhs );
1121  return;
1122  }
1123 
1124  // Evaluation of the right-hand side dense matrix operand
1125  RT A( rhs.mat_ );
1126 
1127  // Checking the evaluated operands
1128  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1129  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1130  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1131  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
1132 
1133  // Performing the sparse vector-dense matrix multiplication
1134  smpAssign( ~lhs, x * A );
1135  }
1137  //**********************************************************************************************
1138 
1139  //**SMP assignment to sparse vectors************************************************************
1154  template< typename VT2 > // Type of the target sparse vector
1155  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1156  smpAssign( SparseVector<VT2,true>& lhs, const TSVecDMatMultExpr& rhs )
1157  {
1159 
1163 
1164  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1165 
1166  const ResultType tmp( rhs );
1167  smpAssign( ~lhs, tmp );
1168  }
1170  //**********************************************************************************************
1171 
1172  //**SMP addition assignment to dense vectors****************************************************
1186  template< typename VT2 > // Type of the target dense vector
1187  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1189  {
1191 
1192  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1193 
1194  // Evaluation of the left-hand side sparse vector operand
1195  LT x( rhs.vec_ );
1196  if( x.nonZeros() == 0UL ) return;
1197 
1198  // Evaluation of the right-hand side dense matrix operand
1199  RT A( rhs.mat_ );
1200 
1201  // Checking the evaluated operands
1202  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1203  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1204  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1205  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
1206 
1207  // Performing the sparse vector-dense matrix multiplication
1208  smpAddAssign( ~lhs, x * A );
1209  }
1210  //**********************************************************************************************
1211 
1212  //**SMP addition assignment to sparse vectors***************************************************
1213  // No special implementation for the SMP addition assignment to sparse vectors.
1214  //**********************************************************************************************
1215 
1216  //**SMP subtraction assignment to dense vectors*************************************************
1230  template< typename VT2 > // Type of the target dense vector
1231  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1233  {
1235 
1236  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1237 
1239 
1240  // Evaluation of the left-hand side sparse vector operand
1241  LT x( rhs.vec_ );
1242  if( x.nonZeros() == 0UL ) return;
1243 
1244  // Evaluation of the right-hand side dense matrix operand
1245  RT A( rhs.mat_ );
1246 
1247  // Checking the evaluated operands
1248  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
1249  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
1250  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
1251  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
1252 
1253  // Performing the sparse vector-dense matrix multiplication
1254  smpSubAssign( ~lhs, x * A );
1255  }
1256  //**********************************************************************************************
1257 
1258  //**SMP subtraction assignment to sparse vectors************************************************
1259  // No special implementation for the SMP subtraction assignment to sparse vectors.
1260  //**********************************************************************************************
1261 
1262  //**SMP multiplication assignment to dense vectors**********************************************
1276  template< typename VT2 > // Type of the target dense vector
1277  friend inline typename EnableIf< UseSMPAssign<VT2> >::Type
1279  {
1281 
1285 
1286  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
1287 
1288  const ResultType tmp( rhs );
1289  smpMultAssign( ~lhs, tmp );
1290  }
1291  //**********************************************************************************************
1292 
1293  //**SMP multiplication assignment to sparse vectors*********************************************
1294  // No special implementation for the SMP multiplication assignment to sparse vectors.
1295  //**********************************************************************************************
1296 
1297  //**Compile time checks*************************************************************************
1304  //**********************************************************************************************
1305 };
1306 //*************************************************************************************************
1307 
1308 
1309 
1310 
1311 //=================================================================================================
1312 //
1313 // GLOBAL BINARY ARITHMETIC OPERATORS
1314 //
1315 //=================================================================================================
1316 
1317 //*************************************************************************************************
1348 template< typename T1, typename T2 >
1349 inline const typename DisableIf< IsMatMatMultExpr<T2>, TSVecDMatMultExpr<T1,T2> >::Type
1351 {
1353 
1354  if( (~vec).size() != (~mat).rows() )
1355  throw std::invalid_argument( "Vector and matrix sizes do not match" );
1356 
1357  return TSVecDMatMultExpr<T1,T2>( ~vec, ~mat );
1358 }
1359 //*************************************************************************************************
1360 
1361 
1362 
1363 
1364 //=================================================================================================
1365 //
1366 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
1367 //
1368 //=================================================================================================
1369 
1370 //*************************************************************************************************
1383 template< typename T1 // Type of the left-hand side sparse vector
1384  , typename T2 // Type of the right-hand side dense matrix
1385  , bool SO > // Storage order of the right-hand side dense matrix
1386 inline const typename EnableIf< IsMatMatMultExpr<T2>, MultExprTrait<T1,T2> >::Type::Type
1388 {
1390 
1391  return ( vec * (~mat).leftOperand() ) * (~mat).rightOperand();
1392 }
1393 //*************************************************************************************************
1394 
1395 
1396 
1397 
1398 //=================================================================================================
1399 //
1400 // EXPRESSION TRAIT SPECIALIZATIONS
1401 //
1402 //=================================================================================================
1403 
1404 //*************************************************************************************************
1406 template< typename VT, typename MT, bool AF >
1407 struct SubvectorExprTrait< TSVecDMatMultExpr<VT,MT>, AF >
1408 {
1409  public:
1410  //**********************************************************************************************
1411  typedef typename MultExprTrait< VT, typename SubmatrixExprTrait<const MT,AF>::Type >::Type Type;
1412  //**********************************************************************************************
1413 };
1415 //*************************************************************************************************
1416 
1417 } // namespace blaze
1418 
1419 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4599
friend void multAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Multiplication assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ...
Definition: TSVecDMatMultExpr.h:1075
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:4329
TSVecDMatMultExpr< VT, MT > This
Type of this TSVecDMatMultExpr instance.
Definition: TSVecDMatMultExpr.h:179
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:181
Expression object for transpose sparse vector-dense matrix multiplications.The TSVecDMatMultExpr clas...
Definition: Forward.h:147
SelectType< evaluateMatrix, const MRT, MCT >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSVecDMatMultExpr.h:197
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecDMatMultExpr.h:191
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecDMatMultExpr.h:232
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
VT::ResultType VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:100
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Header file for the IsSame and IsStrictlySame type traits.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2408
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:251
VT::CompositeType VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:104
Header file for the DenseVector base class.
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:690
Header file for the Computation base class.
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member enumeration is set to 1, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to 0, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:158
Header file for the RequiresEvaluation type trait.
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: TSVecDMatMultExpr.h:183
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSVecDMatMultExpr.h:318
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:184
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
size_t size() const
Returns the current size/dimension of the vector.
Definition: TSVecDMatMultExpr.h:264
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:253
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
friend void addAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Addition assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ( )...
Definition: TSVecDMatMultExpr.h:657
Header file for the multiplication trait.
MT::CompositeType MCT
Composite type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:105
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: TSVecDMatMultExpr.h:274
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2412
TSVecDMatMultExpr(const VT &vec, const MT &mat)
Constructor for the TSVecDMatMultExpr class.
Definition: TSVecDMatMultExpr.h:218
Header file for the IsMatMatMultExpr type trait class.
MT::ResultType MRT
Result type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:101
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSVecDMatMultExpr.h:308
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:271
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:79
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:188
Constraints on the storage order of matrix types.
Constraint on the data type.
MRT::ElementType MET
Element type of the right-hand side dense matrix expression.
Definition: TSVecDMatMultExpr.h:103
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2406
Header file for the SelectType class template.
Header file for all forward declarations for expression class templates.
MultTrait< VRT, MRT >::Type ResultType
Result type for expression template evaluations.
Definition: TSVecDMatMultExpr.h:180
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the serial shim.
void smpAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:92
friend EnableIf< UseSMPAssign< VT2 > >::Type smpMultAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
SMP multiplication assignment of a transpose sparse vector-dense matrix multiplication to a dense vec...
Definition: TSVecDMatMultExpr.h:1278
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:748
Header file for run time assertion macros.
Base template for the MultTrait class.
Definition: MultTrait.h:141
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecDMatMultExpr.h:185
friend EnableIf< UseSMPAssign< VT2 > >::Type smpAddAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
SMP addition assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ( ...
Definition: TSVecDMatMultExpr.h:1188
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Header file for the reset shim.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSVecDMatMultExpr.h:296
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsBlasCompatible.h:99
SelectType< evaluateVector, const VRT, VCT >::Type LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecDMatMultExpr.h:194
Header file for the TVecMatMultExpr base class.
Header file for the RemoveReference type trait.
Header file for all intrinsic functionality.
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:79
const size_t SMP_TSVECDMATMULT_THRESHOLD
SMP sparse vector/row-major dense matrix multiplication threshold.This threshold specifies when a spa...
Definition: Thresholds.h:460
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSVecDMatMultExpr.h:328
RightOperand mat_
Right-hand side dense matrix of the multiplication expression.
Definition: TSVecDMatMultExpr.h:336
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecDMatMultExpr.h:335
Header file for the IsComputation type trait class.
friend EnableIf< UseSMPAssign< VT2 > >::Type smpSubAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
SMP subtraction assignment of a transpose sparse vector-dense matrix multiplication to a dense vector...
Definition: TSVecDMatMultExpr.h:1232
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:108
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2403
Header file for basic type definitions.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: TransposeFlag.h:81
Header file for the SubvectorExprTrait class template.
VRT::ElementType VET
Element type of the left-hand side sparse vector expression.
Definition: TSVecDMatMultExpr.h:102
friend void subAssign(DenseVector< VT2, true > &lhs, const TSVecDMatMultExpr &rhs)
Subtraction assignment of a transpose sparse vector-dense matrix multiplication to a dense vector ( )...
Definition: TSVecDMatMultExpr.h:865
Header file for the IsResizable type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
RightOperand rightOperand() const
Returns the right-hand side dense matrix operand.
Definition: TSVecDMatMultExpr.h:284
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:154
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
EnableIf< IsIntegral< T >, Set< T, sizeof(T)> >::Type::Type set(T value)
Sets all values in the vector to the given integral value.
Definition: Set.h:209
ResultType::ElementType ElementType
Resulting element type.
Definition: TSVecDMatMultExpr.h:182
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.