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>
50 #include <blaze/math/Exception.h>
55 #include <blaze/math/Functions.h>
93 #include <blaze/util/Assert.h>
94 #include <blaze/util/DisableIf.h>
95 #include <blaze/util/EnableIf.h>
97 #include <blaze/util/InvalidType.h>
99 #include <blaze/util/mpl/And.h>
100 #include <blaze/util/mpl/If.h>
101 #include <blaze/util/mpl/Or.h>
102 #include <blaze/util/Types.h>
103 #include <blaze/util/Unused.h>
104 
105 
106 namespace blaze {
107 
108 //=================================================================================================
109 //
110 // CLASS TSMATSMATMULTEXPR
111 //
112 //=================================================================================================
113 
114 //*************************************************************************************************
121 template< typename MT1 // Type of the left-hand side sparse matrix
122  , typename MT2 > // Type of the right-hand side sparse matrix
123 class TSMatSMatMultExpr : public SparseMatrix< TSMatSMatMultExpr<MT1,MT2>, true >
124  , private MatMatMultExpr
125  , private Computation
126 {
127  private:
128  //**Type definitions****************************************************************************
133  //**********************************************************************************************
134 
135  //**********************************************************************************************
137  enum : bool { evaluateLeft = RequiresEvaluation<MT1>::value };
138  //**********************************************************************************************
139 
140  //**********************************************************************************************
142  enum : bool { evaluateRight = RequiresEvaluation<MT2>::value };
143  //**********************************************************************************************
144 
145  //**********************************************************************************************
147 
154  template< typename T1, typename T2, typename T3 >
155  struct CanExploitSymmetry {
156  enum : bool { value = ( IsRowMajorMatrix<T1>::value && IsSymmetric<T2>::value ) ||
157  ( IsColumnMajorMatrix<T1>::value && IsSymmetric<T3>::value ) };
158  };
160  //**********************************************************************************************
161 
162  //**********************************************************************************************
164 
169  template< typename T1, typename T2, typename T3 >
170  struct IsEvaluationRequired {
171  enum : bool { value = ( evaluateLeft || evaluateRight ) &&
172  !CanExploitSymmetry<T1,T2,T2>::value };
173  };
175  //**********************************************************************************************
176 
177  public:
178  //**Type definitions****************************************************************************
184  typedef const ElementType ReturnType;
185  typedef const ResultType CompositeType;
186 
188  typedef If_< IsExpression<MT1>, const MT1, const MT1& > LeftOperand;
189 
191  typedef If_< IsExpression<MT2>, const MT2, const MT2& > RightOperand;
192  //**********************************************************************************************
193 
194  //**Compilation flags***************************************************************************
196  enum : bool { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
197  !evaluateRight && MT2::smpAssignable };
198  //**********************************************************************************************
199 
200  //**Constructor*********************************************************************************
206  explicit inline TSMatSMatMultExpr( const MT1& lhs, const MT2& rhs ) noexcept
207  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
208  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
209  {
210  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
211  }
212  //**********************************************************************************************
213 
214  //**Access operator*****************************************************************************
221  inline ReturnType operator()( size_t i, size_t j ) const {
222  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
223  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
224 
225  if( IsDiagonal<MT1>::value ) {
226  return lhs_(i,i) * rhs_(i,j);
227  }
228  else if( IsDiagonal<MT2>::value ) {
229  return lhs_(i,j) * rhs_(j,j);
230  }
232  const size_t begin( ( IsUpper<MT1>::value )
233  ?( ( IsLower<MT2>::value )
234  ?( max( ( IsStrictlyUpper<MT1>::value ? i+1UL : i )
235  , ( IsStrictlyLower<MT2>::value ? j+1UL : j ) ) )
236  :( IsStrictlyUpper<MT1>::value ? i+1UL : i ) )
237  :( ( IsLower<MT2>::value )
238  ?( IsStrictlyLower<MT2>::value ? j+1UL : j )
239  :( 0UL ) ) );
240  const size_t end( ( IsLower<MT1>::value )
241  ?( ( IsUpper<MT2>::value )
242  ?( min( ( IsStrictlyLower<MT1>::value ? i : i+1UL )
243  , ( IsStrictlyUpper<MT2>::value ? j : j+1UL ) ) )
244  :( IsStrictlyLower<MT1>::value ? i : i+1UL ) )
245  :( ( IsUpper<MT2>::value )
246  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
247  :( lhs_.columns() ) ) );
248 
249  if( begin >= end ) return ElementType();
250 
251  const size_t n( end - begin );
252 
253  return subvector( row( lhs_, i ), begin, n ) * subvector( column( rhs_, j ), begin, n );
254  }
255  else {
256  return row( lhs_, i ) * column( rhs_, j );
257  }
258  }
259  //**********************************************************************************************
260 
261  //**At function*********************************************************************************
269  inline ReturnType at( size_t i, size_t j ) const {
270  if( i >= lhs_.rows() ) {
271  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
272  }
273  if( j >= rhs_.columns() ) {
274  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
275  }
276  return (*this)(i,j);
277  }
278  //**********************************************************************************************
279 
280  //**Rows function*******************************************************************************
285  inline size_t rows() const noexcept {
286  return lhs_.rows();
287  }
288  //**********************************************************************************************
289 
290  //**Columns function****************************************************************************
295  inline size_t columns() const noexcept {
296  return rhs_.columns();
297  }
298  //**********************************************************************************************
299 
300  //**NonZeros function***************************************************************************
305  inline constexpr size_t nonZeros() const noexcept {
306  return 0UL;
307  }
308  //**********************************************************************************************
309 
310  //**NonZeros function***************************************************************************
316  inline size_t nonZeros( size_t i ) const noexcept {
317  UNUSED_PARAMETER( i );
318  return 0UL;
319  }
320  //**********************************************************************************************
321 
322  //**Left operand access*************************************************************************
327  inline LeftOperand leftOperand() const noexcept {
328  return lhs_;
329  }
330  //**********************************************************************************************
331 
332  //**Right operand access************************************************************************
337  inline RightOperand rightOperand() const noexcept {
338  return rhs_;
339  }
340  //**********************************************************************************************
341 
342  //**********************************************************************************************
348  template< typename T >
349  inline bool canAlias( const T* alias ) const noexcept {
350  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
351  }
352  //**********************************************************************************************
353 
354  //**********************************************************************************************
360  template< typename T >
361  inline bool isAliased( const T* alias ) const noexcept {
362  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
363  }
364  //**********************************************************************************************
365 
366  //**********************************************************************************************
371  inline bool canSMPAssign() const noexcept {
372  return ( rows() * columns() >= SMP_TSMATSMATMULT_THRESHOLD );
373  }
374  //**********************************************************************************************
375 
376  private:
377  //**Member variables****************************************************************************
378  LeftOperand lhs_;
379  RightOperand rhs_;
380  //**********************************************************************************************
381 
382  //**Assignment to dense matrices****************************************************************
395  template< typename MT // Type of the target dense matrix
396  , bool SO > // Storage order of the target dense matrix
398  assign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
399  {
401 
402  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
403  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
404 
405  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
406  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
407 
408  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
409  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
410  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
411  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
412  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
413  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
414 
415  TSMatSMatMultExpr::selectAssignKernel( ~lhs, A, B );
416  }
418  //**********************************************************************************************
419 
420  //**Default assignment to dense matrices********************************************************
434  template< typename MT3 // Type of the left-hand side target matrix
435  , typename MT4 // Type of the left-hand side matrix operand
436  , typename MT5 > // Type of the right-hand side matrix operand
437  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
438  {
439  typedef ConstIterator_<MT4> LeftIterator;
440  typedef ConstIterator_<MT5> RightIterator;
441 
442  for( size_t j=0UL; j<A.columns(); ++j ) {
443  const LeftIterator lend( A.end(j) );
444  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
445  const RightIterator rend( B.end(j) );
446  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
447  {
448  if( IsResizable< ElementType_<MT3> >::value &&
449  isDefault( C(lelem->index(),relem->index()) ) ) {
450  C(lelem->index(),relem->index()) = lelem->value() * relem->value();
451  }
452  else {
453  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
454  }
455  }
456  }
457  }
458  }
460  //**********************************************************************************************
461 
462  //**Assignment to row-major sparse matrices*****************************************************
475  template< typename MT > // Type of the target sparse matrix
476  friend inline DisableIf_< CanExploitSymmetry<MT,MT1,MT2> >
477  assign( SparseMatrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
478  {
480 
482 
483  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
484  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
485 
487 
488  const OppositeType_<MT1> tmp( serial( rhs.lhs_ ) );
489  assign( ~lhs, tmp * rhs.rhs_ );
490  }
492  //**********************************************************************************************
493 
494  //**Assignment to column-major sparse matrices**************************************************
507  template< typename MT > // Type of the target sparse matrix
508  friend inline DisableIf_< CanExploitSymmetry<MT,MT1,MT2> >
509  assign( SparseMatrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
510  {
512 
513  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
514  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
515 
517 
518  const OppositeType_<MT2> tmp( serial( rhs.rhs_ ) );
519  assign( ~lhs, rhs.lhs_ * tmp );
520  }
522  //**********************************************************************************************
523 
524  //**Restructuring assignment to row-major matrices**********************************************
539  template< typename MT > // Type of the target matrix
540  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
541  assign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
542  {
544 
546 
547  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
548  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
549 
550  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
551  }
553  //**********************************************************************************************
554 
555  //**Restructuring assignment to column-major matrices*******************************************
570  template< typename MT > // Type of the target matrix
571  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
572  assign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
573  {
575 
576  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
577  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
578 
579  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
580  }
582  //**********************************************************************************************
583 
584  //**Addition assignment to dense matrices*******************************************************
597  template< typename MT // Type of the target dense matrix
598  , bool SO > // Storage order of the target dense matarix
599  friend inline DisableIf_< CanExploitSymmetry<MT,MT1,MT2> >
600  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
601  {
603 
604  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
605  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
606 
607  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
608  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
609 
610  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
611  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
612  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
613  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
614  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
615  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
616 
617  TSMatSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
618  }
620  //**********************************************************************************************
621 
622  //**Default addition assignment to dense matrices***********************************************
636  template< typename MT3 // Type of the left-hand side target matrix
637  , typename MT4 // Type of the left-hand side matrix operand
638  , typename MT5 > // Type of the right-hand side matrix operand
639  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
640  {
641  typedef ConstIterator_<MT4> LeftIterator;
642  typedef ConstIterator_<MT5> RightIterator;
643 
644  for( size_t j=0UL; j<A.columns(); ++j ) {
645  const LeftIterator lend( A.end(j) );
646  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
647  const RightIterator rend( B.end(j) );
648  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
649  C(lelem->index(),relem->index()) += lelem->value() * relem->value();
650  }
651  }
652  }
653  }
655  //**********************************************************************************************
656 
657  //**Restructuring addition assignment to row-major matrices*************************************
672  template< typename MT > // Type of the target matrix
673  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
674  addAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
675  {
677 
679 
680  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
681  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
682 
683  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
684  }
686  //**********************************************************************************************
687 
688  //**Restructuring addition assignment to column-major matrices**********************************
703  template< typename MT > // Type of the target matrix
704  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
705  addAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
706  {
708 
709  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
710  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
711 
712  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
713  }
715  //**********************************************************************************************
716 
717  //**Addition assignment to sparse matrices******************************************************
718  // No special implementation for the addition assignment to sparse matrices.
719  //**********************************************************************************************
720 
721  //**Subtraction assignment to dense matrices****************************************************
734  template< typename MT // Type of the target dense matrix
735  , bool SO > // Storage order of the target dense matrix
736  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
737  {
739 
740  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
741  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
742 
743  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
744  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
745 
746  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
747  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
748  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
749  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
750  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
751  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
752 
753  TSMatSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
754  }
756  //**********************************************************************************************
757 
758  //**Default subtraction assignment to dense matrices********************************************
772  template< typename MT3 // Type of the left-hand side target matrix
773  , typename MT4 // Type of the left-hand side matrix operand
774  , typename MT5 > // Type of the right-hand side matrix operand
775  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
776  {
777  typedef ConstIterator_<MT4> LeftIterator;
778  typedef ConstIterator_<MT5> RightIterator;
779 
780  for( size_t j=0UL; j<A.columns(); ++j ) {
781  const LeftIterator lend( A.end(j) );
782  for( LeftIterator lelem=A.begin(j); lelem!=lend; ++lelem ) {
783  const RightIterator rend( B.end(j) );
784  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
785  C(lelem->index(),relem->index()) -= lelem->value() * relem->value();
786  }
787  }
788  }
789  }
791  //**********************************************************************************************
792 
793  //**Restructuring subtraction assignment to row-major matrices**********************************
808  template< typename MT > // Type of the target matrix
809  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
810  subAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
811  {
813 
815 
816  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
817  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
818 
819  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
820  }
822  //**********************************************************************************************
823 
824  //**Restructuring subtraction assignment to column-major matrices*******************************
839  template< typename MT > // Type of the target matrix
840  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
841  subAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
842  {
844 
845  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
846  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
847 
848  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
849  }
851  //**********************************************************************************************
852 
853  //**Subtraction assignment to sparse matrices***************************************************
854  // No special implementation for the subtraction assignment to sparse matrices.
855  //**********************************************************************************************
856 
857  //**Multiplication assignment to dense matrices*************************************************
858  // No special implementation for the multiplication assignment to dense matrices.
859  //**********************************************************************************************
860 
861  //**Multiplication assignment to sparse matrices************************************************
862  // No special implementation for the multiplication assignment to sparse matrices.
863  //**********************************************************************************************
864 
865  //**SMP assignment to matrices******************************************************************
881  template< typename MT // Type of the target matrix
882  , bool SO > // Storage order of the target matrix
883  friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
884  smpAssign( Matrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
885  {
887 
888  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
889  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
890 
891  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
892  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
893 
894  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
895  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
896  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
897  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
898  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
899  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
900 
901  smpAssign( ~lhs, A * B );
902  }
904  //**********************************************************************************************
905 
906  //**Restructuring SMP assignment to row-major matrices******************************************
921  template< typename MT > // Type of the target matrix
922  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
923  smpAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
924  {
926 
928 
929  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
930  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
931 
932  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
933  }
935  //**********************************************************************************************
936 
937  //**Restructuring SMP assignment to column-major matrices***************************************
952  template< typename MT > // Type of the target matrix
953  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
954  smpAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
955  {
957 
958  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
959  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
960 
961  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
962  }
964  //**********************************************************************************************
965 
966  //**SMP addition assignment to dense matrices***************************************************
982  template< typename MT // Type of the target dense matrix
983  , bool SO > // Storage order of the target dense matarix
984  friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
985  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
986  {
988 
989  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
990  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
991 
992  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
993  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
994 
995  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
996  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
997  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
998  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
999  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1000  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1001 
1002  smpAddAssign( ~lhs, A * B );
1003  }
1005  //**********************************************************************************************
1006 
1007  //**Restructuring SMP addition assignment to row-major matrices*********************************
1022  template< typename MT > // Type of the target matrix
1023  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1024  smpAddAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
1025  {
1027 
1029 
1030  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1031  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1032 
1033  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1034  }
1036  //**********************************************************************************************
1037 
1038  //**Restructuring SMP addition assignment to column-major matrices******************************
1053  template< typename MT > // Type of the target matrix
1054  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1055  smpAddAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
1056  {
1058 
1059  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1060  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1061 
1062  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1063  }
1065  //**********************************************************************************************
1066 
1067  //**SMP addition assignment to sparse matrices**************************************************
1068  // No special implementation for the SMP addition assignment to sparse matrices.
1069  //**********************************************************************************************
1070 
1071  //**SMP subtraction assignment to dense matrices************************************************
1087  template< typename MT // Type of the target dense matrix
1088  , bool SO > // Storage order of the target dense matrix
1089  friend inline EnableIf_< IsEvaluationRequired<MT,MT1,MT2> >
1090  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatMultExpr& rhs )
1091  {
1093 
1094  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1095  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1096 
1097  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1098  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1099 
1100  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1101  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1102  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1103  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1104  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1105  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1106 
1107  smpSubAssign( ~lhs, A * B );
1108  }
1110  //**********************************************************************************************
1111 
1112  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1127  template< typename MT > // Type of the target matrix
1128  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1129  smpSubAssign( Matrix<MT,false>& lhs, const TSMatSMatMultExpr& rhs )
1130  {
1132 
1134 
1135  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1136  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1137 
1138  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1139  }
1141  //**********************************************************************************************
1142 
1143  //**Restructuring SMP subtraction assignment to column-major matrices***************************
1158  template< typename MT > // Type of the target matrix
1159  friend inline EnableIf_< CanExploitSymmetry<MT,MT1,MT2> >
1160  smpSubAssign( Matrix<MT,true>& lhs, const TSMatSMatMultExpr& rhs )
1161  {
1163 
1164  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1165  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1166 
1167  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1168  }
1170  //**********************************************************************************************
1171 
1172  //**SMP subtraction assignment to sparse matrices***********************************************
1173  // No special implementation for the SMP subtraction assignment to sparse matrices.
1174  //**********************************************************************************************
1175 
1176  //**SMP multiplication assignment to dense matrices*********************************************
1177  // No special implementation for the SMP multiplication assignment to dense matrices.
1178  //**********************************************************************************************
1179 
1180  //**SMP multiplication assignment to sparse matrices********************************************
1181  // No special implementation for the SMP multiplication assignment to sparse matrices.
1182  //**********************************************************************************************
1183 
1184  //**Compile time checks*************************************************************************
1192  //**********************************************************************************************
1193 };
1194 //*************************************************************************************************
1195 
1196 
1197 
1198 
1199 //=================================================================================================
1200 //
1201 // GLOBAL BINARY ARITHMETIC OPERATORS
1202 //
1203 //=================================================================================================
1204 
1205 //*************************************************************************************************
1235 template< typename T1 // Type of the left-hand side sparse matrix
1236  , typename T2 > // Type of the right-hand side sparse matrix
1237 inline const TSMatSMatMultExpr<T1,T2>
1239 {
1241 
1242  if( (~lhs).columns() != (~rhs).rows() ) {
1243  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1244  }
1245 
1246  return TSMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1247 }
1248 //*************************************************************************************************
1249 
1250 
1251 
1252 
1253 //=================================================================================================
1254 //
1255 // ROWS SPECIALIZATIONS
1256 //
1257 //=================================================================================================
1258 
1259 //*************************************************************************************************
1261 template< typename MT1, typename MT2 >
1262 struct Rows< TSMatSMatMultExpr<MT1,MT2> > : public Rows<MT1>
1263 {};
1265 //*************************************************************************************************
1266 
1267 
1268 
1269 
1270 //=================================================================================================
1271 //
1272 // COLUMNS SPECIALIZATIONS
1273 //
1274 //=================================================================================================
1275 
1276 //*************************************************************************************************
1278 template< typename MT1, typename MT2 >
1279 struct Columns< TSMatSMatMultExpr<MT1,MT2> > : public Columns<MT2>
1280 {};
1282 //*************************************************************************************************
1283 
1284 
1285 
1286 
1287 //=================================================================================================
1288 //
1289 // ISLOWER SPECIALIZATIONS
1290 //
1291 //=================================================================================================
1292 
1293 //*************************************************************************************************
1295 template< typename MT1, typename MT2 >
1296 struct IsLower< TSMatSMatMultExpr<MT1,MT2> >
1297  : public BoolConstant< And< IsLower<MT1>, IsLower<MT2> >::value >
1298 {};
1300 //*************************************************************************************************
1301 
1302 
1303 
1304 
1305 //=================================================================================================
1306 //
1307 // ISUNILOWER SPECIALIZATIONS
1308 //
1309 //=================================================================================================
1310 
1311 //*************************************************************************************************
1313 template< typename MT1, typename MT2 >
1314 struct IsUniLower< TSMatSMatMultExpr<MT1,MT2> >
1315  : public BoolConstant< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1316 {};
1318 //*************************************************************************************************
1319 
1320 
1321 
1322 
1323 //=================================================================================================
1324 //
1325 // ISSTRICTLYLOWER SPECIALIZATIONS
1326 //
1327 //=================================================================================================
1328 
1329 //*************************************************************************************************
1331 template< typename MT1, typename MT2 >
1332 struct IsStrictlyLower< TSMatSMatMultExpr<MT1,MT2> >
1333  : public BoolConstant< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1334  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1335 {};
1337 //*************************************************************************************************
1338 
1339 
1340 
1341 
1342 //=================================================================================================
1343 //
1344 // ISUPPER SPECIALIZATIONS
1345 //
1346 //=================================================================================================
1347 
1348 //*************************************************************************************************
1350 template< typename MT1, typename MT2 >
1351 struct IsUpper< TSMatSMatMultExpr<MT1,MT2> >
1352  : public BoolConstant< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1353 {};
1355 //*************************************************************************************************
1356 
1357 
1358 
1359 
1360 //=================================================================================================
1361 //
1362 // ISUNIUPPER SPECIALIZATIONS
1363 //
1364 //=================================================================================================
1365 
1366 //*************************************************************************************************
1368 template< typename MT1, typename MT2 >
1369 struct IsUniUpper< TSMatSMatMultExpr<MT1,MT2> >
1370  : public BoolConstant< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1371 {};
1373 //*************************************************************************************************
1374 
1375 
1376 
1377 
1378 //=================================================================================================
1379 //
1380 // ISSTRICTLYUPPER SPECIALIZATIONS
1381 //
1382 //=================================================================================================
1383 
1384 //*************************************************************************************************
1386 template< typename MT1, typename MT2 >
1387 struct IsStrictlyUpper< TSMatSMatMultExpr<MT1,MT2> >
1388  : public BoolConstant< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1389  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1390 {};
1392 //*************************************************************************************************
1393 
1394 
1395 
1396 
1397 //=================================================================================================
1398 //
1399 // EXPRESSION TRAIT SPECIALIZATIONS
1400 //
1401 //=================================================================================================
1402 
1403 //*************************************************************************************************
1405 template< typename MT1, typename MT2, typename VT >
1406 struct TSMatDVecMultExprTrait< TSMatSMatMultExpr<MT1,MT2>, VT >
1407 {
1408  public:
1409  //**********************************************************************************************
1410  using Type = If_< And< IsSparseMatrix<MT1>, IsColumnMajorMatrix<MT1>
1411  , IsSparseMatrix<MT2>, IsRowMajorMatrix<MT2>
1412  , IsDenseVector<VT>, IsColumnVector<VT> >
1413  , TSMatDVecMultExprTrait_< MT1, SMatDVecMultExprTrait_<MT2,VT> >
1414  , INVALID_TYPE >;
1415  //**********************************************************************************************
1416 };
1418 //*************************************************************************************************
1419 
1420 
1421 //*************************************************************************************************
1423 template< typename MT1, typename MT2, typename VT >
1424 struct TSMatSVecMultExprTrait< TSMatSMatMultExpr<MT1,MT2>, VT >
1425 {
1426  public:
1427  //**********************************************************************************************
1428  using Type = If_< And< IsSparseMatrix<MT1>, IsColumnMajorMatrix<MT1>
1429  , IsSparseMatrix<MT2>, IsRowMajorMatrix<MT2>
1430  , IsSparseVector<VT>, IsColumnVector<VT> >
1431  , TSMatDVecMultExprTrait_< MT1, SMatDVecMultExprTrait_<MT2,VT> >
1432  , INVALID_TYPE >;
1433  //**********************************************************************************************
1434 };
1436 //*************************************************************************************************
1437 
1438 
1439 //*************************************************************************************************
1441 template< typename VT, typename MT1, typename MT2 >
1442 struct TDVecTSMatMultExprTrait< VT, TSMatSMatMultExpr<MT1,MT2> >
1443 {
1444  public:
1445  //**********************************************************************************************
1446  using Type = If_< And< IsDenseVector<VT>, IsRowVector<VT>
1447  , IsSparseMatrix<MT1>, IsColumnMajorMatrix<MT1>
1448  , IsSparseMatrix<MT2>, IsRowMajorMatrix<MT2> >
1449  , TDVecSMatMultExprTrait_< TDVecTSMatMultExprTrait_<VT,MT1>, MT2 >
1450  , INVALID_TYPE >;
1451  //**********************************************************************************************
1452 };
1454 //*************************************************************************************************
1455 
1456 
1457 //*************************************************************************************************
1459 template< typename VT, typename MT1, typename MT2 >
1460 struct TSVecTSMatMultExprTrait< VT, TSMatSMatMultExpr<MT1,MT2> >
1461 {
1462  public:
1463  //**********************************************************************************************
1464  using Type = If_< And< IsSparseVector<VT>, IsRowVector<VT>
1465  , IsSparseMatrix<MT1>, IsColumnMajorMatrix<MT1>
1466  , IsSparseMatrix<MT2>, IsRowMajorMatrix<MT2> >
1467  , TDVecSMatMultExprTrait_< TDVecTSMatMultExprTrait_<VT,MT1>, MT2 >
1468  , INVALID_TYPE >;
1469  //**********************************************************************************************
1470 };
1472 //*************************************************************************************************
1473 
1474 
1475 //*************************************************************************************************
1477 template< typename MT1, typename MT2, bool AF >
1478 struct SubmatrixExprTrait< TSMatSMatMultExpr<MT1,MT2>, AF >
1479 {
1480  public:
1481  //**********************************************************************************************
1482  using Type = MultExprTrait_< SubmatrixExprTrait_<const MT1,AF>
1483  , SubmatrixExprTrait_<const MT2,AF> >;
1484  //**********************************************************************************************
1485 };
1487 //*************************************************************************************************
1488 
1489 
1490 //*************************************************************************************************
1492 template< typename MT1, typename MT2 >
1493 struct RowExprTrait< TSMatSMatMultExpr<MT1,MT2> >
1494 {
1495  public:
1496  //**********************************************************************************************
1497  using Type = MultExprTrait_< RowExprTrait_<const MT1>, MT2 >;
1498  //**********************************************************************************************
1499 };
1501 //*************************************************************************************************
1502 
1503 
1504 //*************************************************************************************************
1506 template< typename MT1, typename MT2 >
1507 struct ColumnExprTrait< TSMatSMatMultExpr<MT1,MT2> >
1508 {
1509  public:
1510  //**********************************************************************************************
1511  using Type = MultExprTrait_< MT1, ColumnExprTrait_<const MT2> >;
1512  //**********************************************************************************************
1513 };
1515 //*************************************************************************************************
1516 
1517 } // namespace blaze
1518 
1519 #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
If_< IsExpression< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:191
Header file for auxiliary alias declarations.
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:129
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:7800
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.
ResultType_< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:130
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:160
Header file for the IsSparseMatrix type trait.
Header file for the serial shim.
Header file for the ColumnExprTrait class template.
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:188
Header file for the IsColumnMajorMatrix type trait.
Header file for the TSVecTSMatMultExprTrait class template.
Header file for the IsRowVector type trait.
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
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:1669
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
size_t nonZeros(size_t i) const noexcept
Returns the number of non-zero elements in the specified row.
Definition: TSMatSMatMultExpr.h:316
Header file for the TDVecSMatMultExprTrait class template.
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:245
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:180
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatSMatMultExpr.h:349
CompositeType_< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:132
Header file for the TSVecSMatMultExprTrait class template.
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:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1716
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:129
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, ColumnExprTrait_< MT > > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:126
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:109
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the MultExprTrait class template.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:184
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:72
SubvectorExprTrait_< VT, unaligned > 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:152
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Header file for the DisableIf class template.
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatSMatMultExpr.h:181
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.
#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
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:98
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 exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSMatSMatMultExpr.h:371
TSMatSMatMultExpr< MT1, MT2 > This
Type of this TSMatSMatMultExpr instance.
Definition: TSMatSMatMultExpr.h:179
Header file for the Columns type trait.
Header file for the TSMatDVecMultExprTrait class template.
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.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
Header file for the SMatSVecMultExprTrait class template.
Header file for the IsTriangular type trait.
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
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:254
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatSMatMultExpr.h:361
Header file for the RowExprTrait class template.
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:109
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, RowExprTrait_< MT > > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:126
ElementType_< ResultType > ElementType
Resulting element type.
Definition: TSMatSMatMultExpr.h:183
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:79
Header file for the SubmatrixExprTrait class template.
TSMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatSMatMultExpr class.
Definition: TSMatSMatMultExpr.h:206
#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
Header file for run time assertion macros.
Utility type for generic codes.
constexpr size_t nonZeros() const noexcept
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatSMatMultExpr.h:305
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:160
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatSMatMultExpr.h:185
Header file for the isDefault shim.
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:131
Constraint on the data type.
Constraints on the storage order of matrix types.
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:100
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: TSMatSMatMultExpr.h:337
Expression object for transpose sparse matrix-sparse matrix multiplications.The TSMatSMatMultExpr cla...
Definition: Forward.h:143
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:243
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatSMatMultExpr.h:182
Header file for the IsDenseVector type trait.
If_< IsExpression< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatMultExpr.h:188
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatSMatMultExpr.h:295
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatSMatMultExpr.h:269
Header file for the IsRowMajorMatrix type trait.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatSMatMultExpr.h:378
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:950
Header file for the IsComputation type trait class.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatSMatMultExpr.h:285
#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
Header file for the IntegralConstant class template.
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatSMatMultExpr.h:327
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:403
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
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:379
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatSMatMultExpr.h:221
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 TSMatSVecMultExprTrait class template.
Header file for the FunctionTrace class.