Blaze  3.6
SMatSMatKronExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATKRONEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATSMATKRONEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
51 #include <blaze/math/Exception.h>
55 #include <blaze/math/shims/Reset.h>
62 #include <blaze/util/Assert.h>
63 #include <blaze/util/DisableIf.h>
64 #include <blaze/util/EnableIf.h>
66 #include <blaze/util/mpl/If.h>
67 #include <blaze/util/Types.h>
68 
69 
70 namespace blaze {
71 
72 //=================================================================================================
73 //
74 // CLASS SMATSMATKRONEXPR
75 //
76 //=================================================================================================
77 
78 //*************************************************************************************************
85 template< typename MT1 // Type of the left-hand side sparse matrix
86  , typename MT2 > // Type of the right-hand side sparse matrix
87 class SMatSMatKronExpr
88  : public MatMatKronExpr< SparseMatrix< SMatSMatKronExpr<MT1,MT2>, false > >
89  , private Computation
90 {
91  private:
92  //**Type definitions****************************************************************************
99  //**********************************************************************************************
100 
101  //**Return type evaluation**********************************************************************
103 
108  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
109 
111  using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
112  //**********************************************************************************************
113 
114  public:
115  //**Type definitions****************************************************************************
122 
125 
127  using CompositeType = const ResultType;
128 
130  using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
131 
133  using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
134  //**********************************************************************************************
135 
136  //**Compilation flags***************************************************************************
138  static constexpr bool smpAssignable = false;
139  //**********************************************************************************************
140 
141  //**Constructor*********************************************************************************
147  explicit inline SMatSMatKronExpr( const MT1& lhs, const MT2& rhs ) noexcept
148  : lhs_( lhs ) // Left-hand side sparse matrix of the Kronecker product expression
149  , rhs_( rhs ) // Right-hand side sparse matrix of the Kronecker product expression
150  {}
151  //**********************************************************************************************
152 
153  //**Access operator*****************************************************************************
160  inline ReturnType operator()( size_t i, size_t j ) const {
161  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
162  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
163  return lhs_( i/rhs_.rows(), j/rhs_.columns() ) * rhs_( i%rhs_.rows(), j%rhs_.columns() );
164  }
165  //**********************************************************************************************
166 
167  //**At function*********************************************************************************
175  inline ReturnType at( size_t i, size_t j ) const {
176  if( i >= rows() ) {
177  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
178  }
179  if( j >= columns() ) {
180  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
181  }
182  return (*this)(i,j);
183  }
184  //**********************************************************************************************
185 
186  //**Rows function*******************************************************************************
191  inline size_t rows() const noexcept {
192  return lhs_.rows() * rhs_.rows();
193  }
194  //**********************************************************************************************
195 
196  //**Columns function****************************************************************************
201  inline size_t columns() const noexcept {
202  return lhs_.columns() * rhs_.columns();
203  }
204  //**********************************************************************************************
205 
206  //**NonZeros function***************************************************************************
211  inline size_t nonZeros() const {
212  return lhs_.nonZeros() * rhs_.nonZeros();
213  }
214  //**********************************************************************************************
215 
216  //**NonZeros function***************************************************************************
222  inline size_t nonZeros( size_t i ) const {
223  return lhs_.nonZeros( i/rhs_.rows() ) * rhs_.nonZeros( i%rhs_.rows() );
224  }
225  //**********************************************************************************************
226 
227  //**Left operand access*************************************************************************
232  inline LeftOperand leftOperand() const noexcept {
233  return lhs_;
234  }
235  //**********************************************************************************************
236 
237  //**Right operand access************************************************************************
242  inline RightOperand rightOperand() const noexcept {
243  return rhs_;
244  }
245  //**********************************************************************************************
246 
247  //**********************************************************************************************
253  template< typename T >
254  inline bool canAlias( const T* alias ) const noexcept {
255  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
256  }
257  //**********************************************************************************************
258 
259  //**********************************************************************************************
265  template< typename T >
266  inline bool isAliased( const T* alias ) const noexcept {
267  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
268  }
269  //**********************************************************************************************
270 
271  private:
272  //**Member variables****************************************************************************
275  //**********************************************************************************************
276 
277  //**Assignment to dense matrices****************************************************************
289  template< typename MT // Type of the target dense matrix
290  , bool SO2 > // Storage order of the target dense matrix
291  friend inline void assign( DenseMatrix<MT,SO2>& lhs, const SMatSMatKronExpr& rhs )
292  {
294 
295  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
296  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
297 
298  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
299  return;
300  }
301 
302  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
303  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
304 
305  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
306  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
307  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
308  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
309 
310  const size_t M( B.rows() );
311  const size_t N( B.columns() );
312 
313  for( size_t i=0UL; i<A.rows(); ++i )
314  for( size_t k=0UL; k<M; ++k )
315  for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
316  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
317  (~lhs)(i*M+k,aelem->index()*N+belem->index()) = aelem->value() * belem->value();
318  }
320  //**********************************************************************************************
321 
322  //**Assignment to row-major sparse matrices*****************************************************
335  template< typename MT > // Type of the target sparse matrix
336  friend inline void assign( SparseMatrix<MT,false>& lhs, const SMatSMatKronExpr& rhs )
337  {
339 
340  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
341  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
342 
343  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
344  return;
345  }
346 
347  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
348  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
349 
350  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
351  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
352  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
353  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
354 
355  const size_t M( B.rows() );
356  const size_t N( B.columns() );
357 
358  for( size_t i=0UL; i<A.rows(); ++i ) {
359  for( size_t k=0UL; k<M; ++k ) {
360  for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
361  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
362  (~lhs).append( i*M+k, aelem->index()*N+belem->index(), aelem->value() * belem->value(), true );
363  (~lhs).finalize( i*M+k );
364  }
365  }
366  }
368  //**********************************************************************************************
369 
370  //**Assignment to column-major sparse matrices**************************************************
383  template< typename MT > // Type of the target sparse matrix
384  friend inline void assign( SparseMatrix<MT,true>& lhs, const SMatSMatKronExpr& rhs )
385  {
387 
388  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
389  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
390 
391  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
392  return;
393  }
394 
395  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
396  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
397 
398  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
399  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
400  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
401  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
402 
403  const size_t M( B.rows() );
404  const size_t N( B.columns() );
405 
406  // Counting the number of elements per column in A
407  std::vector<size_t> lnonzeros( A.columns(), 0UL );
408  for( size_t i=0UL; i<A.rows(); ++i ) {
409  const auto aend( A.end(i) );
410  for( auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
411  ++lnonzeros[aelem->index()];
412  }
413  }
414 
415  // Counting the number of elements per column B
416  std::vector<size_t> rnonzeros( N, 0UL );
417  for( size_t i=0UL; i<M; ++i ) {
418  const auto bend( B.end(i) );
419  for( auto belem=B.begin(i); belem!=bend; ++belem ) {
420  ++rnonzeros[belem->index()];
421  }
422  }
423 
424  // Resizing the left-hand side sparse matrix
425  for( size_t i=0UL; i<A.columns(); ++i ) {
426  for( size_t j=0UL; j<N; ++j ) {
427  (~lhs).reserve( i*N+j, lnonzeros[i]*rnonzeros[j] );
428  }
429  }
430 
431  // Performing the Kronecker product
432  for( size_t i=0UL; i<A.rows(); ++i )
433  for( size_t k=0UL; k<M; ++k )
434  for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
435  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
436  (~lhs).append( i*M+k, aelem->index()*N+belem->index(), aelem->value() * belem->value(), true );
437  }
439  //**********************************************************************************************
440 
441  //**Addition assignment to dense matrices*******************************************************
454  template< typename MT // Type of the target dense matrix
455  , bool SO2 > // Storage order of the target dense matrix
456  friend inline void addAssign( DenseMatrix<MT,SO2>& lhs, const SMatSMatKronExpr& rhs )
457  {
459 
460  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
461  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
462 
463  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
464  return;
465  }
466 
467  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
468  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
469 
470  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
471  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
472  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
473  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
474 
475  const size_t M( B.rows() );
476  const size_t N( B.columns() );
477 
478  for( size_t i=0UL; i<A.rows(); ++i )
479  for( size_t k=0UL; k<M; ++k )
480  for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
481  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
482  (~lhs)(i*M+k,aelem->index()*N+belem->index()) += aelem->value() * belem->value();
483  }
485  //**********************************************************************************************
486 
487  //**Addition assignment to sparse matrices******************************************************
488  // No special implementation for the addition assignment to sparse matrices.
489  //**********************************************************************************************
490 
491  //**Subtraction assignment to dense matrices****************************************************
504  template< typename MT // Type of the target dense matrix
505  , bool SO2 > // Storage order of the target dense matrix
506  friend inline void subAssign( DenseMatrix<MT,SO2>& lhs, const SMatSMatKronExpr& rhs )
507  {
509 
510  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
511  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
512 
513  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
514  return;
515  }
516 
517  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
518  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
519 
520  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
521  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
522  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
523  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
524 
525  const size_t M( B.rows() );
526  const size_t N( B.columns() );
527 
528  for( size_t i=0UL; i<A.rows(); ++i )
529  for( size_t k=0UL; k<M; ++k )
530  for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
531  for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
532  (~lhs)(i*M+k,aelem->index()*N+belem->index()) -= aelem->value() * belem->value();
533  }
535  //**********************************************************************************************
536 
537  //**Subtraction assignment to sparse matrices***************************************************
538  // No special implementation for the subtraction assignment to sparse matrices.
539  //**********************************************************************************************
540 
541  //**Schur product assignment to dense matrices**************************************************
554  template< typename MT // Type of the target dense matrix
555  , bool SO2 > // Storage order of the target dense matrix
556  friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs, const SMatSMatKronExpr& rhs )
557  {
559 
560  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
561  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
562 
563  if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
564  return;
565  }
566 
567  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
568  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
569 
570  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
571  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
572  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
573  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
574 
575  const size_t M( B.rows() );
576  const size_t N( B.columns() );
577 
578  for( size_t i=0UL; i<A.rows(); ++i ) {
579  for( size_t k=0UL; k<M; ++k )
580  {
581  size_t j( 0UL );
582 
583  for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem ) {
584  for( auto belem=B.begin(k); belem!=B.end(k); ++belem, ++j ) {
585  const size_t index( aelem->index()*N+belem->index() );
586  for( ; j<index; ++j )
587  reset( (~lhs)(i*M+k,j) );
588  (~lhs)(i*M+k,j) *= aelem->value() * belem->value();
589  }
590  }
591 
592  for( ; j<(~lhs).columns(); ++j )
593  reset( (~lhs)(i*M+k,j) );
594  }
595  }
596  }
598  //**********************************************************************************************
599 
600  //**Schur product assignment to sparse matrices*************************************************
601  // No special implementation for the Schur product assignment to sparse matrices.
602  //**********************************************************************************************
603 
604  //**Multiplication assignment to dense matrices*************************************************
605  // No special implementation for the multiplication assignment to dense matrices.
606  //**********************************************************************************************
607 
608  //**Multiplication assignment to sparse matrices************************************************
609  // No special implementation for the multiplication assignment to sparse matrices.
610  //**********************************************************************************************
611 
612  //**Compile time checks*************************************************************************
622  //**********************************************************************************************
623 };
624 //*************************************************************************************************
625 
626 
627 
628 
629 //=================================================================================================
630 //
631 // GLOBAL FUNCTIONS
632 //
633 //=================================================================================================
634 
635 //*************************************************************************************************
648 template< typename MT1 // Type of the left-hand side sparse matrix
649  , typename MT2 // Type of the right-hand side sparse matrix
650  , DisableIf_t< ( IsIdentity_v<MT1> && IsIdentity_v<MT2> ) ||
651  ( IsZero_v<MT1> || IsZero_v<MT2> ) >* = nullptr >
652 inline const SMatSMatKronExpr<MT1,MT2>
653  smatsmatkron( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
654 {
656 
657  return SMatSMatKronExpr<MT1,MT2>( ~lhs, ~rhs );
658 }
660 //*************************************************************************************************
661 
662 
663 //*************************************************************************************************
676 template< typename MT1 // Type of the left-hand side sparse matrix
677  , typename MT2 // Type of the right-hand side sparse matrix
678  , EnableIf_t< IsIdentity_v<MT1> && IsIdentity_v<MT2> >* = nullptr >
679 inline decltype(auto)
680  smatsmatkron( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
681 {
683 
684  using ReturnType = const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
685 
688 
689  return ReturnType( (~lhs).rows()*(~rhs).rows() );
690 }
692 //*************************************************************************************************
693 
694 
695 //*************************************************************************************************
708 template< typename MT1 // Type of the left-hand side sparse matrix
709  , typename MT2 // Type of the right-hand side sparse matrix
710  , EnableIf_t< IsZero_v<MT1> || IsZero_v<MT2> >* = nullptr >
711 inline decltype(auto)
712  smatsmatkron( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
713 {
715 
716  using ReturnType = const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
717 
720 
721  return ReturnType( (~lhs).rows()*(~rhs).rows(), (~lhs).columns()*(~rhs).columns() );
722 }
724 //*************************************************************************************************
725 
726 
727 //*************************************************************************************************
750 template< typename MT1 // Type of the left-hand side sparse matrix
751  , typename MT2 > // Type of the right-hand side sparse matrix
752 inline decltype(auto)
753  kron( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
754 {
756 
757  return smatsmatkron( ~lhs, ~rhs );
758 }
759 //*************************************************************************************************
760 
761 } // namespace blaze
762 
763 #endif
Constraint on the data type.
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
Expression object for sparse matrix-sparse matrix Kronecker product.The SMatSMatKronExpr class repres...
Definition: Forward.h:131
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
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatSMatKronExpr.h:120
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SMatSMatKronExpr.h:111
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.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatSMatKronExpr.h:254
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatSMatKronExpr.h:119
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.
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:97
Header file for the Computation base class.
Header file for the reset shim.
Constraints on the storage order of matrix types.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatSMatKronExpr.h:222
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatSMatKronExpr.h:138
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:98
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatSMatKronExpr.h:232
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatSMatKronExpr.h:211
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
SMatSMatKronExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatSMatKronExpr class.
Definition: SMatSMatKronExpr.h:147
Header file for the SparseMatrix base class.
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatSMatKronExpr.h:124
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:130
Constraint on the data type.
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
#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
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:96
RightOperand rhs_
Right-hand side sparse matrix of the Kronecker product expression.
Definition: SMatSMatKronExpr.h:274
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: SMatSMatKronExpr.h:242
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSMatKronExpr.h:127
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:95
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:133
Header file for the Kron product trait.
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
Constraint on the data type.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatSMatKronExpr.h:160
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
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatSMatKronExpr.h:118
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
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
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatSMatKronExpr.h:266
LeftOperand lhs_
Left-hand side sparse matrix of the Kronecker product expression.
Definition: SMatSMatKronExpr.h:273
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
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:94
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:93
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatSMatKronExpr.h:191
#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
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SMatSMatKronExpr.h:108
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
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatSMatKronExpr.h:175
#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
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatSMatKronExpr.h:201
#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
#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_t< ResultType > ElementType
Resulting element type.
Definition: SMatSMatKronExpr.h:121