TSMatTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <vector>
53 #include <blaze/math/Functions.h>
54 #include <blaze/math/Infinity.h>
56 #include <blaze/math/shims/Reset.h>
88 #include <blaze/util/Assert.h>
89 #include <blaze/util/Byte.h>
90 #include <blaze/util/DisableIf.h>
91 #include <blaze/util/EnableIf.h>
92 #include <blaze/util/Exception.h>
93 #include <blaze/util/InvalidType.h>
95 #include <blaze/util/mpl/And.h>
96 #include <blaze/util/mpl/Or.h>
97 #include <blaze/util/SelectType.h>
98 #include <blaze/util/Types.h>
101 #include <blaze/util/Unused.h>
103 
104 
105 namespace blaze {
106 
107 //=================================================================================================
108 //
109 // CLASS TSMATTSMATMULTEXPR
110 //
111 //=================================================================================================
112 
113 //*************************************************************************************************
120 template< typename MT1 // Type of the left-hand side sparse matrix
121  , typename MT2 > // Type of the right-hand side sparse matrix
122 class TSMatTSMatMultExpr : public SparseMatrix< TSMatTSMatMultExpr<MT1,MT2>, true >
123  , private MatMatMultExpr
124  , private Computation
125 {
126  private:
127  //**Type definitions****************************************************************************
128  typedef typename MT1::ResultType RT1;
129  typedef typename MT2::ResultType RT2;
130  typedef typename MT1::CompositeType CT1;
131  typedef typename MT2::CompositeType CT2;
132  //**********************************************************************************************
133 
134  //**********************************************************************************************
136  enum { evaluateLeft = RequiresEvaluation<MT1>::value };
137  //**********************************************************************************************
138 
139  //**********************************************************************************************
141  enum { evaluateRight = RequiresEvaluation<MT2>::value };
142  //**********************************************************************************************
143 
144  //**********************************************************************************************
146 
151  template< typename T1, typename T2, typename T3 >
152  struct CanExploitSymmetry {
153  enum { value = IsRowMajorMatrix<T1>::value &&
154  IsSymmetric<T2>::value && IsSymmetric<T3>::value };
155  };
157  //**********************************************************************************************
158 
159  //**********************************************************************************************
161 
166  template< typename T1, typename T2, typename T3 >
167  struct IsEvaluationRequired {
168  enum { value = ( evaluateLeft || evaluateRight ) &&
169  !CanExploitSymmetry<T1,T2,T3>::value };
170  };
172  //**********************************************************************************************
173 
174  public:
175  //**Type definitions****************************************************************************
181  typedef const ElementType ReturnType;
182  typedef const ResultType CompositeType;
183 
185  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
186 
188  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
189  //**********************************************************************************************
190 
191  //**Compilation flags***************************************************************************
193  enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
194  !evaluateRight && MT2::smpAssignable };
195  //**********************************************************************************************
196 
197  //**Constructor*********************************************************************************
203  explicit inline TSMatTSMatMultExpr( const MT1& lhs, const MT2& rhs )
204  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
205  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
206  {
207  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
208  }
209  //**********************************************************************************************
210 
211  //**Access operator*****************************************************************************
218  inline ReturnType operator()( size_t i, size_t j ) const {
219  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
220  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
221 
223 
224  ElementType tmp = ElementType();
225 
226  // Early exit
227  if( lhs_.columns() == 0UL )
228  return tmp;
229 
230  // Fast computation in case the right-hand side sparse matrix directly provides iterators
232  {
233  // Evaluation of the right-hand side sparse matrix operand
234  CT2 B( rhs_ );
235 
236  const ConstIterator end( ( IsLower<MT1>::value )?( B.upperBound(i,j) ):( B.end(j) ) );
237  ConstIterator element( ( IsUpper<MT1>::value )?( B.lowerBound(i,j) ):( B.begin(j) ) );
238 
239  // Early exit in case row i is empty
240  if( element == end )
241  return tmp;
242 
243  // Calculating element (i,j)
244  tmp = lhs_(i,element->index()) * element->value();
245  ++element;
246  for( ; element!=end; ++element ) {
247  tmp += lhs_(i,element->index()) * element->value();
248  }
249  }
250 
251  // Default computation in case the right-hand side sparse matrix doesn't provide iterators
252  else {
253  const size_t kbegin( max( ( IsUpper<MT1>::value )?( i ):( 0UL ),
254  ( IsLower<MT2>::value )?( j ):( 0UL ) ) );
255  const size_t kend ( min( ( IsLower<MT1>::value )?( i+1UL ):( lhs_.columns() ),
256  ( IsUpper<MT2>::value )?( j+1UL ):( lhs_.columns() ) ) );
257 
258  tmp = lhs_(i,kbegin) * rhs_(kbegin,j);
259  for( size_t k=kbegin+1UL; k<kend; ++k ) {
260  tmp += lhs_(i,k) * rhs_(k,j);
261  }
262  }
263 
264  return tmp;
265  }
266  //**********************************************************************************************
267 
268  //**At function*********************************************************************************
276  inline ReturnType at( size_t i, size_t j ) const {
277  if( i >= lhs_.rows() ) {
278  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
279  }
280  if( j >= rhs_.columns() ) {
281  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
282  }
283  return (*this)(i,j);
284  }
285  //**********************************************************************************************
286 
287  //**Rows function*******************************************************************************
292  inline size_t rows() const {
293  return lhs_.rows();
294  }
295  //**********************************************************************************************
296 
297  //**Columns function****************************************************************************
302  inline size_t columns() const {
303  return rhs_.columns();
304  }
305  //**********************************************************************************************
306 
307  //**NonZeros function***************************************************************************
312  inline size_t nonZeros() const {
313  return 0UL;
314  }
315  //**********************************************************************************************
316 
317  //**NonZeros function***************************************************************************
323  inline size_t nonZeros( size_t i ) const {
324  UNUSED_PARAMETER( i );
325  return 0UL;
326  }
327  //**********************************************************************************************
328 
329  //**Left operand access*************************************************************************
334  inline LeftOperand leftOperand() const {
335  return lhs_;
336  }
337  //**********************************************************************************************
338 
339  //**Right operand access************************************************************************
344  inline RightOperand rightOperand() const {
345  return rhs_;
346  }
347  //**********************************************************************************************
348 
349  //**********************************************************************************************
355  template< typename T >
356  inline bool canAlias( const T* alias ) const {
357  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
358  }
359  //**********************************************************************************************
360 
361  //**********************************************************************************************
367  template< typename T >
368  inline bool isAliased( const T* alias ) const {
369  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
370  }
371  //**********************************************************************************************
372 
373  //**********************************************************************************************
378  inline bool canSMPAssign() const {
379  return ( rows() > SMP_TSMATTSMATMULT_THRESHOLD );
380  }
381  //**********************************************************************************************
382 
383  private:
384  //**Member variables****************************************************************************
385  LeftOperand lhs_;
386  RightOperand rhs_;
387  //**********************************************************************************************
388 
389  //**Assignment to dense matrices****************************************************************
402  template< typename MT // Type of the target dense matrix
403  , bool SO > // Storage order of the target dense matrix
404  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
405  assign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
406  {
408 
409  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
410  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
411 
412  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
413  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
414 
415  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
416  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
417  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
418  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
419  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
420  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
421 
422  TSMatTSMatMultExpr::selectAssignKernel( ~lhs, A, B );
423  }
425  //**********************************************************************************************
426 
427  //**Default assignment to dense matrices********************************************************
441  template< typename MT3 // Type of the left-hand side target matrix
442  , typename MT4 // Type of the left-hand side matrix operand
443  , typename MT5 > // Type of the right-hand side matrix operand
444  static inline void selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
445  {
446  typedef typename MT4::ConstIterator LeftIterator;
447  typedef typename MT5::ConstIterator RightIterator;
448 
449  for( size_t j=0UL; j<C.columns(); ++j ) {
450  const RightIterator rend( B.end(j) );
451  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
452  const LeftIterator lend( A.end( relem->index() ) );
453  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
454  {
456  isDefault( C(lelem->index(),j) ) ) {
457  C(lelem->index(),j) = lelem->value() * relem->value();
458  }
459  else {
460  C(lelem->index(),j) += lelem->value() * relem->value();
461  }
462  }
463  }
464  }
465  }
467  //**********************************************************************************************
468 
469  //**Assignment to row-major sparse matrices*****************************************************
482  template< typename MT > // Type of the target sparse matrix
483  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
484  assign( SparseMatrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
485  {
487 
489 
490  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
491  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
492 
495 
496  const ResultType tmp( serial( rhs ) );
497  (~lhs).reserve( tmp.nonZeros() );
498  assign( ~lhs, tmp );
499  }
501  //**********************************************************************************************
502 
503  //**Assignment to column-major sparse matrices**************************************************
516  template< typename MT > // Type of the target sparse matrix
517  friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatTSMatMultExpr& rhs )
518  {
520 
521  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
522  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
523 
524  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
525  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
526 
527  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
528  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
529 
530  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
531  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
532  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
533  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
534  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
535  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
536 
537  // (Over-)Estimating the number of non-zero entries in the resulting matrix
538  size_t nonzeros( 0UL );
539 
540  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
541  const RightIterator rend( B.end(j) );
542  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
543  nonzeros += A.nonZeros( relem->index() );
544  }
545  }
546 
547  if( nonzeros > (~lhs).rows() * (~lhs).columns() ) {
548  nonzeros = (~lhs).rows() * (~lhs).columns();
549  }
550 
551  (~lhs).reserve( nonzeros );
552  nonzeros = 0UL;
553 
554  // Performing the matrix-matrix multiplication
555  std::vector<ElementType> values ( (~lhs).rows(), ElementType() );
556  std::vector<byte> valid ( (~lhs).rows(), 0 );
557  std::vector<size_t> indices( (~lhs).rows(), 0UL );
558  size_t minIndex( inf ), maxIndex( 0UL );
559 
560  for( size_t j=0UL; j<(~lhs).columns(); ++j )
561  {
562  const RightIterator rend( B.end(j) );
563  for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
564  {
565  const LeftIterator lend( A.end( relem->index() ) );
566  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
567  {
568  if( !valid[lelem->index()] ) {
569  values[lelem->index()] = lelem->value() * relem->value();
570  valid [lelem->index()] = 1;
571  indices[nonzeros] = lelem->index();
572  ++nonzeros;
573  if( lelem->index() < minIndex ) minIndex = lelem->index();
574  if( lelem->index() > maxIndex ) maxIndex = lelem->index();
575  }
576  else {
577  values[lelem->index()] += lelem->value() * relem->value();
578  }
579  }
580  }
581 
582  BLAZE_INTERNAL_ASSERT( nonzeros <= (~lhs).rows(), "Invalid number of non-zero elements" );
583 
584  if( nonzeros > 0UL )
585  {
586  BLAZE_INTERNAL_ASSERT( minIndex <= maxIndex, "Invalid index detected" );
587 
588  if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
589  {
590  std::sort( indices.begin(), indices.begin() + nonzeros );
591 
592  for( size_t i=0UL; i<nonzeros; ++i )
593  {
594  const size_t index( indices[i] );
595  if( !isDefault( values[index] ) ) {
596  (~lhs).append( index, j, values[index] );
597  reset( values[index] );
598  }
599 
600  reset( valid [index] );
601  }
602  }
603  else {
604  for( size_t i=minIndex; i<=maxIndex; ++i )
605  {
606  if( !isDefault( values[i] ) ) {
607  (~lhs).append( i, j, values[i] );
608  reset( values[i] );
609  }
610 
611  reset( valid [i] );
612  }
613  }
614 
615  nonzeros = 0UL;
616  minIndex = inf;
617  maxIndex = 0UL;
618  }
619 
620  (~lhs).finalize( j );
621  }
622  }
624  //**********************************************************************************************
625 
626  //**Restructuring assignment to row-major matrices**********************************************
641  template< typename MT > // Type of the target matrix
642  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
643  assign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
644  {
646 
648 
649  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
650  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
651 
652  assign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
653  }
655  //**********************************************************************************************
656 
657  //**Addition assignment to dense matrices*******************************************************
670  template< typename MT // Type of the target dense matrix
671  , bool SO > // Storage order of the target dense matarix
672  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
673  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
674  {
676 
677  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
678  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
679 
680  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
681  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
682 
683  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
684  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
685  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
686  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
687  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
688  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
689 
690  TSMatTSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
691  }
693  //**********************************************************************************************
694 
695  //**Default addition assignment to dense matrices***********************************************
709  template< typename MT3 // Type of the left-hand side target matrix
710  , typename MT4 // Type of the left-hand side matrix operand
711  , typename MT5 > // Type of the right-hand side matrix operand
712  static inline void selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
713  {
714  typedef typename MT4::ConstIterator LeftIterator;
715  typedef typename MT5::ConstIterator RightIterator;
716 
717  for( size_t j=0UL; j<C.columns(); ++j ) {
718  const RightIterator rend( B.end(j) );
719  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
720  const LeftIterator lend( A.end( relem->index() ) );
721  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
722  C(lelem->index(),j) += lelem->value() * relem->value();
723  }
724  }
725  }
726  }
728  //**********************************************************************************************
729 
730  //**Restructuring addition assignment to row-major matrices*************************************
745  template< typename MT > // Type of the target matrix
746  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
747  addAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
748  {
750 
752 
753  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
754  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
755 
756  addAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
757  }
759  //**********************************************************************************************
760 
761  //**Addition assignment to sparse matrices******************************************************
762  // No special implementation for the addition assignment to sparse matrices.
763  //**********************************************************************************************
764 
765  //**Subtraction assignment to dense matrices****************************************************
778  template< typename MT // Type of the target dense matrix
779  , bool SO > // Storage order of the target dense matarix
780  friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
781  subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
782  {
784 
785  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
786  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
787 
788  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
789  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
790 
791  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
792  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
793 
794  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
795  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
796  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
797  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
798  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
799  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
800 
801  TSMatTSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
802  }
804  //**********************************************************************************************
805 
806  //**Default subtraction assignment to dense matrices********************************************
820  template< typename MT3 // Type of the left-hand side target matrix
821  , typename MT4 // Type of the left-hand side matrix operand
822  , typename MT5 > // Type of the right-hand side matrix operand
823  static inline void selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
824  {
825  typedef typename MT4::ConstIterator LeftIterator;
826  typedef typename MT5::ConstIterator RightIterator;
827 
828  for( size_t j=0UL; j<C.columns(); ++j ) {
829  const RightIterator rend( B.end(j) );
830  for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
831  const LeftIterator lend( A.end( relem->index() ) );
832  for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
833  C(lelem->index(),j) -= lelem->value() * relem->value();
834  }
835  }
836  }
837  }
839  //**********************************************************************************************
840 
841  //**Restructuring subtraction assignment to row-major matrices**********************************
857  template< typename MT > // Type of the target matrix
858  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
859  subAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
860  {
862 
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  subAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
869  }
871  //**********************************************************************************************
872 
873  //**Subtraction assignment to sparse matrices***************************************************
874  // No special implementation for the subtraction assignment to sparse matrices.
875  //**********************************************************************************************
876 
877  //**Multiplication assignment to dense matrices*************************************************
878  // No special implementation for the multiplication assignment to dense matrices.
879  //**********************************************************************************************
880 
881  //**Multiplication assignment to sparse matrices************************************************
882  // No special implementation for the multiplication assignment to sparse matrices.
883  //**********************************************************************************************
884 
885  //**SMP assignment to matrices******************************************************************
901  template< typename MT // Type of the target matrix
902  , bool SO > // Storage order of the target matrix
903  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
904  smpAssign( Matrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
905  {
907 
908  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
909  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
910 
911  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
912  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
913 
914  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
915  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
916  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
917  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
918  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
919  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
920 
921  smpAssign( ~lhs, A * B );
922  }
924  //**********************************************************************************************
925 
926  //**Restructuring SMP assignment to row-major matrices******************************************
941  template< typename MT > // Type of the target matrix
942  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
943  smpAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
944  {
946 
948 
949  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
950  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
951 
952  smpAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
953  }
955  //**********************************************************************************************
956 
957  //**SMP addition assignment to dense matrices***************************************************
973  template< typename MT // Type of the target dense matrix
974  , bool SO > // Storage order of the target dense matarix
975  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
976  smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
977  {
979 
980  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
981  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
982 
983  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
984  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
985 
986  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
987  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
988  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
989  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
990  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
991  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
992 
993  smpAddAssign( ~lhs, A * B );
994  }
996  //**********************************************************************************************
997 
998  //**Restructuring SMP addition assignment to row-major matrices*********************************
1014  template< typename MT > // Type of the target matrix
1015  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1016  smpAddAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
1017  {
1019 
1021 
1022  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1023  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1024 
1025  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1026  }
1028  //**********************************************************************************************
1029 
1030  //**SMP addition assignment to sparse matrices**************************************************
1031  // No special implementation for the SMP addition assignment to sparse matrices.
1032  //**********************************************************************************************
1033 
1034  //**SMP subtraction assignment to dense matrices************************************************
1050  template< typename MT // Type of the target dense matrix
1051  , bool SO > // Storage order of the target dense matarix
1052  friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1053  smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatMultExpr& rhs )
1054  {
1056 
1057  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1058  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1059 
1060  CT1 A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1061  CT2 B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1062 
1063  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1064  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1065  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1066  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1067  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1068  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1069 
1070  smpSubAssign( ~lhs, A * B );
1071  }
1073  //**********************************************************************************************
1074 
1075  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1091  template< typename MT > // Type of the target matrix
1092  friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1093  smpSubAssign( Matrix<MT,false>& lhs, const TSMatTSMatMultExpr& rhs )
1094  {
1096 
1098 
1099  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1100  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1101 
1102  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * trans( rhs.rhs_ ) );
1103  }
1105  //**********************************************************************************************
1106 
1107  //**SMP subtraction assignment to sparse matrices***********************************************
1108  // No special implementation for the SMP subtraction assignment to sparse matrices.
1109  //**********************************************************************************************
1110 
1111  //**SMP multiplication assignment to dense matrices*********************************************
1112  // No special implementation for the SMP multiplication assignment to dense matrices.
1113  //**********************************************************************************************
1114 
1115  //**SMP multiplication assignment to sparse matrices********************************************
1116  // No special implementation for the SMP multiplication assignment to sparse matrices.
1117  //**********************************************************************************************
1118 
1119  //**Compile time checks*************************************************************************
1127  //**********************************************************************************************
1128 };
1129 //*************************************************************************************************
1130 
1131 
1132 
1133 
1134 //=================================================================================================
1135 //
1136 // GLOBAL BINARY ARITHMETIC OPERATORS
1137 //
1138 //=================================================================================================
1139 
1140 //*************************************************************************************************
1167 template< typename T1 // Type of the left-hand side sparse matrix
1168  , typename T2 > // Type of the right-hand side sparse matrix
1169 inline const TSMatTSMatMultExpr<T1,T2>
1171 {
1173 
1174  if( (~lhs).columns() != (~rhs).rows() ) {
1175  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1176  }
1177 
1178  return TSMatTSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1179 }
1180 //*************************************************************************************************
1181 
1182 
1183 
1184 
1185 //=================================================================================================
1186 //
1187 // ROWS SPECIALIZATIONS
1188 //
1189 //=================================================================================================
1190 
1191 //*************************************************************************************************
1193 template< typename MT1, typename MT2 >
1194 struct Rows< TSMatTSMatMultExpr<MT1,MT2> > : public Rows<MT1>
1195 {};
1197 //*************************************************************************************************
1198 
1199 
1200 
1201 
1202 //=================================================================================================
1203 //
1204 // COLUMNS SPECIALIZATIONS
1205 //
1206 //=================================================================================================
1207 
1208 //*************************************************************************************************
1210 template< typename MT1, typename MT2 >
1211 struct Columns< TSMatTSMatMultExpr<MT1,MT2> > : public Columns<MT2>
1212 {};
1214 //*************************************************************************************************
1215 
1216 
1217 
1218 
1219 //=================================================================================================
1220 //
1221 // ISLOWER SPECIALIZATIONS
1222 //
1223 //=================================================================================================
1224 
1225 //*************************************************************************************************
1227 template< typename MT1, typename MT2 >
1228 struct IsLower< TSMatTSMatMultExpr<MT1,MT2> >
1229  : public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
1230 {};
1232 //*************************************************************************************************
1233 
1234 
1235 
1236 
1237 //=================================================================================================
1238 //
1239 // ISUNILOWER SPECIALIZATIONS
1240 //
1241 //=================================================================================================
1242 
1243 //*************************************************************************************************
1245 template< typename MT1, typename MT2 >
1246 struct IsUniLower< TSMatTSMatMultExpr<MT1,MT2> >
1247  : public IsTrue< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1248 {};
1250 //*************************************************************************************************
1251 
1252 
1253 
1254 
1255 //=================================================================================================
1256 //
1257 // ISSTRICTLYLOWER SPECIALIZATIONS
1258 //
1259 //=================================================================================================
1260 
1261 //*************************************************************************************************
1263 template< typename MT1, typename MT2 >
1264 struct IsStrictlyLower< TSMatTSMatMultExpr<MT1,MT2> >
1265  : public IsTrue< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1266  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1267 {};
1269 //*************************************************************************************************
1270 
1271 
1272 
1273 
1274 //=================================================================================================
1275 //
1276 // ISUPPER SPECIALIZATIONS
1277 //
1278 //=================================================================================================
1279 
1280 //*************************************************************************************************
1282 template< typename MT1, typename MT2 >
1283 struct IsUpper< TSMatTSMatMultExpr<MT1,MT2> >
1284  : public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1285 {};
1287 //*************************************************************************************************
1288 
1289 
1290 
1291 
1292 //=================================================================================================
1293 //
1294 // ISUNIUPPER SPECIALIZATIONS
1295 //
1296 //=================================================================================================
1297 
1298 //*************************************************************************************************
1300 template< typename MT1, typename MT2 >
1301 struct IsUniUpper< TSMatTSMatMultExpr<MT1,MT2> >
1302  : public IsTrue< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1303 {};
1305 //*************************************************************************************************
1306 
1307 
1308 
1309 
1310 //=================================================================================================
1311 //
1312 // ISSTRICTLYUPPER SPECIALIZATIONS
1313 //
1314 //=================================================================================================
1315 
1316 //*************************************************************************************************
1318 template< typename MT1, typename MT2 >
1319 struct IsStrictlyUpper< TSMatTSMatMultExpr<MT1,MT2> >
1320  : public IsTrue< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1321  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1322 {};
1324 //*************************************************************************************************
1325 
1326 
1327 
1328 
1329 //=================================================================================================
1330 //
1331 // EXPRESSION TRAIT SPECIALIZATIONS
1332 //
1333 //=================================================================================================
1334 
1335 //*************************************************************************************************
1337 template< typename MT1, typename MT2, typename VT >
1338 struct TSMatDVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
1339 {
1340  public:
1341  //**********************************************************************************************
1342  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1343  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1344  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1345  , typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1346  , INVALID_TYPE >::Type Type;
1347  //**********************************************************************************************
1348 };
1350 //*************************************************************************************************
1351 
1352 
1353 //*************************************************************************************************
1355 template< typename MT1, typename MT2, typename VT >
1356 struct TSMatSVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
1357 {
1358  public:
1359  //**********************************************************************************************
1360  typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1361  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1362  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1363  , typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1364  , INVALID_TYPE >::Type Type;
1365  //**********************************************************************************************
1366 };
1368 //*************************************************************************************************
1369 
1370 
1371 //*************************************************************************************************
1373 template< typename VT, typename MT1, typename MT2 >
1374 struct TDVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
1375 {
1376  public:
1377  //**********************************************************************************************
1378  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1379  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1380  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1381  , typename TDVecTSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1382  , INVALID_TYPE >::Type Type;
1383  //**********************************************************************************************
1384 };
1386 //*************************************************************************************************
1387 
1388 
1389 //*************************************************************************************************
1391 template< typename VT, typename MT1, typename MT2 >
1392 struct TSVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
1393 {
1394  public:
1395  //**********************************************************************************************
1396  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1397  IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1398  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1399  , typename TSVecTSMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1400  , INVALID_TYPE >::Type Type;
1401  //**********************************************************************************************
1402 };
1404 //*************************************************************************************************
1405 
1406 
1407 //*************************************************************************************************
1409 template< typename MT1, typename MT2, bool AF >
1410 struct SubmatrixExprTrait< TSMatTSMatMultExpr<MT1,MT2>, AF >
1411 {
1412  public:
1413  //**********************************************************************************************
1414  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1415  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1416  //**********************************************************************************************
1417 };
1419 //*************************************************************************************************
1420 
1421 
1422 //*************************************************************************************************
1424 template< typename MT1, typename MT2 >
1425 struct RowExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
1426 {
1427  public:
1428  //**********************************************************************************************
1429  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1430  //**********************************************************************************************
1431 };
1433 //*************************************************************************************************
1434 
1435 
1436 //*************************************************************************************************
1438 template< typename MT1, typename MT2 >
1439 struct ColumnExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
1440 {
1441  public:
1442  //**********************************************************************************************
1443  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1444  //**********************************************************************************************
1445 };
1447 //*************************************************************************************************
1448 
1449 } // namespace blaze
1450 
1451 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
Header file for mathematical functions.
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7820
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:188
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:181
Header file for basic type definitions.
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:250
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:179
Header file for the ColumnExprTrait class template.
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
Header file for the TSVecTSMatMultExprTrait class template.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:259
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSMatTSMatMultExpr.h:356
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Header file for the RequiresEvaluation type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTSMatMultExpr.h:368
Header file for the IsUniLower type trait.
LeftOperand leftOperand() const
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:334
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:117
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatTSMatMultExpr.h:276
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TSMatTSMatMultExpr.h:292
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:79
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
Header file for the Or class template.
Header file for the TDVecTSMatMultExprTrait class template.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatTSMatMultExpr.h:323
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:130
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
Header file for the Columns type trait.
Header file for the TSMatDVecMultExprTrait class template.
Numerical infinity for built-in data types.
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSMatTSMatMultExpr.h:386
Expression object for transpose sparse matrix-transpose sparse matrix multiplications.The TSMatTSMatMultExpr class represents the compile time expression for multiplications between two column-major sparse matrices.
Definition: Forward.h:158
TSMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TSMatTSMatMultExpr class.
Definition: TSMatTSMatMultExpr.h:203
Header file for the IsLower type trait.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatTSMatMultExpr.h:385
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:131
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:165
Header file for the byte type.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTSMatMultExpr.h:218
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:344
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
EnableIf< IsDenseMatrix< MT1 > >::Type smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
Header file for the SubmatrixExprTrait class template.
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Header file for run time assertion macros.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:178
EnableIf< IsDenseMatrix< MT1 > >::Type smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:138
Header file for the reset shim.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TSMatTSMatMultExpr.h:302
Header file for the isDefault shim.
Constraint on the data type.
Constraints on the storage order of matrix types.
const Infinity inf
Global Infinity instance.The blaze::inf instance can be used wherever a built-in data type is expecte...
Definition: Infinity.h:1098
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:177
Header file for the RemoveReference type trait.
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
Header file for the IsDenseVector type trait.
TSMatTSMatMultExpr< MT1, MT2 > This
Type of this TSMatTSMatMultExpr instance.
Definition: TSMatTSMatMultExpr.h:176
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTSMatMultExpr.h:182
ResultType::ElementType ElementType
Resulting element type.
Definition: TSMatTSMatMultExpr.h:180
Header file for the IsRowMajorMatrix type trait.
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:129
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
Header file for the IsTrue value trait.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatTSMatMultExpr.h:312
Header file for the IsUpper type trait.
Header file for exception macros.
Header file for the IsColumnVector type trait.
Constraint on the data type.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:185
Header file for the IsResizable type trait.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSMatTSMatMultExpr.h:378
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Header file for the IsExpression type trait class.
Header file for the TSMatSVecMultExprTrait class template.
Header file for the FunctionTrace class.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:128