35#ifndef _BLAZE_MATH_EXPRESSIONS_DMATDMATKRONEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_DMATDMATKRONEXPR_H_
90 :
public MatMatKronExpr< DenseMatrix< DMatDMatKronExpr<MT1,MT2,SO>, SO > >
112 static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
202 inline size_t rows() const noexcept {
213 return lhs_.columns() *
rhs_.columns();
243 template<
typename T >
244 inline bool canAlias(
const T* alias )
const noexcept {
245 return (
lhs_.canAlias( alias ) ||
rhs_.canAlias( alias ) );
255 template<
typename T >
256 inline bool isAliased(
const T* alias )
const noexcept {
257 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
267 return rhs_.isAligned();
300 template<
typename MT >
315 const size_t M( B.rows() );
316 const size_t N( B.columns() );
320 for(
size_t i=0UL; i<A.rows(); ++i ) {
321 for(
size_t j=0UL; j<A.columns(); ++j ) {
322 if( !isDefault<strict>( A(i,j) ) ) {
323 for(
size_t l=0UL; l<N; ++l )
324 for(
size_t k=0UL; k<M; ++k )
325 (*lhs)(i*M+k,j*N+l) = A(i,j) * B(k,l);
328 for(
size_t l=0UL; l<N; ++l )
329 for(
size_t k=0UL; k<M; ++k )
330 reset( (*lhs)(i*M+k,j*N+l) );
337 for(
size_t i=0UL; i<A.rows(); ++i ) {
338 for(
size_t k=0UL; k<M; ++k ) {
339 for(
size_t j=0UL; j<A.columns(); ++j ) {
340 if( !isDefault<strict>( A(i,j) ) ) {
341 for(
size_t l=0UL; l<N; ++l )
342 (*lhs)(i*M+k,j*N+l) = A(i,j) * B(k,l);
345 for(
size_t l=0UL; l<N; ++l )
346 reset( (*lhs)(i*M+k,j*N+l) );
369 template<
typename MT >
384 const size_t M( B.rows() );
385 const size_t N( B.columns() );
389 for(
size_t j=0UL; j<A.columns(); ++j ) {
390 for(
size_t l=0UL; l<N; ++l ) {
391 for(
size_t i=0UL; i<A.rows(); ++i ) {
392 if( !isDefault<strict>( A(i,j) ) ) {
393 for(
size_t k=0UL; k<M; ++k )
394 (*lhs)(i*M+k,j*N+l) = A(i,j) * B(k,l);
397 for(
size_t k=0UL; k<M; ++k )
398 reset( (*lhs)(i*M+k,j*N+l) );
406 for(
size_t j=0UL; j<A.columns(); ++j ) {
407 for(
size_t i=0UL; i<A.rows(); ++i ) {
408 if( !isDefault<strict>( A(i,j) ) ) {
409 for(
size_t k=0UL; k<M; ++k )
410 for(
size_t l=0UL; l<N; ++l )
411 (*lhs)(i*M+k,j*N+l) = A(i,j) * B(k,l);
414 for(
size_t k=0UL; k<M; ++k )
415 for(
size_t l=0UL; l<N; ++l )
416 reset( (*lhs)(i*M+k,j*N+l) );
437 template<
typename MT
439 friend inline void assign( SparseMatrix<MT,SO2>& lhs,
const DMatDMatKronExpr& rhs )
443 using TmpType = If_t< SO == SO2, ResultType, OppositeType >;
455 const TmpType tmp(
serial( rhs ) );
474 template<
typename MT >
475 friend inline void addAssign( DenseMatrix<MT,false>& lhs,
const DMatDMatKronExpr& rhs )
482 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
489 const size_t M( B.rows() );
490 const size_t N( B.columns() );
494 for(
size_t i=0UL; i<A.rows(); ++i )
495 for(
size_t j=0UL; j<A.columns(); ++j )
496 if( !isDefault<strict>( A(i,j) ) )
497 for(
size_t l=0UL; l<N; ++l )
499 const size_t kbegin( ( IsLower_v<MT2> )
500 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
502 const size_t kend( ( IsUpper_v<MT2> )
503 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
507 for(
size_t k=kbegin; k<kend; ++k )
508 (*lhs)(i*M+k,j*N+l) += A(i,j) * B(k,l);
513 for(
size_t i=0UL; i<A.rows(); ++i )
514 for(
size_t k=0UL; k<M; ++k )
516 const size_t lbegin( ( IsUpper_v<MT2> )
517 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
519 const size_t lend( ( IsLower_v<MT2> )
520 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
524 for(
size_t j=0UL; j<A.columns(); ++j )
525 if( !isDefault<strict>( A(i,j) ) )
526 for(
size_t l=lbegin; l<lend; ++l )
527 (*lhs)(i*M+k,j*N+l) += A(i,j) * B(k,l);
547 template<
typename MT >
548 friend inline void addAssign( DenseMatrix<MT,true>& lhs,
const DMatDMatKronExpr& rhs )
555 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
562 const size_t M( B.rows() );
563 const size_t N( B.columns() );
567 for(
size_t j=0UL; j<A.columns(); ++j )
568 for(
size_t l=0UL; l<N; ++l )
570 const size_t kbegin( ( IsLower_v<MT2> )
571 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
573 const size_t kend( ( IsUpper_v<MT2> )
574 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
578 for(
size_t i=0UL; i<A.rows(); ++i )
579 if( !isDefault<strict>( A(i,j) ) )
580 for(
size_t k=kbegin; k<kend; ++k )
581 (*lhs)(i*M+k,j*N+l) += A(i,j) * B(k,l);
586 for(
size_t j=0UL; j<A.columns(); ++j )
587 for(
size_t i=0UL; i<A.rows(); ++i )
588 if( !isDefault<strict>( A(i,j) ) )
589 for(
size_t k=0UL; k<M; ++k )
591 const size_t lbegin( ( IsUpper_v<MT2> )
592 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
594 const size_t lend( ( IsLower_v<MT2> )
595 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
599 for(
size_t l=lbegin; l<lend; ++l )
600 (*lhs)(i*M+k,j*N+l) += A(i,j) * B(k,l);
624 template<
typename MT >
625 friend inline void subAssign( DenseMatrix<MT,false>& lhs,
const DMatDMatKronExpr& rhs )
632 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
639 const size_t M( B.rows() );
640 const size_t N( B.columns() );
644 for(
size_t i=0UL; i<A.rows(); ++i )
645 for(
size_t j=0UL; j<A.columns(); ++j )
646 if( !isDefault<strict>( A(i,j) ) )
647 for(
size_t l=0UL; l<N; ++l )
649 const size_t kbegin( ( IsLower_v<MT2> )
650 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
652 const size_t kend( ( IsUpper_v<MT2> )
653 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
657 for(
size_t k=kbegin; k<kend; ++k )
658 (*lhs)(i*M+k,j*N+l) -= A(i,j) * B(k,l);
663 for(
size_t i=0UL; i<A.rows(); ++i )
664 for(
size_t k=0UL; k<M; ++k )
666 const size_t lbegin( ( IsUpper_v<MT2> )
667 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
669 const size_t lend( ( IsLower_v<MT2> )
670 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
674 for(
size_t j=0UL; j<A.columns(); ++j )
675 if( !isDefault<strict>( A(i,j) ) )
676 for(
size_t l=lbegin; l<lend; ++l )
677 (*lhs)(i*M+k,j*N+l) -= A(i,j) * B(k,l);
697 template<
typename MT >
698 friend inline void subAssign( DenseMatrix<MT,true>& lhs,
const DMatDMatKronExpr& rhs )
705 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
712 const size_t M( B.rows() );
713 const size_t N( B.columns() );
717 for(
size_t j=0UL; j<A.columns(); ++j )
718 for(
size_t l=0UL; l<N; ++l )
720 const size_t kbegin( ( IsLower_v<MT2> )
721 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
723 const size_t kend( ( IsUpper_v<MT2> )
724 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
728 for(
size_t i=0UL; i<A.rows(); ++i )
729 if( !isDefault<strict>( A(i,j) ) )
730 for(
size_t k=kbegin; k<kend; ++k )
731 (*lhs)(i*M+k,j*N+l) -= A(i,j) * B(k,l);
736 for(
size_t j=0UL; j<A.columns(); ++j )
737 for(
size_t i=0UL; i<A.rows(); ++i )
738 if( !isDefault<strict>( A(i,j) ) )
739 for(
size_t k=0UL; k<M; ++k )
741 const size_t lbegin( ( IsUpper_v<MT2> )
742 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
744 const size_t lend( ( IsLower_v<MT2> )
745 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
749 for(
size_t l=lbegin; l<lend; ++l )
750 (*lhs)(i*M+k,j*N+l) -= A(i,j) * B(k,l);
774 template<
typename MT >
775 friend inline void schurAssign( DenseMatrix<MT,false>& lhs,
const DMatDMatKronExpr& rhs )
782 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
789 const size_t M( B.rows() );
790 const size_t N( B.columns() );
794 for(
size_t i=0UL; i<A.rows(); ++i ) {
795 for(
size_t j=0UL; j<A.columns(); ++j ) {
796 if( !isDefault<strict>( A(i,j) ) ) {
797 for(
size_t l=0UL; l<N; ++l )
798 for(
size_t k=0UL; k<M; ++k )
799 (*lhs)(i*M+k,j*N+l) *= A(i,j) * B(k,l);
802 for(
size_t l=0UL; l<N; ++l )
803 for(
size_t k=0UL; k<M; ++k )
804 reset( (*lhs)(i*M+k,j*N+l) );
811 for(
size_t i=0UL; i<A.rows(); ++i ) {
812 for(
size_t k=0UL; k<M; ++k ) {
813 for(
size_t j=0UL; j<A.columns(); ++j ) {
814 if( !isDefault<strict>( A(i,j) ) ) {
815 for(
size_t l=0UL; l<N; ++l )
816 (*lhs)(i*M+k,j*N+l) *= A(i,j) * B(k,l);
819 for(
size_t l=0UL; l<N; ++l )
820 reset( (*lhs)(i*M+k,j*N+l) );
843 template<
typename MT >
844 friend inline void schurAssign( DenseMatrix<MT,true>& lhs,
const DMatDMatKronExpr& rhs )
851 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
858 const size_t M( B.rows() );
859 const size_t N( B.columns() );
863 for(
size_t j=0UL; j<A.columns(); ++j ) {
864 for(
size_t l=0UL; l<N; ++l ) {
865 for(
size_t i=0UL; i<A.rows(); ++i ) {
866 if( !isDefault<strict>( A(i,j) ) ) {
867 for(
size_t k=0UL; k<M; ++k )
868 (*lhs)(i*M+k,j*N+l) *= A(i,j) * B(k,l);
871 for(
size_t k=0UL; k<M; ++k )
872 reset( (*lhs)(i*M+k,j*N+l) );
880 for(
size_t j=0UL; j<A.columns(); ++j ) {
881 for(
size_t i=0UL; i<A.rows(); ++i ) {
882 if( !isDefault<strict>( A(i,j) ) ) {
883 for(
size_t k=0UL; k<M; ++k )
884 for(
size_t l=0UL; l<N; ++l )
885 (*lhs)(i*M+k,j*N+l) *= A(i,j) * B(k,l);
888 for(
size_t k=0UL; k<M; ++k )
889 for(
size_t l=0UL; l<N; ++l )
890 reset( (*lhs)(i*M+k,j*N+l) );
952template<
typename MT1
962 return ReturnType( *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 the alignment flag enumeration.
Header file for run time assertion macros.
Header file for the function trace functionality.
Header file for the If class template.
Header file for the isDefault shim.
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.
Expression object for dense matrix-dense matrix Kronecker products.
Definition: DMatDMatKronExpr.h:92
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: DMatDMatKronExpr.h:112
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatDMatKronExpr.h:135
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DMatDMatKronExpr.h:126
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: DMatDMatKronExpr.h:146
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:100
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatDMatKronExpr.h:127
ElementType_t< MT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:101
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatDMatKronExpr.h:171
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatDMatKronExpr.h:276
CompositeType_t< MT1 > CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:99
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:96
ElementType_t< MT2 > ET2
Element type of the right-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:102
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:141
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DMatDMatKronExpr.h:132
LeftOperand lhs_
Left-hand side dense matrix of the Kronecker product expression.
Definition: DMatDMatKronExpr.h:283
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatDMatKronExpr.h:128
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: DMatDMatKronExpr.h:149
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatDMatKronExpr.h:266
ReturnType_t< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:98
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:138
RightOperand rhs_
Right-hand side dense matrix of the Kronecker product expression.
Definition: DMatDMatKronExpr.h:284
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DMatDMatKronExpr.h:212
RightOperand rightOperand() const noexcept
Returns the right-hand side dense matrix operand.
Definition: DMatDMatKronExpr.h:232
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DMatDMatKronExpr.h:186
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DMatDMatKronExpr.h:129
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DMatDMatKronExpr.h:202
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatDMatKronExpr.h:244
ReturnType_t< MT1 > RN1
Return type of the left-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:97
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: DMatDMatKronExpr.h:115
DMatDMatKronExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the DMatDMatKronExpr class.
Definition: DMatDMatKronExpr.h:158
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DMatDMatKronExpr.h:256
ResultType_t< MT1 > RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatDMatKronExpr.h:95
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense matrix operand.
Definition: DMatDMatKronExpr.h:222
Base class for dense matrices.
Definition: DenseMatrix.h:82
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.
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_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.
Definition: StorageOrder.h:84
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.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_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
#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 all forward declarations for expression class templates.
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 basic type definitions.