Blaze 3.9
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>
62#include <blaze/util/Assert.h>
63#include <blaze/util/EnableIf.h>
65#include <blaze/util/mpl/If.h>
66#include <blaze/util/Types.h>
67
68
69namespace blaze {
70
71//=================================================================================================
72//
73// CLASS SMATSMATKRONEXPR
74//
75//=================================================================================================
76
77//*************************************************************************************************
84template< typename MT1 // Type of the left-hand side sparse matrix
85 , typename MT2 > // Type of the right-hand side sparse matrix
87 : public MatMatKronExpr< SparseMatrix< SMatSMatKronExpr<MT1,MT2>, false > >
88 , private Computation
89{
90 private:
91 //**Type definitions****************************************************************************
98 //**********************************************************************************************
99
100 //**Return type evaluation**********************************************************************
102
107 static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
108
110 using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
111 //**********************************************************************************************
112
113 public:
114 //**Type definitions****************************************************************************
117
120
125
128
131
133 using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
134
136 using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
137 //**********************************************************************************************
138
139 //**Compilation flags***************************************************************************
141 static constexpr bool smpAssignable = false;
142 //**********************************************************************************************
143
144 //**Constructor*********************************************************************************
150 inline SMatSMatKronExpr( const MT1& lhs, const MT2& rhs ) noexcept
151 : lhs_( lhs ) // Left-hand side sparse matrix of the Kronecker product expression
152 , rhs_( rhs ) // Right-hand side sparse matrix of the Kronecker product expression
153 {}
154 //**********************************************************************************************
155
156 //**Access operator*****************************************************************************
163 inline ReturnType operator()( size_t i, size_t j ) const {
164 BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
165 BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
166 return lhs_( i/rhs_.rows(), j/rhs_.columns() ) * rhs_( i%rhs_.rows(), j%rhs_.columns() );
167 }
168 //**********************************************************************************************
169
170 //**At function*********************************************************************************
178 inline ReturnType at( size_t i, size_t j ) const {
179 if( i >= rows() ) {
180 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
181 }
182 if( j >= columns() ) {
183 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
184 }
185 return (*this)(i,j);
186 }
187 //**********************************************************************************************
188
189 //**Rows function*******************************************************************************
194 inline size_t rows() const noexcept {
195 return lhs_.rows() * rhs_.rows();
196 }
197 //**********************************************************************************************
198
199 //**Columns function****************************************************************************
204 inline size_t columns() const noexcept {
205 return lhs_.columns() * rhs_.columns();
206 }
207 //**********************************************************************************************
208
209 //**NonZeros function***************************************************************************
214 inline size_t nonZeros() const {
215 return lhs_.nonZeros() * rhs_.nonZeros();
216 }
217 //**********************************************************************************************
218
219 //**NonZeros function***************************************************************************
225 inline size_t nonZeros( size_t i ) const {
226 return lhs_.nonZeros( i/rhs_.rows() ) * rhs_.nonZeros( i%rhs_.rows() );
227 }
228 //**********************************************************************************************
229
230 //**Left operand access*************************************************************************
235 inline LeftOperand leftOperand() const noexcept {
236 return lhs_;
237 }
238 //**********************************************************************************************
239
240 //**Right operand access************************************************************************
245 inline RightOperand rightOperand() const noexcept {
246 return rhs_;
247 }
248 //**********************************************************************************************
249
250 //**********************************************************************************************
256 template< typename T >
257 inline bool canAlias( const T* alias ) const noexcept {
258 return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
259 }
260 //**********************************************************************************************
261
262 //**********************************************************************************************
268 template< typename T >
269 inline bool isAliased( const T* alias ) const noexcept {
270 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
271 }
272 //**********************************************************************************************
273
274 private:
275 //**Member variables****************************************************************************
278 //**********************************************************************************************
279
280 //**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 SMatSMatKronExpr& 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 i=0UL; i<A.rows(); ++i )
317 for( size_t k=0UL; k<M; ++k )
318 for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
319 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
320 (*lhs)(i*M+k,aelem->index()*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 SMatSMatKronExpr& 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 for( size_t i=0UL; i<A.rows(); ++i ) {
362 for( size_t k=0UL; k<M; ++k ) {
363 for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
364 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
365 (*lhs).append( i*M+k, aelem->index()*N+belem->index(), aelem->value() * belem->value(), true );
366 (*lhs).finalize( i*M+k );
367 }
368 }
369 }
371 //**********************************************************************************************
372
373 //**Assignment to column-major sparse matrices**************************************************
386 template< typename MT > // Type of the target sparse matrix
387 friend inline void assign( SparseMatrix<MT,true>& lhs, const SMatSMatKronExpr& rhs )
388 {
390
391 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
392 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
393
394 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
395 return;
396 }
397
398 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
399 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
400
401 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
402 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
403 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
404 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
405
406 const size_t M( B.rows() );
407 const size_t N( B.columns() );
408
409 // Counting the number of elements per column in A
410 std::vector<size_t> lnonzeros( A.columns(), 0UL );
411 for( size_t i=0UL; i<A.rows(); ++i ) {
412 const auto aend( A.end(i) );
413 for( auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
414 ++lnonzeros[aelem->index()];
415 }
416 }
417
418 // Counting the number of elements per column B
419 std::vector<size_t> rnonzeros( N, 0UL );
420 for( size_t i=0UL; i<M; ++i ) {
421 const auto bend( B.end(i) );
422 for( auto belem=B.begin(i); belem!=bend; ++belem ) {
423 ++rnonzeros[belem->index()];
424 }
425 }
426
427 // Resizing the left-hand side sparse matrix
428 for( size_t i=0UL; i<A.columns(); ++i ) {
429 for( size_t j=0UL; j<N; ++j ) {
430 (*lhs).reserve( i*N+j, lnonzeros[i]*rnonzeros[j] );
431 }
432 }
433
434 // Performing the Kronecker product
435 for( size_t i=0UL; i<A.rows(); ++i )
436 for( size_t k=0UL; k<M; ++k )
437 for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
438 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
439 (*lhs).append( i*M+k, aelem->index()*N+belem->index(), aelem->value() * belem->value(), true );
440 }
442 //**********************************************************************************************
443
444 //**Addition assignment to dense matrices*******************************************************
457 template< typename MT // Type of the target dense matrix
458 , bool SO2 > // Storage order of the target dense matrix
459 friend inline void addAssign( DenseMatrix<MT,SO2>& lhs, const SMatSMatKronExpr& rhs )
460 {
462
463 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
464 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
465
466 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
467 return;
468 }
469
470 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
471 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
472
473 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
474 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
475 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
476 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
477
478 const size_t M( B.rows() );
479 const size_t N( B.columns() );
480
481 for( size_t i=0UL; i<A.rows(); ++i )
482 for( size_t k=0UL; k<M; ++k )
483 for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
484 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
485 (*lhs)(i*M+k,aelem->index()*N+belem->index()) += aelem->value() * belem->value();
486 }
488 //**********************************************************************************************
489
490 //**Addition assignment to sparse matrices******************************************************
491 // No special implementation for the addition assignment to sparse matrices.
492 //**********************************************************************************************
493
494 //**Subtraction assignment to dense matrices****************************************************
507 template< typename MT // Type of the target dense matrix
508 , bool SO2 > // Storage order of the target dense matrix
509 friend inline void subAssign( DenseMatrix<MT,SO2>& lhs, const SMatSMatKronExpr& rhs )
510 {
512
513 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
514 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
515
516 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
517 return;
518 }
519
520 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
521 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
522
523 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
524 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
525 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
526 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
527
528 const size_t M( B.rows() );
529 const size_t N( B.columns() );
530
531 for( size_t i=0UL; i<A.rows(); ++i )
532 for( size_t k=0UL; k<M; ++k )
533 for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem )
534 for( auto belem=B.begin(k); belem!=B.end(k); ++belem )
535 (*lhs)(i*M+k,aelem->index()*N+belem->index()) -= aelem->value() * belem->value();
536 }
538 //**********************************************************************************************
539
540 //**Subtraction assignment to sparse matrices***************************************************
541 // No special implementation for the subtraction assignment to sparse matrices.
542 //**********************************************************************************************
543
544 //**Schur product assignment to dense matrices**************************************************
557 template< typename MT // Type of the target dense matrix
558 , bool SO2 > // Storage order of the target dense matrix
559 friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs, const SMatSMatKronExpr& rhs )
560 {
562
563 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
564 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
565
566 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
567 return;
568 }
569
570 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
571 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
572
573 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
574 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
575 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
576 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
577
578 const size_t M( B.rows() );
579 const size_t N( B.columns() );
580
581 for( size_t i=0UL; i<A.rows(); ++i ) {
582 for( size_t k=0UL; k<M; ++k )
583 {
584 size_t j( 0UL );
585
586 for( auto aelem=A.begin(i); aelem!=A.end(i); ++aelem ) {
587 for( auto belem=B.begin(k); belem!=B.end(k); ++belem, ++j ) {
588 const size_t index( aelem->index()*N+belem->index() );
589 for( ; j<index; ++j )
590 reset( (*lhs)(i*M+k,j) );
591 (*lhs)(i*M+k,j) *= aelem->value() * belem->value();
592 }
593 }
594
595 for( ; j<(*lhs).columns(); ++j )
596 reset( (*lhs)(i*M+k,j) );
597 }
598 }
599 }
601 //**********************************************************************************************
602
603 //**Schur product assignment to sparse matrices*************************************************
604 // No special implementation for the Schur product assignment to sparse matrices.
605 //**********************************************************************************************
606
607 //**Multiplication assignment to dense matrices*************************************************
608 // No special implementation for the multiplication assignment to dense matrices.
609 //**********************************************************************************************
610
611 //**Multiplication assignment to sparse matrices************************************************
612 // No special implementation for the multiplication assignment to sparse matrices.
613 //**********************************************************************************************
614
615 //**Compile time checks*************************************************************************
625 //**********************************************************************************************
626};
627//*************************************************************************************************
628
629
630
631
632//=================================================================================================
633//
634// GLOBAL FUNCTIONS
635//
636//=================================================================================================
637
638//*************************************************************************************************
651template< typename MT1 // Type of the left-hand side sparse matrix
652 , typename MT2 // Type of the right-hand side sparse matrix
653 , DisableIf_t< ( IsIdentity_v<MT1> && IsIdentity_v<MT2> ) ||
654 ( IsZero_v<MT1> || IsZero_v<MT2> ) >* = nullptr >
655inline const SMatSMatKronExpr<MT1,MT2>
656 smatsmatkron( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
657{
659
660 return SMatSMatKronExpr<MT1,MT2>( *lhs, *rhs );
661}
663//*************************************************************************************************
664
665
666//*************************************************************************************************
679template< typename MT1 // Type of the left-hand side sparse matrix
680 , typename MT2 // Type of the right-hand side sparse matrix
681 , EnableIf_t< IsIdentity_v<MT1> && IsIdentity_v<MT2> >* = nullptr >
682inline decltype(auto)
683 smatsmatkron( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
684{
686
687 using ReturnType = const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
688
691
692 return ReturnType( (*lhs).rows()*(*rhs).rows() );
693}
695//*************************************************************************************************
696
697
698//*************************************************************************************************
711template< typename MT1 // Type of the left-hand side sparse matrix
712 , typename MT2 // Type of the right-hand side sparse matrix
713 , EnableIf_t< IsZero_v<MT1> || IsZero_v<MT2> >* = nullptr >
714inline decltype(auto)
715 smatsmatkron( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
716{
718
719 using ReturnType = const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
720
723
724 return ReturnType( (*lhs).rows()*(*rhs).rows(), (*lhs).columns()*(*rhs).columns() );
725}
727//*************************************************************************************************
728
729
730//*************************************************************************************************
753template< typename MT1 // Type of the left-hand side sparse matrix
754 , typename MT2 > // Type of the right-hand side sparse matrix
755inline decltype(auto)
757{
759
760 return smatsmatkron( *lhs, *rhs );
761}
762//*************************************************************************************************
763
764} // namespace blaze
765
766#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.
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.
Constraints on the storage order of matrix types.
Constraint on the data type.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Expression object for sparse matrix-sparse matrix Kronecker product.
Definition: SMatSMatKronExpr.h:89
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatSMatKronExpr.h:127
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:92
RightOperand rhs_
Right-hand side sparse matrix of the Kronecker product expression.
Definition: SMatSMatKronExpr.h:277
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatSMatKronExpr.h:214
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:94
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SMatSMatKronExpr.h:110
SMatSMatKronExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatSMatKronExpr class.
Definition: SMatSMatKronExpr.h:150
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:97
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatSMatKronExpr.h:257
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SMatSMatKronExpr.h:107
ElementType_t< ResultType > ElementType
Resulting element type.
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:133
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSMatKronExpr.h:130
LeftOperand lhs_
Left-hand side sparse matrix of the Kronecker product expression.
Definition: SMatSMatKronExpr.h:276
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:136
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:93
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: SMatSMatKronExpr.h:245
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:96
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatSMatKronExpr.h:204
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatSMatKronExpr.h:178
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatSMatKronExpr.h:269
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatSMatKronExpr.h:122
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatSMatKronExpr.h:141
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatSMatKronExpr.h:123
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatSMatKronExpr.h:163
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatSMatKronExpr.h:194
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: SMatSMatKronExpr.h:95
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatSMatKronExpr.h:121
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatSMatKronExpr.h:235
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatSMatKronExpr.h:225
Base class for sparse matrices.
Definition: SparseMatrix.h:77
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_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
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
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.