SMatTDMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_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>
109 #include <blaze/system/Thresholds.h>
110 #include <blaze/util/Assert.h>
112 #include <blaze/util/DisableIf.h>
113 #include <blaze/util/EnableIf.h>
116 #include <blaze/util/InvalidType.h>
117 #include <blaze/util/mpl/And.h>
118 #include <blaze/util/mpl/Bool.h>
119 #include <blaze/util/mpl/If.h>
120 #include <blaze/util/mpl/Or.h>
121 #include <blaze/util/TrueType.h>
122 #include <blaze/util/Types.h>
125 
126 
127 namespace blaze {
128 
129 //=================================================================================================
130 //
131 // CLASS SMATTDMATMULTEXPR
132 //
133 //=================================================================================================
134 
135 //*************************************************************************************************
142 template< typename MT1 // Type of the left-hand side sparse matrix
143  , typename MT2 // Type of the right-hand side dense matrix
144  , bool SF // Symmetry flag
145  , bool HF // Hermitian flag
146  , bool LF // Lower flag
147  , bool UF > // Upper flag
148 class SMatTDMatMultExpr : public DenseMatrix< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, false >
149  , private MatMatMultExpr
150  , private Computation
151 {
152  private:
153  //**Type definitions****************************************************************************
160  //**********************************************************************************************
161 
162  //**********************************************************************************************
164  enum : bool { evaluateLeft = IsComputation<MT1>::value || RequiresEvaluation<MT1>::value };
165  //**********************************************************************************************
166 
167  //**********************************************************************************************
169  enum : bool { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
170  //**********************************************************************************************
171 
172  //**********************************************************************************************
174  enum : bool {
175  SYM = ( SF && !( HF || LF || UF ) ),
176  HERM = ( HF && !( LF || UF ) ),
177  LOW = ( LF || ( ( SF || HF ) && UF ) ),
178  UPP = ( UF || ( ( SF || HF ) && LF ) )
179  };
180  //**********************************************************************************************
181 
182  //**********************************************************************************************
184 
189  template< typename T1, typename T2, typename T3 >
190  struct CanExploitSymmetry {
191  enum : bool { value = IsSymmetric<T3>::value };
192  };
194  //**********************************************************************************************
195 
196  //**********************************************************************************************
198 
202  template< typename T1, typename T2, typename T3 >
203  struct IsEvaluationRequired {
204  enum : bool { value = ( evaluateLeft || evaluateRight ) &&
205  CanExploitSymmetry<T1,T2,T3>::value };
206  };
208  //**********************************************************************************************
209 
210  //**********************************************************************************************
212 
215  template< typename T1, typename T2, typename T3 >
216  struct UseOptimizedKernel {
217  enum : bool { value = useOptimizedKernels &&
219  !IsResizable< ElementType_<T1> >::value &&
221  };
223  //**********************************************************************************************
224 
225  //**********************************************************************************************
227 
230  typedef IfTrue_< HERM
231  , DeclHerm
232  , IfTrue_< SYM
233  , DeclSym
234  , IfTrue_< LOW
235  , IfTrue_< UPP
236  , DeclDiag
237  , DeclLow >
238  , IfTrue_< UPP
239  , DeclUpp
240  , Noop > > > > ForwardFunctor;
242  //**********************************************************************************************
243 
244  public:
245  //**Type definitions****************************************************************************
248 
253  typedef const ElementType ReturnType;
254  typedef const ResultType CompositeType;
255 
257  typedef If_< IsExpression<MT1>, const MT1, const MT1& > LeftOperand;
258 
260  typedef If_< IsExpression<MT2>, const MT2, const MT2& > RightOperand;
261 
264 
267  //**********************************************************************************************
268 
269  //**Compilation flags***************************************************************************
271  enum : bool { simdEnabled = false };
272 
274  enum : bool { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
275  !evaluateRight && MT2::smpAssignable };
276  //**********************************************************************************************
277 
278  //**Constructor*********************************************************************************
284  explicit inline SMatTDMatMultExpr( const MT1& lhs, const MT2& rhs ) noexcept
285  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
286  , rhs_( rhs ) // Right-hand side dense matrix of the multiplication expression
287  {
288  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
289  }
290  //**********************************************************************************************
291 
292  //**Access operator*****************************************************************************
299  inline ReturnType operator()( size_t i, size_t j ) const {
300  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
301  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
302 
303  if( IsDiagonal<MT1>::value ) {
304  return lhs_(i,i) * rhs_(i,j);
305  }
306  else if( IsDiagonal<MT2>::value ) {
307  return lhs_(i,j) * rhs_(j,j);
308  }
310  const size_t begin( ( IsUpper<MT1>::value )
311  ?( ( IsLower<MT2>::value )
312  ?( max( ( IsStrictlyUpper<MT1>::value ? i+1UL : i )
313  , ( IsStrictlyLower<MT2>::value ? j+1UL : j ) ) )
314  :( IsStrictlyUpper<MT1>::value ? i+1UL : i ) )
315  :( ( IsLower<MT2>::value )
316  ?( IsStrictlyLower<MT2>::value ? j+1UL : j )
317  :( 0UL ) ) );
318  const size_t end( ( IsLower<MT1>::value )
319  ?( ( IsUpper<MT2>::value )
320  ?( min( ( IsStrictlyLower<MT1>::value ? i : i+1UL )
321  , ( IsStrictlyUpper<MT2>::value ? j : j+1UL ) ) )
322  :( IsStrictlyLower<MT1>::value ? i : i+1UL ) )
323  :( ( IsUpper<MT2>::value )
324  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
325  :( lhs_.columns() ) ) );
326 
327  if( begin >= end ) return ElementType();
328 
329  const size_t n( end - begin );
330 
331  return subvector( row( lhs_, i ), begin, n ) * subvector( column( rhs_, j ), begin, n );
332  }
333  else {
334  return row( lhs_, i ) * column( rhs_, j );
335  }
336  }
337  //**********************************************************************************************
338 
339  //**At function*********************************************************************************
347  inline ReturnType at( size_t i, size_t j ) const {
348  if( i >= lhs_.rows() ) {
349  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
350  }
351  if( j >= rhs_.columns() ) {
352  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
353  }
354  return (*this)(i,j);
355  }
356  //**********************************************************************************************
357 
358  //**Rows function*******************************************************************************
363  inline size_t rows() const noexcept {
364  return lhs_.rows();
365  }
366  //**********************************************************************************************
367 
368  //**Columns function****************************************************************************
373  inline size_t columns() const noexcept {
374  return rhs_.columns();
375  }
376  //**********************************************************************************************
377 
378  //**Left operand access*************************************************************************
383  inline LeftOperand leftOperand() const noexcept {
384  return lhs_;
385  }
386  //**********************************************************************************************
387 
388  //**Right operand access************************************************************************
393  inline RightOperand rightOperand() const noexcept {
394  return rhs_;
395  }
396  //**********************************************************************************************
397 
398  //**********************************************************************************************
404  template< typename T >
405  inline bool canAlias( const T* alias ) const noexcept {
406  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
407  }
408  //**********************************************************************************************
409 
410  //**********************************************************************************************
416  template< typename T >
417  inline bool isAliased( const T* alias ) const noexcept {
418  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
419  }
420  //**********************************************************************************************
421 
422  //**********************************************************************************************
427  inline bool isAligned() const noexcept {
428  return rhs_.isAligned();
429  }
430  //**********************************************************************************************
431 
432  //**********************************************************************************************
437  inline bool canSMPAssign() const noexcept {
438  return ( rows() * columns() >= SMP_SMATTDMATMULT_THRESHOLD ) && !IsDiagonal<MT2>::value;
439  }
440  //**********************************************************************************************
441 
442  private:
443  //**Member variables****************************************************************************
444  LeftOperand lhs_;
445  RightOperand rhs_;
446  //**********************************************************************************************
447 
448  //**Assignment to dense matrices****************************************************************
461  template< typename MT // Type of the target dense matrix
462  , bool SO > // Storage order of the target dense matrix
464  assign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
465  {
467 
468  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
469  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
470 
471  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
472  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
473 
474  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
475  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
476  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
477  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
478  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
479  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
480 
481  SMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
482  }
484  //**********************************************************************************************
485 
486  //**Default assignment to dense matrices********************************************************
500  template< typename MT3 // Type of the left-hand side target matrix
501  , typename MT4 // Type of the left-hand side matrix operand
502  , typename MT5 > // Type of the right-hand side matrix operand
504  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
505  {
507 
508  const size_t M( A.rows() );
509  const size_t N( B.columns() );
510 
511  BLAZE_INTERNAL_ASSERT( !( SYM || HERM || LOW || UPP ) || M == N, "Broken invariant detected" );
512 
513  {
514  size_t j( 0UL );
515 
516  for( ; (j+4UL) <= N; j+=4UL ) {
517  for( size_t i=( SYM || HERM || LOW ? j : 0UL ); i<( UPP ? j+4UL : M ); ++i )
518  {
519  const ConstIterator end( ( IsUpper<MT5>::value )
520  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
521  :( A.end(i) ) );
522  ConstIterator element( ( IsLower<MT5>::value )
523  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
524  :( A.begin(i) ) );
525 
526  if( element == end ) {
527  reset( C(i,j ) );
528  reset( C(i,j+1UL) );
529  reset( C(i,j+2UL) );
530  reset( C(i,j+3UL) );
531  continue;
532  }
533 
534  C(i,j ) = element->value() * B(element->index(),j );
535  C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
536  C(i,j+2UL) = element->value() * B(element->index(),j+2UL);
537  C(i,j+3UL) = element->value() * B(element->index(),j+3UL);
538  ++element;
539  for( ; element!=end; ++element ) {
540  C(i,j ) += element->value() * B(element->index(),j );
541  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
542  C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
543  C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
544  }
545  }
546  }
547 
548  for( ; (j+2UL) <= N; j+=2UL ) {
549  for( size_t i=( SYM || HERM || LOW ? j : 0UL ); i<( UPP ? j+2UL : M ); ++i )
550  {
551  const ConstIterator end( ( IsUpper<MT5>::value )
552  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
553  :( A.end(i) ) );
554  ConstIterator element( ( IsLower<MT5>::value )
555  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
556  :( A.begin(i) ) );
557 
558  if( element == end ) {
559  reset( C(i,j ) );
560  reset( C(i,j+1UL) );
561  continue;
562  }
563 
564  C(i,j ) = element->value() * B(element->index(),j );
565  C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
566  ++element;
567  for( ; element!=end; ++element ) {
568  C(i,j ) += element->value() * B(element->index(),j );
569  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
570  }
571  }
572  }
573 
574  for( ; j<N; ++j ) {
575  for( size_t i=( SYM || HERM || LOW ? j : 0UL ); i<( UPP ? j+1UL : M ); ++i )
576  {
577  const ConstIterator end( ( IsUpper<MT5>::value )
578  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
579  :( A.end(i) ) );
580  ConstIterator element( ( IsLower<MT5>::value )
581  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
582  :( A.begin(i) ) );
583 
584  if( element == end ) {
585  reset( C(i,j) );
586  continue;
587  }
588 
589  C(i,j) = element->value() * B(element->index(),j);
590  ++element;
591  for( ; element!=end; ++element ) {
592  C(i,j) += element->value() * B(element->index(),j);
593  }
594  }
595  }
596  }
597 
598  if( SYM || HERM ) {
599  for( size_t j=1UL; j<N; ++j ) {
600  for( size_t i=0UL; i<j; ++i ) {
601  C(i,j) = HERM ? conj( C(j,i) ) : C(j,i);
602  }
603  }
604  }
605  else if( LOW && !UPP ) {
606  for( size_t j=1UL; j<N; ++j ) {
607  for( size_t i=0UL; i<j; ++i ) {
608  reset( C(i,j) );
609  }
610  }
611  }
612  else if( !LOW && UPP ) {
613  for( size_t i=1UL; i<M; ++i ) {
614  for( size_t j=0UL; j<i; ++j ) {
615  reset( C(i,j) );
616  }
617  }
618  }
619  }
621  //**********************************************************************************************
622 
623  //**Optimized assignment to dense matrices******************************************************
637  template< typename MT3 // Type of the left-hand side target matrix
638  , typename MT4 // Type of the left-hand side matrix operand
639  , typename MT5 > // Type of the right-hand side matrix operand
641  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
642  {
644 
645  const size_t M( A.rows() );
646  const size_t N( B.columns() );
647 
648  BLAZE_INTERNAL_ASSERT( !( SYM || HERM || LOW || UPP ) || M == N, "Broken invariant detected" );
649 
650  reset( C );
651 
652  {
653  size_t j( 0UL );
654 
655  for( ; (j+4UL) <= N; j+=4UL ) {
656  for( size_t i=( SYM || HERM || LOW ? j : 0UL ); i<( UPP ? j+4UL : M ); ++i )
657  {
658  const ConstIterator end( ( IsUpper<MT5>::value )
659  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
660  :( A.end(i) ) );
661  ConstIterator element( ( IsLower<MT5>::value )
662  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
663  :( A.begin(i) ) );
664 
665  const size_t nonzeros( end - element );
666  const size_t kpos( nonzeros & size_t(-4) );
667  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
668 
669  for( size_t k=0UL; k<kpos; k+=4UL )
670  {
671  const size_t i1( element->index() );
672  const ET1 v1( element->value() );
673  ++element;
674  const size_t i2( element->index() );
675  const ET1 v2( element->value() );
676  ++element;
677  const size_t i3( element->index() );
678  const ET1 v3( element->value() );
679  ++element;
680  const size_t i4( element->index() );
681  const ET1 v4( element->value() );
682  ++element;
683 
684  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
685 
686  C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
687  C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
688  C(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
689  C(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
690  }
691 
692  for( ; element!=end; ++element )
693  {
694  const size_t i1( element->index() );
695  const ET1 v1( element->value() );
696 
697  C(i,j ) += v1 * B(i1,j );
698  C(i,j+1UL) += v1 * B(i1,j+1UL);
699  C(i,j+2UL) += v1 * B(i1,j+2UL);
700  C(i,j+3UL) += v1 * B(i1,j+3UL);
701  }
702  }
703  }
704 
705  for( ; (j+2UL) <= N; j+=2UL ) {
706  for( size_t i=( SYM || HERM || LOW ? j : 0UL ); i<( UPP ? j+2UL : M ); ++i )
707  {
708  const ConstIterator end( ( IsUpper<MT5>::value )
709  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
710  :( A.end(i) ) );
711  ConstIterator element( ( IsLower<MT5>::value )
712  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
713  :( A.begin(i) ) );
714 
715  const size_t nonzeros( end - element );
716  const size_t kpos( nonzeros & size_t(-4) );
717  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
718 
719  for( size_t k=0UL; k<kpos; k+=4UL )
720  {
721  const size_t i1( element->index() );
722  const ET1 v1( element->value() );
723  ++element;
724  const size_t i2( element->index() );
725  const ET1 v2( element->value() );
726  ++element;
727  const size_t i3( element->index() );
728  const ET1 v3( element->value() );
729  ++element;
730  const size_t i4( element->index() );
731  const ET1 v4( element->value() );
732  ++element;
733 
734  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
735 
736  C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
737  C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
738  }
739 
740  for( ; element!=end; ++element )
741  {
742  const size_t i1( element->index() );
743  const ET1 v1( element->value() );
744 
745  C(i,j ) += v1 * B(i1,j );
746  C(i,j+1UL) += v1 * B(i1,j+1UL);
747  }
748  }
749  }
750 
751  for( ; j<N; ++j ) {
752  for( size_t i=( SYM || HERM || LOW ? j : 0UL ); i<( UPP ? j+1UL : M ); ++i )
753  {
754  const ConstIterator end( ( IsUpper<MT5>::value )
755  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
756  :( A.end(i) ) );
757  ConstIterator element( ( IsLower<MT5>::value )
758  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
759  :( A.begin(i) ) );
760 
761  const size_t nonzeros( end - element );
762  const size_t kpos( nonzeros & size_t(-4) );
763  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
764 
765  for( size_t k=0UL; k<kpos; k+=4UL )
766  {
767  const size_t i1( element->index() );
768  const ET1 v1( element->value() );
769  ++element;
770  const size_t i2( element->index() );
771  const ET1 v2( element->value() );
772  ++element;
773  const size_t i3( element->index() );
774  const ET1 v3( element->value() );
775  ++element;
776  const size_t i4( element->index() );
777  const ET1 v4( element->value() );
778  ++element;
779 
780  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
781 
782  C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
783  }
784 
785  for( ; element!=end; ++element )
786  {
787  const size_t i1( element->index() );
788  const ET1 v1( element->value() );
789 
790  C(i,j) += v1 * B(i1,j);
791  }
792  }
793  }
794  }
795 
796  if( SYM || HERM ) {
797  for( size_t j=1UL; j<N; ++j ) {
798  for( size_t i=0UL; i<j; ++i ) {
799  C(i,j) = HERM ? conj( C(j,i) ) : C(j,i);
800  }
801  }
802  }
803  }
805  //**********************************************************************************************
806 
807  //**Assignment to sparse matrices***************************************************************
820  template< typename MT // Type of the target sparse matrix
821  , bool SO > // Storage order of the target sparse matrix
823  assign( SparseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
824  {
826 
828 
835 
836  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
837  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
838 
839  const ForwardFunctor fwd;
840 
841  const TmpType tmp( serial( rhs ) );
842  assign( ~lhs, fwd( tmp ) );
843  }
845  //**********************************************************************************************
846 
847  //**Restructuring assignment********************************************************************
862  template< typename MT // Type of the target matrix
863  , bool SO > // Storage order of the target matrix
865  assign( Matrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
866  {
868 
869  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
870  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
871 
872  const ForwardFunctor fwd;
873 
874  assign( ~lhs, fwd( rhs.lhs_ * trans( rhs.rhs_ ) ) );
875  }
877  //**********************************************************************************************
878 
879  //**Addition assignment to dense matrices*******************************************************
892  template< typename MT // Type of the target dense matrix
893  , bool SO > // Storage order of the target dense matrix
895  addAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
896  {
898 
899  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
900  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
901 
902  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
903  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
904 
905  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
906  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
907  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
908  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
909  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
910  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
911 
912  SMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
913  }
915  //**********************************************************************************************
916 
917  //**Default addition assignment to dense matrices***********************************************
931  template< typename MT3 // Type of the left-hand side target matrix
932  , typename MT4 // Type of the left-hand side matrix operand
933  , typename MT5 > // Type of the right-hand side matrix operand
935  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
936  {
938 
939  const size_t M( A.rows() );
940  const size_t N( B.columns() );
941 
942  BLAZE_INTERNAL_ASSERT( !( LOW || UPP ) || M == N, "Broken invariant detected" );
943 
944  {
945  size_t j( 0UL );
946 
947  for( ; (j+4UL) <= N; j+=4UL ) {
948  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+4UL : M ); ++i )
949  {
950  const ConstIterator end( ( IsUpper<MT5>::value )
951  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
952  :( A.end(i) ) );
953  ConstIterator element( ( IsLower<MT5>::value )
954  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
955  :( A.begin(i) ) );
956 
957  for( ; element!=end; ++element ) {
958  C(i,j ) += element->value() * B(element->index(),j );
959  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
960  C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
961  C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
962  }
963  }
964  }
965 
966  for( ; (j+2UL) <= N; j+=2UL ) {
967  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+2UL : M ); ++i )
968  {
969  const ConstIterator end( ( IsUpper<MT5>::value )
970  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
971  :( A.end(i) ) );
972  ConstIterator element( ( IsLower<MT5>::value )
973  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
974  :( A.begin(i) ) );
975 
976  for( ; element!=end; ++element ) {
977  C(i,j ) += element->value() * B(element->index(),j );
978  C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
979  }
980  }
981  }
982 
983  for( ; j<N; ++j ) {
984  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+1UL : M ); ++i )
985  {
986  const ConstIterator end( ( IsUpper<MT5>::value )
987  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
988  :( A.end(i) ) );
989  ConstIterator element( ( IsLower<MT5>::value )
990  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
991  :( A.begin(i) ) );
992 
993  for( ; element!=end; ++element ) {
994  C(i,j) += element->value() * B(element->index(),j);
995  }
996  }
997  }
998  }
999  }
1001  //**********************************************************************************************
1002 
1003  //**Optimized addition assignment to dense matrices*********************************************
1017  template< typename MT3 // Type of the left-hand side target matrix
1018  , typename MT4 // Type of the left-hand side matrix operand
1019  , typename MT5 > // Type of the right-hand side matrix operand
1021  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1022  {
1024 
1025  const size_t M( A.rows() );
1026  const size_t N( B.columns() );
1027 
1028  BLAZE_INTERNAL_ASSERT( !( LOW || UPP ) || M == N, "Broken invariant detected" );
1029 
1030  {
1031  size_t j( 0UL );
1032 
1033  for( ; (j+4UL) <= N; j+=4UL ) {
1034  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+4UL : M ); ++i )
1035  {
1036  const ConstIterator end( ( IsUpper<MT5>::value )
1037  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1038  :( A.end(i) ) );
1039  ConstIterator element( ( IsLower<MT5>::value )
1040  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1041  :( A.begin(i) ) );
1042 
1043  const size_t nonzeros( end - element );
1044  const size_t kpos( nonzeros & size_t(-4) );
1045  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1046 
1047  for( size_t k=0UL; k<kpos; k+=4UL )
1048  {
1049  const size_t i1( element->index() );
1050  const ET1 v1( element->value() );
1051  ++element;
1052  const size_t i2( element->index() );
1053  const ET1 v2( element->value() );
1054  ++element;
1055  const size_t i3( element->index() );
1056  const ET1 v3( element->value() );
1057  ++element;
1058  const size_t i4( element->index() );
1059  const ET1 v4( element->value() );
1060  ++element;
1061 
1062  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1063 
1064  C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1065  C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1066  C(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1067  C(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1068  }
1069 
1070  for( ; element!=end; ++element )
1071  {
1072  const size_t i1( element->index() );
1073  const ET1 v1( element->value() );
1074 
1075  C(i,j ) += v1 * B(i1,j );
1076  C(i,j+1UL) += v1 * B(i1,j+1UL);
1077  C(i,j+2UL) += v1 * B(i1,j+2UL);
1078  C(i,j+3UL) += v1 * B(i1,j+3UL);
1079  }
1080  }
1081  }
1082 
1083  for( ; (j+2UL) <= N; j+=2UL ) {
1084  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+2UL : M ); ++i )
1085  {
1086  const ConstIterator end( ( IsUpper<MT5>::value )
1087  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1088  :( A.end(i) ) );
1089  ConstIterator element( ( IsLower<MT5>::value )
1090  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1091  :( A.begin(i) ) );
1092 
1093  const size_t nonzeros( end - element );
1094  const size_t kpos( nonzeros & size_t(-4) );
1095  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1096 
1097  for( size_t k=0UL; k<kpos; k+=4UL )
1098  {
1099  const size_t i1( element->index() );
1100  const ET1 v1( element->value() );
1101  ++element;
1102  const size_t i2( element->index() );
1103  const ET1 v2( element->value() );
1104  ++element;
1105  const size_t i3( element->index() );
1106  const ET1 v3( element->value() );
1107  ++element;
1108  const size_t i4( element->index() );
1109  const ET1 v4( element->value() );
1110  ++element;
1111 
1112  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1113 
1114  C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1115  C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1116  }
1117 
1118  for( ; element!=end; ++element )
1119  {
1120  const size_t i1( element->index() );
1121  const ET1 v1( element->value() );
1122 
1123  C(i,j ) += v1 * B(i1,j );
1124  C(i,j+1UL) += v1 * B(i1,j+1UL);
1125  }
1126  }
1127  }
1128 
1129  for( ; j<N; ++j ) {
1130  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+1UL : M ); ++i )
1131  {
1132  const ConstIterator end( ( IsUpper<MT5>::value )
1133  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
1134  :( A.end(i) ) );
1135  ConstIterator element( ( IsLower<MT5>::value )
1136  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1137  :( A.begin(i) ) );
1138 
1139  const size_t nonzeros( end - element );
1140  const size_t kpos( nonzeros & size_t(-4) );
1141  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1142 
1143  for( size_t k=0UL; k<kpos; k+=4UL )
1144  {
1145  const size_t i1( element->index() );
1146  const ET1 v1( element->value() );
1147  ++element;
1148  const size_t i2( element->index() );
1149  const ET1 v2( element->value() );
1150  ++element;
1151  const size_t i3( element->index() );
1152  const ET1 v3( element->value() );
1153  ++element;
1154  const size_t i4( element->index() );
1155  const ET1 v4( element->value() );
1156  ++element;
1157 
1158  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1159 
1160  C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1161  }
1162 
1163  for( ; element!=end; ++element )
1164  {
1165  const size_t i1( element->index() );
1166  const ET1 v1( element->value() );
1167 
1168  C(i,j) += v1 * B(i1,j);
1169  }
1170  }
1171  }
1172  }
1173  }
1175  //**********************************************************************************************
1176 
1177  //**Restructuring addition assignment***********************************************************
1192  template< typename MT // Type of the target matrix
1193  , bool SO > // Storage order of the target matrix
1195  addAssign( Matrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1196  {
1198 
1199  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1200  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1201 
1202  const ForwardFunctor fwd;
1203 
1204  addAssign( ~lhs, fwd( rhs.lhs_ * trans( rhs.rhs_ ) ) );
1205  }
1207  //**********************************************************************************************
1208 
1209  //**Addition assignment to sparse matrices******************************************************
1210  // No special implementation for the addition assignment to sparse matrices.
1211  //**********************************************************************************************
1212 
1213  //**Subtraction assignment to dense matrices****************************************************
1226  template< typename MT // Type of the target dense matrix
1227  , bool SO > // Storage order of the target dense matrix
1229  subAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1230  {
1232 
1233  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1234  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1235 
1236  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
1237  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
1238 
1239  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1240  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1241  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1242  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1243  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1244  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1245 
1246  SMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1247  }
1249  //**********************************************************************************************
1250 
1251  //**Default subtraction assignment to dense matrices********************************************
1265  template< typename MT3 // Type of the left-hand side target matrix
1266  , typename MT4 // Type of the left-hand side matrix operand
1267  , typename MT5 > // Type of the right-hand side matrix operand
1269  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1270  {
1272 
1273  const size_t M( A.rows() );
1274  const size_t N( B.columns() );
1275 
1276  BLAZE_INTERNAL_ASSERT( !( LOW || UPP ) || M == N, "Broken invariant detected" );
1277 
1278  {
1279  size_t j( 0UL );
1280 
1281  for( ; (j+4UL) <= N; j+=4UL ) {
1282  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+4UL : M ); ++i )
1283  {
1284  const ConstIterator end( ( IsUpper<MT5>::value )
1285  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1286  :( A.end(i) ) );
1287  ConstIterator element( ( IsLower<MT5>::value )
1288  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1289  :( A.begin(i) ) );
1290 
1291  for( ; element!=end; ++element ) {
1292  C(i,j ) -= element->value() * B(element->index(),j );
1293  C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1294  C(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
1295  C(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
1296  }
1297  }
1298  }
1299 
1300  for( ; (j+2UL) <= N; j+=2UL ) {
1301  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+2UL : M ); ++i )
1302  {
1303  const ConstIterator end( ( IsUpper<MT5>::value )
1304  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1305  :( A.end(i) ) );
1306  ConstIterator element( ( IsLower<MT5>::value )
1307  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1308  :( A.begin(i) ) );
1309 
1310  for( ; element!=end; ++element ) {
1311  C(i,j ) -= element->value() * B(element->index(),j );
1312  C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1313  }
1314  }
1315  }
1316 
1317  for( ; j<N; ++j ) {
1318  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+1UL : M ); ++i )
1319  {
1320  const ConstIterator end( ( IsUpper<MT5>::value )
1321  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
1322  :( A.end(i) ) );
1323  ConstIterator element( ( IsLower<MT5>::value )
1324  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1325  :( A.begin(i) ) );
1326 
1327  for( ; element!=end; ++element ) {
1328  C(i,j) -= element->value() * B(element->index(),j);
1329  }
1330  }
1331  }
1332  }
1333  }
1335  //**********************************************************************************************
1336 
1337  //**Optimized subtraction assignment to dense matrices******************************************
1351  template< typename MT3 // Type of the left-hand side target matrix
1352  , typename MT4 // Type of the left-hand side matrix operand
1353  , typename MT5 > // Type of the right-hand side matrix operand
1355  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1356  {
1358 
1359  const size_t M( A.rows() );
1360  const size_t N( B.columns() );
1361 
1362  BLAZE_INTERNAL_ASSERT( !( LOW || UPP ) || M == N, "Broken invariant detected" );
1363 
1364  {
1365  size_t j( 0UL );
1366 
1367  for( ; (j+4UL) <= N; j+=4UL ) {
1368  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+4UL : M ); ++i )
1369  {
1370  const ConstIterator end( ( IsUpper<MT5>::value )
1371  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1372  :( A.end(i) ) );
1373  ConstIterator element( ( IsLower<MT5>::value )
1374  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1375  :( A.begin(i) ) );
1376 
1377  const size_t nonzeros( end - element );
1378  const size_t kpos( nonzeros & size_t(-4) );
1379  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1380 
1381  for( size_t k=0UL; k<kpos; k+=4UL )
1382  {
1383  const size_t i1( element->index() );
1384  const ET1 v1( element->value() );
1385  ++element;
1386  const size_t i2( element->index() );
1387  const ET1 v2( element->value() );
1388  ++element;
1389  const size_t i3( element->index() );
1390  const ET1 v3( element->value() );
1391  ++element;
1392  const size_t i4( element->index() );
1393  const ET1 v4( element->value() );
1394  ++element;
1395 
1396  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1397 
1398  C(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1399  C(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1400  C(i,j+2UL) -= v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1401  C(i,j+3UL) -= v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1402  }
1403 
1404  for( ; element!=end; ++element )
1405  {
1406  const size_t i1( element->index() );
1407  const ET1 v1( element->value() );
1408 
1409  C(i,j ) -= v1 * B(i1,j );
1410  C(i,j+1UL) -= v1 * B(i1,j+1UL);
1411  C(i,j+2UL) -= v1 * B(i1,j+2UL);
1412  C(i,j+3UL) -= v1 * B(i1,j+3UL);
1413  }
1414  }
1415  }
1416 
1417  for( ; (j+2UL) <= N; j+=2UL ) {
1418  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+2UL : M ); ++i )
1419  {
1420  const ConstIterator end( ( IsUpper<MT5>::value )
1421  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1422  :( A.end(i) ) );
1423  ConstIterator element( ( IsLower<MT5>::value )
1424  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1425  :( A.begin(i) ) );
1426 
1427  const size_t nonzeros( end - element );
1428  const size_t kpos( nonzeros & size_t(-4) );
1429  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1430 
1431  for( size_t k=0UL; k<kpos; k+=4UL )
1432  {
1433  const size_t i1( element->index() );
1434  const ET1 v1( element->value() );
1435  ++element;
1436  const size_t i2( element->index() );
1437  const ET1 v2( element->value() );
1438  ++element;
1439  const size_t i3( element->index() );
1440  const ET1 v3( element->value() );
1441  ++element;
1442  const size_t i4( element->index() );
1443  const ET1 v4( element->value() );
1444  ++element;
1445 
1446  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1447 
1448  C(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1449  C(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1450  }
1451 
1452  for( ; element!=end; ++element )
1453  {
1454  const size_t i1( element->index() );
1455  const ET1 v1( element->value() );
1456 
1457  C(i,j ) -= v1 * B(i1,j );
1458  C(i,j+1UL) -= v1 * B(i1,j+1UL);
1459  }
1460  }
1461  }
1462 
1463  for( ; j<N; ++j ) {
1464  for( size_t i=( LOW ? j : 0UL ); i<( UPP ? j+1UL : M ); ++i )
1465  {
1466  const ConstIterator end( ( IsUpper<MT5>::value )
1467  ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
1468  :( A.end(i) ) );
1469  ConstIterator element( ( IsLower<MT5>::value )
1470  ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1471  :( A.begin(i) ) );
1472 
1473  const size_t nonzeros( end - element );
1474  const size_t kpos( nonzeros & size_t(-4) );
1475  BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == kpos, "Invalid end calculation" );
1476 
1477  for( size_t k=0UL; k<kpos; k+=4UL )
1478  {
1479  const size_t i1( element->index() );
1480  const ET1 v1( element->value() );
1481  ++element;
1482  const size_t i2( element->index() );
1483  const ET1 v2( element->value() );
1484  ++element;
1485  const size_t i3( element->index() );
1486  const ET1 v3( element->value() );
1487  ++element;
1488  const size_t i4( element->index() );
1489  const ET1 v4( element->value() );
1490  ++element;
1491 
1492  BLAZE_INTERNAL_ASSERT( i1 < i2 && i2 < i3 && i3 < i4, "Invalid sparse matrix index detected" );
1493 
1494  C(i,j) -= v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1495  }
1496 
1497  for( ; element!=end; ++element )
1498  {
1499  const size_t i1( element->index() );
1500  const ET1 v1( element->value() );
1501 
1502  C(i,j) -= v1 * B(i1,j);
1503  }
1504  }
1505  }
1506  }
1507  }
1509  //**********************************************************************************************
1510 
1511  //**Restructuring subtraction assignment********************************************************
1526  template< typename MT // Type of the target matrix
1527  , bool SO > // Storage order of the target matrix
1529  subAssign( Matrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1530  {
1532 
1533  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1534  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1535 
1536  const ForwardFunctor fwd;
1537 
1538  subAssign( ~lhs, fwd( rhs.lhs_ * trans( rhs.rhs_ ) ) );
1539  }
1541  //**********************************************************************************************
1542 
1543  //**Subtraction assignment to sparse matrices***************************************************
1544  // No special implementation for the subtraction assignment to sparse matrices.
1545  //**********************************************************************************************
1546 
1547  //**Multiplication assignment to dense matrices*************************************************
1548  // No special implementation for the multiplication assignment to dense matrices.
1549  //**********************************************************************************************
1550 
1551  //**Multiplication assignment to sparse matrices************************************************
1552  // No special implementation for the multiplication assignment to sparse matrices.
1553  //**********************************************************************************************
1554 
1555  //**SMP assignment to dense matrices************************************************************
1570  template< typename MT // Type of the target dense matrix
1571  , bool SO > // Storage order of the target dense matrix
1573  smpAssign( DenseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1574  {
1576 
1577  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1578  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1579 
1580  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1581  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
1582 
1583  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1584  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1585  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1586  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1587  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1588  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1589 
1590  smpAssign( ~lhs, A * B );
1591  }
1593  //**********************************************************************************************
1594 
1595  //**SMP assignment to sparse matrices***********************************************************
1610  template< typename MT // Type of the target sparse matrix
1611  , bool SO > // Storage order of the target sparse matrix
1613  smpAssign( SparseMatrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1614  {
1616 
1618 
1625 
1626  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1627  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1628 
1629  const ForwardFunctor fwd;
1630 
1631  const TmpType tmp( rhs );
1632  smpAssign( ~lhs, fwd( tmp ) );
1633  }
1635  //**********************************************************************************************
1636 
1637  //**Restructuring SMP assignment****************************************************************
1652  template< typename MT // Type of the target matrix
1653  , bool SO > // Storage order of the target matrix
1655  smpAssign( Matrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1656  {
1658 
1659  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1660  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1661 
1662  const ForwardFunctor fwd;
1663 
1664  smpAssign( ~lhs, fwd( rhs.lhs_ * trans( rhs.rhs_ ) ) );
1665  }
1667  //**********************************************************************************************
1668 
1669  //**SMP addition assignment to dense matrices***************************************************
1685  template< typename MT // Type of the target dense matrix
1686  , bool SO > // Storage order of the target dense matrix
1689  {
1691 
1692  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1693  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1694 
1695  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1696  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
1697 
1698  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1699  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1700  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1701  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1702  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1703  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1704 
1705  smpAddAssign( ~lhs, A * B );
1706  }
1708  //**********************************************************************************************
1709 
1710  //**Restructuring SMP addition assignment*******************************************************
1725  template< typename MT // Type of the target matrix
1726  , bool SO > // Storage order of the target matrix
1728  smpAddAssign( Matrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1729  {
1731 
1732  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1733  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1734 
1735  const ForwardFunctor fwd;
1736 
1737  smpAddAssign( ~lhs, fwd( rhs.lhs_ * trans( rhs.rhs_ ) ) );
1738  }
1740  //**********************************************************************************************
1741 
1742  //**SMP addition assignment to sparse matrices**************************************************
1743  // No special implementation for the SMP addition assignment to sparse matrices.
1744  //**********************************************************************************************
1745 
1746  //**SMP subtraction assignment to dense matrices************************************************
1762  template< typename MT // Type of the target dense matrix
1763  , bool SO > // Storage order of the target dense matrix
1766  {
1768 
1769  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1770  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1771 
1772  LT A( rhs.lhs_ ); // Evaluation of the left-hand side sparse matrix operand
1773  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
1774 
1775  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1776  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1777  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1778  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1779  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1780  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1781 
1782  smpSubAssign( ~lhs, A * B );
1783  }
1785  //**********************************************************************************************
1786 
1787  //**Restructuring SMP subtraction assignment****************************************************
1802  template< typename MT // Type of the target matrix
1803  , bool SO > // Storage order of the target matrix
1805  smpSubAssign( Matrix<MT,SO>& lhs, const SMatTDMatMultExpr& rhs )
1806  {
1808 
1809  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1810  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1811 
1812  const ForwardFunctor fwd;
1813 
1814  smpSubAssign( ~lhs, fwd( rhs.lhs_ * trans( rhs.rhs_ ) ) );
1815  }
1817  //**********************************************************************************************
1818 
1819  //**SMP subtraction assignment to sparse matrices***********************************************
1820  // No special implementation for the SMP subtraction assignment to sparse matrices.
1821  //**********************************************************************************************
1822 
1823  //**SMP multiplication assignment to dense matrices*********************************************
1824  // No special implementation for the SMP multiplication assignment to dense matrices.
1825  //**********************************************************************************************
1826 
1827  //**SMP multiplication assignment to sparse matrices********************************************
1828  // No special implementation for the SMP multiplication assignment to sparse matrices.
1829  //**********************************************************************************************
1830 
1831  //**Compile time checks*************************************************************************
1839  //**********************************************************************************************
1840 };
1841 //*************************************************************************************************
1842 
1843 
1844 
1845 
1846 //=================================================================================================
1847 //
1848 // GLOBAL BINARY ARITHMETIC OPERATORS
1849 //
1850 //=================================================================================================
1851 
1852 //*************************************************************************************************
1883 template< typename T1 // Type of the left-hand side sparse matrix
1884  , typename T2 > // Type of the right-hand side dense matrix
1887 {
1889 
1890  if( (~lhs).columns() != (~rhs).rows() ) {
1891  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1892  }
1893 
1895 }
1896 //*************************************************************************************************
1897 
1898 
1899 
1900 
1901 //=================================================================================================
1902 //
1903 // GLOBAL FUNCTIONS
1904 //
1905 //=================================================================================================
1906 
1907 //*************************************************************************************************
1933 template< typename MT1 // Type of the left-hand side dense matrix
1934  , typename MT2 // Type of the right-hand side dense matrix
1935  , bool SF // Symmetry flag
1936  , bool HF // Hermitian flag
1937  , bool LF // Lower flag
1938  , bool UF > // Upper flag
1941 {
1943 
1944  if( !isSquare( dm ) ) {
1945  BLAZE_THROW_INVALID_ARGUMENT( "Invalid symmetric matrix specification" );
1946  }
1947 
1948  return SMatTDMatMultExpr<MT1,MT2,true,HF,LF,UF>( dm.leftOperand(), dm.rightOperand() );
1949 }
1951 //*************************************************************************************************
1952 
1953 
1954 //*************************************************************************************************
1980 template< typename MT1 // Type of the left-hand side dense matrix
1981  , typename MT2 // Type of the right-hand side dense matrix
1982  , bool SF // Symmetry flag
1983  , bool HF // Hermitian flag
1984  , bool LF // Lower flag
1985  , bool UF > // Upper flag
1988 {
1990 
1991  if( !isSquare( dm ) ) {
1992  BLAZE_THROW_INVALID_ARGUMENT( "Invalid Hermitian matrix specification" );
1993  }
1994 
1995  return SMatTDMatMultExpr<MT1,MT2,SF,true,LF,UF>( dm.leftOperand(), dm.rightOperand() );
1996 }
1998 //*************************************************************************************************
1999 
2000 
2001 //*************************************************************************************************
2027 template< typename MT1 // Type of the left-hand side dense matrix
2028  , typename MT2 // Type of the right-hand side dense matrix
2029  , bool SF // Symmetry flag
2030  , bool HF // Hermitian flag
2031  , bool LF // Lower flag
2032  , bool UF > // Upper flag
2035 {
2037 
2038  if( !isSquare( dm ) ) {
2039  BLAZE_THROW_INVALID_ARGUMENT( "Invalid lower matrix specification" );
2040  }
2041 
2042  return SMatTDMatMultExpr<MT1,MT2,SF,HF,true,UF>( dm.leftOperand(), dm.rightOperand() );
2043 }
2045 //*************************************************************************************************
2046 
2047 
2048 //*************************************************************************************************
2074 template< typename MT1 // Type of the left-hand side dense matrix
2075  , typename MT2 // Type of the right-hand side dense matrix
2076  , bool SF // Symmetry flag
2077  , bool HF // Hermitian flag
2078  , bool LF // Lower flag
2079  , bool UF > // Upper flag
2082 {
2084 
2085  if( !isSquare( dm ) ) {
2086  BLAZE_THROW_INVALID_ARGUMENT( "Invalid upper matrix specification" );
2087  }
2088 
2089  return SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,true>( dm.leftOperand(), dm.rightOperand() );
2090 }
2092 //*************************************************************************************************
2093 
2094 
2095 //*************************************************************************************************
2121 template< typename MT1 // Type of the left-hand side dense matrix
2122  , typename MT2 // Type of the right-hand side dense matrix
2123  , bool SF // Symmetry flag
2124  , bool HF // Hermitian flag
2125  , bool LF // Lower flag
2126  , bool UF > // Upper flag
2129 {
2131 
2132  if( !isSquare( dm ) ) {
2133  BLAZE_THROW_INVALID_ARGUMENT( "Invalid diagonal matrix specification" );
2134  }
2135 
2136  return SMatTDMatMultExpr<MT1,MT2,SF,HF,true,true>( dm.leftOperand(), dm.rightOperand() );
2137 }
2139 //*************************************************************************************************
2140 
2141 
2142 
2143 
2144 //=================================================================================================
2145 //
2146 // ROWS SPECIALIZATIONS
2147 //
2148 //=================================================================================================
2149 
2150 //*************************************************************************************************
2152 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2153 struct Rows< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> > : public Rows<MT1>
2154 {};
2156 //*************************************************************************************************
2157 
2158 
2159 
2160 
2161 //=================================================================================================
2162 //
2163 // COLUMNS SPECIALIZATIONS
2164 //
2165 //=================================================================================================
2166 
2167 //*************************************************************************************************
2169 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2170 struct Columns< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> > : public Columns<MT2>
2171 {};
2173 //*************************************************************************************************
2174 
2175 
2176 
2177 
2178 //=================================================================================================
2179 //
2180 // ISALIGNED SPECIALIZATIONS
2181 //
2182 //=================================================================================================
2183 
2184 //*************************************************************************************************
2186 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2187 struct IsAligned< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2188  : public BoolConstant< IsAligned<MT2>::value >
2189 {};
2191 //*************************************************************************************************
2192 
2193 
2194 
2195 
2196 //=================================================================================================
2197 //
2198 // ISSYMMETRIC SPECIALIZATIONS
2199 //
2200 //=================================================================================================
2201 
2202 //*************************************************************************************************
2204 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2205 struct IsSymmetric< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2206  : public BoolConstant< Or< Bool<SF>
2207  , And< Bool<HF>
2208  , IsBuiltin< ElementType_< SMatTDMatMultExpr<MT1,MT2,false,true,false,false> > > >
2209  , And< Bool<LF>, Bool<UF> > >::value >
2210 {};
2212 //*************************************************************************************************
2213 
2214 
2215 
2216 
2217 //=================================================================================================
2218 //
2219 // ISHERMITIAN SPECIALIZATIONS
2220 //
2221 //=================================================================================================
2222 
2223 //*************************************************************************************************
2225 template< typename MT1, typename MT2, bool SF, bool LF, bool UF >
2226 struct IsHermitian< SMatTDMatMultExpr<MT1,MT2,SF,true,LF,UF> >
2227  : public TrueType
2228 {};
2230 //*************************************************************************************************
2231 
2232 
2233 
2234 
2235 //=================================================================================================
2236 //
2237 // ISLOWER SPECIALIZATIONS
2238 //
2239 //=================================================================================================
2240 
2241 //*************************************************************************************************
2243 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2244 struct IsLower< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2245  : public BoolConstant< Or< Bool<LF>
2246  , And< IsLower<MT1>, IsLower<MT2> >
2247  , And< Or< Bool<SF>, Bool<HF> >
2248  , IsUpper<MT1>, IsUpper<MT2> > >::value >
2249 {};
2251 //*************************************************************************************************
2252 
2253 
2254 
2255 
2256 //=================================================================================================
2257 //
2258 // ISUNILOWER SPECIALIZATIONS
2259 //
2260 //=================================================================================================
2261 
2262 //*************************************************************************************************
2264 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2265 struct IsUniLower< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2266  : public BoolConstant< Or< And< IsUniLower<MT1>, IsUniLower<MT2> >
2267  , And< Or< Bool<SF>, Bool<HF> >
2268  , IsUniUpper<MT1>, IsUniUpper<MT2> > >::value >
2269 {};
2271 //*************************************************************************************************
2272 
2273 
2274 
2275 
2276 //=================================================================================================
2277 //
2278 // ISSTRICTLYLOWER SPECIALIZATIONS
2279 //
2280 //=================================================================================================
2281 
2282 //*************************************************************************************************
2284 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2285 struct IsStrictlyLower< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2286  : public BoolConstant< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
2287  , And< IsStrictlyLower<MT2>, IsLower<MT1> >
2288  , And< Or< Bool<SF>, Bool<HF> >
2289  , Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
2290  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > > > >::value >
2291 {};
2293 //*************************************************************************************************
2294 
2295 
2296 
2297 
2298 //=================================================================================================
2299 //
2300 // ISUPPER SPECIALIZATIONS
2301 //
2302 //=================================================================================================
2303 
2304 //*************************************************************************************************
2306 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2307 struct IsUpper< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2308  : public BoolConstant< Or< Bool<UF>
2309  , And< IsUpper<MT1>, IsUpper<MT2> >
2310  , And< Or< Bool<SF>, Bool<HF> >
2311  , IsLower<MT1>, IsLower<MT2> > >::value >
2312 {};
2314 //*************************************************************************************************
2315 
2316 
2317 
2318 
2319 //=================================================================================================
2320 //
2321 // ISUNIUPPER SPECIALIZATIONS
2322 //
2323 //=================================================================================================
2324 
2325 //*************************************************************************************************
2327 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2328 struct IsUniUpper< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2329  : public BoolConstant< Or< And< IsUniUpper<MT1>, IsUniUpper<MT2> >
2330  , And< Or< Bool<SF>, Bool<HF> >
2331  , IsUniLower<MT1>, IsUniLower<MT2> > >::value >
2332 {};
2334 //*************************************************************************************************
2335 
2336 
2337 
2338 
2339 //=================================================================================================
2340 //
2341 // ISSTRICTLYUPPER SPECIALIZATIONS
2342 //
2343 //=================================================================================================
2344 
2345 //*************************************************************************************************
2347 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2348 struct IsStrictlyUpper< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2349  : public BoolConstant< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
2350  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> >
2351  , And< Or< Bool<SF>, Bool<HF> >
2352  , Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
2353  , And< IsStrictlyLower<MT2>, IsLower<MT1> > > > >::value >
2354 {};
2356 //*************************************************************************************************
2357 
2358 
2359 
2360 
2361 //=================================================================================================
2362 //
2363 // EXPRESSION TRAIT SPECIALIZATIONS
2364 //
2365 //=================================================================================================
2366 
2367 //*************************************************************************************************
2369 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF, typename VT >
2370 struct DMatDVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, VT >
2371 {
2372  public:
2373  //**********************************************************************************************
2378  , INVALID_TYPE >;
2379  //**********************************************************************************************
2380 };
2382 //*************************************************************************************************
2383 
2384 
2385 //*************************************************************************************************
2387 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF, typename VT >
2388 struct DMatSVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, VT >
2389 {
2390  public:
2391  //**********************************************************************************************
2396  , INVALID_TYPE >;
2397  //**********************************************************************************************
2398 };
2400 //*************************************************************************************************
2401 
2402 
2403 //*************************************************************************************************
2405 template< typename VT, typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2406 struct TDVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2407 {
2408  public:
2409  //**********************************************************************************************
2414  , INVALID_TYPE >;
2415  //**********************************************************************************************
2416 };
2418 //*************************************************************************************************
2419 
2420 
2421 //*************************************************************************************************
2423 template< typename VT, typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2424 struct TSVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2425 {
2426  public:
2427  //**********************************************************************************************
2432  , INVALID_TYPE >;
2433  //**********************************************************************************************
2434 };
2436 //*************************************************************************************************
2437 
2438 
2439 //*************************************************************************************************
2441 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2442 struct DMatDeclSymExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2443 {
2444  public:
2445  //**********************************************************************************************
2449  , INVALID_TYPE >;
2450  //**********************************************************************************************
2451 };
2453 //*************************************************************************************************
2454 
2455 
2456 //*************************************************************************************************
2458 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2459 struct DMatDeclHermExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2460 {
2461  public:
2462  //**********************************************************************************************
2466  , INVALID_TYPE >;
2467  //**********************************************************************************************
2468 };
2470 //*************************************************************************************************
2471 
2472 
2473 //*************************************************************************************************
2475 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2476 struct DMatDeclLowExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2477 {
2478  public:
2479  //**********************************************************************************************
2483  , INVALID_TYPE >;
2484  //**********************************************************************************************
2485 };
2487 //*************************************************************************************************
2488 
2489 
2490 //*************************************************************************************************
2492 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2493 struct DMatDeclUppExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2494 {
2495  public:
2496  //**********************************************************************************************
2500  , INVALID_TYPE >;
2501  //**********************************************************************************************
2502 };
2504 //*************************************************************************************************
2505 
2506 
2507 //*************************************************************************************************
2509 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2510 struct DMatDeclDiagExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2511 {
2512  public:
2513  //**********************************************************************************************
2517  , INVALID_TYPE >;
2518  //**********************************************************************************************
2519 };
2521 //*************************************************************************************************
2522 
2523 
2524 //*************************************************************************************************
2526 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF, bool AF >
2527 struct SubmatrixExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, AF >
2528 {
2529  public:
2530  //**********************************************************************************************
2533  //**********************************************************************************************
2534 };
2536 //*************************************************************************************************
2537 
2538 
2539 //*************************************************************************************************
2541 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2542 struct RowExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2543 {
2544  public:
2545  //**********************************************************************************************
2546  using Type = MultExprTrait_< RowExprTrait_<const MT1>, MT2 >;
2547  //**********************************************************************************************
2548 };
2550 //*************************************************************************************************
2551 
2552 
2553 //*************************************************************************************************
2555 template< typename MT1, typename MT2, bool SF, bool HF, bool LF, bool UF >
2556 struct ColumnExprTrait< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2557 {
2558  public:
2559  //**********************************************************************************************
2561  //**********************************************************************************************
2562 };
2564 //*************************************************************************************************
2565 
2566 } // namespace blaze
2567 
2568 #endif
ElementType_< RT2 > ET2
Element type of the right-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:157
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.
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:154
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
Header file for the SMatDVecMultExprTrait class template.
Header file for the Rows type trait.
Header file for the IsUniUpper type trait.
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:260
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.
IfTrue_< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatTDMatMultExpr.h:266
Header file for the DMatDeclDiagExprTrait class template.
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose dense matrix operand.
Definition: SMatTDMatMultExpr.h:393
typename TSVecTDMatMultExprTrait< VT, MT >::Type TSVecTDMatMultExprTrait_
Auxiliary alias declaration for the TSVecTDMatMultExprTrait class template.The TSVecTDMatMultExprTrai...
Definition: TSVecTDMatMultExprTrait.h:124
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseMatrix type trait.
Header file for the serial shim.
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
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatTDMatMultExpr.h:373
Header file for the IsRowVector type trait.
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1755
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Header file for the TDVecSMatMultExprTrait class template.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatTDMatMultExpr.h:417
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.
Flag for upper matrices.
Definition: SMatTDMatMultExpr.h:178
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 TSVecSMatMultExprTrait class template.
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h: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
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatTDMatMultExpr.h:363
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
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SMatTDMatMultExpr.h:252
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
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
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatTDMatMultExpr.h:405
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTDMatMultExpr.h:250
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.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:253
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
#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
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: SMatTDMatMultExpr.h:437
Header file for the TSVecTDMatMultExprTrait class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2939
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatTDMatMultExpr.h:427
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 TDMatSVecMultExprTrait class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Flag for symmetric matrices.
Definition: SMatTDMatMultExpr.h:175
Header file for the DenseMatrix base class.
Header file for the DMatDeclLowExprTrait class template.
Header file for the Columns type trait.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Evaluation of the expression type of a dense matrix/sparse vector multiplication.Via this type trait ...
Definition: DMatSVecMultExprTrait.h:80
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.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:444
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
Expression object for sparse matrix-transpose dense matrix multiplications.The SMatTDMatMultExpr clas...
Definition: Forward.h:112
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTDMatMultExpr.h:254
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
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
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.
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
IfTrue_< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:263
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
Header file for the IsSparseVector type trait.
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
typename TDVecTDMatMultExprTrait< VT, MT >::Type TDVecTDMatMultExprTrait_
Auxiliary alias declaration for the TDVecTDMatMultExprTrait class template.The TDVecTDMatMultExprTrai...
Definition: TDVecTDMatMultExprTrait.h:120
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
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:251
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
Flag for lower matrices.
Definition: SMatTDMatMultExpr.h:177
SMatTDMatMultExpr< MT1, MT2, SF, HF, LF, UF > This
Type of this SMatTDMatMultExpr instance.
Definition: SMatTDMatMultExpr.h:247
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
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:249
Constraints on the storage order of matrix types.
Generic wrapper for the declherm() function.
Definition: DeclHerm.h:58
typename SMatDVecMultExprTrait< MT, VT >::Type SMatDVecMultExprTrait_
Auxiliary alias declaration for the SMatDVecMultExprTrait class template.The SMatDVecMultExprTrait_ a...
Definition: SMatDVecMultExprTrait.h:119
SMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatTDMatMultExpr class.
Definition: SMatTDMatMultExpr.h:284
Header file for the Noop functor.
Header file for the RemoveReference type trait.
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:158
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.
CompositeType_< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:159
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
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:257
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
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:383
Evaluation of the expression type of a sparse vector/dense matrix multiplication.Via this type trait ...
Definition: TSVecDMatMultExprTrait.h:78
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.
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:445
Header file for the IsBuiltin type trait.
ResultType_< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:155
Header file for the TDVecDMatMultExprTrait class template.
ElementType_< RT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:156
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTDMatMultExpr.h:299
Header file for the TDMatDVecMultExprTrait 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.
Flag for Hermitian matrices.
Definition: SMatTDMatMultExpr.h:176
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
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.
Header file for the TDVecTDMatMultExprTrait class template.
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
Header file for the TrueType type/value trait base class.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatTDMatMultExpr.h:347