DMatTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATTSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
55 #include <blaze/math/Functions.h>
63 #include <blaze/math/shims/Reset.h>
107 #include <blaze/system/Thresholds.h>
108 #include <blaze/util/Assert.h>
110 #include <blaze/util/DisableIf.h>
111 #include <blaze/util/EnableIf.h>
114 #include <blaze/util/InvalidType.h>
115 #include <blaze/util/mpl/And.h>
116 #include <blaze/util/mpl/Bool.h>
117 #include <blaze/util/mpl/If.h>
118 #include <blaze/util/mpl/Or.h>
119 #include <blaze/util/TrueType.h>
120 #include <blaze/util/Types.h>
123 
124 
125 namespace blaze {
126 
127 //=================================================================================================
128 //
129 // CLASS DMATTSMATMULTEXPR
130 //
131 //=================================================================================================
132 
133 //*************************************************************************************************
140 template< typename MT1 // Type of the left-hand side dense matrix
141  , typename MT2 // Type of the right-hand side sparse matrix
142  , bool SF // Symmetry flag
143  , bool HF // Hermitian flag
144  , bool LF // Lower flag
145  , bool UF > // Upper flag
146 class DMatTSMatMultExpr : public DenseMatrix< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF>, false >
147  , private MatMatMultExpr
148  , private Computation
149 {
150  private:
151  //**Type definitions****************************************************************************
158  //**********************************************************************************************
159 
160  //**********************************************************************************************
162  enum : bool { evaluateLeft = IsComputation<MT1>::value || RequiresEvaluation<MT1>::value };
163  //**********************************************************************************************
164 
165  //**********************************************************************************************
167  enum : bool { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
168  //**********************************************************************************************
169 
170  //**********************************************************************************************
172  enum : bool {
173  SYM = ( SF && !( HF || LF || UF ) ),
174  HERM = ( HF && !( LF || UF ) ),
175  LOW = ( LF || ( ( SF || HF ) && UF ) ),
176  UPP = ( UF || ( ( SF || HF ) && LF ) )
177  };
178  //**********************************************************************************************
179 
180  //**********************************************************************************************
182 
187  template< typename T1, typename T2, typename T3 >
188  struct CanExploitSymmetry {
189  enum : bool { value = IsSymmetric<T2>::value };
190  };
192  //**********************************************************************************************
193 
194  //**********************************************************************************************
196 
200  template< typename T1, typename T2, typename T3 >
201  struct IsEvaluationRequired {
202  enum : bool { value = ( evaluateLeft || evaluateRight ) &&
203  !CanExploitSymmetry<T1,T2,T3>::value };
204  };
206  //**********************************************************************************************
207 
208  //**********************************************************************************************
210 
213  template< typename T1, typename T2, typename T3 >
214  struct UseOptimizedKernel {
215  enum : bool { value = useOptimizedKernels &&
217  !IsResizable< ElementType_<T1> >::value &&
219  };
221  //**********************************************************************************************
222 
223  //**********************************************************************************************
225 
228  typedef IfTrue_< HERM
229  , DeclHerm
230  , IfTrue_< SYM
231  , DeclSym
232  , IfTrue_< LOW
233  , IfTrue_< UPP
234  , DeclDiag
235  , DeclLow >
236  , IfTrue_< UPP
237  , DeclUpp
238  , Noop > > > > ForwardFunctor;
240  //**********************************************************************************************
241 
242  public:
243  //**Type definitions****************************************************************************
246 
251  typedef const ElementType ReturnType;
252  typedef const ResultType CompositeType;
253 
255  typedef If_< IsExpression<MT1>, const MT1, const MT1& > LeftOperand;
256 
258  typedef If_< IsExpression<MT2>, const MT2, const MT2& > RightOperand;
259 
262 
265  //**********************************************************************************************
266 
267  //**Compilation flags***************************************************************************
269  enum : bool { simdEnabled = false };
270 
272  enum : bool { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
273  !evaluateRight && MT2::smpAssignable };
274  //**********************************************************************************************
275 
276  //**Constructor*********************************************************************************
282  explicit inline DMatTSMatMultExpr( const MT1& lhs, const MT2& rhs ) noexcept
283  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
284  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
285  {
286  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
287  }
288  //**********************************************************************************************
289 
290  //**Access operator*****************************************************************************
297  inline ReturnType operator()( size_t i, size_t j ) const {
298  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
299  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
300 
301  if( IsDiagonal<MT1>::value ) {
302  return lhs_(i,i) * rhs_(i,j);
303  }
304  else if( IsDiagonal<MT2>::value ) {
305  return lhs_(i,j) * rhs_(j,j);
306  }
308  const size_t begin( ( IsUpper<MT1>::value )
309  ?( ( IsLower<MT2>::value )
310  ?( max( ( IsStrictlyUpper<MT1>::value ? i+1UL : i )
311  , ( IsStrictlyLower<MT2>::value ? j+1UL : j ) ) )
312  :( IsStrictlyUpper<MT1>::value ? i+1UL : i ) )
313  :( ( IsLower<MT2>::value )
314  ?( IsStrictlyLower<MT2>::value ? j+1UL : j )
315  :( 0UL ) ) );
316  const size_t end( ( IsLower<MT1>::value )
317  ?( ( IsUpper<MT2>::value )
318  ?( min( ( IsStrictlyLower<MT1>::value ? i : i+1UL )
319  , ( IsStrictlyUpper<MT2>::value ? j : j+1UL ) ) )
320  :( IsStrictlyLower<MT1>::value ? i : i+1UL ) )
321  :( ( IsUpper<MT2>::value )
322  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
323  :( lhs_.columns() ) ) );
324 
325  if( begin >= end ) return ElementType();
326 
327  const size_t n( end - begin );
328 
329  return subvector( row( lhs_, i ), begin, n ) * subvector( column( rhs_, j ), begin, n );
330  }
331  else {
332  return row( lhs_, i ) * column( rhs_, j );
333  }
334  }
335  //**********************************************************************************************
336 
337  //**At function*********************************************************************************
345  inline ReturnType at( size_t i, size_t j ) const {
346  if( i >= lhs_.rows() ) {
347  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
348  }
349  if( j >= rhs_.columns() ) {
350  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
351  }
352  return (*this)(i,j);
353  }
354  //**********************************************************************************************
355 
356  //**Rows function*******************************************************************************
361  inline size_t rows() const noexcept {
362  return lhs_.rows();
363  }
364  //**********************************************************************************************
365 
366  //**Columns function****************************************************************************
371  inline size_t columns() const noexcept {
372  return rhs_.columns();
373  }
374  //**********************************************************************************************
375 
376  //**Left operand access*************************************************************************
381  inline LeftOperand leftOperand() const noexcept {
382  return lhs_;
383  }
384  //**********************************************************************************************
385 
386  //**Right operand access************************************************************************
391  inline RightOperand rightOperand() const noexcept {
392  return rhs_;
393  }
394  //**********************************************************************************************
395 
396  //**********************************************************************************************
402  template< typename T >
403  inline bool canAlias( const T* alias ) const noexcept {
404  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
405  }
406  //**********************************************************************************************
407 
408  //**********************************************************************************************
414  template< typename T >
415  inline bool isAliased( const T* alias ) const noexcept {
416  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
417  }
418  //**********************************************************************************************
419 
420  //**********************************************************************************************
425  inline bool isAligned() const noexcept {
426  return lhs_.isAligned();
427  }
428  //**********************************************************************************************
429 
430  //**********************************************************************************************
435  inline bool canSMPAssign() const noexcept {
436  return ( rows() * columns() >= SMP_DMATTSMATMULT_THRESHOLD ) && !IsDiagonal<MT1>::value;
437  }
438  //**********************************************************************************************
439 
440  private:
441  //**Member variables****************************************************************************
442  LeftOperand lhs_;
443  RightOperand rhs_;
444  //**********************************************************************************************
445 
446  //**Assignment to dense matrices****************************************************************
459  template< typename MT // Type of the target dense matrix
460  , bool SO > // Storage order of the target dense matrix
462  assign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
463  {
465 
466  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
467  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
468 
469  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
470  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
471 
472  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
473  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
474  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
475 
476  DMatTSMatMultExpr::selectAssignKernel( ~lhs, A, B );
477  }
479  //**********************************************************************************************
480 
481  //**Default assignment to dense matrices********************************************************
495  template< typename MT3 // Type of the left-hand side target matrix
496  , typename MT4 // Type of the left-hand side matrix operand
497  , typename MT5 > // Type of the right-hand side matrix operand
499  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
500  {
502 
503  const size_t M( A.rows() );
504  const size_t N( B.columns() );
505 
506  BLAZE_INTERNAL_ASSERT( !( SYM || HERM || LOW || UPP ) || M == N, "Broken invariant detected" );
507 
508  if( LOW && UPP ) {
509  reset( C );
510  }
511 
512  {
513  size_t i( 0UL );
514 
515  for( ; (i+4UL) <= M; i+=4UL ) {
516  for( size_t j=( SYM || HERM || UPP ? i : 0UL ); j<( LOW ? i+4UL : N ); ++j )
517  {
518  ConstIterator element( ( IsUpper<MT4>::value )
519  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
520  :( B.begin(j) ) );
521  const ConstIterator end( ( IsLower<MT4>::value )
522  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+4UL,j) : B.upperBound(i+4UL,j) )
523  :( B.end(j) ) );
524 
525  if( element == end ) {
526  reset( C(i ,j) );
527  reset( C(i+1UL,j) );
528  reset( C(i+2UL,j) );
529  reset( C(i+3UL,j) );
530  continue;
531  }
532 
533  C(i ,j) = A(i ,element->index()) * element->value();
534  C(i+1UL,j) = A(i+1UL,element->index()) * element->value();
535  C(i+2UL,j) = A(i+2UL,element->index()) * element->value();
536  C(i+3UL,j) = A(i+3UL,element->index()) * element->value();
537  ++element;
538  for( ; element!=end; ++element ) {
539  C(i ,j) += A(i ,element->index()) * element->value();
540  C(i+1UL,j) += A(i+1UL,element->index()) * element->value();
541  C(i+2UL,j) += A(i+2UL,element->index()) * element->value();
542  C(i+3UL,j) += A(i+3UL,element->index()) * element->value();
543  }
544  }
545  }
546 
547  for( ; (i+2UL) <= M; i+=2UL ) {
548  for( size_t j=( SYM || HERM || UPP ? i : 0UL ); j<( LOW ? i+2UL : N ); ++j )
549  {
550  ConstIterator element( ( IsUpper<MT4>::value )
551  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
552  :( B.begin(j) ) );
553  const ConstIterator end( ( IsLower<MT4>::value )
554  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+2UL,j) : B.upperBound(i+2UL,j) )
555  :( B.end(j) ) );
556 
557  if( element == end ) {
558  reset( C(i ,j) );
559  reset( C(i+1UL,j) );
560  continue;
561  }
562 
563  C(i ,j) = A(i ,element->index()) * element->value();
564  C(i+1UL,j) = A(i+1UL,element->index()) * element->value();
565  ++element;
566  for( ; element!=end; ++element ) {
567  C(i ,j) += A(i ,element->index()) * element->value();
568  C(i+1UL,j) += A(i+1UL,element->index()) * element->value();
569  }
570  }
571  }
572 
573  for( ; i<M; ++i ) {
574  for( size_t j=( SYM || HERM || UPP ? i : 0UL ); j<( LOW ? i+1UL : N ); ++j )
575  {
576  ConstIterator element( ( IsUpper<MT4>::value )
577  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
578  :( B.begin(j) ) );
579  const ConstIterator end( ( IsLower<MT4>::value )
580  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i,j) : B.upperBound(i,j) )
581  :( B.end(j) ) );
582 
583  if( element == end ) {
584  reset( C(i,j) );
585  continue;
586  }
587 
588  C(i,j) = A(i,element->index()) * element->value();
589  ++element;
590  for( ; element!=end; ++element )
591  C(i,j) += A(i,element->index()) * element->value();
592  }
593  }
594  }
595 
596  if( SYM || HERM ) {
597  for( size_t i=1UL; i<M; ++i ) {
598  for( size_t j=0UL; j<i; ++j ) {
599  C(i,j) = HERM ? conj( C(j,i) ) : C(j,i);
600  }
601  }
602  }
603  else if( LOW && !UPP ) {
604  for( size_t j=1UL; j<N; ++j ) {
605  for( size_t i=0UL; i<j; ++i ) {
606  reset( C(i,j) );
607  }
608  }
609  }
610  else if( !LOW && UPP ) {
611  for( size_t i=1UL; i<M; ++i ) {
612  for( size_t j=0UL; j<i; ++j ) {
613  reset( C(i,j) );
614  }
615  }
616  }
617  }
619  //**********************************************************************************************
620 
621  //**Optimized assignment to dense matrices******************************************************
635  template< typename MT3 // Type of the left-hand side target matrix
636  , typename MT4 // Type of the left-hand side matrix operand
637  , typename MT5 > // Type of the right-hand side matrix operand
639  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
640  {
642 
643  const size_t M( A.rows() );
644  const size_t N( B.columns() );
645 
646  BLAZE_INTERNAL_ASSERT( !( SYM || HERM || LOW || UPP ) || M == N, "Broken invariant detected" );
647 
648  reset( C );
649 
650  {
651  size_t i( 0UL );
652 
653  for( ; (i+4UL) <= M; i+=4UL ) {
654  for( size_t j=( SYM || HERM || UPP ? i : 0UL ); j<( LOW ? i+4UL : N ); ++j )
655  {
656  ConstIterator element( ( IsUpper<MT4>::value )
657  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
658  :( B.begin(j) ) );
659  const ConstIterator end( ( IsLower<MT4>::value )
660  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+4UL,j) : B.upperBound(i+4UL,j) )
661  :( B.end(j) ) );
662 
663  const size_t nonzeros( end - element );
664  const size_t kpos( nonzeros & size_t(-4) );
665  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
666 
667  for( size_t k=0UL; k<kpos; k+=4UL )
668  {
669  const size_t j1( element->index() );
670  const ET2 v1( element->value() );
671  ++element;
672  const size_t j2( element->index() );
673  const ET2 v2( element->value() );
674  ++element;
675  const size_t j3( element->index() );
676  const ET2 v3( element->value() );
677  ++element;
678  const size_t j4( element->index() );
679  const ET2 v4( element->value() );
680  ++element;
681 
682  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
683 
684  C(i ,j) += A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
685  C(i+1UL,j) += A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
686  C(i+2UL,j) += A(i+2UL,j1) * v1 + A(i+2UL,j2) * v2 + A(i+2UL,j3) * v3 + A(i+2UL,j4) * v4;
687  C(i+3UL,j) += A(i+3UL,j1) * v1 + A(i+3UL,j2) * v2 + A(i+3UL,j3) * v3 + A(i+3UL,j4) * v4;
688  }
689 
690  for( ; element!=end; ++element )
691  {
692  const size_t j1( element->index() );
693  const ET2 v1( element->value() );
694 
695  C(i ,j) += A(i ,j1) * v1;
696  C(i+1UL,j) += A(i+1UL,j1) * v1;
697  C(i+2UL,j) += A(i+2UL,j1) * v1;
698  C(i+3UL,j) += A(i+3UL,j1) * v1;
699  }
700  }
701  }
702 
703  for( ; (i+2UL) <= M; i+=2UL ) {
704  for( size_t j=( SYM || HERM || UPP ? i : 0UL ); j<( LOW ? i+2UL : N ); ++j )
705  {
706  ConstIterator element( ( IsUpper<MT4>::value )
707  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
708  :( B.begin(j) ) );
709  const ConstIterator end( ( IsLower<MT4>::value )
710  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+2UL,j) : B.upperBound(i+2UL,j) )
711  :( B.end(j) ) );
712 
713  const size_t nonzeros( end - element );
714  const size_t kpos( nonzeros & size_t(-4) );
715  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
716 
717  for( size_t k=0UL; k<kpos; k+=4UL )
718  {
719  const size_t j1( element->index() );
720  const ET2 v1( element->value() );
721  ++element;
722  const size_t j2( element->index() );
723  const ET2 v2( element->value() );
724  ++element;
725  const size_t j3( element->index() );
726  const ET2 v3( element->value() );
727  ++element;
728  const size_t j4( element->index() );
729  const ET2 v4( element->value() );
730  ++element;
731 
732  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
733 
734  C(i ,j) += A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
735  C(i+1UL,j) += A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
736  }
737 
738  for( ; element!=end; ++element )
739  {
740  const size_t j1( element->index() );
741  const ET2 v1( element->value() );
742 
743  C(i ,j) += A(i ,j1) * v1;
744  C(i+1UL,j) += A(i+1UL,j1) * v1;
745  }
746  }
747  }
748 
749  for( ; i<M; ++i ) {
750  for( size_t j=( SYM || HERM || UPP ? i : 0UL ); j<( LOW ? i+1UL : N ); ++j )
751  {
752  ConstIterator element( ( IsUpper<MT4>::value )
753  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
754  :( B.begin(j) ) );
755  const ConstIterator end( ( IsLower<MT4>::value )
756  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i,j) : B.upperBound(i,j) )
757  :( B.end(j) ) );
758 
759  const size_t nonzeros( end - element );
760  const size_t kpos( nonzeros & size_t(-4) );
761  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
762 
763  for( size_t k=0UL; k<kpos; k+=4UL )
764  {
765  const size_t j1( element->index() );
766  const ET2 v1( element->value() );
767  ++element;
768  const size_t j2( element->index() );
769  const ET2 v2( element->value() );
770  ++element;
771  const size_t j3( element->index() );
772  const ET2 v3( element->value() );
773  ++element;
774  const size_t j4( element->index() );
775  const ET2 v4( element->value() );
776  ++element;
777 
778  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
779 
780  C(i,j) += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
781  }
782 
783  for( ; element!=end; ++element )
784  {
785  const size_t j1( element->index() );
786  const ET2 v1( element->value() );
787 
788  C(i,j) += A(i,j1) * v1;
789  }
790  }
791  }
792  }
793 
794  if( SYM || HERM ) {
795  for( size_t i=1UL; i<M; ++i ) {
796  for( size_t j=0UL; j<i; ++j ) {
797  C(i,j) = HERM ? conj( C(j,i) ) : C(j,i);
798  }
799  }
800  }
801  }
803  //**********************************************************************************************
804 
805  //**Assignment to sparse matrices***************************************************************
818  template< typename MT // Type of the target sparse matrix
819  , bool SO > // Storage order of the target sparse matrix
821  assign( SparseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
822  {
824 
826 
833 
834  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
835  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
836 
837  const ForwardFunctor fwd;
838 
839  const TmpType tmp( serial( rhs ) );
840  assign( ~lhs, fwd( tmp ) );
841  }
843  //**********************************************************************************************
844 
845  //**Restructuring assignment********************************************************************
860  template< typename MT // Type of the target matrix
861  , bool SO > // Storage order of the target matrix
863  assign( Matrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
864  {
866 
867  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
868  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
869 
870  const ForwardFunctor fwd;
871 
872  assign( ~lhs, fwd( trans( rhs.lhs_ ) * rhs.rhs_ ) );
873  }
875  //**********************************************************************************************
876 
877  //**Addition assignment to dense matrices*******************************************************
890  template< typename MT // Type of the target dense matrix
891  , bool SO > // Storage order of the target dense matrix
893  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
894  {
896 
897  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
898  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
899 
900  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
901  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
902 
903  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
904  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
905  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
906 
907  DMatTSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
908  }
910  //**********************************************************************************************
911 
912  //**Default addition assignment to dense matrices***********************************************
926  template< typename MT3 // Type of the left-hand side target matrix
927  , typename MT4 // Type of the left-hand side matrix operand
928  , typename MT5 > // Type of the right-hand side matrix operand
930  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
931  {
933 
934  const size_t M( A.rows() );
935  const size_t N( B.columns() );
936 
937  BLAZE_INTERNAL_ASSERT( !( LOW || UPP ) || M == N, "Broken invariant detected" );
938 
939  {
940  size_t i( 0UL );
941 
942  for( ; (i+4UL) <= M; i+=4UL ) {
943  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+4UL : N ); ++j )
944  {
945  ConstIterator element( ( IsUpper<MT4>::value )
946  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
947  :( B.begin(j) ) );
948  const ConstIterator end( ( IsLower<MT4>::value )
949  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+4UL,j) : B.upperBound(i+4UL,j) )
950  :( B.end(j) ) );
951 
952  for( ; element!=end; ++element ) {
953  C(i ,j) += A(i ,element->index()) * element->value();
954  C(i+1UL,j) += A(i+1UL,element->index()) * element->value();
955  C(i+2UL,j) += A(i+2UL,element->index()) * element->value();
956  C(i+3UL,j) += A(i+3UL,element->index()) * element->value();
957  }
958  }
959  }
960 
961  for( ; (i+2UL) <= M; i+=2UL ) {
962  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+2UL : N ); ++j )
963  {
964  ConstIterator element( ( IsUpper<MT4>::value )
965  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
966  :( B.begin(j) ) );
967  const ConstIterator end( ( IsLower<MT4>::value )
968  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+2UL,j) : B.upperBound(i+2UL,j) )
969  :( B.end(j) ) );
970 
971  for( ; element!=end; ++element ) {
972  C(i ,j) += A(i ,element->index()) * element->value();
973  C(i+1UL,j) += A(i+1UL,element->index()) * element->value();
974  }
975  }
976  }
977 
978  for( ; i<M; ++i ) {
979  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+1UL : N ); ++j )
980  {
981  ConstIterator element( ( IsUpper<MT4>::value )
982  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
983  :( B.begin(j) ) );
984  const ConstIterator end( ( IsLower<MT4>::value )
985  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i,j) : B.upperBound(i,j) )
986  :( B.end(j) ) );
987 
988  for( ; element!=end; ++element )
989  C(i,j) += A(i,element->index()) * element->value();
990  }
991  }
992  }
993  }
995  //**********************************************************************************************
996 
997  //**Optimized addition assignment to dense matrices*********************************************
1011  template< typename MT3 // Type of the left-hand side target matrix
1012  , typename MT4 // Type of the left-hand side matrix operand
1013  , typename MT5 > // Type of the right-hand side matrix operand
1015  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1016  {
1018 
1019  const size_t M( A.rows() );
1020  const size_t N( B.columns() );
1021 
1022  BLAZE_INTERNAL_ASSERT( !( LOW || UPP ) || M == N, "Broken invariant detected" );
1023 
1024  {
1025  size_t i( 0UL );
1026 
1027  for( ; (i+4UL) <= M; i+=4UL ) {
1028  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+4UL : N ); ++j )
1029  {
1030  ConstIterator element( ( IsUpper<MT4>::value )
1031  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1032  :( B.begin(j) ) );
1033  const ConstIterator end( ( IsLower<MT4>::value )
1034  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+4UL,j) : B.upperBound(i+4UL,j) )
1035  :( B.end(j) ) );
1036 
1037  const size_t nonzeros( end - element );
1038  const size_t kpos( nonzeros & size_t(-4) );
1039  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1040 
1041  for( size_t k=0UL; k<kpos; k+=4UL )
1042  {
1043  const size_t j1( element->index() );
1044  const ET2 v1( element->value() );
1045  ++element;
1046  const size_t j2( element->index() );
1047  const ET2 v2( element->value() );
1048  ++element;
1049  const size_t j3( element->index() );
1050  const ET2 v3( element->value() );
1051  ++element;
1052  const size_t j4( element->index() );
1053  const ET2 v4( element->value() );
1054  ++element;
1055 
1056  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
1057 
1058  C(i ,j) += A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
1059  C(i+1UL,j) += A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
1060  C(i+2UL,j) += A(i+2UL,j1) * v1 + A(i+2UL,j2) * v2 + A(i+2UL,j3) * v3 + A(i+2UL,j4) * v4;
1061  C(i+3UL,j) += A(i+3UL,j1) * v1 + A(i+3UL,j2) * v2 + A(i+3UL,j3) * v3 + A(i+3UL,j4) * v4;
1062  }
1063 
1064  for( ; element!=end; ++element )
1065  {
1066  const size_t j1( element->index() );
1067  const ET2 v1( element->value() );
1068 
1069  C(i ,j) += A(i ,j1) * v1;
1070  C(i+1UL,j) += A(i+1UL,j1) * v1;
1071  C(i+2UL,j) += A(i+2UL,j1) * v1;
1072  C(i+3UL,j) += A(i+3UL,j1) * v1;
1073  }
1074  }
1075  }
1076 
1077  for( ; (i+2UL) <= M; i+=2UL ) {
1078  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+2UL : N ); ++j )
1079  {
1080  ConstIterator element( ( IsUpper<MT4>::value )
1081  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1082  :( B.begin(j) ) );
1083  const ConstIterator end( ( IsLower<MT4>::value )
1084  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+2UL,j) : B.upperBound(i+2UL,j) )
1085  :( B.end(j) ) );
1086 
1087  const size_t nonzeros( end - element );
1088  const size_t kpos( nonzeros & size_t(-4) );
1089  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1090 
1091  for( size_t k=0UL; k<kpos; k+=4UL )
1092  {
1093  const size_t j1( element->index() );
1094  const ET2 v1( element->value() );
1095  ++element;
1096  const size_t j2( element->index() );
1097  const ET2 v2( element->value() );
1098  ++element;
1099  const size_t j3( element->index() );
1100  const ET2 v3( element->value() );
1101  ++element;
1102  const size_t j4( element->index() );
1103  const ET2 v4( element->value() );
1104  ++element;
1105 
1106  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
1107 
1108  C(i ,j) += A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
1109  C(i+1UL,j) += A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
1110  }
1111 
1112  for( ; element!=end; ++element )
1113  {
1114  const size_t j1( element->index() );
1115  const ET2 v1( element->value() );
1116 
1117  C(i ,j) += A(i ,j1) * v1;
1118  C(i+1UL,j) += A(i+1UL,j1) * v1;
1119  }
1120  }
1121  }
1122 
1123  for( ; i<M; ++i ) {
1124  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+1UL : N ); ++j )
1125  {
1126  ConstIterator element( ( IsUpper<MT4>::value )
1127  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1128  :( B.begin(j) ) );
1129  const ConstIterator end( ( IsLower<MT4>::value )
1130  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i,j) : B.upperBound(i,j) )
1131  :( B.end(j) ) );
1132 
1133  const size_t nonzeros( end - element );
1134  const size_t kpos( nonzeros & size_t(-4) );
1135  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1136 
1137  for( size_t k=0UL; k<kpos; k+=4UL )
1138  {
1139  const size_t j1( element->index() );
1140  const ET2 v1( element->value() );
1141  ++element;
1142  const size_t j2( element->index() );
1143  const ET2 v2( element->value() );
1144  ++element;
1145  const size_t j3( element->index() );
1146  const ET2 v3( element->value() );
1147  ++element;
1148  const size_t j4( element->index() );
1149  const ET2 v4( element->value() );
1150  ++element;
1151 
1152  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
1153 
1154  C(i,j) += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
1155  }
1156 
1157  for( ; element!=end; ++element )
1158  {
1159  const size_t j1( element->index() );
1160  const ET2 v1( element->value() );
1161 
1162  C(i,j) += A(i,j1) * v1;
1163  }
1164  }
1165  }
1166  }
1167  }
1169  //**********************************************************************************************
1170 
1171  //**Restructuring addition assignment***********************************************************
1186  template< typename MT // Type of the target matrix
1187  , bool SO > // Storage order of the target matrix
1189  addAssign( Matrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1190  {
1192 
1194 
1195  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1196  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1197 
1198  const ForwardFunctor fwd;
1199 
1200  addAssign( ~lhs, fwd( trans( rhs.lhs_ ) * rhs.rhs_ ) );
1201  }
1203  //**********************************************************************************************
1204 
1205  //**Addition assignment to sparse matrices******************************************************
1206  // No special implementation for the addition assignment to sparse matrices.
1207  //**********************************************************************************************
1208 
1209  //**Subtraction assignment to dense matrices****************************************************
1222  template< typename MT // Type of the target dense matrix
1223  , bool SO > // Storage order of the target dense matrix
1225  subAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1226  {
1228 
1229  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1230  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1231 
1232  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
1233  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
1234 
1235  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1236  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
1237  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
1238 
1239  DMatTSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1240  }
1242  //**********************************************************************************************
1243 
1244  //**Default subtraction assignment to dense matrices********************************************
1258  template< typename MT3 // Type of the left-hand side target matrix
1259  , typename MT4 // Type of the left-hand side matrix operand
1260  , typename MT5 > // Type of the right-hand side matrix operand
1262  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1263  {
1265 
1266  const size_t M( A.rows() );
1267  const size_t N( B.columns() );
1268 
1269  BLAZE_INTERNAL_ASSERT( !( LOW || UPP ) || M == N, "Broken invariant detected" );
1270 
1271  {
1272  size_t i( 0UL );
1273 
1274  for( ; (i+4UL) <= M; i+=4UL ) {
1275  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+4UL : N ); ++j )
1276  {
1277  ConstIterator element( ( IsUpper<MT4>::value )
1278  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1279  :( B.begin(j) ) );
1280  const ConstIterator end( ( IsLower<MT4>::value )
1281  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+4UL,j) : B.upperBound(i+4UL,j) )
1282  :( B.end(j) ) );
1283 
1284  for( ; element!=end; ++element ) {
1285  C(i ,j) -= A(i ,element->index()) * element->value();
1286  C(i+1UL,j) -= A(i+1UL,element->index()) * element->value();
1287  C(i+2UL,j) -= A(i+2UL,element->index()) * element->value();
1288  C(i+3UL,j) -= A(i+3UL,element->index()) * element->value();
1289  }
1290  }
1291  }
1292 
1293  for( ; (i+2UL) <= M; i+=2UL ) {
1294  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+2UL : N ); ++j )
1295  {
1296  ConstIterator element( ( IsUpper<MT4>::value )
1297  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1298  :( B.begin(j) ) );
1299  const ConstIterator end( ( IsLower<MT4>::value )
1300  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+2UL,j) : B.upperBound(i+2UL,j) )
1301  :( B.end(j) ) );
1302 
1303  for( ; element!=end; ++element ) {
1304  C(i ,j) -= A(i ,element->index()) * element->value();
1305  C(i+1UL,j) -= A(i+1UL,element->index()) * element->value();
1306  }
1307  }
1308  }
1309 
1310  for( ; i<M; ++i ) {
1311  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+1UL : N ); ++j )
1312  {
1313  ConstIterator element( ( IsUpper<MT4>::value )
1314  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1315  :( B.begin(j) ) );
1316  const ConstIterator end( ( IsLower<MT4>::value )
1317  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i,j) : B.upperBound(i,j) )
1318  :( B.end(j) ) );
1319 
1320  for( ; element!=end; ++element )
1321  C(i,j) -= A(i,element->index()) * element->value();
1322  }
1323  }
1324  }
1325  }
1327  //**********************************************************************************************
1328 
1329  //**Optimized subtraction assignment to dense matrices******************************************
1343  template< typename MT3 // Type of the left-hand side target matrix
1344  , typename MT4 // Type of the left-hand side matrix operand
1345  , typename MT5 > // Type of the right-hand side matrix operand
1347  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1348  {
1350 
1351  const size_t M( A.rows() );
1352  const size_t N( B.columns() );
1353 
1354  BLAZE_INTERNAL_ASSERT( !( LOW || UPP ) || M == N, "Broken invariant detected" );
1355 
1356  {
1357  size_t i( 0UL );
1358 
1359  for( ; (i+4UL) <= M; i+=4UL ) {
1360  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+4UL : N ); ++j )
1361  {
1362  ConstIterator element( ( IsUpper<MT4>::value )
1363  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1364  :( B.begin(j) ) );
1365  const ConstIterator end( ( IsLower<MT4>::value )
1366  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+4UL,j) : B.upperBound(i+4UL,j) )
1367  :( B.end(j) ) );
1368 
1369  const size_t nonzeros( end - element );
1370  const size_t kpos( nonzeros & size_t(-4) );
1371  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1372 
1373  for( size_t k=0UL; k<kpos; k+=4UL )
1374  {
1375  const size_t j1( element->index() );
1376  const ET2 v1( element->value() );
1377  ++element;
1378  const size_t j2( element->index() );
1379  const ET2 v2( element->value() );
1380  ++element;
1381  const size_t j3( element->index() );
1382  const ET2 v3( element->value() );
1383  ++element;
1384  const size_t j4( element->index() );
1385  const ET2 v4( element->value() );
1386  ++element;
1387 
1388  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
1389 
1390  C(i ,j) -= A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
1391  C(i+1UL,j) -= A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
1392  C(i+2UL,j) -= A(i+2UL,j1) * v1 + A(i+2UL,j2) * v2 + A(i+2UL,j3) * v3 + A(i+2UL,j4) * v4;
1393  C(i+3UL,j) -= A(i+3UL,j1) * v1 + A(i+3UL,j2) * v2 + A(i+3UL,j3) * v3 + A(i+3UL,j4) * v4;
1394  }
1395 
1396  for( ; element!=end; ++element )
1397  {
1398  const size_t j1( element->index() );
1399  const ET2 v1( element->value() );
1400 
1401  C(i ,j) -= A(i ,j1) * v1;
1402  C(i+1UL,j) -= A(i+1UL,j1) * v1;
1403  C(i+2UL,j) -= A(i+2UL,j1) * v1;
1404  C(i+3UL,j) -= A(i+3UL,j1) * v1;
1405  }
1406  }
1407  }
1408 
1409  for( ; (i+2UL) <= M; i+=2UL ) {
1410  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+2UL : N ); ++j )
1411  {
1412  ConstIterator element( ( IsUpper<MT4>::value )
1413  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1414  :( B.begin(j) ) );
1415  const ConstIterator end( ( IsLower<MT4>::value )
1416  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i+2UL,j) : B.upperBound(i+2UL,j) )
1417  :( B.end(j) ) );
1418 
1419  const size_t nonzeros( end - element );
1420  const size_t kpos( nonzeros & size_t(-4) );
1421  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1422 
1423  for( size_t k=0UL; k<kpos; k+=4UL )
1424  {
1425  const size_t j1( element->index() );
1426  const ET2 v1( element->value() );
1427  ++element;
1428  const size_t j2( element->index() );
1429  const ET2 v2( element->value() );
1430  ++element;
1431  const size_t j3( element->index() );
1432  const ET2 v3( element->value() );
1433  ++element;
1434  const size_t j4( element->index() );
1435  const ET2 v4( element->value() );
1436  ++element;
1437 
1438  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
1439 
1440  C(i ,j) -= A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
1441  C(i+1UL,j) -= A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
1442  }
1443 
1444  for( ; element!=end; ++element )
1445  {
1446  const size_t j1( element->index() );
1447  const ET2 v1( element->value() );
1448 
1449  C(i ,j) -= A(i ,j1) * v1;
1450  C(i+1UL,j) -= A(i+1UL,j1) * v1;
1451  }
1452  }
1453  }
1454 
1455  for( ; i<M; ++i ) {
1456  for( size_t j=( UPP ? i : 0UL ); j<( LOW ? i+1UL : N ); ++j )
1457  {
1458  ConstIterator element( ( IsUpper<MT4>::value )
1459  ?( IsStrictlyUpper<MT4>::value ? B.upperBound(i,j) : B.lowerBound(i,j) )
1460  :( B.begin(j) ) );
1461  const ConstIterator end( ( IsLower<MT4>::value )
1462  ?( IsStrictlyLower<MT4>::value ? B.lowerBound(i,j) : B.upperBound(i,j) )
1463  :( B.end(j) ) );
1464 
1465  const size_t nonzeros( end - element );
1466  const size_t kpos( nonzeros & size_t(-4) );
1467  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1468 
1469  for( size_t k=0UL; k<kpos; k+=4UL )
1470  {
1471  const size_t j1( element->index() );
1472  const ET2 v1( element->value() );
1473  ++element;
1474  const size_t j2( element->index() );
1475  const ET2 v2( element->value() );
1476  ++element;
1477  const size_t j3( element->index() );
1478  const ET2 v3( element->value() );
1479  ++element;
1480  const size_t j4( element->index() );
1481  const ET2 v4( element->value() );
1482  ++element;
1483 
1484  BLAZE_INTERNAL_ASSERT( j1 < j2 && j2 < j3 && j3 < j4, "Invalid sparse matrix index detected" );
1485 
1486  C(i,j) -= A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
1487  }
1488 
1489  for( ; element!=end; ++element )
1490  {
1491  const size_t j1( element->index() );
1492  const ET2 v1( element->value() );
1493 
1494  C(i,j) -= A(i,j1) * v1;
1495  }
1496  }
1497  }
1498  }
1499  }
1501  //**********************************************************************************************
1502 
1503  //**Restructuring subtraction assignment********************************************************
1518  template< typename MT // Type of the target matrix
1519  , bool SO > // Storage order of the target matrix
1521  subAssign( Matrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1522  {
1524 
1526 
1527  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1528  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1529 
1530  const ForwardFunctor fwd;
1531 
1532  subAssign( ~lhs, fwd( trans( rhs.lhs_ ) * rhs.rhs_ ) );
1533  }
1535  //**********************************************************************************************
1536 
1537  //**Subtraction assignment to sparse matrices***************************************************
1538  // No special implementation for the subtraction assignment to sparse matrices.
1539  //**********************************************************************************************
1540 
1541  //**Multiplication assignment to dense matrices*************************************************
1542  // No special implementation for the multiplication assignment to dense matrices.
1543  //**********************************************************************************************
1544 
1545  //**Multiplication assignment to sparse matrices************************************************
1546  // No special implementation for the multiplication assignment to sparse matrices.
1547  //**********************************************************************************************
1548 
1549  //**SMP assignment to dense matrices************************************************************
1564  template< typename MT // Type of the target dense matrix
1565  , bool SO > // Storage order of the target dense matrix
1567  smpAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1568  {
1570 
1571  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1572  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1573 
1574  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1575  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1576 
1577  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1578  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
1579  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
1580 
1581  smpAssign( ~lhs, A * B );
1582  }
1584  //**********************************************************************************************
1585 
1586  //**SMP assignment to sparse matrices***********************************************************
1601  template< typename MT // Type of the target sparse matrix
1602  , bool SO > // Storage order of the target sparse matrix
1604  smpAssign( SparseMatrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1605  {
1607 
1609 
1616 
1617  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1618  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1619 
1620  const ForwardFunctor fwd;
1621 
1622  const TmpType tmp( rhs );
1623  smpAssign( ~lhs, fwd( tmp ) );
1624  }
1626  //**********************************************************************************************
1627 
1628  //**Restructuring SMP assignment****************************************************************
1643  template< typename MT // Type of the target matrix
1644  , bool SO > // Storage order of the target matrix
1646  smpAssign( Matrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1647  {
1649 
1651 
1652  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1653  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1654 
1655  const ForwardFunctor fwd;
1656 
1657  smpAssign( ~lhs, fwd( trans( rhs.lhs_ ) * rhs.rhs_ ) );
1658  }
1660  //**********************************************************************************************
1661 
1662  //**SMP addition assignment to dense matrices***************************************************
1678  template< typename MT // Type of the target dense matrix
1679  , bool SO > // Storage order of the target dense matrix
1682  {
1684 
1685  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1686  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1687 
1688  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1689  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1690 
1691  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1692  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
1693  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
1694 
1695  smpAddAssign( ~lhs, A * B );
1696  }
1698  //**********************************************************************************************
1699 
1700  //**Restructuring SMP addition assignment*******************************************************
1715  template< typename MT // Type of the target matrix
1716  , bool SO > // Storage order of the target matrix
1718  smpAddAssign( Matrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1719  {
1721 
1723 
1724  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1725  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1726 
1727  const ForwardFunctor fwd;
1728 
1729  smpAddAssign( ~lhs, fwd( trans( rhs.lhs_ ) * rhs.rhs_ ) );
1730  }
1732  //**********************************************************************************************
1733 
1734  //**SMP addition assignment to sparse matrices**************************************************
1735  // No special implementation for the SMP addition assignment to sparse matrices.
1736  //**********************************************************************************************
1737 
1738  //**SMP subtraction assignment to dense matrices************************************************
1754  template< typename MT // Type of the target dense matrix
1755  , bool SO > // Storage order of the target dense matrix
1758  {
1760 
1761  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1762  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1763 
1764  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1765  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1766 
1767  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1768  BLAZE_INTERNAL_ASSERT( A.columns() == B.rows() , "Invalid matrix sizes" );
1769  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns(), "Invalid number of columns" );
1770 
1771  smpSubAssign( ~lhs, A * B );
1772  }
1774  //**********************************************************************************************
1775 
1776  //**Restructuring SMP subtraction assignment****************************************************
1791  template< typename MT // Type of the target matrix
1792  , bool SO > // Storage order of the target matrix
1794  smpSubAssign( Matrix<MT,SO>& lhs, const DMatTSMatMultExpr& rhs )
1795  {
1797 
1799 
1800  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1801  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1802 
1803  const ForwardFunctor fwd;
1804 
1805  smpSubAssign( ~lhs, fwd( trans( rhs.lhs_ ) * rhs.rhs_ ) );
1806  }
1808  //**********************************************************************************************
1809 
1810  //**SMP subtraction assignment to sparse matrices***********************************************
1811  // No special implementation for the SMP subtraction assignment to sparse matrices.
1812  //**********************************************************************************************
1813 
1814  //**SMP multiplication assignment to dense matrices*********************************************
1815  // No special implementation for the SMP multiplication assignment to dense matrices.
1816  //**********************************************************************************************
1817 
1818  //**SMP multiplication assignment to sparse matrices********************************************
1819  // No special implementation for the SMP multiplication assignment to sparse matrices.
1820  //**********************************************************************************************
1821 
1822  //**Compile time checks*************************************************************************
1830  //**********************************************************************************************
1831 };
1832 //*************************************************************************************************
1833 
1834 
1835 
1836 
1837 //=================================================================================================
1838 //
1839 // GLOBAL BINARY ARITHMETIC OPERATORS
1840 //
1841 //=================================================================================================
1842 
1843 //*************************************************************************************************
1873 template< typename T1 // Type of the left-hand side dense matrix
1874  , typename T2 > // Type of the right-hand side sparse matrix
1877 {
1879 
1880  if( (~lhs).columns() != (~rhs).rows() ) {
1881  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1882  }
1883 
1885 }
1886 //*************************************************************************************************
1887 
1888 
1889 
1890 
1891 //=================================================================================================
1892 //
1893 // GLOBAL FUNCTIONS
1894 //
1895 //=================================================================================================
1896 
1897 //*************************************************************************************************
1921 template< typename MT1 // Type of the left-hand side dense matrix
1922  , typename MT2 // Type of the right-hand side sparse matrix
1923  , bool SF // Symmetry flag
1924  , bool HF // Hermitian flag
1925  , bool LF // Lower flag
1926  , bool UF > // Upper flag
1929 {
1931 
1932  if( !isSquare( dm ) ) {
1933  BLAZE_THROW_INVALID_ARGUMENT( "Invalid symmetric matrix specification" );
1934  }
1935 
1937 }
1939 //*************************************************************************************************
1940 
1941 
1942 //*************************************************************************************************
1966 template< typename MT1 // Type of the left-hand side dense matrix
1967  , typename MT2 // Type of the right-hand side sparse matrix
1968  , bool SF // Symmetry flag
1969  , bool HF // Hermitian flag
1970  , bool LF // Lower flag
1971  , bool UF > // Upper flag
1974 {
1976 
1977  if( !isSquare( dm ) ) {
1978  BLAZE_THROW_INVALID_ARGUMENT( "Invalid Hermitian matrix specification" );
1979  }
1980 
1982 }
1984 //*************************************************************************************************
1985 
1986 
1987 //*************************************************************************************************
2011 template< typename MT1 // Type of the left-hand side dense matrix
2012  , typename MT2 // Type of the right-hand side sparse matrix
2013  , bool SF // Symmetry flag
2014  , bool HF // Hermitian flag
2015  , bool LF // Lower flag
2016  , bool UF > // Upper flag
2019 {
2021 
2022  if( !isSquare( dm ) ) {
2023  BLAZE_THROW_INVALID_ARGUMENT( "Invalid lower matrix specification" );
2024  }
2025 
2027 }
2029 //*************************************************************************************************
2030 
2031 
2032 //*************************************************************************************************
2056 template< typename MT1 // Type of the left-hand side dense matrix
2057  , typename MT2 // Type of the right-hand side sparse matrix
2058  , bool SF // Symmetry flag
2059  , bool HF // Hermitian flag
2060  , bool LF // Lower flag
2061  , bool UF > // Upper flag
2064 {
2066 
2067  if( !isSquare( dm ) ) {
2068  BLAZE_THROW_INVALID_ARGUMENT( "Invalid upper matrix specification" );
2069  }
2070 
2072 }
2074 //*************************************************************************************************
2075 
2076 
2077 //*************************************************************************************************
2101 template< typename MT1 // Type of the left-hand side dense matrix
2102  , typename MT2 // Type of the right-hand side sparse matrix
2103  , bool SF // Symmetry flag
2104  , bool HF // Hermitian flag
2105  , bool LF // Lower flag
2106  , bool UF > // Upper flag
2109 {
2111 
2112  if( !isSquare( dm ) ) {
2113  BLAZE_THROW_INVALID_ARGUMENT( "Invalid diagonal matrix specification" );
2114  }
2115 
2117 }
2119 //*************************************************************************************************
2120 
2121 
2122 
2123 
2124 //=================================================================================================
2125 //
2126 // ROWS SPECIALIZATIONS
2127 //
2128 //=================================================================================================
2129 
2130 //*************************************************************************************************
2132 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2133 struct Rows< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> > : public Rows<MT1>
2134 {};
2136 //*************************************************************************************************
2137 
2138 
2139 
2140 
2141 //=================================================================================================
2142 //
2143 // COLUMNS SPECIALIZATIONS
2144 //
2145 //=================================================================================================
2146 
2147 //*************************************************************************************************
2149 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2150 struct Columns< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> > : public Columns<MT2>
2151 {};
2153 //*************************************************************************************************
2154 
2155 
2156 
2157 
2158 //=================================================================================================
2159 //
2160 // ISALIGNED SPECIALIZATIONS
2161 //
2162 //=================================================================================================
2163 
2164 //*************************************************************************************************
2166 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2167 struct IsAligned< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2168  : public BoolConstant< IsAligned<MT1>::value >
2169 {};
2171 //*************************************************************************************************
2172 
2173 
2174 
2175 
2176 //=================================================================================================
2177 //
2178 // ISSYMMETRIC SPECIALIZATIONS
2179 //
2180 //=================================================================================================
2181 
2182 //*************************************************************************************************
2184 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2185 struct IsSymmetric< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2186  : public BoolConstant< Or< Bool<SF>
2187  , And< Bool<HF>
2188  , IsBuiltin< ElementType_< DMatTSMatMultExpr<MT1,MT2,false,true,false,false> > > >
2189  , And< Bool<LF>, Bool<UF> > >::value >
2190 {};
2192 //*************************************************************************************************
2193 
2194 
2195 
2196 
2197 //=================================================================================================
2198 //
2199 // ISHERMITIAN SPECIALIZATIONS
2200 //
2201 //=================================================================================================
2202 
2203 //*************************************************************************************************
2205 template< typename MT1, typename MT2, bool SF, bool LF, bool UF >
2206 struct IsHermitian< DMatTSMatMultExpr<MT1,MT2,SF,true,LF,UF> >
2207  : public TrueType
2208 {};
2210 //*************************************************************************************************
2211 
2212 
2213 
2214 
2215 //=================================================================================================
2216 //
2217 // ISLOWER SPECIALIZATIONS
2218 //
2219 //=================================================================================================
2220 
2221 //*************************************************************************************************
2223 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2224 struct IsLower< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2225  : public BoolConstant< Or< Bool<LF>
2226  , And< IsLower<MT1>, IsLower<MT2> >
2227  , And< Or< Bool<SF>, Bool<HF> >
2228  , IsUpper<MT1>, IsUpper<MT2> > >::value >
2229 {};
2231 //*************************************************************************************************
2232 
2233 
2234 
2235 
2236 //=================================================================================================
2237 //
2238 // ISUNILOWER SPECIALIZATIONS
2239 //
2240 //=================================================================================================
2241 
2242 //*************************************************************************************************
2244 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2245 struct IsUniLower< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2246  : public BoolConstant< Or< And< IsUniLower<MT1>, IsUniLower<MT2> >
2247  , And< Or< Bool<SF>, Bool<HF> >
2248  , IsUniUpper<MT1>, IsUniUpper<MT2> > >::value >
2249 {};
2251 //*************************************************************************************************
2252 
2253 
2254 
2255 
2256 //=================================================================================================
2257 //
2258 // ISSTRICTLYLOWER SPECIALIZATIONS
2259 //
2260 //=================================================================================================
2261 
2262 //*************************************************************************************************
2264 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2265 struct IsStrictlyLower< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2266  : public BoolConstant< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
2267  , And< IsStrictlyLower<MT2>, IsLower<MT1> >
2268  , And< Or< Bool<SF>, Bool<HF> >
2269  , Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
2270  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > > > >::value >
2271 {};
2273 //*************************************************************************************************
2274 
2275 
2276 
2277 
2278 //=================================================================================================
2279 //
2280 // ISUPPER SPECIALIZATIONS
2281 //
2282 //=================================================================================================
2283 
2284 //*************************************************************************************************
2286 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2287 struct IsUpper< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2288  : public BoolConstant< Or< Bool<UF>
2289  , And< IsUpper<MT1>, IsUpper<MT2> >
2290  , And< Or< Bool<SF>, Bool<HF> >
2291  , IsLower<MT1>, IsLower<MT2> > >::value >
2292 {};
2294 //*************************************************************************************************
2295 
2296 
2297 
2298 
2299 //=================================================================================================
2300 //
2301 // ISUNIUPPER SPECIALIZATIONS
2302 //
2303 //=================================================================================================
2304 
2305 //*************************************************************************************************
2307 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2308 struct IsUniUpper< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2309  : public BoolConstant< Or< And< IsUniUpper<MT1>, IsUniUpper<MT2> >
2310  , And< Or< Bool<SF>, Bool<HF> >
2311  , IsUniLower<MT1>, IsUniLower<MT2> > >::value >
2312 {};
2314 //*************************************************************************************************
2315 
2316 
2317 
2318 
2319 //=================================================================================================
2320 //
2321 // ISSTRICTLYUPPER SPECIALIZATIONS
2322 //
2323 //=================================================================================================
2324 
2325 //*************************************************************************************************
2327 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2328 struct IsStrictlyUpper< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2329  : public BoolConstant< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
2330  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> >
2331  , And< Or< Bool<SF>, Bool<HF> >
2332  , Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
2333  , And< IsStrictlyLower<MT2>, IsLower<MT1> > > > >::value >
2334 {};
2336 //*************************************************************************************************
2337 
2338 
2339 
2340 
2341 //=================================================================================================
2342 //
2343 // EXPRESSION TRAIT SPECIALIZATIONS
2344 //
2345 //=================================================================================================
2346 
2347 //*************************************************************************************************
2349 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF, typename VT >
2350 struct DMatDVecMultExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF>, VT >
2351 {
2352  public:
2353  //**********************************************************************************************
2358  , INVALID_TYPE >;
2359  //**********************************************************************************************
2360 };
2362 //*************************************************************************************************
2363 
2364 
2365 //*************************************************************************************************
2367 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF, typename VT >
2368 struct DMatSVecMultExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF>, VT >
2369 {
2370  public:
2371  //**********************************************************************************************
2376  , INVALID_TYPE >;
2377  //**********************************************************************************************
2378 };
2380 //*************************************************************************************************
2381 
2382 
2383 //*************************************************************************************************
2385 template< typename VT, typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2386 struct TDVecDMatMultExprTrait< VT, DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2387 {
2388  public:
2389  //**********************************************************************************************
2394  , INVALID_TYPE >;
2395  //**********************************************************************************************
2396 };
2398 //*************************************************************************************************
2399 
2400 
2401 //*************************************************************************************************
2403 template< typename VT, typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2404 struct TSVecDMatMultExprTrait< VT, DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2405 {
2406  public:
2407  //**********************************************************************************************
2412  , INVALID_TYPE >;
2413  //**********************************************************************************************
2414 };
2416 //*************************************************************************************************
2417 
2418 
2419 //*************************************************************************************************
2421 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2422 struct DMatDeclSymExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2423 {
2424  public:
2425  //**********************************************************************************************
2429  , INVALID_TYPE >;
2430  //**********************************************************************************************
2431 };
2433 //*************************************************************************************************
2434 
2435 
2436 //*************************************************************************************************
2438 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2439 struct DMatDeclHermExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2440 {
2441  public:
2442  //**********************************************************************************************
2446  , INVALID_TYPE >;
2447  //**********************************************************************************************
2448 };
2450 //*************************************************************************************************
2451 
2452 
2453 //*************************************************************************************************
2455 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2456 struct DMatDeclLowExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2457 {
2458  public:
2459  //**********************************************************************************************
2463  , INVALID_TYPE >;
2464  //**********************************************************************************************
2465 };
2467 //*************************************************************************************************
2468 
2469 
2470 //*************************************************************************************************
2472 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2473 struct DMatDeclUppExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2474 {
2475  public:
2476  //**********************************************************************************************
2480  , INVALID_TYPE >;
2481  //**********************************************************************************************
2482 };
2484 //*************************************************************************************************
2485 
2486 
2487 //*************************************************************************************************
2489 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2490 struct DMatDeclDiagExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2491 {
2492  public:
2493  //**********************************************************************************************
2497  , INVALID_TYPE >;
2498  //**********************************************************************************************
2499 };
2501 //*************************************************************************************************
2502 
2503 
2504 //*************************************************************************************************
2506 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF, bool AF >
2507 struct SubmatrixExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF>, AF >
2508 {
2509  public:
2510  //**********************************************************************************************
2513  //**********************************************************************************************
2514 };
2516 //*************************************************************************************************
2517 
2518 
2519 //*************************************************************************************************
2521 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2522 struct RowExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2523 {
2524  public:
2525  //**********************************************************************************************
2526  using Type = MultExprTrait_< RowExprTrait_<const MT1>, MT2 >;
2527  //**********************************************************************************************
2528 };
2530 //*************************************************************************************************
2531 
2532 
2533 //*************************************************************************************************
2535 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2536 struct ColumnExprTrait< DMatTSMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2537 {
2538  public:
2539  //**********************************************************************************************
2541  //**********************************************************************************************
2542 };
2544 //*************************************************************************************************
2545 
2546 } // namespace blaze
2547 
2548 #endif
typename SubmatrixExprTrait< MT, AF >::Type SubmatrixExprTrait_
Auxiliary alias declaration for the SubmatrixExprTrait type trait.The SubmatrixExprTrait_ alias decla...
Definition: SubmatrixExprTrait.h:134
#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
Evaluation of the expression type of a dense matrix declupp operation.Via this type trait it is possi...
Definition: DMatDeclUppExprTrait.h:75
Compile time check for row vector types.This type trait tests whether or not the given template argum...
Definition: IsRowVector.h:80
const DMatForEachExpr< MT, Conj, SO > conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatForEachExpr.h:1214
Header file for auxiliary alias declarations.
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:72
Header file for mathematical functions.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
Header file for the Rows type trait.
Header file for the IsUniUpper type trait.
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.
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatTSMatMultExpr.h:248
Header file for the DMatDeclDiagExprTrait class template.
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DMatTSMatMultExpr.h:247
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
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DMatTSMatMultExpr.h:371
Header file for the IsSparseMatrix type trait.
Header file for the serial shim.
ResultType_< MT1 > RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatTSMatMultExpr.h:152
Header file for the IsDiagonal type trait.
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:61
Header file for the ColumnExprTrait class template.
Header file for the DeclUpp functor.
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:194
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:533
DMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the DMatTSMatMultExpr class.
Definition: DMatTSMatMultExpr.h:282
Header file for the IsRowVector type trait.
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense matrix operand.
Definition: DMatTSMatMultExpr.h:381
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
Flag for upper matrices.
Definition: DMatTSMatMultExpr.h:176
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:1755
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DMatTSMatMultExpr.h:345
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatTSMatMultExpr.h:252
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatTSMatMultExpr.h:435
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
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.
DisableIf_< IsSymmetric< MT >, const DMatDeclSymExpr< MT, SO > > declsym(const DenseMatrix< MT, SO > &dm)
Declares the given non-symmetric dense matrix expression dm as symmetric.
Definition: DMatDeclSymExpr.h:841
Evaluation of the expression type of a dense matrix/dense vector multiplication.Via this type trait i...
Definition: DMatDVecMultExprTrait.h:78
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.
System settings for performance optimizations.
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:1802
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
IfTrue_< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: DMatTSMatMultExpr.h:264
ElementType_< RT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: DMatTSMatMultExpr.h:154
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:71
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:119
Constraint on the data type.
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
CompositeType_< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: DMatTSMatMultExpr.h:157
Evaluation of the expression type of a dense matrix declsym operation.Via this type trait it is possi...
Definition: DMatDeclSymExprTrait.h:75
Constraint on the data type.
Constraint on the data type.
typename MultExprTrait< T1, T2 >::Type MultExprTrait_
Auxiliary alias declaration for the MultExprTrait class template.The MultExprTrait_ alias declaration...
Definition: MultExprTrait.h:344
Header file for the MultExprTrait class template.
DisableIf_< IsHermitian< MT >, const DMatDeclHermExpr< MT, SO > > declherm(const DenseMatrix< MT, SO > &dm)
Declares the given non-Hermitian dense matrix expression dm as Hermitian.
Definition: DMatDeclHermExpr.h:841
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
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: DMatTSMatMultExpr.h:443
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
Header file for the DisableIf class template.
Compile time check for dense vector types.This type trait tests whether or not the given template par...
Definition: IsDenseVector.h:78
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 DeclLow functor.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DMatTSMatMultExpr.h:415
Header file for the If class template.
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:83
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatTSMatMultExpr.h:403
#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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2939
Generic wrapper for the decllow() function.
Definition: DeclLow.h:58
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.
Flag for lower matrices.
Definition: DMatTSMatMultExpr.h:175
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the DenseMatrix base class.
Header file for the DMatDeclLowExprTrait class template.
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
Evaluation of the expression type of a dense matrix/sparse vector multiplication.Via this type trait ...
Definition: DMatSVecMultExprTrait.h:80
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: DMatTSMatMultExpr.h:391
Compile time check for sparse vector types.This type trait tests whether or not the given template pa...
Definition: IsSparseVector.h:78
Evaluation of the expression type type of a submatrix operation.Via this type trait it is possible to...
Definition: SubmatrixExprTrait.h:80
Header file for the DMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< 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:128
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:60
Generic wrapper for the null function.
Definition: Noop.h:58
Header file for the IsTriangular type trait.
Header file for the DMatDeclUppExprTrait class template.
Header file for the DMatDeclSymExprTrait class template.
Compile time check for column vector types.This type trait tests whether or not the given template ar...
Definition: IsColumnVector.h:80
Constraints on the storage order of matrix types.
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
Header file for the exception macros of the math module.
DisableIf_< IsLower< MT >, const DMatDeclLowExpr< MT, SO > > decllow(const DenseMatrix< MT, SO > &dm)
Declares the given non-lower dense matrix expression dm as lower.
Definition: DMatDeclLowExpr.h:842
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DMatTSMatMultExpr.h:361
Evaluation of the expression type type of a row operation.Via this type trait it is possible to evalu...
Definition: RowExprTrait.h:79
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:260
const ElementType ReturnType
Return type for expression template evaluations.
Definition: DMatTSMatMultExpr.h:251
Header file for the DeclDiag functor.
Evaluation of the expression type of a dense matrix declherm operation.Via this type trait it is poss...
Definition: DMatDeclHermExprTrait.h:75
Compile time check for dense matrix types.This type trait tests whether or not the given template par...
Definition: IsDenseMatrix.h:78
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the IsDenseMatrix type trait.
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatTSMatMultExpr.h:425
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< 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:128
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 lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:86
Header file for the conjugate shim.
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
Base class for all matrix/matrix multiplication expression templates.The MatMatMultExpr class serves ...
Definition: MatMatMultExpr.h:65
ResultType_< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: DMatTSMatMultExpr.h:153
IfTrue_< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: DMatTSMatMultExpr.h:261
Flag for Hermitian matrices.
Definition: DMatTSMatMultExpr.h:174
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.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
CompositeType_< MT1 > CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatTSMatMultExpr.h:156
ElementType_< RT2 > ET2
Element type of the right-hand side sparse matrix expression.
Definition: DMatTSMatMultExpr.h:155
Header file for run time assertion macros.
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:83
Utility type for generic codes.
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
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: DMatTSMatMultExpr.h:442
Header file for the reset shim.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:93
Header file for the DMatDeclHermExprTrait class template.
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Expression object for dense matrix-transpose sparse matrix multiplications.The DMatTSMatMultExpr clas...
Definition: DMatTSMatMultExpr.h:146
typename TDVecTSMatMultExprTrait< VT, MT >::Type TDVecTSMatMultExprTrait_
Auxiliary alias declaration for the TDVecTSMatMultExprTrait class template.The TDVecTSMatMultExprTrai...
Definition: TDVecTSMatMultExprTrait.h:120
Constraints on the storage order of matrix types.
Generic wrapper for the declherm() function.
Definition: DeclHerm.h:58
typename DMatSVecMultExprTrait< MT, VT >::Type DMatSVecMultExprTrait_
Auxiliary alias declaration for the DMatSVecMultExprTrait class template.The DMatSVecMultExprTrait_ a...
Definition: DMatSVecMultExprTrait.h:123
Header file for the Noop functor.
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: DMatTSMatMultExpr.h:258
Header file for the RemoveReference type trait.
typename DMatDVecMultExprTrait< MT, VT >::Type DMatDVecMultExprTrait_
Auxiliary alias declaration for the DMatDVecMultExprTrait class template.The DMatDVecMultExprTrait_ a...
Definition: DMatDVecMultExprTrait.h:119
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:243
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:84
Header file for the IsDenseVector type trait.
ElementType_< ResultType > ElementType
Resulting element type.
Definition: DMatTSMatMultExpr.h:250
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatTSMatMultExpr.h:255
Generic wrapper for the declupp() function.
Definition: DeclUpp.h:58
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
Evaluation of the expression type of a dense vector/dense matrix multiplication.Via this type trait i...
Definition: TDVecDMatMultExprTrait.h:78
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
Evaluation of the expression type of a sparse vector/dense matrix multiplication.Via this type trait ...
Definition: TSVecDMatMultExprTrait.h:78
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatTSMatMultExpr.h:249
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:733
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
Flag for symmetric matrices.
Definition: DMatTSMatMultExpr.h:173
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:59
Header file for the TDVecDMatMultExprTrait class template.
Header file for the IntegralConstant class template.
Compile time evaluation of the number of columns of a matrix.The Columns type trait evaluates the num...
Definition: Columns.h:76
Evaluation of the expression type of a dense matrix decllow operation.Via this type trait it is possi...
Definition: DMatDeclLowExprTrait.h:75
Generic wrapper for the decldiag() function.
Definition: DeclDiag.h:58
Evaluation of the expression type of a dense matrix decldiag operation.Via this type trait it is poss...
Definition: DMatDeclDiagExprTrait.h:75
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:76
Header file for the TSVecDMatMultExprTrait class template.
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
Header file for the DeclHerm functor.
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.
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Constraint on the data type.
Generic wrapper for the declsym() function.
Definition: DeclSym.h:58
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:677
Header file for the IsResizable type trait.
const DMatDMatMultExpr< T1, T2, false, false, false, false > 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:7505
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
DisableIf_< IsDiagonal< MT >, const DMatDeclDiagExpr< MT, SO > > decldiag(const DenseMatrix< MT, SO > &dm)
Declares the given non-diagonal dense matrix expression dm as diagonal.
Definition: DMatDeclDiagExpr.h:841
DisableIf_< IsUpper< MT >, const DMatDeclUppExpr< MT, SO > > declupp(const DenseMatrix< MT, SO > &dm)
Declares the given non-upper dense matrix expression dm as upper.
Definition: DMatDeclUppExpr.h:842
Evaluation of the expression type type of a column operation.Via this type trait it is possible to ev...
Definition: ColumnExprTrait.h:78
#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
Header file for the Bool class template.
DMatTSMatMultExpr< MT1, MT2, SF, HF, LF, UF > This
Type of this DMatTSMatMultExpr instance.
Definition: DMatTSMatMultExpr.h:245
Header file for the DeclSym functor.
#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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTSMatMultExpr.h:297
Header file for the TrueType type/value trait base class.
Header file for the IsExpression type trait class.
Header file for the TSMatSVecMultExprTrait class template.
Header file for the function trace functionality.