SVecTDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECTDVECMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SVECTDVECMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
56 #include <blaze/math/Intrinsics.h>
73 #include <blaze/util/Assert.h>
75 #include <blaze/util/EnableIf.h>
76 #include <blaze/util/Exception.h>
78 #include <blaze/util/SelectType.h>
79 #include <blaze/util/Types.h>
82 #include <blaze/util/Unused.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS SVECTDVECMULTEXPR
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
100 template< typename VT1 // Type of the left-hand side sparse vector
101  , typename VT2 > // Type of the right-hand side dense vector
102 class SVecTDVecMultExpr : public SparseMatrix< SVecTDVecMultExpr<VT1,VT2>, true >
103  , private VecTVecMultExpr
104  , private Computation
105 {
106  private:
107  //**Type definitions****************************************************************************
108  typedef typename VT1::ResultType RT1;
109  typedef typename VT2::ResultType RT2;
110  typedef typename VT1::ReturnType RN1;
111  typedef typename VT2::ReturnType RN2;
112  typedef typename VT1::CompositeType CT1;
113  typedef typename VT2::CompositeType CT2;
114  typedef typename VT1::ElementType ET1;
115  typedef typename VT2::ElementType ET2;
116  //**********************************************************************************************
117 
118  //**Return type evaluation**********************************************************************
120 
125  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
126 
129  //**********************************************************************************************
130 
131  //**Evaluation strategy*************************************************************************
133 
139  enum { useAssign = ( IsComputation<VT1>::value || !IsNumeric<ET1>::value ||
141 
143  template< typename MT >
145  struct UseAssign {
146  enum { value = useAssign };
147  };
149  //**********************************************************************************************
150 
151  //**********************************************************************************************
153 
156  template< typename T1, typename T2, typename T3 >
157  struct UseVectorizedKernel {
158  enum { value = useOptimizedKernels &&
159  T1::vectorizable && T3::vectorizable &&
163  };
165  //**********************************************************************************************
166 
167  //**********************************************************************************************
169 
172  template< typename T1, typename T2, typename T3 >
173  struct UseDefaultKernel {
174  enum { value = !UseVectorizedKernel<T1,T2,T3>::value };
175  };
177  //**********************************************************************************************
178 
179  public:
180  //**Type definitions****************************************************************************
186 
189 
192 
194  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
195 
197  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
198 
200  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
201 
203  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
204  //**********************************************************************************************
205 
206  //**Compilation flags***************************************************************************
208  enum { smpAssignable = 0 };
209  //**********************************************************************************************
210 
211  //**ConstIterator class definition**************************************************************
215  {
216  public:
217  //**Type definitions*************************************************************************
220 
223 
225  typedef ET2 RightElement;
226 
227  typedef std::forward_iterator_tag IteratorCategory;
228  typedef Element ValueType;
229  typedef ValueType* PointerType;
230  typedef ValueType& ReferenceType;
232 
233  // STL iterator requirements
234  typedef IteratorCategory iterator_category;
235  typedef ValueType value_type;
236  typedef PointerType pointer;
237  typedef ReferenceType reference;
238  typedef DifferenceType difference_type;
239  //*******************************************************************************************
240 
241  //**Constructor******************************************************************************
244  inline ConstIterator( IteratorType it, RightElement v )
245  : it_( it ) // Iterator over the elements of the left-hand side sparse vector expression
246  , v_ ( v ) // Element of the right-hand side dense vector expression.
247  {}
248  //*******************************************************************************************
249 
250  //**Prefix increment operator****************************************************************
256  ++it_;
257  return *this;
258  }
259  //*******************************************************************************************
260 
261  //**Element access operator******************************************************************
266  inline const Element operator*() const {
267  return Element( it_->value() * v_, it_->index() );
268  }
269  //*******************************************************************************************
270 
271  //**Element access operator******************************************************************
276  inline const ConstIterator* operator->() const {
277  return this;
278  }
279  //*******************************************************************************************
280 
281  //**Value function***************************************************************************
286  inline ReturnType value() const {
287  return it_->value() * v_;
288  }
289  //*******************************************************************************************
290 
291  //**Index function***************************************************************************
296  inline size_t index() const {
297  return it_->index();
298  }
299  //*******************************************************************************************
300 
301  //**Equality operator************************************************************************
307  inline bool operator==( const ConstIterator& rhs ) const {
308  return it_ == rhs.it_;
309  }
310  //*******************************************************************************************
311 
312  //**Inequality operator**********************************************************************
318  inline bool operator!=( const ConstIterator& rhs ) const {
319  return it_ != rhs.it_;
320  }
321  //*******************************************************************************************
322 
323  //**Subtraction operator*********************************************************************
329  inline DifferenceType operator-( const ConstIterator& rhs ) const {
330  return it_ - rhs.it_;
331  }
332  //*******************************************************************************************
333 
334  private:
335  //**Member variables*************************************************************************
336  IteratorType it_;
337  RightElement v_;
338  //*******************************************************************************************
339  };
340  //**********************************************************************************************
341 
342  //**Constructor*********************************************************************************
348  explicit inline SVecTDVecMultExpr( const VT1& lhs, const VT2& rhs )
349  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
350  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
351  {}
352  //**********************************************************************************************
353 
354  //**Access operator*****************************************************************************
361  inline ReturnType operator()( size_t i, size_t j ) const {
362  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
363  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
364 
365  return lhs_[i] * rhs_[j];
366  }
367  //**********************************************************************************************
368 
369  //**At function*********************************************************************************
377  inline ReturnType at( size_t i, size_t j ) const {
378  if( i >= lhs_.size() ) {
379  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
380  }
381  if( j >= rhs_.size() ) {
382  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
383  }
384  return (*this)(i,j);
385  }
386  //**********************************************************************************************
387 
388  //**Begin function******************************************************************************
394  inline ConstIterator begin( size_t i ) const {
395  return ConstIterator( lhs_.begin(), rhs_[i] );
396  }
397  //**********************************************************************************************
398 
399  //**End function********************************************************************************
405  inline ConstIterator end( size_t i ) const {
406  return ConstIterator( lhs_.end(), rhs_[i] );
407  }
408  //**********************************************************************************************
409 
410  //**Rows function*******************************************************************************
415  inline size_t rows() const {
416  return lhs_.size();
417  }
418  //**********************************************************************************************
419 
420  //**Columns function****************************************************************************
425  inline size_t columns() const {
426  return rhs_.size();
427  }
428  //**********************************************************************************************
429 
430  //**NonZeros function***************************************************************************
435  inline size_t nonZeros() const {
436  return lhs_.nonZeros() * rhs_.size();
437  }
438  //**********************************************************************************************
439 
440  //**NonZeros function***************************************************************************
446  inline size_t nonZeros( size_t i ) const {
447  UNUSED_PARAMETER( i );
448  return lhs_.nonZeros();
449  }
450  //**********************************************************************************************
451 
452  //**Find function*******************************************************************************
459  inline ConstIterator find( size_t i, size_t j ) const {
461  return ConstIterator( lhs_.find( i ), rhs_[j] );
462  }
463  //**********************************************************************************************
464 
465  //**LowerBound function*************************************************************************
472  inline ConstIterator lowerBound( size_t i, size_t j ) const {
474  return ConstIterator( lhs_.lowerBound( i ), rhs_[j] );
475  }
476  //**********************************************************************************************
477 
478  //**UpperBound function*************************************************************************
485  inline ConstIterator upperBound( size_t i, size_t j ) const {
487  return ConstIterator( lhs_.upperBound( i ), rhs_[j] );
488  }
489  //**********************************************************************************************
490 
491  //**Left operand access*************************************************************************
496  inline LeftOperand leftOperand() const {
497  return lhs_;
498  }
499  //**********************************************************************************************
500 
501  //**Right operand access************************************************************************
506  inline RightOperand rightOperand() const {
507  return rhs_;
508  }
509  //**********************************************************************************************
510 
511  //**********************************************************************************************
517  template< typename T >
518  inline bool canAlias( const T* alias ) const {
519  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
520  }
521  //**********************************************************************************************
522 
523  //**********************************************************************************************
529  template< typename T >
530  inline bool isAliased( const T* alias ) const {
531  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
532  }
533  //**********************************************************************************************
534 
535  private:
536  //**Member variables****************************************************************************
537  LeftOperand lhs_;
538  RightOperand rhs_;
539  //**********************************************************************************************
540 
541  //**Assignment to row-major dense matrices******************************************************
553  template< typename MT > // Type of the target dense matrix
554  friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
555  {
557 
559 
560  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
561  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
562 
563  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
564  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
565 
566  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
567  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
568  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
569  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
570 
571  SVecTDVecMultExpr::selectAssignKernel( ~lhs, x, y );
572  }
574  //**********************************************************************************************
575 
576  //**Default assignment to row-major dense matrices**********************************************
590  template< typename MT // Type of the left-hand side target matrix
591  , typename VT3 // Type of the left-hand side vector operand
592  , typename VT4 > // Type of the right-hand side vector operand
593  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
594  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
595  {
597 
598  const ConstIterator end( x.end() );
599 
600  for( ConstIterator element=x.begin(); element!=end; ++element ) {
601  if( !isDefault( element->value() ) ) {
602  for( size_t j=0UL; j<y.size(); ++j ) {
603  (~A)(element->index(),j) = element->value() * y[j];
604  }
605  }
606  }
607  }
609  //**********************************************************************************************
610 
611  //**Vectorized assignment to row-major dense matrices*******************************************
625  template< typename MT // Type of the left-hand side target matrix
626  , typename VT3 // Type of the left-hand side vector operand
627  , typename VT4 > // Type of the right-hand side vector operand
628  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
629  selectAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
630  {
632 
633  typedef IntrinsicTrait<ElementType> IT;
634  typedef typename IT::Type IntrinsicType;
635 
636  const size_t N( (~A).columns() );
637 
638  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
639 
640  const size_t jpos( remainder ? ( N & size_t(-IT::size) ) : N );
641  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % IT::size ) ) == jpos, "Invalid end calculation" );
642 
643  const ConstIterator begin( x.begin() );
644  const ConstIterator end ( x.end() );
645 
646  for( ConstIterator element=begin; element!=end; ++element )
647  {
648  const IntrinsicType x1( set( element->value() ) );
649 
650  size_t j( 0UL );
651 
652  for( ; j<jpos; j+=IT::size ) {
653  (~A).store( element->index(), j, x1 * y.load(j) );
654  }
655  for( ; remainder && j<N; ++j ) {
656  (~A)(element->index(),j) = element->value() * y[j];
657  }
658  }
659  }
661  //**********************************************************************************************
662 
663  //**Assignment to column-major dense matrices***************************************************
679  template< typename MT > // Type of the target dense matrix
680  friend inline typename EnableIf< UseAssign<MT> >::Type
681  assign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
682  {
684 
685  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
686  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
687 
689 
690  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
691  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
692 
693  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
694  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
695  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
696  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
697 
698  const ConstIterator end( x.end() );
699 
700  for( size_t i=0UL; i<y.size(); ++i ) {
701  if( !isDefault( y[i] ) ) {
702  for( ConstIterator element=x.begin(); element!=end; ++element ) {
703  (~lhs)(element->index(),i) = element->value() * y[i];
704  }
705  }
706  }
707  }
709  //**********************************************************************************************
710 
711  //**Assignment to row-major sparse matrices*****************************************************
723  template< typename MT > // Type of the target sparse matrix
724  friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
725  {
727 
729 
730  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
731  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns() , "Invalid number of columns" );
732 
734 
735  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
736  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
737 
738  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
739  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
740  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
741  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
742 
743  const ConstIterator begin( x.begin() );
744  const ConstIterator end ( x.end() );
745 
746  if( begin == end )
747  return;
748 
749  (~lhs).reserve( begin->index(), rhs.nonZeros() );
750 
751  size_t index( 0UL );
752 
753  for( ConstIterator element=begin; element!=end; ++element ) {
754  if( !isDefault( element->value() ) ) {
755  for( ; index < element->index(); ++index ) {
756  (~lhs).finalize( index );
757  }
758  for( size_t i=0UL; i<y.size(); ++i ) {
759  (~lhs).append( element->index(), i, element->value() * y[i] );
760  }
761  (~lhs).finalize( index++ );
762  }
763  }
764 
765  for( ; index < x.size(); ++index ) {
766  (~lhs).finalize( index );
767  }
768  }
770  //**********************************************************************************************
771 
772  //**Assignment to column-major sparse matrices**************************************************
788  template< typename MT > // Type of the target sparse matrix
789  friend inline typename EnableIf< UseAssign<MT> >::Type
790  assign( SparseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
791  {
793 
794  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
795  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns() , "Invalid number of columns" );
796  BLAZE_INTERNAL_ASSERT( (~lhs).capacity() >= rhs.nonZeros(), "Insufficient capacity" );
797 
799 
800  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
801  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
802 
803  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
804  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
805  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
806  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
807 
808  const ConstIterator begin( x.begin() );
809  const ConstIterator end ( x.end() );
810 
811  if( begin == end )
812  return;
813 
814  for( size_t i=0UL; i<y.size(); ++i ) {
815  if( !isDefault( y[i] ) ) {
816  for( ConstIterator element=begin; element!=end; ++element ) {
817  (~lhs).append( element->index(), i, element->value() * y[i] );
818  }
819  }
820  (~lhs).finalize( i );
821  }
822  }
824  //**********************************************************************************************
825 
826  //**Addition assignment to row-major dense matrices*********************************************
839  template< typename MT > // Type of the target dense matrix
840  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
841  {
843 
845 
846  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
847  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
848 
849  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
850  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
851 
852  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
853  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
854  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
855  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
856 
857  SVecTDVecMultExpr::selectAddAssignKernel( ~lhs, x, y );
858  }
860  //**********************************************************************************************
861 
862  //**Default addition assignment to row-major dense matrices*************************************
876  template< typename MT // Type of the left-hand side target matrix
877  , typename VT3 // Type of the left-hand side vector operand
878  , typename VT4 > // Type of the right-hand side vector operand
879  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
880  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
881  {
883 
884  const ConstIterator end( x.end() );
885 
886  for( ConstIterator element=x.begin(); element!=end; ++element ) {
887  if( !isDefault( element->value() ) ) {
888  for( size_t i=0UL; i<y.size(); ++i ) {
889  (~A)(element->index(),i) += element->value() * y[i];
890  }
891  }
892  }
893  }
895  //**********************************************************************************************
896 
897  //**Vectorized addition assignment to row-major dense matrices**********************************
911  template< typename MT // Type of the left-hand side target matrix
912  , typename VT3 // Type of the left-hand side vector operand
913  , typename VT4 > // Type of the right-hand side vector operand
914  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
915  selectAddAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
916  {
918 
919  typedef IntrinsicTrait<ElementType> IT;
920  typedef typename IT::Type IntrinsicType;
921 
922  const size_t N( (~A).columns() );
923 
924  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
925 
926  const size_t jpos( remainder ? ( N & size_t(-IT::size) ) : N );
927  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % IT::size ) ) == jpos, "Invalid end calculation" );
928 
929  const ConstIterator begin( x.begin() );
930  const ConstIterator end ( x.end() );
931 
932  for( ConstIterator element=begin; element!=end; ++element )
933  {
934  const IntrinsicType x1( set( element->value() ) );
935 
936  size_t j( 0UL );
937 
938  for( ; j<jpos; j+=IT::size ) {
939  (~A).store( element->index(), j, (~A).load(element->index(),j) + x1 * y.load(j) );
940  }
941  for( ; remainder && j<N; ++j ) {
942  (~A)(element->index(),j) += element->value() * y[j];
943  }
944  }
945  }
947  //**********************************************************************************************
948 
949  //**Addition assignment to column-major dense matrices******************************************
965  template< typename MT > // Type of the target dense matrix
966  friend inline typename EnableIf< UseAssign<MT> >::Type
967  addAssign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
968  {
970 
971  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
972  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
973 
975 
976  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
977  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
978 
979  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
980  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
981  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
982  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
983 
984  const ConstIterator end( x.end() );
985 
986  for( size_t i=0UL; i<y.size(); ++i ) {
987  if( !isDefault( y[i] ) ) {
988  for( ConstIterator element=x.begin(); element!=end; ++element ) {
989  (~lhs)(element->index(),i) += element->value() * y[i];
990  }
991  }
992  }
993  }
995  //**********************************************************************************************
996 
997  //**Addition assignment to sparse matrices******************************************************
998  // No special implementation for the addition assignment to sparse matrices.
999  //**********************************************************************************************
1000 
1001  //**Subtraction assignment to row-major dense matrices******************************************
1014  template< typename MT > // Type of the target dense matrix
1015  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecTDVecMultExpr& rhs )
1016  {
1018 
1020 
1021  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1022  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1023 
1024  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
1025  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1026 
1027  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1028  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1029  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1030  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1031 
1032  SVecTDVecMultExpr::selectSubAssignKernel( ~lhs, x, y );
1033  }
1035  //**********************************************************************************************
1036 
1037  //**Default subtraction assignment to row-major dense matrices**********************************
1051  template< typename MT // Type of the left-hand side target matrix
1052  , typename VT3 // Type of the left-hand side vector operand
1053  , typename VT4 > // Type of the right-hand side vector operand
1054  static inline typename EnableIf< UseDefaultKernel<MT,VT3,VT4> >::Type
1055  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1056  {
1058 
1059  const ConstIterator end( x.end() );
1060 
1061  for( ConstIterator element=x.begin(); element!=end; ++element ) {
1062  if( !isDefault( element->value() ) ) {
1063  for( size_t i=0UL; i<y.size(); ++i ) {
1064  (~A)(element->index(),i) -= element->value() * y[i];
1065  }
1066  }
1067  }
1068  }
1070  //**********************************************************************************************
1071 
1072  //**Vectorized subtraction assignment to row-major dense matrices*******************************
1086  template< typename MT // Type of the left-hand side target matrix
1087  , typename VT3 // Type of the left-hand side vector operand
1088  , typename VT4 > // Type of the right-hand side vector operand
1089  static inline typename EnableIf< UseVectorizedKernel<MT,VT3,VT4> >::Type
1090  selectSubAssignKernel( DenseMatrix<MT,false>& A, const VT3& x, const VT4& y )
1091  {
1093 
1094  typedef IntrinsicTrait<ElementType> IT;
1095  typedef typename IT::Type IntrinsicType;
1096 
1097  const size_t N( (~A).columns() );
1098 
1099  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT4>::value );
1100 
1101  const size_t jpos( remainder ? ( N & size_t(-IT::size) ) : N );
1102  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % IT::size ) ) == jpos, "Invalid end calculation" );
1103 
1104  const ConstIterator begin( x.begin() );
1105  const ConstIterator end ( x.end() );
1106 
1107  for( ConstIterator element=begin; element!=end; ++element )
1108  {
1109  const IntrinsicType x1( set( element->value() ) );
1110 
1111  size_t j( 0UL );
1112 
1113  for( ; j<jpos; j+=IT::size ) {
1114  (~A).store( element->index(), j, (~A).load(element->index(),j) - x1 * y.load(j) );
1115  }
1116  for( ; remainder && j<N; ++j ) {
1117  (~A)(element->index(),j) -= element->value() * y[j];
1118  }
1119  }
1120  }
1122  //**********************************************************************************************
1123 
1124  //**Subtraction assignment to column-major dense matrices***************************************
1140  template< typename MT > // Type of the target dense matrix
1141  friend inline typename EnableIf< UseAssign<MT> >::Type
1142  subAssign( DenseMatrix<MT,true>& lhs, const SVecTDVecMultExpr& rhs )
1143  {
1145 
1146  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1147  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1148 
1150 
1151  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
1152  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1153 
1154  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1155  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1156  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1157  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1158 
1159  const ConstIterator end( x.end() );
1160 
1161  for( size_t i=0UL; i<y.size(); ++i ) {
1162  if( !isDefault( y[i] ) ) {
1163  for( ConstIterator element=x.begin(); element!=end; ++element ) {
1164  (~lhs)(element->index(),i) -= element->value() * y[i];
1165  }
1166  }
1167  }
1168  }
1170  //**********************************************************************************************
1171 
1172  //**Subtraction assignment to sparse matrices***************************************************
1173  // No special implementation for the subtraction assignment to sparse matrices.
1174  //**********************************************************************************************
1175 
1176  //**Multiplication assignment to dense matrices*************************************************
1177  // No special implementation for the multiplication assignment to dense matrices.
1178  //**********************************************************************************************
1179 
1180  //**Multiplication assignment to sparse matrices************************************************
1181  // No special implementation for the multiplication assignment to sparse matrices.
1182  //**********************************************************************************************
1183 
1184  //**Compile time checks*************************************************************************
1192  //**********************************************************************************************
1193 };
1194 //*************************************************************************************************
1195 
1196 
1197 
1198 
1199 //=================================================================================================
1200 //
1201 // GLOBAL BINARY ARITHMETIC OPERATORS
1202 //
1203 //=================================================================================================
1204 
1205 //*************************************************************************************************
1234 template< typename T1 // Type of the left-hand side sparse vector
1235  , typename T2 > // Type of the right-hand side dense vector
1236 inline const SVecTDVecMultExpr<T1,T2>
1238 {
1240 
1241  return SVecTDVecMultExpr<T1,T2>( ~lhs, ~rhs );
1242 }
1243 //*************************************************************************************************
1244 
1245 
1246 
1247 
1248 //=================================================================================================
1249 //
1250 // ROWS SPECIALIZATIONS
1251 //
1252 //=================================================================================================
1253 
1254 //*************************************************************************************************
1256 template< typename VT1, typename VT2 >
1257 struct Rows< SVecTDVecMultExpr<VT1,VT2> > : public Size<VT1>
1258 {};
1260 //*************************************************************************************************
1261 
1262 
1263 
1264 
1265 //=================================================================================================
1266 //
1267 // COLUMNS SPECIALIZATIONS
1268 //
1269 //=================================================================================================
1270 
1271 //*************************************************************************************************
1273 template< typename VT1, typename VT2 >
1274 struct Columns< SVecTDVecMultExpr<VT1,VT2> > : public Size<VT2>
1275 {};
1277 //*************************************************************************************************
1278 
1279 
1280 
1281 
1282 //=================================================================================================
1283 //
1284 // EXPRESSION TRAIT SPECIALIZATIONS
1285 //
1286 //=================================================================================================
1287 
1288 //*************************************************************************************************
1290 template< typename VT1, typename VT2, bool AF >
1291 struct SubmatrixExprTrait< SVecTDVecMultExpr<VT1,VT2>, AF >
1292 {
1293  public:
1294  //**********************************************************************************************
1295  typedef typename MultExprTrait< typename SubvectorExprTrait<const VT1,AF>::Type
1296  , typename SubvectorExprTrait<const VT2,AF>::Type >::Type Type;
1297  //**********************************************************************************************
1298 };
1300 //*************************************************************************************************
1301 
1302 
1303 //*************************************************************************************************
1305 template< typename VT1, typename VT2 >
1306 struct RowExprTrait< SVecTDVecMultExpr<VT1,VT2> >
1307 {
1308  public:
1309  //**********************************************************************************************
1310  typedef typename MultExprTrait< typename VT1::ReturnType, VT2 >::Type Type;
1311  //**********************************************************************************************
1312 };
1314 //*************************************************************************************************
1315 
1316 
1317 //*************************************************************************************************
1319 template< typename VT1, typename VT2 >
1320 struct ColumnExprTrait< SVecTDVecMultExpr<VT1,VT2> >
1321 {
1322  public:
1323  //**********************************************************************************************
1324  typedef typename MultExprTrait< VT1, typename VT2::ReturnType >::Type Type;
1325  //**********************************************************************************************
1326 };
1328 //*************************************************************************************************
1329 
1330 } // namespace blaze
1331 
1332 #endif
Pointer difference type of the Blaze library.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:87
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
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:7820
Iterator over the elements of the sparse vector-dense vector outer product expression.
Definition: SVecTDVecMultExpr.h:214
Header file for basic type definitions.
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SVecTDVecMultExpr.h:227
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:252
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: ColumnVector.h:79
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified column.
Definition: SVecTDVecMultExpr.h:446
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: SVecTDVecMultExpr.h:496
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
Header file for the ColumnExprTrait class template.
DifferenceType difference_type
Difference between two iterators.
Definition: SVecTDVecMultExpr.h:238
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SVecTDVecMultExpr.h:425
ValueType * PointerType
Pointer return type.
Definition: SVecTDVecMultExpr.h:229
Expression object for sparse vector-dense vector outer products.The SVecTDVecMultExpr class represent...
Definition: Forward.h:134
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SVecTDVecMultExpr.h:435
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SVecTDVecMultExpr.h:182
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:340
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:259
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of column i.
Definition: SVecTDVecMultExpr.h:394
ResultType::ElementType ElementType
Resulting element type.
Definition: SVecTDVecMultExpr.h:185
VT2::ReturnType RN2
Return type of the right-hand side dense vector expression.
Definition: SVecTDVecMultExpr.h:111
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of column i.
Definition: SVecTDVecMultExpr.h:405
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
System settings for performance optimizations.
ValueIndexPair< ElementType > Element
Element type of the sparse matrix expression.
Definition: SVecTDVecMultExpr.h:219
SVecTDVecMultExpr< VT1, VT2 > This
Type of this SVecTDVecMultExpr instance.
Definition: SVecTDVecMultExpr.h:181
RemoveReference< LeftOperand >::Type::ConstIterator IteratorType
Iterator type of the sparse vector expression.
Definition: SVecTDVecMultExpr.h:222
RightElement v_
Element of the right-hand side dense vector expression.
Definition: SVecTDVecMultExpr.h:337
const SelectType< returnExpr, ExprReturnType, ElementType >::Type ReturnType
Return type for expression template evaluations.
Definition: SVecTDVecMultExpr.h:188
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
ValueType value_type
Type of the underlying pointers.
Definition: SVecTDVecMultExpr.h:235
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Constraint on the data type.
Header file for the SparseMatrix base class.
Constraint on the transpose flag of vector types.
Constraint on the data type.
Header file for the MultExprTrait class template.
const ConstIterator * operator->() const
Direct access to the sparse matrix element at the current iterator position.
Definition: SVecTDVecMultExpr.h:276
IteratorType it_
Iterator over the elements of the left-hand side sparse vector expression.
Definition: SVecTDVecMultExpr.h:336
VT2::ResultType RT2
Result type of the right-hand side dense vector expression.
Definition: SVecTDVecMultExpr.h:109
Header file for the ValueIndexPair class.
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
ReferenceType reference
Reference return type.
Definition: SVecTDVecMultExpr.h:237
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: SVecTDVecMultExpr.h:318
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SVecTDVecMultExpr.h:184
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_VECTVECMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid vector/vector ...
Definition: VecTVecMultExpr.h:161
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SVecTDVecMultExpr.h:415
MultExprTrait< RN1, RN2 >::Type ExprReturnType
Expression return type for the subscript operator.
Definition: SVecTDVecMultExpr.h:128
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: SVecTDVecMultExpr.h:307
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
Header file for the Columns type trait.
ConstIterator find(size_t i, size_t j) const
Searches for a specific matrix element.
Definition: SVecTDVecMultExpr.h:459
SVecTDVecMultExpr(const VT1 &lhs, const VT2 &rhs)
Constructor for the SVecTDVecMultExpr class.
Definition: SVecTDVecMultExpr.h:348
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two expression iterators.
Definition: SVecTDVecMultExpr.h:329
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
ReturnType value() const
Access to the current value of the sparse element.
Definition: SVecTDVecMultExpr.h:286
Constraint on the data type.
LeftOperand lhs_
Left-hand side sparse vector of the multiplication expression.
Definition: SVecTDVecMultExpr.h:537
SelectType< IsComputation< VT2 >::value, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense vector operand.
Definition: SVecTDVecMultExpr.h:203
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2586
Constraint on the data type.
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
Header file for the VecTVecMultExpr base class.
RightOperand rhs_
Right-hand side dense vector of the multiplication expression.
Definition: SVecTDVecMultExpr.h:538
Header file for the EnableIf class template.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SVecTDVecMultExpr.h:518
Header file for the serial shim.
Element ValueType
Type of the underlying pointers.
Definition: SVecTDVecMultExpr.h:228
Header file for the IsNumeric type trait.
ConstIterator lowerBound(size_t i, size_t j) const
Returns an iterator to the first index not less then the given index.
Definition: SVecTDVecMultExpr.h:472
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
Header file for the SubmatrixExprTrait class template.
VT1::ResultType RT1
Result type of the left-hand side sparse vector expression.
Definition: SVecTDVecMultExpr.h:108
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2587
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:1232
Header file for run time assertion macros.
SelectType< useAssign, const ResultType, const SVecTDVecMultExpr & >::Type CompositeType
Data type for composite expression templates.
Definition: SVecTDVecMultExpr.h:191
Base template for the MultTrait class.
Definition: MultTrait.h:138
ConstIterator & operator++()
Pre-increment operator.
Definition: SVecTDVecMultExpr.h:255
VT1::ReturnType RN1
Return type of the left-hand side sparse vector expression.
Definition: SVecTDVecMultExpr.h:110
VT1::CompositeType CT1
Composite type of the left-hand side sparse vector expression.
Definition: SVecTDVecMultExpr.h:112
VT2::CompositeType CT2
Composite type of the right-hand side dense vector expression.
Definition: SVecTDVecMultExpr.h:113
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
const bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
SelectType< IsExpression< VT1 >::value, const VT1, const VT1 & >::Type LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecTDVecMultExpr.h:194
const Element operator*() const
Direct access to the sparse matrix element at the current iterator position.
Definition: SVecTDVecMultExpr.h:266
Header file for the isDefault shim.
Constraint on the data type.
ET2 RightElement
Element type of the dense vector expression.
Definition: SVecTDVecMultExpr.h:225
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:118
ConstIterator upperBound(size_t i, size_t j) const
Returns an iterator to the first index greater then the given index.
Definition: SVecTDVecMultExpr.h:485
Constraint on the data type.
ConstIterator(IteratorType it, RightElement v)
Constructor for the ConstIterator class.
Definition: SVecTDVecMultExpr.h:244
Header file for the RemoveReference type trait.
ValueType & ReferenceType
Reference return type.
Definition: SVecTDVecMultExpr.h:230
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SVecTDVecMultExpr.h:361
RightOperand rightOperand() const
Returns the right-hand side dense vector operand.
Definition: SVecTDVecMultExpr.h:506
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:70
IteratorCategory iterator_category
The iterator category.
Definition: SVecTDVecMultExpr.h:234
Header file for the IsComputation type trait class.
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:118
#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:2583
SelectType< IsExpression< VT2 >::value, const VT2, const VT2 & >::Type RightOperand
Composite type of the right-hand side dense vector expression.
Definition: SVecTDVecMultExpr.h:197
#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: RowVector.h:79
Header file for the SubvectorExprTrait class template.
SelectType< IsComputation< VT1 >::value, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side dense vector operand.
Definition: SVecTDVecMultExpr.h:200
Header file for exception macros.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SVecTDVecMultExpr.h:530
size_t index() const
Access to the current index of the sparse element.
Definition: SVecTDVecMultExpr.h:296
Header file for the Size type trait.
Evaluation of the resulting expression type of a multiplication.Via this type trait it is possible to...
Definition: MultExprTrait.h:137
#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
VT1::ElementType ET1
Element type of the left-hand side sparse vector expression.
Definition: SVecTDVecMultExpr.h:114
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SVecTDVecMultExpr.h:231
PointerType pointer
Pointer return type.
Definition: SVecTDVecMultExpr.h:236
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SVecTDVecMultExpr.h:377
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SVecTDVecMultExpr.h:183
VT2::ElementType ET2
Element type of the right-hand side dense vector expression.
Definition: SVecTDVecMultExpr.h:115