SMatTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
73 #include <blaze/util/Assert.h>
74 #include <blaze/util/DisableIf.h>
75 #include <blaze/util/EnableIf.h>
78 #include <blaze/util/InvalidType.h>
79 #include <blaze/util/mpl/And.h>
80 #include <blaze/util/mpl/If.h>
81 #include <blaze/util/mpl/Or.h>
82 #include <blaze/util/Types.h>
84 #include <blaze/util/Unused.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS SMATTSMATMULTEXPR
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
102 template< typename MT1 // Type of the left-hand side sparse matrix
103  , typename MT2 > // Type of the right-hand side sparse matrix
104 class SMatTSMatMultExpr
105  : public MatMatMultExpr< SparseMatrix< SMatTSMatMultExpr<MT1,MT2>, false > >
106  , private Computation
107 {
108  private:
109  //**Type definitions****************************************************************************
114  //**********************************************************************************************
115 
116  //**********************************************************************************************
118 
125  template< typename T1, typename T2, typename T3 >
126  struct CanExploitSymmetry {
127  enum : bool { value = ( IsRowMajorMatrix<T1>::value && IsSymmetric<T3>::value ) ||
129  };
131  //**********************************************************************************************
132 
133  public:
134  //**Type definitions****************************************************************************
140  using ReturnType = const ElementType;
141  using CompositeType = const ResultType;
142 
144  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
145 
147  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
148  //**********************************************************************************************
149 
150  //**Compilation flags***************************************************************************
152  enum : bool { smpAssignable = false };
153  //**********************************************************************************************
154 
155  //**Constructor*********************************************************************************
161  explicit inline SMatTSMatMultExpr( const MT1& lhs, const MT2& rhs ) noexcept
162  : lhs_( lhs ) // Left-hand side sparse matrix of the multiplication expression
163  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
164  {
165  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
166  }
167  //**********************************************************************************************
168 
169  //**Access operator*****************************************************************************
176  inline ReturnType operator()( size_t i, size_t j ) const {
177  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
178  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
179 
180  return row( lhs_, i ) * column( rhs_, j );
181  }
182  //**********************************************************************************************
183 
184  //**At function*********************************************************************************
192  inline ReturnType at( size_t i, size_t j ) const {
193  if( i >= lhs_.rows() ) {
194  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
195  }
196  if( j >= rhs_.columns() ) {
197  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
198  }
199  return (*this)(i,j);
200  }
201  //**********************************************************************************************
202 
203  //**Rows function*******************************************************************************
208  inline size_t rows() const noexcept {
209  return lhs_.rows();
210  }
211  //**********************************************************************************************
212 
213  //**Columns function****************************************************************************
218  inline size_t columns() const noexcept {
219  return rhs_.columns();
220  }
221  //**********************************************************************************************
222 
223  //**NonZeros function***************************************************************************
228  inline constexpr size_t nonZeros() const noexcept {
229  return 0UL;
230  }
231  //**********************************************************************************************
232 
233  //**NonZeros function***************************************************************************
239  inline size_t nonZeros( size_t i ) const noexcept {
240  UNUSED_PARAMETER( i );
241  return 0UL;
242  }
243  //**********************************************************************************************
244 
245  //**Left operand access*************************************************************************
250  inline LeftOperand leftOperand() const noexcept {
251  return lhs_;
252  }
253  //**********************************************************************************************
254 
255  //**Right operand access************************************************************************
260  inline RightOperand rightOperand() const noexcept {
261  return rhs_;
262  }
263  //**********************************************************************************************
264 
265  //**********************************************************************************************
271  template< typename T >
272  inline bool canAlias( const T* alias ) const noexcept {
273  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
274  }
275  //**********************************************************************************************
276 
277  //**********************************************************************************************
283  template< typename T >
284  inline bool isAliased( const T* alias ) const noexcept {
285  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
286  }
287  //**********************************************************************************************
288 
289  //**********************************************************************************************
294  inline bool canSMPAssign() const noexcept {
295  return ( rows() * columns() >= SMP_SMATTSMATMULT_THRESHOLD );
296  }
297  //**********************************************************************************************
298 
299  private:
300  //**Member variables****************************************************************************
303  //**********************************************************************************************
304 
305  //**Assignment to row-major matrices************************************************************
318  template< typename MT > // Type of the target matrix
320  assign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
321  {
323 
324  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
325  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
326 
328 
329  const OppositeType_<MT2> tmp( serial( rhs.rhs_ ) );
330  assign( ~lhs, rhs.lhs_ * tmp );
331  }
333  //**********************************************************************************************
334 
335  //**Restructuring assignment to row-major matrices**********************************************
350  template< typename MT > // Type of the target matrix
352  assign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
353  {
355 
356  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
357  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
358 
359  assign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
360  }
362  //**********************************************************************************************
363 
364  //**Assignment to column-major matrices*********************************************************
377  template< typename MT > // Type of the target matrix
379  assign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
380  {
382 
384 
385  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
386  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
387 
389 
390  const OppositeType_<MT1> tmp( serial( rhs.lhs_ ) );
391  assign( ~lhs, tmp * rhs.rhs_ );
392  }
394  //**********************************************************************************************
395 
396  //**Restructuring assignment to column-major matrices*******************************************
411  template< typename MT > // Type of the target matrix
413  assign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
414  {
416 
418 
419  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
420  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
421 
422  assign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
423  }
425  //**********************************************************************************************
426 
427  //**Addition assignment to row-major dense matrices*********************************************
440  template< typename MT > // Type of the target dense matrix
442  addAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
443  {
445 
446  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
447  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
448 
450 
451  const OppositeType_<MT2> tmp( serial( rhs.rhs_ ) );
452  addAssign( ~lhs, rhs.lhs_ * tmp );
453  }
455  //**********************************************************************************************
456 
457  //**Restructuring addition assignment to row-major matrices*************************************
472  template< typename MT > // Type of the target matrix
474  addAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
475  {
477 
478  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
479  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
480 
481  addAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
482  }
484  //**********************************************************************************************
485 
486  //**Addition assignment to column-major dense matrices******************************************
499  template< typename MT > // Type of the target dense matrix
501  addAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
502  {
504 
506 
507  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
508  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
509 
511 
512  const OppositeType_<MT1> tmp( serial( rhs.lhs_ ) );
513  addAssign( ~lhs, tmp * rhs.rhs_ );
514  }
516  //**********************************************************************************************
517 
518  //**Restructuring addition assignment to column-major matrices**********************************
533  template< typename MT > // Type of the target matrix
535  addAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
536  {
538 
540 
541  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
542  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
543 
544  addAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
545  }
547  //**********************************************************************************************
548 
549  //**Addition assignment to sparse matrices******************************************************
550  // No special implementation for the addition assignment to sparse matrices.
551  //**********************************************************************************************
552 
553  //**Subtraction assignment to row-major dense matrices******************************************
566  template< typename MT > // Type of the target dense matrix
568  subAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
569  {
571 
572  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
573  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
574 
576 
577  const OppositeType_<MT2> tmp( serial( rhs.rhs_ ) );
578  subAssign( ~lhs, rhs.lhs_ * tmp );
579  }
581  //**********************************************************************************************
582 
583  //**Restructuring subtraction assignment to row-major matrices**********************************
598  template< typename MT > // Type of the target matrix
600  subAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
601  {
603 
604  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
605  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
606 
607  subAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
608  }
610  //**********************************************************************************************
611 
612  //**Subtraction assignment to column-major dense matrices***************************************
625  template< typename MT > // Type of the target dense matrix
627  subAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
628  {
630 
632 
633  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
634  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
635 
637 
638  const OppositeType_<MT1> tmp( serial( rhs.lhs_ ) );
639  subAssign( ~lhs, tmp * rhs.rhs_ );
640  }
642  //**********************************************************************************************
643 
644  //**Restructuring subtraction assignment to column-major matrices*******************************
659  template< typename MT > // Type of the target matrix
661  subAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
662  {
664 
666 
667  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
668  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
669 
670  subAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
671  }
673  //**********************************************************************************************
674 
675  //**Subtraction assignment to sparse matrices***************************************************
676  // No special implementation for the subtraction assignment to sparse matrices.
677  //**********************************************************************************************
678 
679  //**Schur product assignment to row-major dense matrices****************************************
692  template< typename MT // Type of the target dense matrix
693  , bool SO > // Storage order of the target dense matrix
694  friend inline void schurAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatMultExpr& rhs )
695  {
697 
701 
702  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
703  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
704 
705  const ResultType tmp( serial( rhs ) );
706  schurAssign( ~lhs, tmp );
707  }
709  //**********************************************************************************************
710 
711  //**Schur product assignment to sparse matrices*************************************************
712  // No special implementation for the Schur product assignment to sparse matrices.
713  //**********************************************************************************************
714 
715  //**Multiplication assignment to dense matrices*************************************************
716  // No special implementation for the multiplication assignment to dense matrices.
717  //**********************************************************************************************
718 
719  //**Multiplication assignment to sparse matrices************************************************
720  // No special implementation for the multiplication assignment to sparse matrices.
721  //**********************************************************************************************
722 
723  //**SMP assignment to row-major matrices********************************************************
738  template< typename MT > // Type of the target matrix
740  smpAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
741  {
743 
744  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
745  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
746 
748 
749  const OppositeType_<MT2> tmp( rhs.rhs_ );
750  smpAssign( ~lhs, rhs.lhs_ * tmp );
751  }
753  //**********************************************************************************************
754 
755  //**Restructuring SMP assignment to row-major matrices******************************************
770  template< typename MT > // Type of the target matrix
772  smpAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
773  {
775 
776  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
777  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
778 
779  smpAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
780  }
782  //**********************************************************************************************
783 
784  //**SMP assignment to column-major matrices*****************************************************
799  template< typename MT > // Type of the target matrix
801  smpAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
802  {
804 
806 
807  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
808  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
809 
811 
812  const OppositeType_<MT1> tmp( rhs.lhs_ );
813  smpAssign( ~lhs, tmp * rhs.rhs_ );
814  }
816  //**********************************************************************************************
817 
818  //**Restructuring SMP assignment to column-major matrices***************************************
833  template< typename MT > // Type of the target matrix
835  smpAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
836  {
838 
840 
841  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
842  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
843 
844  smpAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
845  }
847  //**********************************************************************************************
848 
849  //**SMP addition assignment to row-major dense matrices*****************************************
864  template< typename MT > // Type of the target dense matrix
867  {
869 
870  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
871  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
872 
874 
875  const OppositeType_<MT2> tmp( rhs.rhs_ );
876  smpAddAssign( ~lhs, rhs.lhs_ * tmp );
877  }
879  //**********************************************************************************************
880 
881  //**SMP addition assignment to column-major dense matrices**************************************
896  template< typename MT > // Type of the target dense matrix
899  {
901 
903 
904  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
905  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
906 
908 
909  const OppositeType_<MT1> tmp( rhs.lhs_ );
910  smpAddAssign( ~lhs, tmp * rhs.rhs_ );
911  }
913  //**********************************************************************************************
914 
915  //**Restructuring SMP addition assignment to row-major matrices*********************************
930  template< typename MT > // Type of the target matrix
933  {
935 
936  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
937  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
938 
939  smpAddAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
940  }
942  //**********************************************************************************************
943 
944  //**Restructuring SMP addition assignment to column-major matrices******************************
959  template< typename MT > // Type of the target matrix
962  {
964 
966 
967  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
968  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
969 
970  smpAddAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
971  }
973  //**********************************************************************************************
974 
975  //**SMP addition assignment to sparse matrices**************************************************
976  // No special implementation for the SMP addition assignment to sparse matrices.
977  //**********************************************************************************************
978 
979  //**SMP subtraction assignment to row-major dense matrices**************************************
994  template< typename MT > // Type of the target dense matrix
997  {
999 
1000  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1001  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1002 
1004 
1005  const OppositeType_<MT2> tmp( rhs.rhs_ );
1006  smpSubAssign( ~lhs, rhs.lhs_ * tmp );
1007  }
1009  //**********************************************************************************************
1010 
1011  //**SMP subtraction assignment to column-major dense matrices***********************************
1026  template< typename MT > // Type of the target dense matrix
1029  {
1031 
1033 
1034  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1035  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1036 
1038 
1039  const OppositeType_<MT1> tmp( rhs.lhs_ );
1040  smpSubAssign( ~lhs, tmp * rhs.rhs_ );
1041  }
1043  //**********************************************************************************************
1044 
1045  //**Restructuring SMP subtraction assignment to row-major matrices******************************
1060  template< typename MT > // Type of the target matrix
1062  smpSubAssign( Matrix<MT,false>& lhs, const SMatTSMatMultExpr& rhs )
1063  {
1065 
1066  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1067  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1068 
1069  smpSubAssign( ~lhs, rhs.lhs_ * trans( rhs.rhs_ ) );
1070  }
1072  //**********************************************************************************************
1073 
1074  //**Restructuring SMP subtraction assignment to column-major matrices***************************
1089  template< typename MT > // Type of the target matrix
1091  smpSubAssign( Matrix<MT,true>& lhs, const SMatTSMatMultExpr& rhs )
1092  {
1094 
1096 
1097  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1098  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1099 
1100  smpSubAssign( ~lhs, trans( rhs.lhs_ ) * rhs.rhs_ );
1101  }
1103  //**********************************************************************************************
1104 
1105  //**SMP subtraction assignment to sparse matrices***********************************************
1106  // No special implementation for the SMP subtraction assignment to sparse matrices.
1107  //**********************************************************************************************
1108 
1109  //**SMP Schur product assignment to row-major dense matrices************************************
1122  template< typename MT // Type of the target dense matrix
1123  , bool SO > // Storage order of the target dense matrix
1124  friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatMultExpr& rhs )
1125  {
1127 
1131 
1132  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1133  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1134 
1135  const ResultType tmp( rhs );
1136  smpSchurAssign( ~lhs, tmp );
1137  }
1139  //**********************************************************************************************
1140 
1141  //**SMP Schur product assignment to sparse matrices*********************************************
1142  // No special implementation for the SMP Schur product assignment to sparse matrices.
1143  //**********************************************************************************************
1144 
1145  //**SMP multiplication assignment to dense matrices*********************************************
1146  // No special implementation for the SMP multiplication assignment to dense matrices.
1147  //**********************************************************************************************
1148 
1149  //**SMP multiplication assignment to sparse matrices********************************************
1150  // No special implementation for the SMP multiplication assignment to sparse matrices.
1151  //**********************************************************************************************
1152 
1153  //**Compile time checks*************************************************************************
1161  //**********************************************************************************************
1162 };
1163 //*************************************************************************************************
1164 
1165 
1166 
1167 
1168 //=================================================================================================
1169 //
1170 // GLOBAL BINARY ARITHMETIC OPERATORS
1171 //
1172 //=================================================================================================
1173 
1174 //*************************************************************************************************
1204 template< typename MT1 // Type of the left-hand side sparse matrix
1205  , typename MT2 > // Type of the right-hand side sparse matrix
1206 inline decltype(auto)
1207  operator*( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
1208 {
1210 
1211  if( (~lhs).columns() != (~rhs).rows() ) {
1212  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1213  }
1214 
1215  using ReturnType = const SMatTSMatMultExpr<MT1,MT2>;
1216  return ReturnType( ~lhs, ~rhs );
1217 }
1218 //*************************************************************************************************
1219 
1220 
1221 
1222 
1223 //=================================================================================================
1224 //
1225 // ROWS SPECIALIZATIONS
1226 //
1227 //=================================================================================================
1228 
1229 //*************************************************************************************************
1231 template< typename MT1, typename MT2 >
1232 struct Rows< SMatTSMatMultExpr<MT1,MT2> >
1233  : public Rows<MT1>
1234 {};
1236 //*************************************************************************************************
1237 
1238 
1239 
1240 
1241 //=================================================================================================
1242 //
1243 // COLUMNS SPECIALIZATIONS
1244 //
1245 //=================================================================================================
1246 
1247 //*************************************************************************************************
1249 template< typename MT1, typename MT2 >
1250 struct Columns< SMatTSMatMultExpr<MT1,MT2> >
1251  : public Columns<MT2>
1252 {};
1254 //*************************************************************************************************
1255 
1256 
1257 
1258 
1259 //=================================================================================================
1260 //
1261 // ISLOWER SPECIALIZATIONS
1262 //
1263 //=================================================================================================
1264 
1265 //*************************************************************************************************
1267 template< typename MT1, typename MT2 >
1268 struct IsLower< SMatTSMatMultExpr<MT1,MT2> >
1269  : public BoolConstant< And< IsLower<MT1>, IsLower<MT2> >::value >
1270 {};
1272 //*************************************************************************************************
1273 
1274 
1275 
1276 
1277 //=================================================================================================
1278 //
1279 // ISUNILOWER SPECIALIZATIONS
1280 //
1281 //=================================================================================================
1282 
1283 //*************************************************************************************************
1285 template< typename MT1, typename MT2 >
1286 struct IsUniLower< SMatTSMatMultExpr<MT1,MT2> >
1287  : public BoolConstant< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1288 {};
1290 //*************************************************************************************************
1291 
1292 
1293 
1294 
1295 //=================================================================================================
1296 //
1297 // ISSTRICTLYLOWER SPECIALIZATIONS
1298 //
1299 //=================================================================================================
1300 
1301 //*************************************************************************************************
1303 template< typename MT1, typename MT2 >
1304 struct IsStrictlyLower< SMatTSMatMultExpr<MT1,MT2> >
1305  : public BoolConstant< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1306  , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1307 {};
1309 //*************************************************************************************************
1310 
1311 
1312 
1313 
1314 //=================================================================================================
1315 //
1316 // ISUPPER SPECIALIZATIONS
1317 //
1318 //=================================================================================================
1319 
1320 //*************************************************************************************************
1322 template< typename MT1, typename MT2 >
1323 struct IsUpper< SMatTSMatMultExpr<MT1,MT2> >
1324  : public BoolConstant< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1325 {};
1327 //*************************************************************************************************
1328 
1329 
1330 
1331 
1332 //=================================================================================================
1333 //
1334 // ISUNIUPPER SPECIALIZATIONS
1335 //
1336 //=================================================================================================
1337 
1338 //*************************************************************************************************
1340 template< typename MT1, typename MT2 >
1341 struct IsUniUpper< SMatTSMatMultExpr<MT1,MT2> >
1342  : public BoolConstant< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1343 {};
1345 //*************************************************************************************************
1346 
1347 
1348 
1349 
1350 //=================================================================================================
1351 //
1352 // ISSTRICTLYUPPER SPECIALIZATIONS
1353 //
1354 //=================================================================================================
1355 
1356 //*************************************************************************************************
1358 template< typename MT1, typename MT2 >
1359 struct IsStrictlyUpper< SMatTSMatMultExpr<MT1,MT2> >
1360  : public BoolConstant< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1361  , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1362 {};
1364 //*************************************************************************************************
1365 
1366 } // namespace blaze
1367 
1368 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTSMatMultExpr.h:140
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
Header file for basic type definitions.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatTSMatMultExpr.h:218
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the serial shim.
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
Header file for the IsColumnMajorMatrix type trait.
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTSMatMultExpr.h:141
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:250
Column< MT > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:124
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: SMatTSMatMultExpr.h:260
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.
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
Header file for the SparseMatrix base class.
Row< MT > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:124
Constraint on the data type.
Expression object for sparse matrix-transpose sparse matrix multiplications.The SMatTSMatMultExpr cla...
Definition: Forward.h:126
ResultType_< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:111
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTSMatMultExpr.h:176
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
Header file for the DisableIf class template.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatTSMatMultExpr.h:250
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:110
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatTSMatMultExpr.h:138
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatTSMatMultExpr.h:284
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the Columns type trait.
constexpr size_t nonZeros() const noexcept
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatTSMatMultExpr.h:228
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Header file for the IsLower type trait.
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTSMatMultExpr.h:137
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Constraint on the data type.
Header file for all forward declarations for expression class templates.
SMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatTSMatMultExpr class.
Definition: SMatTSMatMultExpr.h:161
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:144
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatTSMatMultExpr.h:208
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:108
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:86
CompositeType_< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:113
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#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
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:147
Header file for run time assertion macros.
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:110
Utility type for generic codes.
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatTSMatMultExpr.h:272
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatTSMatMultExpr.h:192
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
Constraint on the data type.
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTSMatMultExpr.h:301
Header file for the RemoveReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:263
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:110
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatTSMatMultExpr.h:136
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
size_t nonZeros(size_t i) const noexcept
Returns the number of non-zero elements in the specified row.
Definition: SMatTSMatMultExpr.h:239
Header file for the IntegralConstant class template.
Compile time evaluation of the number of columns of a matrix.The Columns type trait evaluates the num...
Definition: Columns.h:75
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:75
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: SMatTSMatMultExpr.h:302
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: SMatTSMatMultExpr.h:294
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Constraint on the data type.
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTSMatMultExpr.h:112
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:61
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SMatTSMatMultExpr.h:139