Blaze 3.9
DMatDMatKronExpr.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_EXPRESSIONS_DMATDMATKRONEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_DMATDMATKRONEXPR_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <utility>
44#include <blaze/math/Aliases.h>
65#include <blaze/util/Assert.h>
67#include <blaze/util/mpl/If.h>
68#include <blaze/util/Types.h>
69
70
71namespace blaze {
72
73//=================================================================================================
74//
75// CLASS DMATDMATKRONEXPR
76//
77//=================================================================================================
78
79//*************************************************************************************************
86template< typename MT1 // Type of the left-hand side dense matrix
87 , typename MT2 // Type of the right-hand side dense matrix
88 , bool SO > // Storage order
90 : public MatMatKronExpr< DenseMatrix< DMatDMatKronExpr<MT1,MT2,SO>, SO > >
91 , private Computation
92{
93 private:
94 //**Type definitions****************************************************************************
103 //**********************************************************************************************
104
105 //**Return type evaluation**********************************************************************
107
112 static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
113
115 using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
116 //**********************************************************************************************
117
118 public:
119 //**Type definitions****************************************************************************
122
125
130
133
136
138 using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
139
141 using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
142 //**********************************************************************************************
143
144 //**Compilation flags***************************************************************************
146 static constexpr bool simdEnabled = false;
147
149 static constexpr bool smpAssignable = false;
150 //**********************************************************************************************
151
152 //**Constructor*********************************************************************************
158 inline DMatDMatKronExpr( const MT1& lhs, const MT2& rhs ) noexcept
159 : lhs_( lhs ) // Left-hand side dense matrix of the Kronecker product expression
160 , rhs_( rhs ) // Right-hand side dense matrix of the Kronecker product expression
161 {}
162 //**********************************************************************************************
163
164 //**Access operator*****************************************************************************
171 inline ReturnType operator()( size_t i, size_t j ) const {
172 BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
173 BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
174 return lhs_( i/rhs_.rows(), j/rhs_.columns() ) * rhs_( i%rhs_.rows(), j%rhs_.columns() );
175 }
176 //**********************************************************************************************
177
178 //**At function*********************************************************************************
186 inline ReturnType at( size_t i, size_t j ) const {
187 if( i >= rows() ) {
188 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
189 }
190 if( j >= columns() ) {
191 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
192 }
193 return (*this)(i,j);
194 }
195 //**********************************************************************************************
196
197 //**Rows function*******************************************************************************
202 inline size_t rows() const noexcept {
203 return lhs_.rows() * rhs_.rows();
204 }
205 //**********************************************************************************************
206
207 //**Columns function****************************************************************************
212 inline size_t columns() const noexcept {
213 return lhs_.columns() * rhs_.columns();
214 }
215 //**********************************************************************************************
216
217 //**Left operand access*************************************************************************
222 inline LeftOperand leftOperand() const noexcept {
223 return lhs_;
224 }
225 //**********************************************************************************************
226
227 //**Right operand access************************************************************************
232 inline RightOperand rightOperand() const noexcept {
233 return rhs_;
234 }
235 //**********************************************************************************************
236
237 //**********************************************************************************************
243 template< typename T >
244 inline bool canAlias( const T* alias ) const noexcept {
245 return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
246 }
247 //**********************************************************************************************
248
249 //**********************************************************************************************
255 template< typename T >
256 inline bool isAliased( const T* alias ) const noexcept {
257 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
258 }
259 //**********************************************************************************************
260
261 //**********************************************************************************************
266 inline bool isAligned() const noexcept {
267 return rhs_.isAligned();
268 }
269 //**********************************************************************************************
270
271 //**********************************************************************************************
276 inline bool canSMPAssign() const noexcept {
277 return false;
278 }
279 //**********************************************************************************************
280
281 private:
282 //**Member variables****************************************************************************
285 //**********************************************************************************************
286
287 //**Assignment to row-major dense matrices******************************************************
300 template< typename MT > // Type of the target dense matrix
301 friend inline void assign( DenseMatrix<MT,false>& lhs, const DMatDMatKronExpr& rhs )
302 {
304
305 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
306 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
307
308 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
309 return;
310 }
311
312 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
313 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
314
315 const size_t M( B.rows() );
316 const size_t N( B.columns() );
317
318 if( SO )
319 {
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);
326 }
327 else {
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) );
331 }
332 }
333 }
334 }
335 else
336 {
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);
343 }
344 else {
345 for( size_t l=0UL; l<N; ++l )
346 reset( (*lhs)(i*M+k,j*N+l) );
347 }
348 }
349 }
350 }
351 }
352 }
354 //**********************************************************************************************
355
356 //**Assignment to column-major dense matrices***************************************************
369 template< typename MT > // Type of the target dense matrix
370 friend inline void assign( DenseMatrix<MT,true>& lhs, const DMatDMatKronExpr& rhs )
371 {
373
374 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
375 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
376
377 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
378 return;
379 }
380
381 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
382 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
383
384 const size_t M( B.rows() );
385 const size_t N( B.columns() );
386
387 if( SO )
388 {
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);
395 }
396 else {
397 for( size_t k=0UL; k<M; ++k )
398 reset( (*lhs)(i*M+k,j*N+l) );
399 }
400 }
401 }
402 }
403 }
404 else
405 {
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);
412 }
413 else {
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) );
417 }
418 }
419 }
420 }
421 }
423 //**********************************************************************************************
424
425 //**Assignment to sparse matrices***************************************************************
437 template< typename MT // Type of the target sparse matrix
438 , bool SO2 > // Storage order of the target sparse matrix
439 friend inline void assign( SparseMatrix<MT,SO2>& lhs, const DMatDMatKronExpr& rhs )
440 {
442
443 using TmpType = If_t< SO == SO2, ResultType, OppositeType >;
444
451
452 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
453 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
454
455 const TmpType tmp( serial( rhs ) );
456 assign( *lhs, tmp );
457 }
459 //**********************************************************************************************
460
461 //**Addition assignment to row-major dense matrices*********************************************
474 template< typename MT > // Type of the target dense matrix
475 friend inline void addAssign( DenseMatrix<MT,false>& lhs, const DMatDMatKronExpr& rhs )
476 {
478
479 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
480 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
481
482 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
483 return;
484 }
485
486 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
487 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
488
489 const size_t M( B.rows() );
490 const size_t N( B.columns() );
491
492 if( SO )
493 {
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 )
498 {
499 const size_t kbegin( ( IsLower_v<MT2> )
500 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
501 :( 0UL ) );
502 const size_t kend( ( IsUpper_v<MT2> )
503 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
504 :( M ) );
505 BLAZE_INTERNAL_ASSERT( kbegin <= kend, "Invalid loop indices detected" );
506
507 for( size_t k=kbegin; k<kend; ++k )
508 (*lhs)(i*M+k,j*N+l) += A(i,j) * B(k,l);
509 }
510 }
511 else
512 {
513 for( size_t i=0UL; i<A.rows(); ++i )
514 for( size_t k=0UL; k<M; ++k )
515 {
516 const size_t lbegin( ( IsUpper_v<MT2> )
517 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
518 :( 0UL ) );
519 const size_t lend( ( IsLower_v<MT2> )
520 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
521 :( N ) );
522 BLAZE_INTERNAL_ASSERT( lbegin <= lend, "Invalid loop indices detected" );
523
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);
528 }
529 }
530 }
532 //**********************************************************************************************
533
534 //**Addition assignment to column-major dense matrices******************************************
547 template< typename MT > // Type of the target dense matrix
548 friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DMatDMatKronExpr& rhs )
549 {
551
552 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
553 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
554
555 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
556 return;
557 }
558
559 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
560 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
561
562 const size_t M( B.rows() );
563 const size_t N( B.columns() );
564
565 if( SO )
566 {
567 for( size_t j=0UL; j<A.columns(); ++j )
568 for( size_t l=0UL; l<N; ++l )
569 {
570 const size_t kbegin( ( IsLower_v<MT2> )
571 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
572 :( 0UL ) );
573 const size_t kend( ( IsUpper_v<MT2> )
574 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
575 :( M ) );
576 BLAZE_INTERNAL_ASSERT( kbegin <= kend, "Invalid loop indices detected" );
577
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);
582 }
583 }
584 else
585 {
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 )
590 {
591 const size_t lbegin( ( IsUpper_v<MT2> )
592 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
593 :( 0UL ) );
594 const size_t lend( ( IsLower_v<MT2> )
595 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
596 :( N ) );
597 BLAZE_INTERNAL_ASSERT( lbegin <= lend, "Invalid loop indices detected" );
598
599 for( size_t l=lbegin; l<lend; ++l )
600 (*lhs)(i*M+k,j*N+l) += A(i,j) * B(k,l);
601 }
602 }
603 }
605 //**********************************************************************************************
606
607 //**Addition assignment to sparse matrices******************************************************
608 // No special implementation for the addition assignment to sparse matrices.
609 //**********************************************************************************************
610
611 //**Subtraction assignment to row-major dense matrices******************************************
624 template< typename MT > // Type of the target dense matrix
625 friend inline void subAssign( DenseMatrix<MT,false>& lhs, const DMatDMatKronExpr& rhs )
626 {
628
629 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
630 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
631
632 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
633 return;
634 }
635
636 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
637 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
638
639 const size_t M( B.rows() );
640 const size_t N( B.columns() );
641
642 if( SO )
643 {
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 )
648 {
649 const size_t kbegin( ( IsLower_v<MT2> )
650 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
651 :( 0UL ) );
652 const size_t kend( ( IsUpper_v<MT2> )
653 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
654 :( M ) );
655 BLAZE_INTERNAL_ASSERT( kbegin <= kend, "Invalid loop indices detected" );
656
657 for( size_t k=kbegin; k<kend; ++k )
658 (*lhs)(i*M+k,j*N+l) -= A(i,j) * B(k,l);
659 }
660 }
661 else
662 {
663 for( size_t i=0UL; i<A.rows(); ++i )
664 for( size_t k=0UL; k<M; ++k )
665 {
666 const size_t lbegin( ( IsUpper_v<MT2> )
667 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
668 :( 0UL ) );
669 const size_t lend( ( IsLower_v<MT2> )
670 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
671 :( N ) );
672 BLAZE_INTERNAL_ASSERT( lbegin <= lend, "Invalid loop indices detected" );
673
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);
678 }
679 }
680 }
682 //**********************************************************************************************
683
684 //**Subtraction assignment to column-major dense matrices***************************************
697 template< typename MT > // Type of the target dense matrix
698 friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DMatDMatKronExpr& rhs )
699 {
701
702 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
703 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
704
705 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
706 return;
707 }
708
709 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
710 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
711
712 const size_t M( B.rows() );
713 const size_t N( B.columns() );
714
715 if( SO )
716 {
717 for( size_t j=0UL; j<A.columns(); ++j )
718 for( size_t l=0UL; l<N; ++l )
719 {
720 const size_t kbegin( ( IsLower_v<MT2> )
721 ?( ( IsStrictlyLower_v<MT2> ? l+1UL : l ) )
722 :( 0UL ) );
723 const size_t kend( ( IsUpper_v<MT2> )
724 ?( IsStrictlyUpper_v<MT2> ? l : l+1UL )
725 :( M ) );
726 BLAZE_INTERNAL_ASSERT( kbegin <= kend, "Invalid loop indices detected" );
727
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);
732 }
733 }
734 else
735 {
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 )
740 {
741 const size_t lbegin( ( IsUpper_v<MT2> )
742 ?( ( IsStrictlyUpper_v<MT2> ? k+1UL : k ) )
743 :( 0UL ) );
744 const size_t lend( ( IsLower_v<MT2> )
745 ?( IsStrictlyLower_v<MT2> ? k : k+1UL )
746 :( N ) );
747 BLAZE_INTERNAL_ASSERT( lbegin <= lend, "Invalid loop indices detected" );
748
749 for( size_t l=lbegin; l<lend; ++l )
750 (*lhs)(i*M+k,j*N+l) -= A(i,j) * B(k,l);
751 }
752 }
753 }
755 //**********************************************************************************************
756
757 //**Subtraction assignment to sparse matrices***************************************************
758 // No special implementation for the subtraction assignment to sparse matrices.
759 //**********************************************************************************************
760
761 //**Schur product assignment to row-major dense matrices****************************************
774 template< typename MT > // Type of the target dense matrix
775 friend inline void schurAssign( DenseMatrix<MT,false>& lhs, const DMatDMatKronExpr& rhs )
776 {
778
779 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
780 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
781
782 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
783 return;
784 }
785
786 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
787 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
788
789 const size_t M( B.rows() );
790 const size_t N( B.columns() );
791
792 if( SO )
793 {
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);
800 }
801 else {
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) );
805 }
806 }
807 }
808 }
809 else
810 {
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);
817 }
818 else {
819 for( size_t l=0UL; l<N; ++l )
820 reset( (*lhs)(i*M+k,j*N+l) );
821 }
822 }
823 }
824 }
825 }
826 }
828 //**********************************************************************************************
829
830 //**Schur product assignment to column-major dense matrices*************************************
843 template< typename MT > // Type of the target dense matrix
844 friend inline void schurAssign( DenseMatrix<MT,true>& lhs, const DMatDMatKronExpr& rhs )
845 {
847
848 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
849 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
850
851 if( rhs.rows() == 0UL || rhs.columns() == 0UL ) {
852 return;
853 }
854
855 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
856 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
857
858 const size_t M( B.rows() );
859 const size_t N( B.columns() );
860
861 if( SO )
862 {
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);
869 }
870 else {
871 for( size_t k=0UL; k<M; ++k )
872 reset( (*lhs)(i*M+k,j*N+l) );
873 }
874 }
875 }
876 }
877 }
878 else
879 {
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);
886 }
887 else {
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) );
891 }
892 }
893 }
894 }
895 }
897 //**********************************************************************************************
898
899 //**Schur product assignment to sparse matrices*************************************************
900 // No special implementation for the Schur product assignment to sparse matrices.
901 //**********************************************************************************************
902
903 //**Multiplication assignment to dense matrices*************************************************
904 // No special implementation for the multiplication assignment to dense matrices.
905 //**********************************************************************************************
906
907 //**Multiplication assignment to sparse matrices************************************************
908 // No special implementation for the multiplication assignment to sparse matrices.
909 //**********************************************************************************************
910
911 //**Compile time checks*************************************************************************
918 //**********************************************************************************************
919};
920//*************************************************************************************************
921
922
923
924
925//=================================================================================================
926//
927// GLOBAL FUNCTIONS
928//
929//=================================================================================================
930
931//*************************************************************************************************
952template< typename MT1 // Type of the left-hand side dense matrix
953 , bool SO1 // Storage order of the left-hand side dense matrix
954 , typename MT2 // Type of the right-hand side dense matrix
955 , bool SO2 > // Storage order of the right-hand side dense matrix
956inline decltype(auto)
958{
960
961 using ReturnType = const DMatDMatKronExpr<MT1,MT2,SO2>;
962 return ReturnType( *lhs, *rhs );
963}
964//*************************************************************************************************
965
966} // namespace blaze
967
968#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 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.