TSMatSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <vector>
54 #include <blaze/math/Functions.h>
91 #include <blaze/util/Assert.h>
92 #include <blaze/util/DisableIf.h>
93 #include <blaze/util/EnableIf.h>
94 #include <blaze/util/Exception.h>
95 #include <blaze/util/InvalidType.h>
97 #include <blaze/util/mpl/And.h>
98 #include <blaze/util/mpl/Or.h>
99 #include <blaze/util/SelectType.h>
100 #include <blaze/util/Types.h>
101 #include <blaze/util/Unused.h>
103 
104 
105 namespace blaze {
106 
107 //=================================================================================================
108 //
109 // CLASS TSMATSMATMULTEXPR
110 //
111 //=================================================================================================
112 
113 //*************************************************************************************************
120 template< typename MT1 // Type of the left-hand side sparse matrix
121  , typename MT2 > // Type of the right-hand side sparse matrix
122 class TSMatSMatMultExpr : public SparseMatrix< TSMatSMatMultExpr<MT1,MT2>, true >
123  , private MatMatMultExpr
124  , private Computation
125 {
126  private:
127  //**Type definitions****************************************************************************
128  typedef typename MT1::ResultType RT1;
129  typedef typename MT2::ResultType RT2;
130  typedef typename MT1::CompositeType CT1;
131  typedef typename MT2::CompositeType CT2;
132  //**********************************************************************************************
133 
134  //**********************************************************************************************
136  enum { evaluateLeft = RequiresEvaluation<MT1>::value };
137  //**********************************************************************************************
138 
139  //**********************************************************************************************
141  enum { evaluateRight = RequiresEvaluation<MT2>::value };
142  //**********************************************************************************************
143 
144  //**********************************************************************************************
146 
153  template< typename T1, typename T2, typename T3 >
154  struct CanExploitSymmetry {
155  enum { value = ( IsRowMajorMatrix<T1>::value && IsSymmetric<T2>::value ) ||
156  ( IsColumnMajorMatrix<T1>::value && IsSymmetric<T3>::value ) };
157  };
159  //**********************************************************************************************
160 
161  //**********************************************************************************************
163 
168  template< typename T1, typename T2, typename T3 >
169  struct IsEvaluationRequired {
170  enum { value = ( evaluateLeft || evaluateRight ) &&
171  !CanExploitSymmetry<T1,T2,T2>::value };
172  };
174  //**********************************************************************************************
175 
176  public:
177  //**Type definitions****************************************************************************
183  typedef const ElementType ReturnType;
184  typedef const ResultType CompositeType;
185 
187  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
188 
190  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
191  //**********************************************************************************************
192 
193  //**Compilation flags***************************************************************************
195  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
196  !evaluateRight && MT2::smpAssignable };
197  //**********************************************************************************************
198 
199  //**Constructor*********************************************************************************
205  explicit inline TSMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
206  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
207  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
208  {
209  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
210  }
211  //**********************************************************************************************
212 
213  //**Access operator*****************************************************************************
220  inline ReturnType operator()( size_t i, size_t j ) const {
221  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
222  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
223 
224  ElementType tmp = ElementType();
225 
226  if( lhs_.columns() != 0UL )
227  {
228  const size_t kbegin( max( ( IsUpper<MT1>::value )?( i ):( 0UL ),
229  ( IsLower<MT2>::value )?( j ):( 0UL ) ) );
230  const size_t kend ( min( ( IsLower<MT1>::value )?( i+1UL ):( lhs_.columns() ),
231  ( IsUpper<MT2>::value )?( j+1UL ):( lhs_.columns() ) ) );
232 
233  tmp = lhs_(i,kbegin) * rhs_(kbegin,j);
234  for( size_t k=kbegin+1UL; k<kend; ++k ) {
235  tmp += lhs_(i,k) * rhs_(k,j);
236  }
237  }
238 
239  return tmp;
240  }
241  //**********************************************************************************************
242 
243  //**At function*********************************************************************************
251  inline ReturnType at( size_t i, size_t j ) const {
252  if( i >= lhs_.rows() ) {
253  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
254  }
255  if( j >= rhs_.columns() ) {
256  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
257  }
258  return (*this)(i,j);
259  }
260  //**********************************************************************************************
261 
262  //**Rows function*******************************************************************************
267  inline size_t rows() const {
268  return lhs_.rows();
269  }
270  //**********************************************************************************************
271 
272  //**Columns function****************************************************************************
277  inline size_t columns() const {
278  return rhs_.columns();
279  }
280  //**********************************************************************************************
281 
282  //**NonZeros function***************************************************************************
287  inline size_t nonZeros() const {
288  return 0UL;
289  }
290  //**********************************************************************************************
291 
292  //**NonZeros function***************************************************************************
298  inline size_t nonZeros( size_t i ) const {
299  UNUSED_PARAMETER( i );
300  return 0UL;
301  }
302  //**********************************************************************************************
303 
304  //**Left operand access*************************************************************************
309  inline LeftOperand leftOperand() const {
310  return lhs_;
311  }
312  //**********************************************************************************************
313 
314  //**Right operand access************************************************************************
319  inline RightOperand rightOperand() const {
320  return rhs_;
321  }
322  //**********************************************************************************************
323 
324  //**********************************************************************************************
330  template< typename T >
331  inline bool canAlias( const T* alias ) const {
332  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
333  }
334  //**********************************************************************************************
335 
336  //**********************************************************************************************
342  template< typename T >
343  inline bool isAliased( const T* alias ) const {
344  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
345  }
346  //**********************************************************************************************
347 
348  //**********************************************************************************************
353  inline bool canSMPAssign() const {
354  return ( rows() > SMP_TSMATSMATMULT_THRESHOLD );
355  }
356  //**********************************************************************************************
357 
358  private:
359  //**Member variables****************************************************************************
360  LeftOperand lhs_;
361  RightOperand rhs_;
362  //**********************************************************************************************
363 
364  //**Assignment to dense matrices****************************************************************
377  template< typename MT // Type of the target dense matrix
378  , bool SO > // Storage order of the target dense matrix
379  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
380  assign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
381  {
383 
384  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
385  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
386 
387  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
388  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
389 
390  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
391  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
392  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
393  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
394  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
395  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
396 
397  TSMatSMatMultExpr::selectAssignKernel( ~lhs, A, B );
398  }
400  //**********************************************************************************************
401 
402  //**Default assignment to dense matrices********************************************************
416  template< typename MT3 // Type of the left-hand side target matrix
417  , typename MT4 // Type of the left-hand side matrix operand
418  , typename MT5 > // Type of the right-hand side matrix operand
419  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
420  {
421  typedef typename MT4::ConstIterator LeftIterator;
422  typedef typename MT5::ConstIterator RightIterator;
423 
424  for( size_t j=0UL; j<A.columns(); ++j ) {
425  const LeftIterator lend( A.end(j) );
426  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
427  const RightIterator rend( B.end(j) );
428  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
429  {
431  isDefault( C(lelem->index(),relem->index()) ) ) {
432  C(lelem->index(),relem->index()) = lelem->value() * relem->value();
433  }
434  else {
435  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
436  }
437  }
438  }
439  }
440  }
442  //**********************************************************************************************
443 
444  //**Assignment to row-major sparse matrices*****************************************************
457  template< typename MT > // Type of the target sparse matrix
458  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
459  assign( SparseMatrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
460  {
462 
464 
465  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
466  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
467 
469 
470  const typename MT1::OppositeType tmp( serial( rhs.lhs_ ) );
471  assign( ~lhs, tmp * rhs.rhs_ );
472  }
474  //**********************************************************************************************
475 
476  //**Assignment to column-major sparse matrices**************************************************
489  template< typename MT > // Type of the target sparse matrix
490  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
491  assign( SparseMatrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
492  {
494 
495  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
496  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
497 
499 
500  const typename MT2::OppositeType tmp( serial( rhs.rhs_ ) );
501  assign( ~lhs, rhs.lhs_ * tmp );
502  }
504  //**********************************************************************************************
505 
506  //**Restructuring assignment to row-major matrices**********************************************
521  template< typename MT > // Type of the target matrix
522  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
523  assign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
524  {
526 
528 
529  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
530  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
531 
532  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
533  }
535  //**********************************************************************************************
536 
537  //**Restructuring assignment to column-major matrices*******************************************
552  template< typename MT > // Type of the target matrix
553  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
554  assign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
555  {
557 
558  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
559  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
560 
561  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
562  }
564  //**********************************************************************************************
565 
566  //**Addition assignment to dense matrices*******************************************************
579  template< typename MT // Type of the target dense matrix
580  , bool SO > // Storage order of the target dense matarix
581  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
582  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
583  {
585 
586  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
587  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
588 
589  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
590  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
591 
592  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
593  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
594  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
595  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
596  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
597  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
598 
599  TSMatSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
600  }
602  //**********************************************************************************************
603 
604  //**Default addition assignment to dense matrices***********************************************
618  template< typename MT3 // Type of the left-hand side target matrix
619  , typename MT4 // Type of the left-hand side matrix operand
620  , typename MT5 > // Type of the right-hand side matrix operand
621  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
622  {
623  typedef typename MT4::ConstIterator LeftIterator;
624  typedef typename MT5::ConstIterator RightIterator;
625 
626  for( size_t j=0UL; j<A.columns(); ++j ) {
627  const LeftIterator lend( A.end(j) );
628  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
629  const RightIterator rend( B.end(j) );
630  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
631  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
632  }
633  }
634  }
635  }
637  //**********************************************************************************************
638 
639  //**Restructuring addition assignment to row-major matrices*************************************
654  template< typename MT > // Type of the target matrix
655  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
656  addAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
657  {
659 
661 
662  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
663  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
664 
665  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
666  }
668  //**********************************************************************************************
669 
670  //**Restructuring addition assignment to column-major matrices**********************************
685  template< typename MT > // Type of the target matrix
686  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
687  addAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
688  {
690 
691  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
692  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
693 
694  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
695  }
697  //**********************************************************************************************
698 
699  //**Addition assignment to sparse matrices******************************************************
700  // No special implementation for the addition assignment to sparse matrices.
701  //**********************************************************************************************
702 
703  //**Subtraction assignment to dense matrices****************************************************
716  template< typename MT // Type of the target dense matrix
717  , bool SO > // Storage order of the target dense matrix
718  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
719  {
721 
722  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
723  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
724 
725  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
726  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
727 
728  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
729  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
730  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
731  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
732  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
733  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
734 
735  TSMatSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
736  }
738  //**********************************************************************************************
739 
740  //**Default subtraction assignment to dense matrices********************************************
754  template< typename MT3 // Type of the left-hand side target matrix
755  , typename MT4 // Type of the left-hand side matrix operand
756  , typename MT5 > // Type of the right-hand side matrix operand
757  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
758  {
759  typedef typename MT4::ConstIterator LeftIterator;
760  typedef typename MT5::ConstIterator RightIterator;
761 
762  for( size_t j=0UL; j<A.columns(); ++j ) {
763  const LeftIterator lend( A.end(j) );
764  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
765  const RightIterator rend( B.end(j) );
766  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
767  C(lelem->index(),relem->index()) -= lelem->value() * relem->value();
768  }
769  }
770  }
771  }
773  //**********************************************************************************************
774 
775  //**Restructuring subtraction assignment to row-major matrices**********************************
790  template< typename MT > // Type of the target matrix
791  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
792  subAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
793  {
795 
797 
798  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
799  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
800 
801  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
802  }
804  //**********************************************************************************************
805 
806  //**Restructuring subtraction assignment to column-major matrices*******************************
821  template< typename MT > // Type of the target matrix
822  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
823  subAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
824  {
826 
827  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
828  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
829 
830  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
831  }
833  //**********************************************************************************************
834 
835  //**Subtraction assignment to sparse matrices***************************************************
836  // No special implementation for the subtraction assignment to sparse matrices.
837  //**********************************************************************************************
838 
839  //**Multiplication assignment to dense matrices*************************************************
840  // No special implementation for the multiplication assignment to dense matrices.
841  //**********************************************************************************************
842 
843  //**Multiplication assignment to sparse matrices************************************************
844  // No special implementation for the multiplication assignment to sparse matrices.
845  //**********************************************************************************************
846 
847  //**SMP assignment to matrices******************************************************************
863  template< typename MT // Type of the target matrix
864  , bool SO > // Storage order of the target matrix
865  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
866  smpAssign( Matrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
867  {
869 
870  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
871  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
872 
873  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
874  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
875 
876  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
877  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
878  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
879  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
880  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
881  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
882 
883  smpAssign( ~lhs, A * B );
884  }
886  //**********************************************************************************************
887 
888  //**Restructuring SMP assignment to row-major matrices******************************************
903  template< typename MT > // Type of the target matrix
904  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
905  smpAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
906  {
908 
910 
911  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
912  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
913 
914  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
915  }
917  //**********************************************************************************************
918 
919  //**Restructuring SMP assignment to column-major matrices***************************************
934  template< typename MT > // Type of the target matrix
935  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
936  smpAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
937  {
939 
940  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
941  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
942 
943  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
944  }
946  //**********************************************************************************************
947 
948  //**SMP addition assignment to dense matrices***************************************************
964  template< typename MT // Type of the target dense matrix
965  , bool SO > // Storage order of the target dense matarix
966  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
967  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& 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 
974  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
975  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
976 
977  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
978  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
979  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
980  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
981  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
982  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
983 
984  smpAddAssign( ~lhs, A * B );
985  }
987  //**********************************************************************************************
988 
989  //**Restructuring SMP addition assignment to row-major matrices*********************************
1004  template< typename MT > // Type of the target matrix
1005  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1006  smpAddAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
1007  {
1009 
1011 
1012  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1013  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1014 
1015  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1016  }
1018  //**********************************************************************************************
1019 
1020  //**Restructuring SMP addition assignment to column-major matrices******************************
1035  template< typename MT > // Type of the target matrix
1036  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1037  smpAddAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
1038  {
1040 
1041  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1042  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1043 
1044  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1045  }
1047  //**********************************************************************************************
1048 
1049  //**SMP addition assignment to sparse matrices**************************************************
1050  // No special implementation for the SMP addition assignment to sparse matrices.
1051  //**********************************************************************************************
1052 
1053  //**SMP subtraction assignment to dense matrices************************************************
1069  template< typename MT // Type of the target dense matrix
1070  , bool SO > // Storage order of the target dense matrix
1071  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1072  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
1073  {
1075 
1076  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1077  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1078 
1079  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1080  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1081 
1082  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1083  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1084  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1085  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1086  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1087  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1088 
1089  smpSubAssign( ~lhs, A * B );
1090  }
1092  //**********************************************************************************************
1093 
1094  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1109  template< typename MT > // Type of the target matrix
1110  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1111  smpSubAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
1112  {
1114 
1116 
1117  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1118  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1119 
1120  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1121  }
1123  //**********************************************************************************************
1124 
1125  //**Restructuring SMP subtraction assignment to column-major matrices***************************
1140  template< typename MT > // Type of the target matrix
1141  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1142  smpSubAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& 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 
1149  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1150  }
1152  //**********************************************************************************************
1153 
1154  //**SMP subtraction assignment to sparse matrices***********************************************
1155  // No special implementation for the SMP subtraction assignment to sparse matrices.
1156  //**********************************************************************************************
1157 
1158  //**SMP multiplication assignment to dense matrices*********************************************
1159  // No special implementation for the SMP multiplication assignment to dense matrices.
1160  //**********************************************************************************************
1161 
1162  //**SMP multiplication assignment to sparse matrices********************************************
1163  // No special implementation for the SMP multiplication assignment to sparse matrices.
1164  //**********************************************************************************************
1165 
1166  //**Compile time checks*************************************************************************
1174  //**********************************************************************************************
1175 };
1176 //*************************************************************************************************
1177 
1178 
1179 
1180 
1181 //=================================================================================================
1182 //
1183 // GLOBAL BINARY ARITHMETIC OPERATORS
1184 //
1185 //=================================================================================================
1186 
1187 //*************************************************************************************************
1217 template< typename T1 // Type of the left-hand side sparse matrix
1218  , typename T2 > // Type of the right-hand side sparse matrix
1219 inline const TSMatSMatMultExpr<T1,T2>
1221 {
1223 
1224  if( (~lhs).columns() != (~rhs).rows() ) {
1225  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1226  }
1227 
1228  return TSMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1229 }
1230 //*************************************************************************************************
1231 
1232 
1233 
1234 
1235 //=================================================================================================
1236 //
1237 // ROWS SPECIALIZATIONS
1238 //
1239 //=================================================================================================
1240 
1241 //*************************************************************************************************
1243 template< typename MT1, typename MT2 >
1244 struct Rows< TSMatSMatMultExpr<MT1,MT2> > : public Rows<MT1>
1245 {};
1247 //*************************************************************************************************
1248 
1249 
1250 
1251 
1252 //=================================================================================================
1253 //
1254 // COLUMNS SPECIALIZATIONS
1255 //
1256 //=================================================================================================
1257 
1258 //*************************************************************************************************
1260 template< typename MT1, typename MT2 >
1261 struct Columns< TSMatSMatMultExpr<MT1,MT2> > : public Columns<MT2>
1262 {};
1264 //*************************************************************************************************
1265 
1266 
1267 
1268 
1269 //=================================================================================================
1270 //
1271 // ISLOWER SPECIALIZATIONS
1272 //
1273 //=================================================================================================
1274 
1275 //*************************************************************************************************
1277 template< typename MT1, typename MT2 >
1278 struct IsLower< TSMatSMatMultExpr<MT1,MT2> >
1279  : public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
1280 {};
1282 //*************************************************************************************************
1283 
1284 
1285 
1286 
1287 //=================================================================================================
1288 //
1289 // ISUNILOWER SPECIALIZATIONS
1290 //
1291 //=================================================================================================
1292 
1293 //*************************************************************************************************
1295 template< typename MT1, typename MT2 >
1296 struct IsUniLower< TSMatSMatMultExpr<MT1,MT2> >
1297  : public IsTrue< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1298 {};
1300 //*************************************************************************************************
1301 
1302 
1303 
1304 
1305 //=================================================================================================
1306 //
1307 // ISSTRICTLYLOWER SPECIALIZATIONS
1308 //
1309 //=================================================================================================
1310 
1311 //*************************************************************************************************
1313 template< typename MT1, typename MT2 >
1314 struct IsStrictlyLower< TSMatSMatMultExpr<MT1,MT2> >
1315  : public IsTrue< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1316  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1317 {};
1319 //*************************************************************************************************
1320 
1321 
1322 
1323 
1324 //=================================================================================================
1325 //
1326 // ISUPPER SPECIALIZATIONS
1327 //
1328 //=================================================================================================
1329 
1330 //*************************************************************************************************
1332 template< typename MT1, typename MT2 >
1333 struct IsUpper< TSMatSMatMultExpr<MT1,MT2> >
1334  : public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1335 {};
1337 //*************************************************************************************************
1338 
1339 
1340 
1341 
1342 //=================================================================================================
1343 //
1344 // ISUNIUPPER SPECIALIZATIONS
1345 //
1346 //=================================================================================================
1347 
1348 //*************************************************************************************************
1350 template< typename MT1, typename MT2 >
1351 struct IsUniUpper< TSMatSMatMultExpr<MT1,MT2> >
1352  : public IsTrue< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1353 {};
1355 //*************************************************************************************************
1356 
1357 
1358 
1359 
1360 //=================================================================================================
1361 //
1362 // ISSTRICTLYUPPER SPECIALIZATIONS
1363 //
1364 //=================================================================================================
1365 
1366 //*************************************************************************************************
1368 template< typename MT1, typename MT2 >
1369 struct IsStrictlyUpper< TSMatSMatMultExpr<MT1,MT2> >
1370  : public IsTrue< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1371  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1372 {};
1374 //*************************************************************************************************
1375 
1376 
1377 
1378 
1379 //=================================================================================================
1380 //
1381 // EXPRESSION TRAIT SPECIALIZATIONS
1382 //
1383 //=================================================================================================
1384 
1385 //*************************************************************************************************
1387 template< typename MT1, typename MT2, typename VT >
1388 struct TSMatDVecMultExprTrait< TSMatSMatMultExpr<MT1,MT2>, VT >
1389 {
1390  public:
1391  //**********************************************************************************************
1392  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1393  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1394  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1395  , typename TSMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1396  , INVALID_TYPE >::Type Type;
1397  //**********************************************************************************************
1398 };
1400 //*************************************************************************************************
1401 
1402 
1403 //*************************************************************************************************
1405 template< typename MT1, typename MT2, typename VT >
1406 struct TSMatSVecMultExprTrait< TSMatSMatMultExpr<MT1,MT2>, VT >
1407 {
1408  public:
1409  //**********************************************************************************************
1410  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1411  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1412  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1413  , typename TSMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1414  , INVALID_TYPE >::Type Type;
1415  //**********************************************************************************************
1416 };
1418 //*************************************************************************************************
1419 
1420 
1421 //*************************************************************************************************
1423 template< typename VT, typename MT1, typename MT2 >
1424 struct TDVecTSMatMultExprTrait< VT, TSMatSMatMultExpr<MT1,MT2> >
1425 {
1426  public:
1427  //**********************************************************************************************
1428  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1429  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1430  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1431  , typename TDVecSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1432  , INVALID_TYPE >::Type Type;
1433  //**********************************************************************************************
1434 };
1436 //*************************************************************************************************
1437 
1438 
1439 //*************************************************************************************************
1441 template< typename VT, typename MT1, typename MT2 >
1442 struct TSVecTSMatMultExprTrait< VT, TSMatSMatMultExpr<MT1,MT2> >
1443 {
1444  public:
1445  //**********************************************************************************************
1446  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1447  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1448  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1449  , typename TDVecSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1450  , INVALID_TYPE >::Type Type;
1451  //**********************************************************************************************
1452 };
1454 //*************************************************************************************************
1455 
1456 
1457 //*************************************************************************************************
1459 template< typename MT1, typename MT2, bool AF >
1460 struct SubmatrixExprTrait< TSMatSMatMultExpr<MT1,MT2>, AF >
1461 {
1462  public:
1463  //**********************************************************************************************
1464  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1465  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1466  //**********************************************************************************************
1467 };
1469 //*************************************************************************************************
1470 
1471 
1472 //*************************************************************************************************
1474 template< typename MT1, typename MT2 >
1475 struct RowExprTrait< TSMatSMatMultExpr<MT1,MT2> >
1476 {
1477  public:
1478  //**********************************************************************************************
1479  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1480  //**********************************************************************************************
1481 };
1483 //*************************************************************************************************
1484 
1485 
1486 //*************************************************************************************************
1488 template< typename MT1, typename MT2 >
1489 struct ColumnExprTrait< TSMatSMatMultExpr<MT1,MT2> >
1490 {
1491  public:
1492  //**********************************************************************************************
1493  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1494  //**********************************************************************************************
1495 };
1497 //*************************************************************************************************
1498 
1499 } // namespace blaze
1500 
1501 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
Header file for mathematical functions.
Header file for the SMatDVecMultExprTrait class template.
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
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
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:187
Header file for basic type definitions.
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:181
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
Header file for the ColumnExprTrait class template.
Header file for the IsColumnMajorMatrix type trait.
Header file for the TSVecTSMatMultExprTrait class template.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
Header file for the IsRowVector type trait.
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
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
Header file for the TDVecSMatMultExprTrait class template.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatSMatMultExpr.h:331
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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatSMatMultExpr.h:353
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
Header file for the TSVecSMatMultExprTrait class template.
Header file for the IsUniLower type trait.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2584
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:117
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:131
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatSMatMultExpr.h:298
Header file for the SparseMatrix base class.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:190
Constraint on the data type.
Header file for the MultExprTrait class template.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:183
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
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.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatSMatMultExpr.h:267
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:79
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: TSMatSMatMultExpr.h:319
Header file for the Or class template.
Header file for the TDVecTSMatMultExprTrait class template.
#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
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
TSMatSMatMultExpr< MT1, MT2 > This
Type of this TSMatSMatMultExpr instance.
Definition: TSMatSMatMultExpr.h:178
Header file for the Columns type trait.
Header file for the TSMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatSMatMultExpr.h:309
TSMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatSMatMultExpr class.
Definition: TSMatSMatMultExpr.h:205
Header file for the SMatSVecMultExprTrait class template.
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the complete DynamicVector implementation.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:165
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatSMatMultExpr.h:287
EnableIf< IsDenseMatrix< MT1 > >::Type smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseVector type trait.
#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.
#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: RowMajorMatrix.h:79
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:179
Header file for run time assertion macros.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatSMatMultExpr.h:277
EnableIf< IsDenseMatrix< MT1 > >::Type smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:138
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatSMatMultExpr.h:182
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:130
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatSMatMultExpr.h:180
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatSMatMultExpr.h:184
Header file for the isDefault shim.
Constraint on the data type.
Constraints on the storage order of matrix types.
Expression object for transpose sparse matrix-sparse matrix multiplications.The TSMatSMatMultExpr cla...
Definition: Forward.h:153
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
Header file for the IsDenseVector type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatSMatMultExpr.h:343
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatSMatMultExpr.h:251
Header file for the IsRowMajorMatrix type trait.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatSMatMultExpr.h:360
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
Header file for the IsComputation type trait class.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
#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
Header file for the IsTrue value trait.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:128
Header file for the IsUpper type trait.
Header file for exception macros.
Header file for the IsColumnVector type trait.
Constraint on the data type.
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSMatSMatMultExpr.h:361
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatSMatMultExpr.h:220
Header file for the IsResizable type trait.
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:129
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#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
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Header file for the IsExpression type trait class.
Header file for the TSMatSVecMultExprTrait class template.
Header file for the FunctionTrace class.