Blaze 3.9
TSMatTSMatSchurExpr.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATSCHUREXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATSCHUREXPR_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <utility>
44#include <blaze/math/Aliases.h>
71#include <blaze/util/Assert.h>
72#include <blaze/util/EnableIf.h>
76#include <blaze/util/mpl/If.h>
77#include <blaze/util/Types.h>
78
79
80namespace blaze {
81
82//=================================================================================================
83//
84// CLASS TSMATTSMATSCHUREXPR
85//
86//=================================================================================================
87
88//*************************************************************************************************
95template< typename MT1 // Type of the left-hand side sparse matrix
96 , typename MT2 > // Type of the right-hand side sparse matrix
98 : public SchurExpr< SparseMatrix< TSMatTSMatSchurExpr<MT1,MT2>, true > >
99 , private Computation
100{
101 private:
102 //**Type definitions****************************************************************************
109 //**********************************************************************************************
110
111 //**Return type evaluation**********************************************************************
113
118 static constexpr bool returnExpr = !IsTemporary_v<RN1> && !IsTemporary_v<RN2>;
119
121 using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
122 //**********************************************************************************************
123
124 //**Serial evaluation strategy******************************************************************
126
131 template< typename T1, typename T2, typename T3 >
132 static constexpr bool UseSymmetricKernel_v =
133 ( IsRowMajorMatrix_v<T1> && IsSymmetric_v<T2> && IsSymmetric_v<T3> );
135 //**********************************************************************************************
136
137 public:
138 //**Type definitions****************************************************************************
141
144
149
152
155
157 using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
158
160 using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
161 //**********************************************************************************************
162
163 //**Compilation flags***************************************************************************
165 static constexpr bool smpAssignable = false;
166 //**********************************************************************************************
167
168 //**Constructor*********************************************************************************
174 inline TSMatTSMatSchurExpr( const MT1& lhs, const MT2& rhs ) noexcept
175 : lhs_( lhs ) // Left-hand side sparse matrix of the Schur product expression
176 , rhs_( rhs ) // Right-hand side sparse matrix of the Schur product expression
177 {
178 BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
179 BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
180 }
181 //**********************************************************************************************
182
183 //**Access operator*****************************************************************************
190 inline ReturnType operator()( size_t i, size_t j ) const {
191 BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
192 BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
193 return lhs_(i,j) * rhs_(i,j);
194 }
195 //**********************************************************************************************
196
197 //**At function*********************************************************************************
205 inline ReturnType at( size_t i, size_t j ) const {
206 if( i >= lhs_.rows() ) {
207 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
208 }
209 if( j >= lhs_.columns() ) {
210 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
211 }
212 return (*this)(i,j);
213 }
214 //**********************************************************************************************
215
216 //**Rows function*******************************************************************************
221 inline size_t rows() const noexcept {
222 return lhs_.rows();
223 }
224 //**********************************************************************************************
225
226 //**Columns function****************************************************************************
231 inline size_t columns() const noexcept {
232 return lhs_.columns();
233 }
234 //**********************************************************************************************
235
236 //**NonZeros function***************************************************************************
241 inline size_t nonZeros() const {
242 return min( lhs_.nonZeros(), rhs_.nonZeros() );
243 }
244 //**********************************************************************************************
245
246 //**NonZeros function***************************************************************************
252 inline size_t nonZeros( size_t i ) const {
253 return min( lhs_.nonZeros(i), rhs_.nonZeros(i) );
254 }
255 //**********************************************************************************************
256
257 //**Left operand access*************************************************************************
262 inline LeftOperand leftOperand() const noexcept {
263 return lhs_;
264 }
265 //**********************************************************************************************
266
267 //**Right operand access************************************************************************
272 inline RightOperand rightOperand() const noexcept {
273 return rhs_;
274 }
275 //**********************************************************************************************
276
277 //**********************************************************************************************
283 template< typename T >
284 inline bool canAlias( const T* alias ) const noexcept {
285 return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
286 }
287 //**********************************************************************************************
288
289 //**********************************************************************************************
295 template< typename T >
296 inline bool isAliased( const T* alias ) const noexcept {
297 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
298 }
299 //**********************************************************************************************
300
301 private:
302 //**Member variables****************************************************************************
305 //**********************************************************************************************
306
307 //**Assignment to dense matrices****************************************************************
320 template< typename MT // Type of the target dense matrix
321 , bool SO > // Storage order of the target dense matrix
322 friend inline auto assign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
324 {
326
327 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
328 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
329
330 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
331 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
332
333 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
334 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
335 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
336 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
337 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
338 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
339
340 for( size_t j=0UL; j<(*lhs).columns(); ++j )
341 {
342 const auto lend( A.end(j) );
343 const auto rend( B.end(j) );
344
345 auto l( A.begin(j) );
346 auto r( B.begin(j) );
347
348 for( ; l!=lend; ++l ) {
349 while( r!=rend && r->index() < l->index() ) ++r;
350 if( r==rend ) break;
351 if( l->index() == r->index() ) {
352 (*lhs)(l->index(),j) = l->value() * r->value();
353 ++r;
354 }
355 }
356 }
357 }
359 //**********************************************************************************************
360
361 //**Assignment to row-major sparse matrices*****************************************************
374 template< typename MT > // Type of the target sparse matrix
375 friend inline auto assign( SparseMatrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
377 {
379
381
382 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
383 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
384
385 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
386 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
387
388 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
389 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
390 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
391 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
392 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
393 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
394
395 const size_t m( rhs.rows() );
396 const size_t n( rhs.columns() );
397
398 // Counting the number of elements per column
399 std::vector<size_t> nonzeros( m, 0UL );
400 for( size_t j=0UL; j<n; ++j )
401 {
402 const auto lend( A.end(j) );
403 const auto rend( B.end(j) );
404
405 auto l( A.begin(j) );
406 auto r( B.begin(j) );
407
408 for( ; l!=lend; ++l ) {
409 while( r!=rend && r->index() < l->index() ) ++r;
410 if( r==rend ) break;
411 if( l->index() == r->index() ) {
412 ++nonzeros[l->index()];
413 ++r;
414 }
415 }
416 }
417
418 // Resizing the left-hand side sparse matrix
419 for( size_t i=0UL; i<m; ++i ) {
420 (*lhs).reserve( i, nonzeros[i] );
421 }
422
423 // Performing the Schur product
424 for( size_t j=0UL; j<n; ++j )
425 {
426 const auto lend( A.end(j) );
427 const auto rend( B.end(j) );
428
429 auto l( A.begin(j) );
430 auto r( B.begin(j) );
431
432 for( ; l!=lend; ++l ) {
433 while( r!=rend && r->index() < l->index() ) ++r;
434 if( r==rend ) break;
435 if( l->index() == r->index() ) {
436 (*lhs).append( l->index(), j, l->value() * r->value() );
437 ++r;
438 }
439 }
440 }
441 }
443 //**********************************************************************************************
444
445 //**Assignment to column-major sparse matrices**************************************************
458 template< typename MT > // Type of the target sparse matrix
459 friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatTSMatSchurExpr& 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 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
467 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
468
469 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
470 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
471 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
472 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
473 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
474 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
475
476 // Final memory allocation (based on the evaluated operands)
477 (*lhs).reserve( min( A.nonZeros(), B.nonZeros() ) );
478
479 // Performing the Schur product
480 for( size_t j=0UL; j<(*lhs).columns(); ++j )
481 {
482 const auto lend( A.end(j) );
483 const auto rend( B.end(j) );
484
485 auto l( A.begin(j) );
486 auto r( B.begin(j) );
487
488 for( ; l!=lend; ++l ) {
489 while( r!=rend && r->index() < l->index() ) ++r;
490 if( r==rend ) break;
491 if( l->index() == r->index() ) {
492 (*lhs).append( l->index(), j, l->value() * r->value() );
493 ++r;
494 }
495 }
496
497 (*lhs).finalize( j );
498 }
499 }
501 //**********************************************************************************************
502
503 //**Restructuring assignment to row-major matrices**********************************************
516 template< typename MT > // Type of the target matrix
517 friend inline auto assign( Matrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
518 -> EnableIf_t< UseSymmetricKernel_v<MT,MT1,MT2> >
519 {
521
523
524 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
525 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
526
527 assign( *lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
528 }
530 //**********************************************************************************************
531
532 //**Addition assignment to dense matrices*******************************************************
545 template< typename MT // Type of the target dense matrix
546 , bool SO > // Storage order of the target dense matrix
547 friend inline auto addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
548 -> DisableIf_t< UseSymmetricKernel_v<MT,MT1,MT2> >
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 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
556 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
557
558 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
559 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
560 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
561 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
562 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
563 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
564
565 for( size_t j=0UL; j<(*lhs).columns(); ++j )
566 {
567 const auto lend( A.end(j) );
568 const auto rend( B.end(j) );
569
570 auto l( A.begin(j) );
571 auto r( B.begin(j) );
572
573 for( ; l!=lend; ++l ) {
574 while( r!=rend && r->index() < l->index() ) ++r;
575 if( r==rend ) break;
576 if( l->index() == r->index() ) {
577 (*lhs)(l->index(),j) += l->value() * r->value();
578 ++r;
579 }
580 }
581 }
582 }
584 //**********************************************************************************************
585
586 //**Restructuring addition assignment to row-major matrices*************************************
599 template< typename MT > // Type of the target matrix
600 friend inline auto addAssign( Matrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
601 -> EnableIf_t< UseSymmetricKernel_v<MT,MT1,MT2> >
602 {
604
606
607 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
608 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
609
610 addAssign( *lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
611 }
613 //**********************************************************************************************
614
615 //**Addition assignment to sparse matrices******************************************************
616 // No special implementation for the addition assignment to sparse matrices.
617 //**********************************************************************************************
618
619 //**Subtraction assignment to dense matrices****************************************************
632 template< typename MT // Type of the target dense matrix
633 , bool SO > // Storage order of the target dense matrix
634 friend inline auto subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
635 -> DisableIf_t< UseSymmetricKernel_v<MT,MT1,MT2> >
636 {
638
639 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
640 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
641
642 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
643 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
644
645 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
646 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
647 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
648 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
649 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
650 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
651
652 for( size_t j=0UL; j<(*lhs).columns(); ++j )
653 {
654 const auto lend( A.end(j) );
655 const auto rend( B.end(j) );
656
657 auto l( A.begin(j) );
658 auto r( B.begin(j) );
659
660 for( ; l!=lend; ++l ) {
661 while( r!=rend && r->index() < l->index() ) ++r;
662 if( r==rend ) break;
663 if( l->index() == r->index() ) {
664 (*lhs)(l->index(),j) -= l->value() * r->value();
665 ++r;
666 }
667 }
668 }
669 }
671 //**********************************************************************************************
672
673 //**Restructuring subtraction assignment to row-major matrices**********************************
686 template< typename MT > // Type of the target matrix
687 friend inline auto subAssign( Matrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
688 -> EnableIf_t< UseSymmetricKernel_v<MT,MT1,MT2> >
689 {
691
693
694 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
695 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
696
697 subAssign( *lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
698 }
700 //**********************************************************************************************
701
702 //**Subtraction assignment to sparse matrices***************************************************
703 // No special implementation for the subtraction assignment to sparse matrices.
704 //**********************************************************************************************
705
706 //**Schur product assignment to dense matrices**************************************************
719 template< typename MT // Type of the target dense matrix
720 , bool SO > // Storage order of the target dense matrix
721 friend inline auto schurAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
722 -> DisableIf_t< UseSymmetricKernel_v<MT,MT1,MT2> >
723 {
725
726 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
727 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
728
729 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
730 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
731
732 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
733 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
734 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
735 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
736 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
737 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
738
739 for( size_t j=0UL; j<(*lhs).columns(); ++j )
740 {
741 const auto lend( A.end(j) );
742 const auto rend( B.end(j) );
743
744 auto l( A.begin(j) );
745 auto r( B.begin(j) );
746
747 size_t i( 0UL );
748
749 for( ; l!=lend; ++l ) {
750 while( r!=rend && r->index() < l->index() ) ++r;
751 if( r==rend ) break;
752 if( l->index() == r->index() ) {
753 for( ; i<l->index(); ++i )
754 reset( (*lhs)(i,j) );
755 (*lhs)(l->index(),j) *= l->value() * r->value();
756 ++r;
757 ++i;
758 }
759 }
760
761 for( ; i<(*lhs).rows(); ++i )
762 reset( (*lhs)(i,j) );
763 }
764 }
766 //**********************************************************************************************
767
768 //**Restructuring Schur product assignment to row-major matrices********************************
781 template< typename MT > // Type of the target matrix
782 friend inline auto schurAssign( Matrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
783 -> EnableIf_t< UseSymmetricKernel_v<MT,MT1,MT2> >
784 {
786
788
789 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
790 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
791
792 schurAssign( *lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
793 }
795 //**********************************************************************************************
796
797 //**Schur product assignment to sparse matrices*************************************************
798 // No special implementation for the Schur product assignment to sparse matrices.
799 //**********************************************************************************************
800
801 //**Multiplication assignment to dense matrices*************************************************
802 // No special implementation for the multiplication assignment to dense matrices.
803 //**********************************************************************************************
804
805 //**Multiplication assignment to sparse matrices************************************************
806 // No special implementation for the multiplication assignment to sparse matrices.
807 //**********************************************************************************************
808
809 //**SMP assignment to dense matrices************************************************************
810 // No special implementation for the SMP assignment to dense matrices.
811 //**********************************************************************************************
812
813 //**SMP assignment to sparse matrices***********************************************************
814 // No special implementation for the SMP assignment to sparse matrices.
815 //**********************************************************************************************
816
817 //**SMP addition assignment to dense matrices***************************************************
818 // No special implementation for the SMP addition assignment to dense matrices.
819 //**********************************************************************************************
820
821 //**SMP addition assignment to sparse matrices**************************************************
822 // No special implementation for the SMP addition assignment to sparse matrices.
823 //**********************************************************************************************
824
825 //**SMP subtraction assignment to dense matrices************************************************
826 // No special implementation for the SMP subtraction assignment to dense matrices.
827 //**********************************************************************************************
828
829 //**SMP subtraction assignment to sparse matrices***********************************************
830 // No special implementation for the SMP subtraction assignment to sparse matrices.
831 //**********************************************************************************************
832
833 //**SMP Schur product assignment to dense matrices**********************************************
846 template< typename MT // Type of the target dense matrix
847 , bool SO > // Storage order of the target dense matrix
848 friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
849 {
851
852 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
853 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
854
855 smpSchurAssign( *lhs, rhs.lhs_ );
856 smpSchurAssign( *lhs, rhs.rhs_ );
857 }
859 //**********************************************************************************************
860
861 //**SMP Schur product assignment to sparse matrices*********************************************
862 // No special implementation for the SMP Schur product assignment to sparse matrices.
863 //**********************************************************************************************
864
865 //**SMP multiplication assignment to dense matrices*********************************************
866 // No special implementation for the SMP multiplication assignment to dense matrices.
867 //**********************************************************************************************
868
869 //**SMP multiplication assignment to sparse matrices********************************************
870 // No special implementation for the SMP multiplication assignment to sparse matrices.
871 //**********************************************************************************************
872
873 //**Compile time checks*************************************************************************
883 //**********************************************************************************************
884};
885//*************************************************************************************************
886
887
888
889
890//=================================================================================================
891//
892// GLOBAL BINARY ARITHMETIC OPERATORS
893//
894//=================================================================================================
895
896//*************************************************************************************************
908template< typename MT1 // Type of the left-hand side sparse matrix
909 , typename MT2 // Type of the right-hand side sparse matrix
910 , DisableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
911 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) ||
912 ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
913 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
914 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
915 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
916 ( IsZero_v<MT1> || IsZero_v<MT2> ) >* = nullptr >
917inline const TSMatTSMatSchurExpr<MT1,MT2>
919{
921
922 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
923 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
924
925 return TSMatTSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
926}
927//*************************************************************************************************
928
929
930//*************************************************************************************************
943template< typename MT1 // Type of the left-hand side sparse matrix
944 , typename MT2 // Type of the right-hand side sparse matrix
945 , EnableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
946 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) >* = nullptr >
947inline decltype(auto)
948 tsmattsmatschur( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
949{
951
952 MAYBE_UNUSED( rhs );
953
954 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
955 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
956
957 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
958
961
962 return ReturnType( (*lhs).rows() );
963}
965//*************************************************************************************************
966
967
968//*************************************************************************************************
981template< typename MT1 // Type of the left-hand side sparse matrix
982 , typename MT2 // Type of the right-hand side sparse matrix
983 , EnableIf_t< ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
984 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
985 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
986 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
987 ( IsZero_v<MT1> || IsZero_v<MT2> ) >* = nullptr >
988inline decltype(auto)
989 tsmattsmatschur( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
990{
992
993 MAYBE_UNUSED( rhs );
994
995 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
996 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
997
998 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
999
1002
1003 return ReturnType( (*lhs).rows(), (*lhs).columns() );
1004}
1006//*************************************************************************************************
1007
1008
1009//*************************************************************************************************
1035template< typename MT1 // Type of the left-hand side sparse matrix
1036 , typename MT2 > // Type of the right-hand side sparse matrix
1037inline decltype(auto)
1038 operator%( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
1039{
1041
1042 if( (*lhs).rows() != (*rhs).rows() || (*lhs).columns() != (*rhs).columns() ) {
1043 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1044 }
1045
1046 return tsmattsmatschur( *lhs, *rhs );
1047}
1048//*************************************************************************************************
1049
1050} // namespace blaze
1051
1052#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.
Constraints on the storage order of matrix types.
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 IntegralConstant class template.
Header file for the IsExpression type trait class.
Header file for the IsLower type trait.
Header file for the IsRowMajorMatrix type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Header file for the IsTemporary type trait class.
Header file for the IsUniLower type trait.
Header file for the IsUniUpper type trait.
Header file for the IsUpper type trait.
Header file for the MAYBE_UNUSED function template.
Header file for the Schur product trait.
Constraint on the data type.
Constraint on the data type.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Expression object for transpose sparse matrix-transpose sparse matrix Schur product.
Definition: TSMatTSMatSchurExpr.h:100
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatTSMatSchurExpr.h:231
LeftOperand lhs_
Left-hand side sparse matrix of the Schur product expression.
Definition: TSMatTSMatSchurExpr.h:303
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:157
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatTSMatSchurExpr.h:205
RightOperand rhs_
Right-hand side sparse matrix of the Schur product expression.
Definition: TSMatTSMatSchurExpr.h:304
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSMatTSMatSchurExpr.h:165
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatTSMatSchurExpr.h:284
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: TSMatTSMatSchurExpr.h:118
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTSMatSchurExpr.h:262
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatTSMatSchurExpr.h:221
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: TSMatTSMatSchurExpr.h:151
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:107
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTSMatSchurExpr.h:146
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: TSMatTSMatSchurExpr.h:121
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:104
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTSMatSchurExpr.h:154
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:160
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:103
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:108
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatTSMatSchurExpr.h:241
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatTSMatSchurExpr.h:252
SchurTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatTSMatSchurExpr.h:145
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTSMatSchurExpr.h:296
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:105
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTSMatSchurExpr.h:190
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:106
TSMatTSMatSchurExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatTSMatSchurExpr class.
Definition: TSMatTSMatSchurExpr.h:174
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTSMatSchurExpr.h:147
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSMatTSMatSchurExpr.h:148
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: TSMatTSMatSchurExpr.h:272
Constraint on the data type.
Constraint on the data type.
Header file for the Computation base class.
Header file for the SchurExpr base class.
Header file for the SparseMatrix base class.
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1339
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#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_BE_IDENTITY_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Identity.h:60
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_SCHUREXPR(T1, T2)
Constraint on the data type.
Definition: SchurExpr.h:103
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:61
typename SchurTrait< T1, T2 >::Type SchurTrait_t
Auxiliary alias declaration for the SchurTrait class template.
Definition: SchurTrait.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
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
const TSMatTSMatSchurExpr< MT1, MT2 > tsmattsmatschur(const SparseMatrix< MT1, true > &lhs, const SparseMatrix< MT2, true > &rhs)
Backend implementation of the Schur product between two column-major sparse matrices ( ).
Definition: TSMatTSMatSchurExpr.h:918
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
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_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
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.
Header file for all forward declarations for expression class templates.
Header file for all forward declarations for sparse vectors and matrices.
Header file for the serial shim.
Base class for all compute expression templates.
Definition: Computation.h:68
Base class for all Schur product expression templates.
Definition: SchurExpr.h:68
Header file for the IsZero type trait.
Header file for basic type definitions.
Header file for the generic min algorithm.