Blaze 3.9
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>
63#include <blaze/util/Assert.h>
64#include <blaze/util/EnableIf.h>
67#include <blaze/util/mpl/If.h>
68#include <blaze/util/Types.h>
69
70
71namespace blaze {
72
73//=================================================================================================
74//
75// CLASS TSMATSMATKRONEXPR
76//
77//=================================================================================================
78
79//*************************************************************************************************
86template< typename MT1 // Type of the left-hand side sparse matrix
87 , typename MT2 > // Type of the right-hand side sparse matrix
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****************************************************************************
119
122
127
130
133
135 using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
136
138 using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
139 //**********************************************************************************************
140
141 //**Compilation flags***************************************************************************
143 static constexpr bool smpAssignable = false;
144 //**********************************************************************************************
145
146 //**Constructor*********************************************************************************
152 inline TSMatSMatKronExpr( const MT1& lhs, const MT2& rhs ) noexcept
153 : lhs_( lhs ) // Left-hand side sparse matrix of the Kronecker product expression
154 , rhs_( rhs ) // Right-hand side sparse matrix of the Kronecker product expression
155 {}
156 //**********************************************************************************************
157
158 //**Access operator*****************************************************************************
165 inline ReturnType operator()( size_t i, size_t j ) const {
166 BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
167 BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
168 return lhs_( i/rhs_.rows(), j/rhs_.columns() ) * rhs_( i%rhs_.rows(), j%rhs_.columns() );
169 }
170 //**********************************************************************************************
171
172 //**At function*********************************************************************************
180 inline ReturnType at( size_t i, size_t j ) const {
181 if( i >= rows() ) {
182 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
183 }
184 if( j >= columns() ) {
185 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
186 }
187 return (*this)(i,j);
188 }
189 //**********************************************************************************************
190
191 //**Rows function*******************************************************************************
196 inline size_t rows() const noexcept {
197 return lhs_.rows() * rhs_.rows();
198 }
199 //**********************************************************************************************
200
201 //**Columns function****************************************************************************
206 inline size_t columns() const noexcept {
207 return lhs_.columns() * rhs_.columns();
208 }
209 //**********************************************************************************************
210
211 //**NonZeros function***************************************************************************
216 inline size_t nonZeros() const {
217 return lhs_.nonZeros() * rhs_.nonZeros();
218 }
219 //**********************************************************************************************
220
221 //**NonZeros function***************************************************************************
227 inline size_t nonZeros( size_t i ) const {
228 MAYBE_UNUSED( i );
229 return 0UL;
230 }
231 //**********************************************************************************************
232
233 //**Left operand access*************************************************************************
238 inline LeftOperand leftOperand() const noexcept {
239 return lhs_;
240 }
241 //**********************************************************************************************
242
243 //**Right operand access************************************************************************
248 inline RightOperand rightOperand() const noexcept {
249 return rhs_;
250 }
251 //**********************************************************************************************
252
253 //**********************************************************************************************
259 template< typename T >
260 inline bool canAlias( const T* alias ) const noexcept {
261 return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
262 }
263 //**********************************************************************************************
264
265 //**********************************************************************************************
271 template< typename T >
272 inline bool isAliased( const T* alias ) const noexcept {
273 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
274 }
275 //**********************************************************************************************
276
277 private:
278 //**Member variables****************************************************************************
281 //**********************************************************************************************
282
283 //**Assignment to dense matrices****************************************************************
296 template< typename MT // Type of the target dense matrix
297 , bool SO2 > // Storage order of the target dense matrix
298 friend inline void assign( DenseMatrix<MT,SO2>& lhs, const TSMatSMatKronExpr& rhs )
299 {
301
302 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
303 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
304
305 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
306 return;
307 }
308
309 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
310 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
311
312 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
313 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
314 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
315 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
316
317 const size_t M( B.rows() );
318 const size_t N( B.columns() );
319
320 for( size_t j=0UL; j<A.columns(); ++j )
321 for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
322 for( size_t k=0UL; k<M; ++k )
323 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
324 (*lhs)(aelem->index()*M+k,j*N+belem->index()) = aelem->value() * belem->value();
325 }
327 //**********************************************************************************************
328
329 //**Assignment to row-major sparse matrices*****************************************************
342 template< typename MT > // Type of the target sparse matrix
343 friend inline void assign( SparseMatrix<MT,false>& lhs, const TSMatSMatKronExpr& rhs )
344 {
346
347 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
348 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
349
350 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
351 return;
352 }
353
354 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
355 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
356
357 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
358 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
359 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
360 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
361
362 const size_t M( B.rows() );
363 const size_t N( B.columns() );
364
365 // Counting the number of elements per row in A
366 std::vector<size_t> nonzeros( A.rows(), 0UL );
367 for( size_t j=0UL; j<A.columns(); ++j ) {
368 const auto end( A.end(j) );
369 for( auto aelem=A.begin(j); aelem!=end; ++aelem ) {
370 ++nonzeros[aelem->index()];
371 }
372 }
373
374 // Resizing the left-hand side sparse matrix
375 for( size_t i=0UL; i<A.rows(); ++i ) {
376 for( size_t j=0UL; j<M; ++j ) {
377 (*lhs).reserve( i*M+j, nonzeros[i]*B.nonZeros(j) );
378 }
379 }
380
381 // Performing the Kronecker product
382 for( size_t j=0UL; j<A.columns(); ++j )
383 for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
384 for( size_t k=0UL; k<M; ++k )
385 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
386 (*lhs).append( aelem->index()*M+k, j*N+belem->index(), aelem->value() * belem->value(), true );
387 }
389 //**********************************************************************************************
390
391 //**Assignment to column-major sparse matrices**************************************************
404 template< typename MT > // Type of the target sparse matrix
405 friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatSMatKronExpr& rhs )
406 {
408
409 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
410 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
411
412 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
413 return;
414 }
415
416 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
417 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
418
419 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
420 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
421 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
422 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
423
424 const size_t M( B.rows() );
425 const size_t N( B.columns() );
426
427 // Counting the number of elements per column in B
428 std::vector<size_t> nonzeros( B.columns(), 0UL );
429 for( size_t i=0UL; i<B.rows(); ++i ) {
430 const auto end( B.end(i) );
431 for( auto belem=B.begin(i); belem!=end; ++belem ) {
432 ++nonzeros[belem->index()];
433 }
434 }
435
436 // Resizing the left-hand side sparse matrix
437 for( size_t i=0UL; i<A.columns(); ++i ) {
438 for( size_t j=0UL; j<N; ++j ) {
439 (*lhs).reserve( i*N+j, A.nonZeros(i)*nonzeros[j] );
440 }
441 }
442
443 // Performing the Kronecker product
444 for( size_t j=0UL; j<A.columns(); ++j )
445 for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
446 for( size_t k=0UL; k<M; ++k )
447 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
448 (*lhs).append( aelem->index()*M+k, j*N+belem->index(), aelem->value() * belem->value(), true );
449 }
451 //**********************************************************************************************
452
453 //**Addition assignment to dense matrices*******************************************************
466 template< typename MT // Type of the target dense matrix
467 , bool SO2 > // Storage order of the target dense matrix
468 friend inline void addAssign( DenseMatrix<MT,SO2>& lhs, const TSMatSMatKronExpr& rhs )
469 {
471
472 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
473 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
474
475 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
476 return;
477 }
478
479 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
480 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
481
482 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
483 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
484 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
485 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
486
487 const size_t M( B.rows() );
488 const size_t N( B.columns() );
489
490 for( size_t j=0UL; j<A.columns(); ++j )
491 for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
492 for( size_t k=0UL; k<M; ++k )
493 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
494 (*lhs)(aelem->index()*M+k,j*N+belem->index()) += aelem->value() * belem->value();
495 }
497 //**********************************************************************************************
498
499 //**Addition assignment to sparse matrices******************************************************
500 // No special implementation for the addition assignment to sparse matrices.
501 //**********************************************************************************************
502
503 //**Subtraction assignment to dense matrices****************************************************
516 template< typename MT // Type of the target dense matrix
517 , bool SO2 > // Storage order of the target dense matrix
518 friend inline void subAssign( DenseMatrix<MT,SO2>& lhs, const TSMatSMatKronExpr& rhs )
519 {
521
522 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
523 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
524
525 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
526 return;
527 }
528
529 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
530 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
531
532 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
533 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
534 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
535 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
536
537 const size_t M( B.rows() );
538 const size_t N( B.columns() );
539
540 for( size_t j=0UL; j<A.columns(); ++j )
541 for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem )
542 for( size_t k=0UL; k<M; ++k )
543 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
544 (*lhs)(aelem->index()*M+k,j*N+belem->index()) -= aelem->value() * belem->value();
545 }
547 //**********************************************************************************************
548
549 //**Subtraction assignment to sparse matrices***************************************************
550 // No special implementation for the subtraction assignment to sparse matrices.
551 //**********************************************************************************************
552
553 //**Schur product assignment to dense matrices**************************************************
566 template< typename MT // Type of the target dense matrix
567 , bool SO2 > // Storage order of the target dense matrix
568 friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs, const TSMatSMatKronExpr& 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
575 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
576 return;
577 }
578
579 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
580 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
581
582 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
583 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
584 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
585 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
586
587 const size_t M( B.rows() );
588 const size_t N( B.columns() );
589
590 for( size_t j=0UL; j<A.columns(); ++j )
591 {
592 size_t i( 0UL );
593
594 for( auto aelem=A.begin(j); aelem!=A.end(j); ++aelem, ++i )
595 {
596 for( ; i<aelem->index(); ++i ) {
597 for( size_t k=0UL; k<M; ++k )
598 for( size_t l=0UL; l<N; ++l )
599 reset( (*lhs)(i*M+k,j*N+l) );
600 }
601
602 for( size_t k=0UL; k<M; ++k )
603 {
604 size_t l( 0UL );
605
606 for( auto belem=B.begin(k); belem!=B.end(k); ++belem, ++l ) {
607 for( ; l<belem->index(); ++l )
608 reset( (*lhs)(i*M+k,j*N+l) );
609 (*lhs)(i*M+k,j*N+l) *= aelem->value() * belem->value();
610 }
611
612 for( ; l<N; ++l ) {
613 reset( (*lhs)(i*M+k,j*N+l) );
614 }
615 }
616 }
617
618 for( ; i<A.rows(); ++i ) {
619 for( size_t k=0UL; k<M; ++k )
620 for( size_t l=0UL; l<N; ++l )
621 reset( (*lhs)(i*M+k,j*N+l) );
622 }
623 }
624 }
626 //**********************************************************************************************
627
628 //**Schur product assignment to sparse matrices*************************************************
629 // No special implementation for the Schur product assignment to sparse matrices.
630 //**********************************************************************************************
631
632 //**Multiplication assignment to dense matrices*************************************************
633 // No special implementation for the multiplication assignment to dense matrices.
634 //**********************************************************************************************
635
636 //**Multiplication assignment to sparse matrices************************************************
637 // No special implementation for the multiplication assignment to sparse matrices.
638 //**********************************************************************************************
639
640 //**Compile time checks*************************************************************************
650 //**********************************************************************************************
651};
652//*************************************************************************************************
653
654
655
656
657//=================================================================================================
658//
659// GLOBAL FUNCTIONS
660//
661//=================================================================================================
662
663//*************************************************************************************************
676template< typename MT1 // Type of the left-hand side sparse matrix
677 , typename MT2 // Type of the right-hand side sparse matrix
678 , DisableIf_t< ( IsIdentity_v<MT1> && IsIdentity_v<MT2> ) ||
679 ( IsZero_v<MT1> || IsZero_v<MT2> ) >* = nullptr >
680inline const TSMatSMatKronExpr<MT1,MT2>
681 tsmatsmatkron( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
682{
684
685 return TSMatSMatKronExpr<MT1,MT2>( *lhs, *rhs );
686}
688//*************************************************************************************************
689
690
691//*************************************************************************************************
704template< typename MT1 // Type of the left-hand side sparse matrix
705 , typename MT2 // Type of the right-hand side sparse matrix
706 , EnableIf_t< IsIdentity_v<MT1> && IsIdentity_v<MT2> >* = nullptr >
707inline decltype(auto)
708 tsmatsmatkron( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
709{
711
712 using ReturnType = const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
713
716
717 return ReturnType( (*lhs).rows()*(*rhs).rows() );
718}
720//*************************************************************************************************
721
722
723//*************************************************************************************************
736template< typename MT1 // Type of the left-hand side sparse matrix
737 , typename MT2 // Type of the right-hand side sparse matrix
738 , EnableIf_t< IsZero_v<MT1> || IsZero_v<MT2> >* = nullptr >
739inline decltype(auto)
740 tsmatsmatkron( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
741{
743
744 using ReturnType = const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
745
747
748 return ReturnType( (*lhs).rows()*(*rhs).rows(), (*lhs).columns()*(*rhs).columns() );
749}
751//*************************************************************************************************
752
753
754//*************************************************************************************************
781template< typename MT1 // Type of the left-hand side sparse matrix
782 , typename MT2 > // Type of the right-hand side sparse matrix
783inline decltype(auto)
785{
787
788 return tsmatsmatkron( *lhs, *rhs );
789}
790//*************************************************************************************************
791
792} // namespace blaze
793
794#endif
Header file for auxiliary alias declarations.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.
Definition: Aliases.h:110
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.
Definition: Aliases.h:470
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.
Definition: Aliases.h:310
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.
Definition: Aliases.h:550
Header file for run time assertion macros.
Constraints on the storage order of matrix types.
Header file for the EnableIf class template.
Header file for the function trace functionality.
Constraint on the data type.
Header file for the If class template.
Header file for the IsExpression type trait class.
Header file for the IsIdentity type trait.
Header file for the IsTemporary type trait class.
Header file for the Kron product trait.
Header file for the MAYBE_UNUSED function template.
Constraints on the storage order of matrix types.
Constraint on the data type.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Expression object for sparse matrix-sparse matrix Kronecker product.
Definition: TSMatSMatKronExpr.h:91
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:99
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatSMatKronExpr.h:165
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:138
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatSMatKronExpr.h:216
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatSMatKronExpr.h:227
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: TSMatSMatKronExpr.h:109
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatSMatKronExpr.h:180
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:94
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: TSMatSMatKronExpr.h:238
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSMatSMatKronExpr.h:126
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatSMatKronExpr.h:206
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:98
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSMatSMatKronExpr.h:143
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatSMatKronExpr.h:125
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:135
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatSMatKronExpr.h:272
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:97
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatSMatKronExpr.h:132
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatSMatKronExpr.h:260
LeftOperand lhs_
Left-hand side sparse matrix of the Kronecker product expression.
Definition: TSMatSMatKronExpr.h:279
RightOperand rhs_
Right-hand side sparse matrix of the Kronecker product expression.
Definition: TSMatSMatKronExpr.h:280
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatSMatKronExpr.h:196
TSMatSMatKronExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatSMatKronExpr class.
Definition: TSMatSMatKronExpr.h:152
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:96
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: TSMatSMatKronExpr.h:112
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatSMatKronExpr.h:95
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: TSMatSMatKronExpr.h:248
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: TSMatSMatKronExpr.h:129
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatSMatKronExpr.h:124
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatSMatKronExpr.h:123
Constraint on the data type.
Constraint on the data type.
Header file for the Computation base class.
Header file for the MatMatKronExpr base class.
Header file for the SparseMatrix base class.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
decltype(auto) kron(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the Kronecker product of two dense matrices ( ).
Definition: DMatDMatKronExpr.h:957
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: SparseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATKRONEXPR(T1, T2)
Constraint on the data type.
Definition: MatMatKronExpr.h:102
#define BLAZE_CONSTRAINT_MUST_BE_IDENTITY_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Identity.h:60
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:61
typename KronTrait< T1, T2 >::Type KronTrait_t
Auxiliary alias declaration for the KronTrait class template.
Definition: KronTrait.h:137
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
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:584
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
typename If< Condition >::template Type< T1, T2 > If_t
Auxiliary alias template for the If class template.
Definition: If.h:108
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
#define BLAZE_FUNCTION_TRACE
Function trace macro.
Definition: FunctionTrace.h:94
Header file for the exception macros of the math module.
Constraints on the storage order of matrix types.
Header file for the reset shim.
Header file for the serial shim.
Base class for all compute expression templates.
Definition: Computation.h:68
Base class for all matrix/matrix Kronecker expression templates.
Definition: MatMatKronExpr.h:69
Header file for the IsZero type trait.
Header file for basic type definitions.