Blaze  3.6
TSMatSMatKronExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATSMATKRONEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATSMATKRONEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
52 #include <blaze/math/Exception.h>
56 #include <blaze/math/shims/Reset.h>
63 #include <blaze/util/Assert.h>
64 #include <blaze/util/DisableIf.h>
65 #include <blaze/util/EnableIf.h>
67 #include <blaze/util/mpl/If.h>
68 #include <blaze/util/Types.h>
69 
70 
71 namespace blaze {
72 
73 //=================================================================================================
74 //
75 // CLASS TSMATSMATKRONEXPR
76 //
77 //=================================================================================================
78 
79 //*************************************************************************************************
86 template< typename MT1 // Type of the left-hand side sparse matrix
87  , typename MT2 > // Type of the right-hand side sparse matrix
88 class TSMatSMatKronExpr
89  : public MatMatKronExpr< SparseMatrix< TSMatSMatKronExpr<MT1,MT2>, false > >
90  , private Computation
91 {
92  private:
93  //**Type definitions****************************************************************************
100  //**********************************************************************************************
101 
102  //**Return type evaluation**********************************************************************
104 
109  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
110 
112  using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
113  //**********************************************************************************************
114 
115  public:
116  //**Type definitions****************************************************************************
123 
126 
128  using CompositeType = const ResultType;
129 
131  using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
132 
134  using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
135  //**********************************************************************************************
136 
137  //**Compilation flags***************************************************************************
139  static constexpr bool smpAssignable = false;
140  //**********************************************************************************************
141 
142  //**Constructor*********************************************************************************
148  explicit inline TSMatSMatKronExpr( const MT1& lhs, const MT2& rhs ) noexcept
149  : lhs_( lhs ) // Left-hand side sparse matrix of the Kronecker product expression
150  , rhs_( rhs ) // Right-hand side sparse matrix of the Kronecker product expression
151  {}
152  //**********************************************************************************************
153 
154  //**Access operator*****************************************************************************
161  inline ReturnType operator()( size_t i, size_t j ) const {
162  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
163  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
164  return lhs_( i/rhs_.rows(), j/rhs_.columns() ) * rhs_( i%rhs_.rows(), j%rhs_.columns() );
165  }
166  //**********************************************************************************************
167 
168  //**At function*********************************************************************************
176  inline ReturnType at( size_t i, size_t j ) const {
177  if( i >= rows() ) {
178  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
179  }
180  if( j >= columns() ) {
181  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
182  }
183  return (*this)(i,j);
184  }
185  //**********************************************************************************************
186 
187  //**Rows function*******************************************************************************
192  inline size_t rows() const noexcept {
193  return lhs_.rows() * rhs_.rows();
194  }
195  //**********************************************************************************************
196 
197  //**Columns function****************************************************************************
202  inline size_t columns() const noexcept {
203  return lhs_.columns() * rhs_.columns();
204  }
205  //**********************************************************************************************
206 
207  //**NonZeros function***************************************************************************
212  inline size_t nonZeros() const {
213  return lhs_.nonZeros() * rhs_.nonZeros();
214  }
215  //**********************************************************************************************
216 
217  //**NonZeros function***************************************************************************
223  inline size_t nonZeros( size_t i ) const {
224  MAYBE_UNUSED( i );
225  return 0UL;
226  }
227  //**********************************************************************************************
228 
229  //**Left operand access*************************************************************************
234  inline LeftOperand leftOperand() const noexcept {
235  return lhs_;
236  }
237  //**********************************************************************************************
238 
239  //**Right operand access************************************************************************
244  inline RightOperand rightOperand() const noexcept {
245  return rhs_;
246  }
247  //**********************************************************************************************
248 
249  //**********************************************************************************************
255  template< typename T >
256  inline bool canAlias( const T* alias ) const noexcept {
257  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
258  }
259  //**********************************************************************************************
260 
261  //**********************************************************************************************
267  template< typename T >
268  inline bool isAliased( const T* alias ) const noexcept {
269  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
270  }
271  //**********************************************************************************************
272 
273  private:
274  //**Member variables****************************************************************************
277  //**********************************************************************************************
278 
279  //**Assignment to dense matrices****************************************************************
292  template< typename MT // Type of the target dense matrix
293  , bool SO2 > // Storage order of the target dense matrix
294  friend inline void assign( DenseMatrix<MT,SO2>& lhs, const TSMatSMatKronExpr& rhs )
295  {
297 
298  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
299  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
300 
301  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
302  return;
303  }
304 
305  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
306  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
307 
308  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
309  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
310  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
311  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
312 
313  const size_t M( B.rows() );
314  const size_t N( B.columns() );
315 
316  for( size_t j=0UL; j<A.columns(); ++j )
317  for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
318  for( size_t k=0UL; k<M; ++k )
319  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
320  (~lhs)(aelem->index()*M+k,j*N+belem->index()) = aelem->value() * belem->value();
321  }
323  //**********************************************************************************************
324 
325  //**Assignment to row-major sparse matrices*****************************************************
338  template< typename MT > // Type of the target sparse matrix
339  friend inline void assign( SparseMatrix<MT,false>& lhs, const TSMatSMatKronExpr& rhs )
340  {
342 
343  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
344  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
345 
346  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
347  return;
348  }
349 
350  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
351  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
352 
353  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
354  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
355  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
356  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
357 
358  const size_t M( B.rows() );
359  const size_t N( B.columns() );
360 
361  // Counting the number of elements per row in A
362  std::vector<size_t> nonzeros( A.rows(), 0UL );
363  for( size_t j=0UL; j<A.columns(); ++j ) {
364  const auto end( A.end(j) );
365  for( auto aelem=A.begin(j); aelem!=end; ++aelem ) {
366  ++nonzeros[aelem->index()];
367  }
368  }
369 
370  // Resizing the left-hand side sparse matrix
371  for( size_t i=0UL; i<A.rows(); ++i ) {
372  for( size_t j=0UL; j<M; ++j ) {
373  (~lhs).reserve( i*M+j, nonzeros[i]*B.nonZeros(j) );
374  }
375  }
376 
377  // Performing the Kronecker product
378  for( size_t j=0UL; j<A.columns(); ++j )
379  for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
380  for( size_t k=0UL; k<M; ++k )
381  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
382  (~lhs).append( aelem->index()*M+k, j*N+belem->index(), aelem->value() * belem->value(), true );
383  }
385  //**********************************************************************************************
386 
387  //**Assignment to column-major sparse matrices**************************************************
400  template< typename MT > // Type of the target sparse matrix
401  friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatSMatKronExpr& rhs )
402  {
404 
405  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
406  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
407 
408  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
409  return;
410  }
411 
412  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
413  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
414 
415  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
416  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
417  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
418  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
419 
420  const size_t M( B.rows() );
421  const size_t N( B.columns() );
422 
423  // Counting the number of elements per column in B
424  std::vector<size_t> nonzeros( B.columns(), 0UL );
425  for( size_t i=0UL; i<B.rows(); ++i ) {
426  const auto end( B.end(i) );
427  for( auto belem=B.begin(i); belem!=end; ++belem ) {
428  ++nonzeros[belem->index()];
429  }
430  }
431 
432  // Resizing the left-hand side sparse matrix
433  for( size_t i=0UL; i<A.columns(); ++i ) {
434  for( size_t j=0UL; j<N; ++j ) {
435  (~lhs).reserve( i*N+j, A.nonZeros(i)*nonzeros[j] );
436  }
437  }
438 
439  // Performing the Kronecker product
440  for( size_t j=0UL; j<A.columns(); ++j )
441  for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
442  for( size_t k=0UL; k<M; ++k )
443  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
444  (~lhs).append( aelem->index()*M+k, j*N+belem->index(), aelem->value() * belem->value(), true );
445  }
447  //**********************************************************************************************
448 
449  //**Addition assignment to dense matrices*******************************************************
462  template< typename MT // Type of the target dense matrix
463  , bool SO2 > // Storage order of the target dense matrix
464  friend inline void addAssign( DenseMatrix<MT,SO2>& lhs, const TSMatSMatKronExpr& 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  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
472  return;
473  }
474 
475  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
476  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
477 
478  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
479  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
480  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
481  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
482 
483  const size_t M( B.rows() );
484  const size_t N( B.columns() );
485 
486  for( size_t j=0UL; j<A.columns(); ++j )
487  for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
488  for( size_t k=0UL; k<M; ++k )
489  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
490  (~lhs)(aelem->index()*M+k,j*N+belem->index()) += aelem->value() * belem->value();
491  }
493  //**********************************************************************************************
494 
495  //**Addition assignment to sparse matrices******************************************************
496  // No special implementation for the addition assignment to sparse matrices.
497  //**********************************************************************************************
498 
499  //**Subtraction assignment to dense matrices****************************************************
512  template< typename MT // Type of the target dense matrix
513  , bool SO2 > // Storage order of the target dense matrix
514  friend inline void subAssign( DenseMatrix<MT,SO2>& lhs, const TSMatSMatKronExpr& rhs )
515  {
517 
518  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
519  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
520 
521  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
522  return;
523  }
524 
525  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
526  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
527 
528  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
529  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
530  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
531  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
532 
533  const size_t M( B.rows() );
534  const size_t N( B.columns() );
535 
536  for( size_t j=0UL; j<A.columns(); ++j )
537  for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
538  for( size_t k=0UL; k<M; ++k )
539  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
540  (~lhs)(aelem->index()*M+k,j*N+belem->index()) -= aelem->value() * belem->value();
541  }
543  //**********************************************************************************************
544 
545  //**Subtraction assignment to sparse matrices***************************************************
546  // No special implementation for the subtraction assignment to sparse matrices.
547  //**********************************************************************************************
548 
549  //**Schur product assignment to dense matrices**************************************************
562  template< typename MT // Type of the target dense matrix
563  , bool SO2 > // Storage order of the target dense matrix
564  friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs, const TSMatSMatKronExpr& rhs )
565  {
567 
568  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
569  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
570 
571  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
572  return;
573  }
574 
575  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
576  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
577 
578  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
579  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
580  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
581  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
582 
583  const size_t M( B.rows() );
584  const size_t N( B.columns() );
585 
586  for( size_t j=0UL; j<A.columns(); ++j )
587  {
588  size_t i( 0UL );
589 
590  for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem, ++i )
591  {
592  for( ; i<aelem->index(); ++i ) {
593  for( size_t k=0UL; k<M; ++k )
594  for( size_t l=0UL; l<N; ++l )
595  reset( (~lhs)(i*M+k,j*N+l) );
596  }
597 
598  for( size_t k=0UL; k<M; ++k )
599  {
600  size_t l( 0UL );
601 
602  for( auto belem=B.begin(k); belem!=B.end(k); ++belem, ++l ) {
603  for( ; l<belem->index(); ++l )
604  reset( (~lhs)(i*M+k,j*N+l) );
605  (~lhs)(i*M+k,j*N+l) *= aelem->value() * belem->value();
606  }
607 
608  for( ; l<N; ++l ) {
609  reset( (~lhs)(i*M+k,j*N+l) );
610  }
611  }
612  }
613 
614  for( ; i<A.rows(); ++i ) {
615  for( size_t k=0UL; k<M; ++k )
616  for( size_t l=0UL; l<N; ++l )
617  reset( (~lhs)(i*M+k,j*N+l) );
618  }
619  }
620  }
622  //**********************************************************************************************
623 
624  //**Schur product assignment to sparse matrices*************************************************
625  // No special implementation for the Schur product assignment to sparse matrices.
626  //**********************************************************************************************
627 
628  //**Multiplication assignment to dense matrices*************************************************
629  // No special implementation for the multiplication assignment to dense matrices.
630  //**********************************************************************************************
631 
632  //**Multiplication assignment to sparse matrices************************************************
633  // No special implementation for the multiplication assignment to sparse matrices.
634  //**********************************************************************************************
635 
636  //**Compile time checks*************************************************************************
646  //**********************************************************************************************
647 };
648 //*************************************************************************************************
649 
650 
651 
652 
653 //=================================================================================================
654 //
655 // GLOBAL FUNCTIONS
656 //
657 //=================================================================================================
658 
659 //*************************************************************************************************
672 template< typename MT1 // Type of the left-hand side sparse matrix
673  , typename MT2 // Type of the right-hand side sparse matrix
674  , DisableIf_t< ( IsIdentity_v<MT1> && IsIdentity_v<MT2> ) ||
675  ( IsZero_v<MT1> || IsZero_v<MT2> ) >* = nullptr >
676 inline const TSMatSMatKronExpr<MT1,MT2>
677  tsmatsmatkron( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
678 {
680 
681  return TSMatSMatKronExpr<MT1,MT2>( ~lhs, ~rhs );
682 }
684 //*************************************************************************************************
685 
686 
687 //*************************************************************************************************
700 template< typename MT1 // Type of the left-hand side sparse matrix
701  , typename MT2 // Type of the right-hand side sparse matrix
702  , EnableIf_t< IsIdentity_v<MT1> && IsIdentity_v<MT2> >* = nullptr >
703 inline decltype(auto)
704  tsmatsmatkron( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
705 {
707 
708  using ReturnType = const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
709 
712 
713  return ReturnType( (~lhs).rows()*(~rhs).rows() );
714 }
716 //*************************************************************************************************
717 
718 
719 //*************************************************************************************************
732 template< typename MT1 // Type of the left-hand side sparse matrix
733  , typename MT2 // Type of the right-hand side sparse matrix
734  , EnableIf_t< IsZero_v<MT1> || IsZero_v<MT2> >* = nullptr >
735 inline decltype(auto)
736  tsmatsmatkron( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
737 {
739 
740  using ReturnType = const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
741 
743 
744  return ReturnType( (~lhs).rows()*(~rhs).rows(), (~lhs).columns()*(~rhs).columns() );
745 }
747 //*************************************************************************************************
748 
749 
750 //*************************************************************************************************
777 template< typename MT1 // Type of the left-hand side sparse matrix
778  , typename MT2 > // Type of the right-hand side sparse matrix
779 inline decltype(auto)
780  kron( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
781 {
783 
784  return tsmatsmatkron( ~lhs, ~rhs );
785 }
786 //*************************************************************************************************
787 
788 } // namespace blaze
789 
790 #endif
Constraint on the data type.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatSMatKronExpr.h:192
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSMatSMatKronExpr.h:122
Header file for auxiliary alias declarations.
#define BLAZE_CONSTRAINT_MUST_BE_IDENTITY_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not an identity matrix type,...
Definition: Identity.h:60
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatSMatKronExpr.h:161
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:98
Header file for basic type definitions.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
LeftOperand lhs_
Left-hand side sparse matrix of the Kronecker product expression.
Definition: TSMatSMatKronExpr.h:275
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
Header file for the serial shim.
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: TSMatSMatKronExpr.h:109
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: TSMatSMatKronExpr.h:112
Expression object for sparse matrix-sparse matrix Kronecker product.The TSMatSMatKronExpr class repre...
Definition: Forward.h:183
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
Constraint on the data type.
Header file for the IsIdentity type trait.
Header file for the Computation base class.
Header file for the reset shim.
Constraints on the storage order of matrix types.
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
decltype(auto) kron(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the Kronecker product of two dense matrices ( ).
Definition: DMatDMatKronExpr.h:954
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
Header file for the MatMatKronExpr base class.
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes....
Definition: Forward.h:145
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatSMatKronExpr.h:176
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:96
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatSMatKronExpr.h:223
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is not a zero vector or matrix type,...
Definition: Zero.h:61
typename KronTrait< T1, T2 >::Type KronTrait_t
Auxiliary alias declaration for the KronTrait class template.The KronTrait_t alias declaration provid...
Definition: KronTrait.h:163
#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
TSMatSMatKronExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatSMatKronExpr class.
Definition: TSMatSMatKronExpr.h:148
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: TSMatSMatKronExpr.h:125
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
Header file for the Kron product trait.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatSMatKronExpr.h:256
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSMatSMatKronExpr.h:139
Constraints on the storage order of matrix types.
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:131
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:95
Header file for the exception macros of the math module.
Constraint on the data type.
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:438
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatSMatKronExpr.h:121
Header file for the EnableIf class template.
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
#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 T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatSMatKronExpr.h:128
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: TSMatSMatKronExpr.h:234
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: TSMatSMatKronExpr.h:244
Header file for the IsZero type trait.
#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
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatSMatKronExpr.h:268
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:94
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:808
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
RightOperand rhs_
Right-hand side sparse matrix of the Kronecker product expression.
Definition: TSMatSMatKronExpr.h:276
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:99
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatSMatKronExpr.h:212
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatSMatKronExpr.h:119
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATKRONEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatKronExpr.h:102
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatSMatKronExpr.h:202
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:134
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:97
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is a zero vector or matrix type,...
Definition: Zero.h:81
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatSMatKronExpr.h:120
#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.