35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATDMATKRONEXPR_H_ 36 #define _BLAZE_MATH_EXPRESSIONS_SMATDMATKRONEXPR_H_ 90 template<
typename MT1
93 class SMatDMatKronExpr
94 :
public MatMatKronExpr< SparseMatrix< SMatDMatKronExpr<MT1,MT2,SO>, SO > >
114 static constexpr
bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
197 inline size_t rows() const noexcept {
208 return lhs_.columns() *
rhs_.columns();
262 template<
typename T >
263 inline bool canAlias(
const T* alias )
const noexcept {
264 return (
lhs_.canAlias( alias ) ||
rhs_.canAlias( alias ) );
274 template<
typename T >
275 inline bool isAliased(
const T* alias )
const noexcept {
276 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
298 template<
typename MT
307 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
319 const size_t M( B.rows() );
320 const size_t N( B.columns() );
324 for(
size_t j=0UL; j<A.columns(); ++j ) {
325 const auto aend( A.end(j) );
326 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
327 for(
size_t l=0UL; l<N; ++l )
329 const size_t kbegin( ( IsLower_v<MT2> )
330 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
332 const size_t kend( ( IsUpper_v<MT2> )
333 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
337 for(
size_t k=kbegin; k<kend; ++k ) {
338 (~lhs)(aelem->index()*M+k,j*N+l) = aelem->value() * B(k,l);
346 for(
size_t i=0UL; i<A.rows(); ++i ) {
347 const auto aend( A.end(i) );
348 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
349 for(
size_t k=0UL; k<M; ++k )
351 const size_t lbegin( ( IsUpper_v<MT2> )
352 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
354 const size_t lend( ( IsLower_v<MT2> )
355 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
359 for(
size_t l=lbegin; l<lend; ++l )
360 (~lhs)(i*M+k,aelem->index()*N+l) = aelem->value() * B(k,l);
382 template<
typename MT >
390 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
402 const size_t M( B.rows() );
403 const size_t N( B.columns() );
408 std::vector<size_t> nonzeros( A.rows(), 0UL );
409 for(
size_t j=0UL; j<A.columns(); ++j ) {
410 const auto end( A.end(j) );
411 for(
auto aelem=A.begin(j); aelem!=
end; ++aelem ) {
412 ++nonzeros[aelem->index()];
417 for(
size_t i=0UL; i<A.rows(); ++i ) {
418 for(
size_t j=0UL; j<M; ++j ) {
419 (~lhs).reserve( i*M+j, nonzeros[i]*B.columns() );
424 for(
size_t j=0UL; j<A.columns(); ++j ) {
425 const auto aend( A.end(j) );
426 for(
size_t l=0UL; l<N; ++l )
428 const size_t kbegin( ( IsLower_v<MT2> )
429 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
431 const size_t kend( ( IsUpper_v<MT2> )
432 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
436 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
437 for(
size_t k=kbegin; k<kend; ++k ) {
438 (~lhs).append( aelem->index()*M+k, j*N+l, aelem->value() * B(k,l), true );
446 for(
size_t i=0UL; i<A.rows(); ++i ) {
447 const auto aend( A.end(i) );
448 for(
size_t k=0UL; k<M; ++k )
450 const size_t lbegin( ( IsUpper_v<MT2> )
451 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
453 const size_t lend( ( IsLower_v<MT2> )
454 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
458 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
459 for(
size_t l=lbegin; l<lend; ++l ) {
460 (~lhs).append( i*M+k, aelem->index()*N+l, aelem->value() * B(k,l), true );
463 (~lhs).finalize( i*M+k );
484 template<
typename MT >
485 friend inline void assign( SparseMatrix<MT,true>& lhs,
const SMatDMatKronExpr& rhs )
492 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
504 const size_t M( B.rows() );
505 const size_t N( B.columns() );
509 for(
size_t j=0UL; j<A.columns(); ++j ) {
510 const auto aend( A.end(j) );
511 for(
size_t l=0UL; l<N; ++l )
513 const size_t kbegin( ( IsLower_v<MT2> )
514 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
516 const size_t kend( ( IsUpper_v<MT2> )
517 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
521 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
522 for(
size_t k=kbegin; k<kend; ++k ) {
523 (~lhs).append( aelem->index()*M+k, j*N+l, aelem->value() * B(k,l), true );
526 (~lhs).finalize( j*N+l );
533 std::vector<size_t> nonzeros( A.columns(), 0UL );
534 for(
size_t i=0UL; i<A.rows(); ++i ) {
535 const auto end( A.end(i) );
536 for(
auto aelem=A.begin(i); aelem!=
end; ++aelem ) {
537 ++nonzeros[aelem->index()];
542 for(
size_t i=0UL; i<A.columns(); ++i ) {
543 for(
size_t j=0UL; j<N; ++j ) {
544 (~lhs).reserve( i*N+j, nonzeros[i]*B.rows() );
549 for(
size_t i=0UL; i<A.rows(); ++i ) {
550 const auto aend( A.end(i) );
551 for(
size_t k=0UL; k<M; ++k )
553 const size_t lbegin( ( IsUpper_v<MT2> )
554 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
556 const size_t lend( ( IsLower_v<MT2> )
557 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
561 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
562 for(
size_t l=lbegin; l<lend; ++l ) {
563 (~lhs).append( i*M+k, aelem->index()*N+l, aelem->value() * B(k,l), true );
586 template<
typename MT
588 friend inline void addAssign( DenseMatrix<MT,SO2>& lhs,
const SMatDMatKronExpr& rhs )
595 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
607 const size_t M( B.rows() );
608 const size_t N( B.columns() );
612 for(
size_t j=0UL; j<A.columns(); ++j ) {
613 const auto aend( A.end(j) );
614 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
615 for(
size_t l=0UL; l<N; ++l )
617 const size_t kbegin( ( IsLower_v<MT2> )
618 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
620 const size_t kend( ( IsUpper_v<MT2> )
621 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
625 for(
size_t k=kbegin; k<kend; ++k ) {
626 (~lhs)(aelem->index()*M+k,j*N+l) += aelem->value() * B(k,l);
634 for(
size_t i=0UL; i<A.rows(); ++i ) {
635 const auto aend( A.end(i) );
636 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
637 for(
size_t k=0UL; k<M; ++k )
639 const size_t lbegin( ( IsUpper_v<MT2> )
640 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
642 const size_t lend( ( IsLower_v<MT2> )
643 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
647 for(
size_t l=lbegin; l<lend; ++l ) {
648 (~lhs)(i*M+k,aelem->index()*N+l) += aelem->value() * B(k,l);
675 template<
typename MT
677 friend inline void subAssign( DenseMatrix<MT,SO2>& lhs,
const SMatDMatKronExpr& rhs )
684 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
696 const size_t M( B.rows() );
697 const size_t N( B.columns() );
701 for(
size_t j=0UL; j<A.columns(); ++j ) {
702 const auto aend( A.end(j) );
703 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
704 for(
size_t l=0UL; l<N; ++l )
706 const size_t kbegin( ( IsLower_v<MT2> )
707 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
709 const size_t kend( ( IsUpper_v<MT2> )
710 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
714 for(
size_t k=kbegin; k<kend; ++k ) {
715 (~lhs)(aelem->index()*M+k,j*N+l) -= aelem->value() * B(k,l);
723 for(
size_t i=0UL; i<A.rows(); ++i ) {
724 const auto aend( A.end(i) );
725 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
726 for(
size_t k=0UL; k<M; ++k )
728 const size_t lbegin( ( IsUpper_v<MT2> )
729 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
731 const size_t lend( ( IsLower_v<MT2> )
732 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
736 for(
size_t l=lbegin; l<lend; ++l ) {
737 (~lhs)(i*M+k,aelem->index()*N+l) -= aelem->value() * B(k,l);
764 template<
typename MT
766 friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs,
const SMatDMatKronExpr& rhs )
773 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
785 const size_t M( B.rows() );
786 const size_t N( B.columns() );
790 for(
size_t j=0UL; j<A.columns(); ++j )
793 const auto aend( A.end(j) );
795 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem, ++index )
797 for( ; index<aelem->index(); ++index )
798 for(
size_t l=0UL; l<N; ++l )
799 for(
size_t k=0UL; k<M; ++k )
800 reset( (~lhs)(index*M+k,j*N+l) );
802 for(
size_t l=0UL; l<N; ++l )
803 for(
size_t k=0UL; k<M; ++k )
804 (~lhs)(index*M+k,j*N+l) *= aelem->value() * B(k,l);
807 for( ; index<A.rows(); ++index )
808 for(
size_t l=0UL; l<N; ++l )
809 for(
size_t k=0UL; k<M; ++k )
810 reset( (~lhs)(index*M+k,j*N+l) );
815 for(
size_t i=0UL; i<A.rows(); ++i )
818 const auto aend( A.end(i) );
820 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem, ++index )
822 for( ; index<aelem->index(); ++index )
823 for(
size_t k=0UL; k<M; ++k )
824 for(
size_t l=0UL; l<N; ++l )
825 reset( (~lhs)(i*M+k,index*N+l) );
827 for(
size_t k=0UL; k<M; ++k )
828 for(
size_t l=0UL; l<N; ++l )
829 (~lhs)(i*M+k,index*N+l) *= aelem->value() * B(k,l);
832 for( ; index<A.columns(); ++index )
833 for(
size_t k=0UL; k<M; ++k )
834 for(
size_t l=0UL; l<N; ++l )
835 reset( (~lhs)(i*M+k,index*N+l) );
888 template<
typename MT1
892 , DisableIf_t< IsZero_v<MT1> >* =
nullptr >
893 inline const SMatDMatKronExpr<MT1,MT2,SO1>
894 smatdmatkron(
const SparseMatrix<MT1,SO1>& lhs,
const DenseMatrix<MT2,SO2>& rhs )
898 return SMatDMatKronExpr<MT1,MT2,SO1>( ~lhs, ~rhs );
917 template<
typename MT1
921 , EnableIf_t< IsZero_v<MT1> >* =
nullptr >
922 inline decltype(
auto)
923 smatdmatkron( const SparseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
927 using ReturnType =
const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
960 template<
typename MT1
964 inline decltype(
auto)
969 return smatdmatkron( ~lhs, ~rhs );
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatKronExpr.h:103
Header file for auxiliary alias declarations.
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatDMatKronExpr.h:127
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatDMatKronExpr.h:275
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatDMatKronExpr.h:181
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatDMatKronExpr.h:126
Header file for basic type definitions.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatDMatKronExpr.h:197
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
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.
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.In case the given data type T is not a dense or sparse matrix type and in...
Definition: StorageOrder.h:63
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type,...
Definition: DenseMatrix.h:61
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatDMatKronExpr.h:228
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
Constraint on the data type.
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatKronExpr.h:136
Header file for the Computation base class.
Header file for the reset shim.
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatDMatKronExpr.h:100
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
decltype(auto) kron(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the Kronecker product of two dense matrices ( ).
Definition: DMatDMatKronExpr.h:954
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SMatDMatKronExpr.h:114
Header file for the MatMatKronExpr base class.
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatDMatKronExpr.h:124
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
Header file for the SparseMatrix base class.
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatDMatKronExpr.h:144
Constraint on the data type.
Constraint on the data type.
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
Header file for the IsStrictlyUpper type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SMatDMatKronExpr.h:117
#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
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatDMatKronExpr.h:217
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatDMatKronExpr.h:125
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
Header file for the DenseMatrix base class.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatDMatKronExpr.h:263
Header file for the IsLower type trait.
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.
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatDMatKronExpr.h:130
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatDMatKronExpr.h:166
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
RightOperand rightOperand() const noexcept
Returns the right-hand side dense matrix operand.
Definition: SMatDMatKronExpr.h:251
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
RightOperand rhs_
Right-hand side dense matrix of the Kronecker product expression.
Definition: SMatDMatKronExpr.h:283
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
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
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatDMatKronExpr.h:207
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatDMatKronExpr.h:133
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: SMatDMatKronExpr.h:101
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatKronExpr.h:104
Header file for the IsRowMajorMatrix type trait.
#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
ReturnType_t< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: SMatDMatKronExpr.h:102
LeftOperand lhs_
Left-hand side sparse matrix of the Kronecker product expression.
Definition: SMatDMatKronExpr.h:282
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatDMatKronExpr.h:99
SMatDMatKronExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatDMatKronExpr class.
Definition: SMatDMatKronExpr.h:153
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatDMatKronExpr.h:241
Header file for the IsUpper type trait.
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatKronExpr.h:139
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is a zero vector or matrix type,...
Definition: Zero.h:81
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
#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
Expression object for sparse matrix-dense matrix Kronecker product.The SMatDMatKronExpr class represe...
Definition: Forward.h:120
Header file for the IsExpression type trait class.
Header file for the function trace functionality.