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>
44 #include <blaze/math/Aliases.h>
51 #include <blaze/math/Exception.h>
78 #include <blaze/util/Assert.h>
79 #include <blaze/util/DisableIf.h>
80 #include <blaze/util/EnableIf.h>
83 #include <blaze/util/InvalidType.h>
84 #include <blaze/util/mpl/And.h>
85 #include <blaze/util/mpl/If.h>
86 #include <blaze/util/mpl/Or.h>
87 #include <blaze/util/Types.h>
88 #include <blaze/util/Unused.h>
89 
90 
91 namespace blaze {
92 
93 //=================================================================================================
94 //
95 // CLASS TSMATSMATMULTEXPR
96 //
97 //=================================================================================================
98 
99 //*************************************************************************************************
106 template< typename MT1 // Type of the left-hand side sparse matrix
107  , typename MT2 > // Type of the right-hand side sparse matrix
108 class TSMatSMatMultExpr
109  : public MatMatMultExpr< SparseMatrix< TSMatSMatMultExpr<MT1,MT2>, true > >
110  , private Computation
111 {
112  private:
113  //**Type definitions****************************************************************************
118  //**********************************************************************************************
119 
120  //**********************************************************************************************
122  enum : bool { evaluateLeft = RequiresEvaluation<MT1>::value };
123  //**********************************************************************************************
124 
125  //**********************************************************************************************
127  enum : bool { evaluateRight = RequiresEvaluation<MT2>::value };
128  //**********************************************************************************************
129 
130  //**********************************************************************************************
132 
139  template< typename T1, typename T2, typename T3 >
140  struct CanExploitSymmetry {
141  enum : bool { value = ( IsRowMajorMatrix<T1>::value && IsSymmetric<T2>::value ) ||
143  };
145  //**********************************************************************************************
146 
147  //**********************************************************************************************
149 
154  template< typename T1, typename T2, typename T3 >
155  struct IsEvaluationRequired {
156  enum : bool { value = ( evaluateLeft || evaluateRight ) &&
157  !CanExploitSymmetry<T1,T2,T2>::value };
158  };
160  //**********************************************************************************************
161 
162  public:
163  //**Type definitions****************************************************************************
169  using ReturnType = const ElementType;
170  using CompositeType = const ResultType;
171 
173  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
174 
176  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
177  //**********************************************************************************************
178 
179  //**Compilation flags***************************************************************************
181  enum : bool { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
182  !evaluateRight && MT2::smpAssignable };
183  //**********************************************************************************************
184 
185  //**Constructor*********************************************************************************
191  explicit inline TSMatSMatMultExpr( const MT1& lhs, const MT2& rhs ) noexcept
192  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
193  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
194  {
195  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
196  }
197  //**********************************************************************************************
198 
199  //**Access operator*****************************************************************************
206  inline ReturnType operator()( size_t i, size_t j ) const {
207  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
208  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
209 
210  if( IsDiagonal<MT1>::value ) {
211  return lhs_(i,i) * rhs_(i,j);
212  }
213  else if( IsDiagonal<MT2>::value ) {
214  return lhs_(i,j) * rhs_(j,j);
215  }
217  const size_t begin( ( IsUpper<MT1>::value )
218  ?( ( IsLower<MT2>::value )
219  ?( max( ( IsStrictlyUpper<MT1>::value ? i+1UL : i )
220  , ( IsStrictlyLower<MT2>::value ? j+1UL : j ) ) )
221  :( IsStrictlyUpper<MT1>::value ? i+1UL : i ) )
222  :( ( IsLower<MT2>::value )
223  ?( IsStrictlyLower<MT2>::value ? j+1UL : j )
224  :( 0UL ) ) );
225  const size_t end( ( IsLower<MT1>::value )
226  ?( ( IsUpper<MT2>::value )
227  ?( min( ( IsStrictlyLower<MT1>::value ? i : i+1UL )
228  , ( IsStrictlyUpper<MT2>::value ? j : j+1UL ) ) )
229  :( IsStrictlyLower<MT1>::value ? i : i+1UL ) )
230  :( ( IsUpper<MT2>::value )
231  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
232  :( lhs_.columns() ) ) );
233 
234  if( begin >= end ) return ElementType();
235 
236  const size_t n( end - begin );
237 
238  return subvector( row( lhs_, i ), begin, n ) * subvector( column( rhs_, j ), begin, n );
239  }
240  else {
241  return row( lhs_, i ) * column( rhs_, j );
242  }
243  }
244  //**********************************************************************************************
245 
246  //**At function*********************************************************************************
254  inline ReturnType at( size_t i, size_t j ) const {
255  if( i >= lhs_.rows() ) {
256  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
257  }
258  if( j >= rhs_.columns() ) {
259  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
260  }
261  return (*this)(i,j);
262  }
263  //**********************************************************************************************
264 
265  //**Rows function*******************************************************************************
270  inline size_t rows() const noexcept {
271  return lhs_.rows();
272  }
273  //**********************************************************************************************
274 
275  //**Columns function****************************************************************************
280  inline size_t columns() const noexcept {
281  return rhs_.columns();
282  }
283  //**********************************************************************************************
284 
285  //**NonZeros function***************************************************************************
290  inline constexpr size_t nonZeros() const noexcept {
291  return 0UL;
292  }
293  //**********************************************************************************************
294 
295  //**NonZeros function***************************************************************************
301  inline size_t nonZeros( size_t i ) const noexcept {
302  UNUSED_PARAMETER( i );
303  return 0UL;
304  }
305  //**********************************************************************************************
306 
307  //**Left operand access*************************************************************************
312  inline LeftOperand leftOperand() const noexcept {
313  return lhs_;
314  }
315  //**********************************************************************************************
316 
317  //**Right operand access************************************************************************
322  inline RightOperand rightOperand() const noexcept {
323  return rhs_;
324  }
325  //**********************************************************************************************
326 
327  //**********************************************************************************************
333  template< typename T >
334  inline bool canAlias( const T* alias ) const noexcept {
335  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
336  }
337  //**********************************************************************************************
338 
339  //**********************************************************************************************
345  template< typename T >
346  inline bool isAliased( const T* alias ) const noexcept {
347  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
348  }
349  //**********************************************************************************************
350 
351  //**********************************************************************************************
356  inline bool canSMPAssign() const noexcept {
357  return ( rows() * columns() >= SMP_TSMATSMATMULT_THRESHOLD );
358  }
359  //**********************************************************************************************
360 
361  private:
362  //**Member variables****************************************************************************
365  //**********************************************************************************************
366 
367  //**Assignment to dense matrices****************************************************************
380  template< typename MT // Type of the target dense matrix
381  , bool SO > // Storage order of the target dense matrix
383  assign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
384  {
386 
387  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
388  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
389 
390  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
391  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
392 
393  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
394  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
395  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
396  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
397  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
398  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
399 
400  TSMatSMatMultExpr::selectAssignKernel( ~lhs, A, B );
401  }
403  //**********************************************************************************************
404 
405  //**Default assignment to dense matrices********************************************************
419  template< typename MT3 // Type of the left-hand side target matrix
420  , typename MT4 // Type of the left-hand side matrix operand
421  , typename MT5 > // Type of the right-hand side matrix operand
422  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
423  {
424  using LeftIterator = ConstIterator_<MT4>;
425  using RightIterator = ConstIterator_<MT5>;
426 
427  for( size_t j=0UL; j<A.columns(); ++j ) {
428  const LeftIterator lend( A.end(j) );
429  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
430  const RightIterator rend( B.end(j) );
431  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
432  {
433  if( IsResizable< ElementType_<MT3> >::value &&
434  isDefault( C(lelem->index(),relem->index()) ) ) {
435  C(lelem->index(),relem->index()) = lelem->value() * relem->value();
436  }
437  else {
438  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
439  }
440  }
441  }
442  }
443  }
445  //**********************************************************************************************
446 
447  //**Assignment to row-major sparse matrices*****************************************************
460  template< typename MT > // Type of the target sparse matrix
462  assign( SparseMatrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
463  {
465 
467 
468  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
469  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
470 
472 
473  const OppositeType_<MT1> tmp( serial( rhs.lhs_ ) );
474  assign( ~lhs, tmp * rhs.rhs_ );
475  }
477  //**********************************************************************************************
478 
479  //**Assignment to column-major sparse matrices**************************************************
492  template< typename MT > // Type of the target sparse matrix
494  assign( SparseMatrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
495  {
497 
498  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
499  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
500 
502 
503  const OppositeType_<MT2> tmp( serial( rhs.rhs_ ) );
504  assign( ~lhs, rhs.lhs_ * tmp );
505  }
507  //**********************************************************************************************
508 
509  //**Restructuring assignment to row-major matrices**********************************************
524  template< typename MT > // Type of the target matrix
526  assign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
527  {
529 
531 
532  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
533  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
534 
535  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
536  }
538  //**********************************************************************************************
539 
540  //**Restructuring assignment to column-major matrices*******************************************
555  template< typename MT > // Type of the target matrix
557  assign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
558  {
560 
561  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
562  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
563 
564  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
565  }
567  //**********************************************************************************************
568 
569  //**Addition assignment to dense matrices*******************************************************
582  template< typename MT // Type of the target dense matrix
583  , bool SO > // Storage order of the target dense matarix
585  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
586  {
588 
589  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
590  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
591 
592  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
593  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
594 
595  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
596  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
597  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
598  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
599  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
600  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
601 
602  TSMatSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
603  }
605  //**********************************************************************************************
606 
607  //**Default addition assignment to dense matrices***********************************************
621  template< typename MT3 // Type of the left-hand side target matrix
622  , typename MT4 // Type of the left-hand side matrix operand
623  , typename MT5 > // Type of the right-hand side matrix operand
624  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
625  {
626  using LeftIterator = ConstIterator_<MT4>;
627  using RightIterator = ConstIterator_<MT5>;
628 
629  for( size_t j=0UL; j<A.columns(); ++j ) {
630  const LeftIterator lend( A.end(j) );
631  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
632  const RightIterator rend( B.end(j) );
633  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
634  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
635  }
636  }
637  }
638  }
640  //**********************************************************************************************
641 
642  //**Restructuring addition assignment to row-major matrices*************************************
657  template< typename MT > // Type of the target matrix
659  addAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
660  {
662 
664 
665  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
666  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
667 
668  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
669  }
671  //**********************************************************************************************
672 
673  //**Restructuring addition assignment to column-major matrices**********************************
688  template< typename MT > // Type of the target matrix
690  addAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
691  {
693 
694  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
695  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
696 
697  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
698  }
700  //**********************************************************************************************
701 
702  //**Addition assignment to sparse matrices******************************************************
703  // No special implementation for the addition assignment to sparse matrices.
704  //**********************************************************************************************
705 
706  //**Subtraction assignment to dense matrices****************************************************
719  template< typename MT // Type of the target dense matrix
720  , bool SO > // Storage order of the target dense matrix
721  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
722  {
724 
725  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
726  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
727 
728  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
729  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
730 
731  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
732  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
733  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
734  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
735  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
736  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
737 
738  TSMatSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
739  }
741  //**********************************************************************************************
742 
743  //**Default subtraction assignment to dense matrices********************************************
757  template< typename MT3 // Type of the left-hand side target matrix
758  , typename MT4 // Type of the left-hand side matrix operand
759  , typename MT5 > // Type of the right-hand side matrix operand
760  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
761  {
762  using LeftIterator = ConstIterator_<MT4>;
763  using RightIterator = ConstIterator_<MT5>;
764 
765  for( size_t j=0UL; j<A.columns(); ++j ) {
766  const LeftIterator lend( A.end(j) );
767  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
768  const RightIterator rend( B.end(j) );
769  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
770  C(lelem->index(),relem->index()) -= lelem->value() * relem->value();
771  }
772  }
773  }
774  }
776  //**********************************************************************************************
777 
778  //**Restructuring subtraction assignment to row-major matrices**********************************
793  template< typename MT > // Type of the target matrix
795  subAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
796  {
798 
800 
801  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
802  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
803 
804  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
805  }
807  //**********************************************************************************************
808 
809  //**Restructuring subtraction assignment to column-major matrices*******************************
824  template< typename MT > // Type of the target matrix
826  subAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
827  {
829 
830  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
831  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
832 
833  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
834  }
836  //**********************************************************************************************
837 
838  //**Subtraction assignment to sparse matrices***************************************************
839  // No special implementation for the subtraction assignment to sparse matrices.
840  //**********************************************************************************************
841 
842  //**Schur product assignment to dense matrices**************************************************
855  template< typename MT // Type of the target dense matrix
856  , bool SO > // Storage order of the target dense matrix
857  friend inline void schurAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
858  {
860 
864 
865  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
866  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
867 
868  const ResultType tmp( serial( rhs ) );
869  schurAssign( ~lhs, tmp );
870  }
872  //**********************************************************************************************
873 
874  //**Schur product assignment to sparse matrices*************************************************
875  // No special implementation for the Schur product assignment to sparse matrices.
876  //**********************************************************************************************
877 
878  //**Multiplication assignment to dense matrices*************************************************
879  // No special implementation for the multiplication assignment to dense matrices.
880  //**********************************************************************************************
881 
882  //**Multiplication assignment to sparse matrices************************************************
883  // No special implementation for the multiplication assignment to sparse matrices.
884  //**********************************************************************************************
885 
886  //**SMP assignment to matrices******************************************************************
902  template< typename MT // Type of the target matrix
903  , bool SO > // Storage order of the target matrix
905  smpAssign( Matrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
906  {
908 
909  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
910  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
911 
912  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
913  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
914 
915  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
916  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
917  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
918  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
919  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
920  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
921 
922  smpAssign( ~lhs, A * B );
923  }
925  //**********************************************************************************************
926 
927  //**Restructuring SMP assignment to row-major matrices******************************************
942  template< typename MT > // Type of the target matrix
944  smpAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
945  {
947 
949 
950  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
951  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
952 
953  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
954  }
956  //**********************************************************************************************
957 
958  //**Restructuring SMP assignment to column-major matrices***************************************
973  template< typename MT > // Type of the target matrix
975  smpAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
976  {
978 
979  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
980  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
981 
982  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
983  }
985  //**********************************************************************************************
986 
987  //**SMP addition assignment to dense matrices***************************************************
1003  template< typename MT // Type of the target dense matrix
1004  , bool SO > // Storage order of the target dense matarix
1007  {
1009 
1010  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1011  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1012 
1013  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1014  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1015 
1016  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1017  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1018  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1019  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1020  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1021  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1022 
1023  smpAddAssign( ~lhs, A * B );
1024  }
1026  //**********************************************************************************************
1027 
1028  //**Restructuring SMP addition assignment to row-major matrices*********************************
1043  template< typename MT > // Type of the target matrix
1045  smpAddAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
1046  {
1048 
1050 
1051  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1052  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1053 
1054  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1055  }
1057  //**********************************************************************************************
1058 
1059  //**Restructuring SMP addition assignment to column-major matrices******************************
1074  template< typename MT > // Type of the target matrix
1076  smpAddAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
1077  {
1079 
1080  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1081  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1082 
1083  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1084  }
1086  //**********************************************************************************************
1087 
1088  //**SMP addition assignment to sparse matrices**************************************************
1089  // No special implementation for the SMP addition assignment to sparse matrices.
1090  //**********************************************************************************************
1091 
1092  //**SMP subtraction assignment to dense matrices************************************************
1108  template< typename MT // Type of the target dense matrix
1109  , bool SO > // Storage order of the target dense matrix
1112  {
1114 
1115  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1116  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1117 
1118  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1119  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1120 
1121  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1122  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1123  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1124  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1125  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1126  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1127 
1128  smpSubAssign( ~lhs, A * B );
1129  }
1131  //**********************************************************************************************
1132 
1133  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1148  template< typename MT > // Type of the target matrix
1150  smpSubAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
1151  {
1153 
1155 
1156  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1157  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1158 
1159  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1160  }
1162  //**********************************************************************************************
1163 
1164  //**Restructuring SMP subtraction assignment to column-major matrices***************************
1179  template< typename MT > // Type of the target matrix
1181  smpSubAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
1182  {
1184 
1185  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1186  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1187 
1188  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1189  }
1191  //**********************************************************************************************
1192 
1193  //**SMP subtraction assignment to sparse matrices***********************************************
1194  // No special implementation for the SMP subtraction assignment to sparse matrices.
1195  //**********************************************************************************************
1196 
1197  //**SMP Schur product assignment to dense matrices**********************************************
1210  template< typename MT // Type of the target dense matrix
1211  , bool SO > // Storage order of the target dense matrix
1212  friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
1213  {
1215 
1219 
1220  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1221  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1222 
1223  const ResultType tmp( rhs );
1224  smpSchurAssign( ~lhs, tmp );
1225  }
1227  //**********************************************************************************************
1228 
1229  //**SMP Schur product assignment to sparse matrices*********************************************
1230  // No special implementation for the SMP Schur product assignment to sparse matrices.
1231  //**********************************************************************************************
1232 
1233  //**SMP multiplication assignment to dense matrices*********************************************
1234  // No special implementation for the SMP multiplication assignment to dense matrices.
1235  //**********************************************************************************************
1236 
1237  //**SMP multiplication assignment to sparse matrices********************************************
1238  // No special implementation for the SMP multiplication assignment to sparse matrices.
1239  //**********************************************************************************************
1240 
1241  //**Compile time checks*************************************************************************
1249  //**********************************************************************************************
1250 };
1251 //*************************************************************************************************
1252 
1253 
1254 
1255 
1256 //=================================================================================================
1257 //
1258 // GLOBAL BINARY ARITHMETIC OPERATORS
1259 //
1260 //=================================================================================================
1261 
1262 //*************************************************************************************************
1292 template< typename MT1 // Type of the left-hand side sparse matrix
1293  , typename MT2 > // Type of the right-hand side sparse matrix
1294 inline decltype(auto)
1295  operator*( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
1296 {
1298 
1299  if( (~lhs).columns() != (~rhs).rows() ) {
1300  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1301  }
1302 
1303  using ReturnType = const TSMatSMatMultExpr<MT1,MT2>;
1304  return ReturnType( ~lhs, ~rhs );
1305 }
1306 //*************************************************************************************************
1307 
1308 
1309 
1310 
1311 //=================================================================================================
1312 //
1313 // ROWS SPECIALIZATIONS
1314 //
1315 //=================================================================================================
1316 
1317 //*************************************************************************************************
1319 template< typename MT1, typename MT2 >
1320 struct Rows< TSMatSMatMultExpr<MT1,MT2> >
1321  : public Rows<MT1>
1322 {};
1324 //*************************************************************************************************
1325 
1326 
1327 
1328 
1329 //=================================================================================================
1330 //
1331 // COLUMNS SPECIALIZATIONS
1332 //
1333 //=================================================================================================
1334 
1335 //*************************************************************************************************
1337 template< typename MT1, typename MT2 >
1338 struct Columns< TSMatSMatMultExpr<MT1,MT2> >
1339  : public Columns<MT2>
1340 {};
1342 //*************************************************************************************************
1343 
1344 
1345 
1346 
1347 //=================================================================================================
1348 //
1349 // ISLOWER SPECIALIZATIONS
1350 //
1351 //=================================================================================================
1352 
1353 //*************************************************************************************************
1355 template< typename MT1, typename MT2 >
1356 struct IsLower< TSMatSMatMultExpr<MT1,MT2> >
1357  : public BoolConstant< And< IsLower<MT1>, IsLower<MT2> >::value >
1358 {};
1360 //*************************************************************************************************
1361 
1362 
1363 
1364 
1365 //=================================================================================================
1366 //
1367 // ISUNILOWER SPECIALIZATIONS
1368 //
1369 //=================================================================================================
1370 
1371 //*************************************************************************************************
1373 template< typename MT1, typename MT2 >
1374 struct IsUniLower< TSMatSMatMultExpr<MT1,MT2> >
1375  : public BoolConstant< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1376 {};
1378 //*************************************************************************************************
1379 
1380 
1381 
1382 
1383 //=================================================================================================
1384 //
1385 // ISSTRICTLYLOWER SPECIALIZATIONS
1386 //
1387 //=================================================================================================
1388 
1389 //*************************************************************************************************
1391 template< typename MT1, typename MT2 >
1392 struct IsStrictlyLower< TSMatSMatMultExpr<MT1,MT2> >
1393  : public BoolConstant< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1394  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1395 {};
1397 //*************************************************************************************************
1398 
1399 
1400 
1401 
1402 //=================================================================================================
1403 //
1404 // ISUPPER SPECIALIZATIONS
1405 //
1406 //=================================================================================================
1407 
1408 //*************************************************************************************************
1410 template< typename MT1, typename MT2 >
1411 struct IsUpper< TSMatSMatMultExpr<MT1,MT2> >
1412  : public BoolConstant< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1413 {};
1415 //*************************************************************************************************
1416 
1417 
1418 
1419 
1420 //=================================================================================================
1421 //
1422 // ISUNIUPPER SPECIALIZATIONS
1423 //
1424 //=================================================================================================
1425 
1426 //*************************************************************************************************
1428 template< typename MT1, typename MT2 >
1429 struct IsUniUpper< TSMatSMatMultExpr<MT1,MT2> >
1430  : public BoolConstant< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1431 {};
1433 //*************************************************************************************************
1434 
1435 
1436 
1437 
1438 //=================================================================================================
1439 //
1440 // ISSTRICTLYUPPER SPECIALIZATIONS
1441 //
1442 //=================================================================================================
1443 
1444 //*************************************************************************************************
1446 template< typename MT1, typename MT2 >
1447 struct IsStrictlyUpper< TSMatSMatMultExpr<MT1,MT2> >
1448  : public BoolConstant< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1449  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1450 {};
1452 //*************************************************************************************************
1453 
1454 } // namespace blaze
1455 
1456 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:114
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:87
Header file for basic type definitions.
Subvector< VT, AF > subvector(Vector< VT, TF > &vector, size_t index, size_t size)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:322
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatSMatMultExpr.h:206
EnableIf_< IsDenseMatrix< MT1 > > 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:164
Header file for the serial shim.
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
Header file for the IsColumnMajorMatrix type trait.
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatSMatMultExpr.h:312
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1762
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:165
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatSMatMultExpr.h:170
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:250
Column< MT > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:124
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:88
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatSMatMultExpr.h:254
Constraints on the storage order of matrix types.
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:176
Header file for the RequiresEvaluation type trait.
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1809
EnableIf_< IsDenseMatrix< MT1 > > 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:133
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:173
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
Header file for the SparseMatrix base class.
Row< MT > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:124
Constraint on the data type.
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: TSMatSMatMultExpr.h:322
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:72
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
Headerfile for the generic max algorithm.
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
Header file for the If class template.
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSMatSMatMultExpr.h:356
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:110
#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:61
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatSMatMultExpr.h:270
EnableIf_< IsDenseMatrix< MT1 > > 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:102
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the Columns type trait.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Header file for the IsLower type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatSMatMultExpr.h:280
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatSMatMultExpr.h:346
Header file for the IsTriangular type trait.
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:169
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:264
Constraint on the data type.
constexpr size_t nonZeros() const noexcept
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatSMatMultExpr.h:290
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
#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:108
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:86
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
#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:79
TSMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatSMatMultExpr class.
Definition: TSMatSMatMultExpr.h:191
#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:61
CompositeType_< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:117
Header file for run time assertion macros.
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:110
Utility type for generic codes.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatSMatMultExpr.h:334
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:116
ElementType_< ResultType > ElementType
Resulting element type.
Definition: TSMatSMatMultExpr.h:168
Header file for the isDefault shim.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
Constraint on the data type.
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
#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:81
Expression object for transpose sparse matrix-sparse matrix multiplications.The TSMatSMatMultExpr cla...
Definition: Forward.h:164
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:263
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
size_t nonZeros(size_t i) const noexcept
Returns the number of non-zero elements in the specified row.
Definition: TSMatSMatMultExpr.h:301
Header file for the IsRowMajorMatrix type trait.
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatSMatMultExpr.h:166
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatSMatMultExpr.h:363
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:167
Header file for the IsComputation type trait class.
Header file for the IntegralConstant class template.
Compile time evaluation of the number of columns of a matrix.The Columns type trait evaluates the num...
Definition: Columns.h:75
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:75
ResultType_< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:115
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Constraint on the data type.
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSMatSMatMultExpr.h:364
Header file for the IsResizable type trait.
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:61
Header file for the IsExpression type trait class.
Header file for the function trace functionality.