35#ifndef _BLAZE_MATH_EXPRESSIONS_SMATDMATKRONEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_SMATDMATKRONEXPR_H_
91 :
public MatMatKronExpr< SparseMatrix< SMatDMatKronExpr<MT1,MT2,SO>, SO > >
111 static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
198 inline size_t rows() const noexcept {
209 return lhs_.columns() *
rhs_.columns();
263 template<
typename T >
264 inline bool canAlias(
const T* alias )
const noexcept {
265 return (
lhs_.canAlias( alias ) ||
rhs_.canAlias( alias ) );
275 template<
typename T >
276 inline bool isAliased(
const T* alias )
const noexcept {
277 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
299 template<
typename MT
320 const size_t M( B.rows() );
321 const size_t N( B.columns() );
325 for(
size_t j=0UL; j<A.columns(); ++j ) {
326 const auto aend( A.end(j) );
327 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
328 for(
size_t l=0UL; l<N; ++l )
330 const size_t kbegin( ( IsLower_v<MT2> )
331 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
333 const size_t kend( ( IsUpper_v<MT2> )
334 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
338 for(
size_t k=kbegin; k<kend; ++k ) {
339 (*lhs)(aelem->index()*M+k,j*N+l) = aelem->value() * B(k,l);
347 for(
size_t i=0UL; i<A.rows(); ++i ) {
348 const auto aend( A.end(i) );
349 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
350 for(
size_t k=0UL; k<M; ++k )
352 const size_t lbegin( ( IsUpper_v<MT2> )
353 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
355 const size_t lend( ( IsLower_v<MT2> )
356 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
360 for(
size_t l=lbegin; l<lend; ++l )
361 (*lhs)(i*M+k,aelem->index()*N+l) = aelem->value() * B(k,l);
383 template<
typename MT >
403 const size_t M( B.rows() );
404 const size_t N( B.columns() );
409 std::vector<size_t> nonzeros( A.rows(), 0UL );
410 for(
size_t j=0UL; j<A.columns(); ++j ) {
411 const auto end( A.end(j) );
412 for(
auto aelem=A.begin(j); aelem!=
end; ++aelem ) {
413 ++nonzeros[aelem->index()];
418 for(
size_t i=0UL; i<A.rows(); ++i ) {
419 for(
size_t j=0UL; j<M; ++j ) {
420 (*lhs).reserve( i*M+j, nonzeros[i]*B.columns() );
425 for(
size_t j=0UL; j<A.columns(); ++j ) {
426 const auto aend( A.end(j) );
427 for(
size_t l=0UL; l<N; ++l )
429 const size_t kbegin( ( IsLower_v<MT2> )
430 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
432 const size_t kend( ( IsUpper_v<MT2> )
433 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
437 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
438 for(
size_t k=kbegin; k<kend; ++k ) {
439 (*lhs).append( aelem->index()*M+k, j*N+l, aelem->value() * B(k,l),
true );
447 for(
size_t i=0UL; i<A.rows(); ++i ) {
448 const auto aend( A.end(i) );
449 for(
size_t k=0UL; k<M; ++k )
451 const size_t lbegin( ( IsUpper_v<MT2> )
452 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
454 const size_t lend( ( IsLower_v<MT2> )
455 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
459 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
460 for(
size_t l=lbegin; l<lend; ++l ) {
461 (*lhs).append( i*M+k, aelem->index()*N+l, aelem->value() * B(k,l),
true );
464 (*lhs).finalize( i*M+k );
485 template<
typename MT >
486 friend inline void assign( SparseMatrix<MT,true>& lhs,
const SMatDMatKronExpr& rhs )
493 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
505 const size_t M( B.rows() );
506 const size_t N( B.columns() );
510 for(
size_t j=0UL; j<A.columns(); ++j ) {
511 const auto aend( A.end(j) );
512 for(
size_t l=0UL; l<N; ++l )
514 const size_t kbegin( ( IsLower_v<MT2> )
515 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
517 const size_t kend( ( IsUpper_v<MT2> )
518 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
522 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
523 for(
size_t k=kbegin; k<kend; ++k ) {
524 (*lhs).append( aelem->index()*M+k, j*N+l, aelem->value() * B(k,l),
true );
527 (*lhs).finalize( j*N+l );
534 std::vector<size_t> nonzeros( A.columns(), 0UL );
535 for(
size_t i=0UL; i<A.rows(); ++i ) {
536 const auto end( A.end(i) );
537 for(
auto aelem=A.begin(i); aelem!=
end; ++aelem ) {
538 ++nonzeros[aelem->index()];
543 for(
size_t i=0UL; i<A.columns(); ++i ) {
544 for(
size_t j=0UL; j<N; ++j ) {
545 (*lhs).reserve( i*N+j, nonzeros[i]*B.rows() );
550 for(
size_t i=0UL; i<A.rows(); ++i ) {
551 const auto aend( A.end(i) );
552 for(
size_t k=0UL; k<M; ++k )
554 const size_t lbegin( ( IsUpper_v<MT2> )
555 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
557 const size_t lend( ( IsLower_v<MT2> )
558 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
562 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
563 for(
size_t l=lbegin; l<lend; ++l ) {
564 (*lhs).append( i*M+k, aelem->index()*N+l, aelem->value() * B(k,l),
true );
587 template<
typename MT
589 friend inline void addAssign( DenseMatrix<MT,SO2>& lhs,
const SMatDMatKronExpr& rhs )
596 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
608 const size_t M( B.rows() );
609 const size_t N( B.columns() );
613 for(
size_t j=0UL; j<A.columns(); ++j ) {
614 const auto aend( A.end(j) );
615 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
616 for(
size_t l=0UL; l<N; ++l )
618 const size_t kbegin( ( IsLower_v<MT2> )
619 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
621 const size_t kend( ( IsUpper_v<MT2> )
622 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
626 for(
size_t k=kbegin; k<kend; ++k ) {
627 (*lhs)(aelem->index()*M+k,j*N+l) += aelem->value() * B(k,l);
635 for(
size_t i=0UL; i<A.rows(); ++i ) {
636 const auto aend( A.end(i) );
637 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
638 for(
size_t k=0UL; k<M; ++k )
640 const size_t lbegin( ( IsUpper_v<MT2> )
641 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
643 const size_t lend( ( IsLower_v<MT2> )
644 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
648 for(
size_t l=lbegin; l<lend; ++l ) {
649 (*lhs)(i*M+k,aelem->index()*N+l) += aelem->value() * B(k,l);
676 template<
typename MT
678 friend inline void subAssign( DenseMatrix<MT,SO2>& lhs,
const SMatDMatKronExpr& rhs )
685 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
697 const size_t M( B.rows() );
698 const size_t N( B.columns() );
702 for(
size_t j=0UL; j<A.columns(); ++j ) {
703 const auto aend( A.end(j) );
704 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem ) {
705 for(
size_t l=0UL; l<N; ++l )
707 const size_t kbegin( ( IsLower_v<MT2> )
708 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
710 const size_t kend( ( IsUpper_v<MT2> )
711 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
715 for(
size_t k=kbegin; k<kend; ++k ) {
716 (*lhs)(aelem->index()*M+k,j*N+l) -= aelem->value() * B(k,l);
724 for(
size_t i=0UL; i<A.rows(); ++i ) {
725 const auto aend( A.end(i) );
726 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem ) {
727 for(
size_t k=0UL; k<M; ++k )
729 const size_t lbegin( ( IsUpper_v<MT2> )
730 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
732 const size_t lend( ( IsLower_v<MT2> )
733 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
737 for(
size_t l=lbegin; l<lend; ++l ) {
738 (*lhs)(i*M+k,aelem->index()*N+l) -= aelem->value() * B(k,l);
765 template<
typename MT
767 friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs,
const SMatDMatKronExpr& rhs )
774 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
786 const size_t M( B.rows() );
787 const size_t N( B.columns() );
791 for(
size_t j=0UL; j<A.columns(); ++j )
794 const auto aend( A.end(j) );
796 for(
auto aelem=A.begin(j); aelem!=aend; ++aelem, ++index )
798 for( ; index<aelem->index(); ++index )
799 for(
size_t l=0UL; l<N; ++l )
800 for(
size_t k=0UL; k<M; ++k )
801 reset( (*lhs)(index*M+k,j*N+l) );
803 for(
size_t l=0UL; l<N; ++l )
804 for(
size_t k=0UL; k<M; ++k )
805 (*lhs)(index*M+k,j*N+l) *= aelem->value() * B(k,l);
808 for( ; index<A.rows(); ++index )
809 for(
size_t l=0UL; l<N; ++l )
810 for(
size_t k=0UL; k<M; ++k )
811 reset( (*lhs)(index*M+k,j*N+l) );
816 for(
size_t i=0UL; i<A.rows(); ++i )
819 const auto aend( A.end(i) );
821 for(
auto aelem=A.begin(i); aelem!=aend; ++aelem, ++index )
823 for( ; index<aelem->index(); ++index )
824 for(
size_t k=0UL; k<M; ++k )
825 for(
size_t l=0UL; l<N; ++l )
826 reset( (*lhs)(i*M+k,index*N+l) );
828 for(
size_t k=0UL; k<M; ++k )
829 for(
size_t l=0UL; l<N; ++l )
830 (*lhs)(i*M+k,index*N+l) *= aelem->value() * B(k,l);
833 for( ; index<A.columns(); ++index )
834 for(
size_t k=0UL; k<M; ++k )
835 for(
size_t l=0UL; l<N; ++l )
836 reset( (*lhs)(i*M+k,index*N+l) );
889template<
typename MT1
893 , DisableIf_t< IsZero_v<MT1> >* =
nullptr >
894inline const SMatDMatKronExpr<MT1,MT2,SO1>
895 smatdmatkron(
const SparseMatrix<MT1,SO1>& lhs,
const DenseMatrix<MT2,SO2>& rhs )
899 return SMatDMatKronExpr<MT1,MT2,SO1>( *lhs, *rhs );
918template<
typename MT1
922 , EnableIf_t< IsZero_v<MT1> >* =
nullptr >
924 smatdmatkron(
const SparseMatrix<MT1,SO1>& lhs,
const DenseMatrix<MT2,SO2>& rhs )
928 using ReturnType =
const KronTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
933 return ReturnType( (*lhs).rows()*(*rhs).rows(), (*lhs).columns()*(*rhs).columns() );
961template<
typename MT1
970 return smatdmatkron( *lhs, *rhs );
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.
Header file for the If class template.
Header file for the IsExpression type trait class.
Header file for the IsLower type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsTemporary type trait class.
Header file for the IsUpper type trait.
Header file for the Kron product trait.
Constraint on the data type.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Expression object for sparse matrix-dense matrix Kronecker product.
Definition: SMatDMatKronExpr.h:93
ReturnType_t< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: SMatDMatKronExpr.h:99
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatDMatKronExpr.h:128
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatDMatKronExpr.h:229
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatDMatKronExpr.h:167
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatDMatKronExpr.h:276
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatDMatKronExpr.h:134
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatDMatKronExpr.h:131
LeftOperand lhs_
Left-hand side sparse matrix of the Kronecker product expression.
Definition: SMatDMatKronExpr.h:283
SMatDMatKronExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatDMatKronExpr class.
Definition: SMatDMatKronExpr.h:154
RightOperand rightOperand() const noexcept
Returns the right-hand side dense matrix operand.
Definition: SMatDMatKronExpr.h:252
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatDMatKronExpr.h:218
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatDMatKronExpr.h:242
RightOperand rhs_
Right-hand side dense matrix of the Kronecker product expression.
Definition: SMatDMatKronExpr.h:284
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatDMatKronExpr.h:264
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatDMatKronExpr.h:125
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatKronExpr.h:140
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatDMatKronExpr.h:96
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatDMatKronExpr.h:126
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatKronExpr.h:100
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatDMatKronExpr.h:182
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SMatDMatKronExpr.h:111
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatDMatKronExpr.h:208
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatDMatKronExpr.h:97
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatDMatKronExpr.h:127
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatDMatKronExpr.h:198
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: SMatDMatKronExpr.h:98
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatKronExpr.h:101
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SMatDMatKronExpr.h:114
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatKronExpr.h:137
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatDMatKronExpr.h:145
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the Computation base class.
Header file for the DenseMatrix 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_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.h:61
#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_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:61
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.
Definition: StorageOrder.h:63
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
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
#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.