Blaze 3.9
DMatSMatSchurExpr.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_EXPRESSIONS_DMATSMATSCHUREXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_DMATSMATSCHUREXPR_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <iterator>
44#include <utility>
45#include <blaze/math/Aliases.h>
72#include <blaze/util/Assert.h>
73#include <blaze/util/EnableIf.h>
77#include <blaze/util/mpl/If.h>
78#include <blaze/util/mpl/Max.h>
79#include <blaze/util/Types.h>
81
82
83namespace blaze {
84
85//=================================================================================================
86//
87// CLASS DMATSMATSCHUREXPR
88//
89//=================================================================================================
90
91//*************************************************************************************************
98template< typename MT1 // Type of the left-hand side dense matrix
99 , typename MT2 > // Type of the right-hand side sparse matrix
100class DMatSMatSchurExpr
101 : public SchurExpr< SparseMatrix< DMatSMatSchurExpr<MT1,MT2>, false > >
102 , private Computation
103{
104 private:
105 //**Type definitions****************************************************************************
106 using RT1 = ResultType_t<MT1>;
107 using RT2 = ResultType_t<MT2>;
108 using RN1 = ReturnType_t<MT1>;
109 using RN2 = ReturnType_t<MT2>;
110 using CT1 = CompositeType_t<MT1>;
111 using CT2 = CompositeType_t<MT2>;
112 //**********************************************************************************************
113
114 //**Return type evaluation**********************************************************************
116
121 static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
122
124 using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
125 //**********************************************************************************************
126
127 //**Evaluation strategy*************************************************************************
129
135 static constexpr bool useAssign = ( RequiresEvaluation_v<MT1> || RequiresEvaluation_v<MT2> );
136
139 template< typename MT >
140 static constexpr bool UseAssign_v = useAssign;
142 //**********************************************************************************************
143
144 public:
145 //**Type definitions****************************************************************************
147 using This = DMatSMatSchurExpr<MT1,MT2>;
148
150 using BaseType = SchurExpr< SparseMatrix<This,false> >;
151
152 using ResultType = SchurTrait_t<RT1,RT2>;
153 using OppositeType = OppositeType_t<ResultType>;
154 using TransposeType = TransposeType_t<ResultType>;
155 using ElementType = ElementType_t<ResultType>;
156
158 using ReturnType = const If_t< returnExpr, ExprReturnType, ElementType >;
159
161 using CompositeType = If_t< useAssign, const ResultType, const DMatSMatSchurExpr& >;
162
164 using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
165
167 using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
168 //**********************************************************************************************
169
170 //**ConstIterator class definition**************************************************************
173 class ConstIterator
174 {
175 public:
176 //**Type definitions*************************************************************************
178 using Element = ValueIndexPair<ElementType>;
179
181 using RightIterator = ConstIterator_t< RemoveReference_t<RightOperand> >;
182
183 using IteratorCategory = std::forward_iterator_tag;
184 using ValueType = Element;
185 using PointerType = ValueType*;
186 using ReferenceType = ValueType&;
187 using DifferenceType = ptrdiff_t;
188
189 // STL iterator requirements
190 using iterator_category = IteratorCategory;
191 using value_type = ValueType;
192 using pointer = PointerType;
193 using reference = ReferenceType;
194 using difference_type = DifferenceType;
195 //*******************************************************************************************
196
197 //**Constructor******************************************************************************
204 inline ConstIterator( LeftOperand left, RightIterator right, size_t row )
205 : left_ ( left ) // Left-hand side dense matrix expression
206 , right_( right ) // Iterator over the elements of the right-hand side sparse matrix expression
207 , row_ ( row ) // The row index of the iterator
208 {}
209 //*******************************************************************************************
210
211 //**Prefix increment operator****************************************************************
216 inline ConstIterator& operator++() {
217 ++right_;
218 return *this;
219 }
220 //*******************************************************************************************
221
222 //**Element access operator******************************************************************
227 inline const Element operator*() const {
228 return Element( left_(row_,right_->index()) * right_->value(), right_->index() );
229 }
230 //*******************************************************************************************
231
232 //**Element access operator******************************************************************
237 inline const ConstIterator* operator->() const {
238 return this;
239 }
240 //*******************************************************************************************
241
242 //**Value function***************************************************************************
247 inline ReturnType value() const {
248 return left_(row_,right_->index()) * right_->value();
249 }
250 //*******************************************************************************************
251
252 //**Index function***************************************************************************
257 inline size_t index() const {
258 return right_->index();
259 }
260 //*******************************************************************************************
261
262 //**Equality operator************************************************************************
268 inline bool operator==( const ConstIterator& rhs ) const {
269 return right_ == rhs.right_;
270 }
271 //*******************************************************************************************
272
273 //**Inequality operator**********************************************************************
279 inline bool operator!=( const ConstIterator& rhs ) const {
280 return right_ != rhs.right_;
281 }
282 //*******************************************************************************************
283
284 //**Subtraction operator*********************************************************************
290 inline DifferenceType operator-( const ConstIterator& rhs ) const {
291 return right_ - rhs.right_;
292 }
293 //*******************************************************************************************
294
295 private:
296 //**Member variables*************************************************************************
297 LeftOperand left_;
298 RightIterator right_;
299 size_t row_;
300 //*******************************************************************************************
301 };
302 //**********************************************************************************************
303
304 //**Compilation flags***************************************************************************
306 static constexpr bool smpAssignable = false;
307 //**********************************************************************************************
308
309 //**Constructor*********************************************************************************
315 inline DMatSMatSchurExpr( const MT1& lhs, const MT2& rhs ) noexcept
316 : lhs_( lhs ) // Left-hand side dense matrix of the Schur product expression
317 , rhs_( rhs ) // Right-hand side sparse matrix of the Schur product expression
318 {
319 BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
320 BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
321 }
322 //**********************************************************************************************
323
324 //**Access operator*****************************************************************************
331 inline ReturnType operator()( size_t i, size_t j ) const {
332 BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
333 BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
334 return lhs_(i,j) * rhs_(i,j);
335 }
336 //**********************************************************************************************
337
338 //**At function*********************************************************************************
346 inline ReturnType at( size_t i, size_t j ) const {
347 if( i >= lhs_.rows() ) {
348 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
349 }
350 if( j >= lhs_.columns() ) {
351 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
352 }
353 return (*this)(i,j);
354 }
355 //**********************************************************************************************
356
357 //**Begin function******************************************************************************
363 inline ConstIterator begin( size_t i ) const {
364 return ConstIterator( lhs_, rhs_.begin(i), i );
365 }
366 //**********************************************************************************************
367
368 //**End function********************************************************************************
374 inline ConstIterator end( size_t i ) const {
375 return ConstIterator( lhs_, rhs_.end(i), i );
376 }
377 //**********************************************************************************************
378
379 //**Rows function*******************************************************************************
384 inline size_t rows() const noexcept {
385 return lhs_.rows();
386 }
387 //**********************************************************************************************
388
389 //**Columns function****************************************************************************
394 inline size_t columns() const noexcept {
395 return lhs_.columns();
396 }
397 //**********************************************************************************************
398
399 //**NonZeros function***************************************************************************
404 inline size_t nonZeros() const {
405 return rhs_.nonZeros();
406 }
407 //**********************************************************************************************
408
409 //**NonZeros function***************************************************************************
415 inline size_t nonZeros( size_t i ) const {
416 return rhs_.nonZeros(i);
417 }
418 //**********************************************************************************************
419
420 //**Find function*******************************************************************************
427 inline ConstIterator find( size_t i, size_t j ) const {
429 return ConstIterator( lhs_, rhs_.find( i, j ), i );
430 }
431 //**********************************************************************************************
432
433 //**LowerBound function*************************************************************************
440 inline ConstIterator lowerBound( size_t i, size_t j ) const {
442 return ConstIterator( lhs_, rhs_.lowerBound( i, j ), i );
443 }
444 //**********************************************************************************************
445
446 //**UpperBound function*************************************************************************
453 inline ConstIterator upperBound( size_t i, size_t j ) const {
455 return ConstIterator( lhs_, rhs_.upperBound( i, j ), i );
456 }
457 //**********************************************************************************************
458
459 //**Left operand access*************************************************************************
464 inline LeftOperand leftOperand() const noexcept {
465 return lhs_;
466 }
467 //**********************************************************************************************
468
469 //**Right operand access************************************************************************
474 inline RightOperand rightOperand() const noexcept {
475 return rhs_;
476 }
477 //**********************************************************************************************
478
479 //**********************************************************************************************
485 template< typename T >
486 inline bool canAlias( const T* alias ) const noexcept {
487 return ( lhs_.isAliased( alias ) || rhs_.canAlias( alias ) );
488 }
489 //**********************************************************************************************
490
491 //**********************************************************************************************
497 template< typename T >
498 inline bool isAliased( const T* alias ) const noexcept {
499 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
500 }
501 //**********************************************************************************************
502
503 private:
504 //**Member variables****************************************************************************
505 LeftOperand lhs_;
506 RightOperand rhs_;
507 //**********************************************************************************************
508
509 //**Assignment to dense matrices****************************************************************
521 template< typename MT // Type of the target dense matrix
522 , bool SO2 > // Storage order of the target dense matrix
523 friend inline auto assign( DenseMatrix<MT,SO2>& lhs, const DMatSMatSchurExpr& rhs )
524 -> EnableIf_t< UseAssign_v<MT> >
525 {
527
528 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
529 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
530
531 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
532 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
533
534 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
535 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
536 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
537 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
538 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
539 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
540
541 for( size_t i=0UL; i<(*lhs).rows(); ++i ) {
542 for( auto element=B.begin(i); element!=B.end(i); ++element )
543 (*lhs)(i,element->index()) = A(i,element->index()) * element->value();
544 }
545 }
547 //**********************************************************************************************
548
549 //**Assignment to row-major sparse matrices*****************************************************
561 template< typename MT > // Type of the target sparse matrix
562 friend inline auto assign( SparseMatrix<MT,false>& lhs, const DMatSMatSchurExpr& rhs )
563 -> EnableIf_t< UseAssign_v<MT> >
564 {
566
567 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
568 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
569
570 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
571 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
572
573 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
574 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
575 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
576 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
577 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
578 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
579
580 // Final memory allocation (based on the evaluated operands)
581 (*lhs).reserve( B.nonZeros() );
582
583 // Performing the Schur product
584 for( size_t i=0UL; i<(*lhs).rows(); ++i ) {
585 for( auto element=B.begin(i); element!=B.end(i); ++element )
586 (*lhs).append( i, element->index(), A(i,element->index()) * element->value() );
587 (*lhs).finalize( i );
588 }
589 }
591 //**********************************************************************************************
592
593 //**Assignment to column-major sparse matrices**************************************************
606 template< typename MT > // Type of the target sparse matrix
607 friend inline auto assign( SparseMatrix<MT,true>& lhs, const DMatSMatSchurExpr& rhs )
608 -> EnableIf_t< UseAssign_v<MT> >
609 {
611
612 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
613 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
614
615 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
616 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
617
618 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
619 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
620 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
621 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
622 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
623 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
624
625 const size_t m( rhs.rows() );
626 const size_t n( rhs.columns() );
627
628 // Counting the number of elements per column
629 std::vector<size_t> nonzeros( n, 0UL );
630 for( size_t i=0UL; i<m; ++i ) {
631 const auto lend( B.end(i) );
632 for( auto l=B.begin(i); l!=lend; ++l ) {
633 ++nonzeros[l->index()];
634 }
635 }
636
637 // Resizing the left-hand side sparse matrix
638 for( size_t j=0UL; j<n; ++j ) {
639 (*lhs).reserve( j, nonzeros[j] );
640 }
641
642 // Performing the Schur product
643 for( size_t i=0UL; i<(*lhs).rows(); ++i ) {
644 for( auto element=B.begin(i); element!=B.end(i); ++element )
645 (*lhs).append( i, element->index(), A(i,element->index()) * element->value() );
646 }
647 }
649 //**********************************************************************************************
650
651 //**Addition assignment to dense matrices*******************************************************
663 template< typename MT // Type of the target dense matrix
664 , bool SO2 > // Storage order of the target dense matrix
665 friend inline auto addAssign( DenseMatrix<MT,SO2>& lhs, const DMatSMatSchurExpr& rhs )
666 -> EnableIf_t< UseAssign_v<MT> >
667 {
669
670 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
671 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
672
673 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
674 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
675
676 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
677 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
678 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
679 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
680 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
681 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
682
683 for( size_t i=0UL; i<(*lhs).rows(); ++i ) {
684 for( auto element=B.begin(i); element!=B.end(i); ++element )
685 (*lhs)(i,element->index()) += A(i,element->index()) * element->value();
686 }
687 }
689 //**********************************************************************************************
690
691 //**Addition assignment to sparse matrices******************************************************
692 // No special implementation for the addition assignment to sparse matrices.
693 //**********************************************************************************************
694
695 //**Subtraction assignment to dense matrices****************************************************
707 template< typename MT // Type of the target dense matrix
708 , bool SO2 > // Storage order of the target dense matrix
709 friend inline auto subAssign( DenseMatrix<MT,SO2>& lhs, const DMatSMatSchurExpr& rhs )
710 -> EnableIf_t< UseAssign_v<MT> >
711 {
713
714 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
715 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
716
717 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
718 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
719
720 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
721 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
722 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
723 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
724 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
725 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
726
727 for( size_t i=0UL; i<(*lhs).rows(); ++i ) {
728 for( auto element=B.begin(i); element!=B.end(i); ++element )
729 (*lhs)(i,element->index()) -= A(i,element->index()) * element->value();
730 }
731 }
733 //**********************************************************************************************
734
735 //**Subtraction assignment to sparse matrices***************************************************
736 // No special implementation for the subtraction assignment to sparse matrices.
737 //**********************************************************************************************
738
739 //**Schur product assignment to dense matrices**************************************************
752 template< typename MT // Type of the target dense matrix
753 , bool SO2 > // Storage order of the target dense matrix
754 friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs, const DMatSMatSchurExpr& rhs )
755 {
757
758 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
759 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
760
761 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
762 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
763
764 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
765 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
766 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
767 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
768 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
769 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
770
771 for( size_t i=0UL; i<(*lhs).rows(); ++i )
772 {
773 const auto end( B.end(i) );
774 auto begin( B.begin(i) );
775 size_t j( 0UL );
776
777 for( ; begin!=end; ++begin ) {
778 const size_t index( begin->index() );
779 for( ; j<index; ++j )
780 reset( (*lhs)(i,j) );
781 (*lhs)(i,index) *= A(i,index) * begin->value();
782 ++j;
783 }
784
785 for( ; j<(*lhs).columns(); ++j )
786 reset( (*lhs)(i,j) );
787 }
788 }
790 //**********************************************************************************************
791
792 //**Schur product assignment to sparse matrices*************************************************
793 // No special implementation for the Schur product assignment to sparse matrices.
794 //**********************************************************************************************
795
796 //**Multiplication assignment to dense matrices*************************************************
797 // No special implementation for the multiplication assignment to dense matrices.
798 //**********************************************************************************************
799
800 //**Multiplication assignment to sparse matrices************************************************
801 // No special implementation for the multiplication assignment to sparse matrices.
802 //**********************************************************************************************
803
804 //**SMP assignment to dense matrices************************************************************
805 // No special implementation for the SMP assignment to dense matrices.
806 //**********************************************************************************************
807
808 //**SMP assignment to sparse matrices***********************************************************
809 // No special implementation for the SMP assignment to sparse matrices.
810 //**********************************************************************************************
811
812 //**SMP addition assignment to dense matrices***************************************************
813 // No special implementation for the SMP addition assignment to dense matrices.
814 //**********************************************************************************************
815
816 //**SMP addition assignment to sparse matrices**************************************************
817 // No special implementation for the SMP addition assignment to sparse matrices.
818 //**********************************************************************************************
819
820 //**SMP subtraction assignment to dense matrices************************************************
821 // No special implementation for the SMP subtraction assignment to dense matrices.
822 //**********************************************************************************************
823
824 //**SMP subtraction assignment to sparse matrices***********************************************
825 // No special implementation for the SMP subtraction assignment to sparse matrices.
826 //**********************************************************************************************
827
828 //**SMP Schur product assignment to dense matrices**********************************************
841 template< typename MT // Type of the target dense matrix
842 , bool SO > // Storage order of the target dense matrix
843 friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs, const DMatSMatSchurExpr& rhs )
844 {
846
847 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
848 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
849
850 smpSchurAssign( *lhs, rhs.lhs_ );
851 smpSchurAssign( *lhs, rhs.rhs_ );
852 }
854 //**********************************************************************************************
855
856 //**SMP Schur product assignment to sparse matrices*********************************************
857 // No special implementation for the SMP Schur product assignment to sparse matrices.
858 //**********************************************************************************************
859
860 //**SMP multiplication assignment to dense matrices*********************************************
861 // No special implementation for the SMP multiplication assignment to dense matrices.
862 //**********************************************************************************************
863
864 //**SMP multiplication assignment to sparse matrices********************************************
865 // No special implementation for the SMP multiplication assignment to sparse matrices.
866 //**********************************************************************************************
867
868 //**Compile time checks*************************************************************************
876 //**********************************************************************************************
877};
878//*************************************************************************************************
879
880
881
882
883//=================================================================================================
884//
885// GLOBAL BINARY ARITHMETIC OPERATORS
886//
887//=================================================================================================
888
889//*************************************************************************************************
902template< typename MT1 // Type of the left-hand side dense matrix
903 , typename MT2 // Type of the right-hand side sparse matrix
904 , DisableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
905 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) ||
906 ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
907 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
908 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
909 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
910 IsZero_v<MT2> >* = nullptr >
911inline const DMatSMatSchurExpr<MT1,MT2>
912 dmatsmatschur( const DenseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
913{
915
916 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
917 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
918
919 return DMatSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
920}
922//*************************************************************************************************
923
924
925//*************************************************************************************************
939template< typename MT1 // Type of the left-hand side dense matrix
940 , typename MT2 // Type of the right-hand side sparse matrix
941 , EnableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
942 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) >* = nullptr >
943inline decltype(auto)
944 dmatsmatschur( const DenseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
945{
947
948 MAYBE_UNUSED( rhs );
949
950 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
951 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
952
953 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
954
957
958 return ReturnType( (*lhs).rows() );
959}
961//*************************************************************************************************
962
963
964//*************************************************************************************************
978template< typename MT1 // Type of the left-hand side dense matrix
979 , typename MT2 // Type of the right-hand side sparse matrix
980 , EnableIf_t< ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
981 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
982 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
983 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
984 IsZero_v<MT2> >* = nullptr >
985inline decltype(auto)
986 dmatsmatschur( const DenseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
987{
989
990 MAYBE_UNUSED( rhs );
991
992 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
993 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
994
995 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
996
999
1000 return ReturnType( (*lhs).rows(), (*lhs).columns() );
1001}
1003//*************************************************************************************************
1004
1005
1006//*************************************************************************************************
1035template< typename MT1 // Type of the left-hand side dense matrix
1036 , typename MT2 > // Type of the right-hand side sparse matrix
1037inline decltype(auto)
1038 operator%( const DenseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& 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 dmatsmatschur( *lhs, *rhs );
1047}
1048//*************************************************************************************************
1049
1050
1051//*************************************************************************************************
1064template< typename MT1 // Type of the left-hand side dense matrix
1065 , typename MT2 // Type of the right-hand side sparse matrix
1066 , DisableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
1067 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) ||
1068 ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
1069 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
1070 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
1071 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
1072 IsZero_v<MT2> >* = nullptr >
1073inline const DMatSMatSchurExpr<MT1,MT2>
1074 tdmatsmatschur( const DenseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
1075{
1077
1078 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
1079 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
1080
1081 return DMatSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
1082}
1083//*************************************************************************************************
1084
1085
1086//*************************************************************************************************
1100template< typename MT1 // Type of the left-hand side dense matrix
1101 , typename MT2 // Type of the right-hand side sparse matrix
1102 , EnableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
1103 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) >* = nullptr >
1104inline decltype(auto)
1105 tdmatsmatschur( const DenseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
1106{
1108
1109 MAYBE_UNUSED( rhs );
1110
1111 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
1112 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
1113
1114 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1115
1118
1119 return ReturnType( (*lhs).rows() );
1120}
1122//*************************************************************************************************
1123
1124
1125//*************************************************************************************************
1139template< typename MT1 // Type of the left-hand side dense matrix
1140 , typename MT2 // Type of the right-hand side sparse matrix
1141 , EnableIf_t< ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
1142 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
1143 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
1144 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
1145 IsZero_v<MT2> >* = nullptr >
1146inline decltype(auto)
1147 tdmatsmatschur( const DenseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
1148{
1150
1151 MAYBE_UNUSED( rhs );
1152
1153 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
1154 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
1155
1156 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1157
1160
1161 return ReturnType( (*lhs).rows(), (*lhs).columns() );
1162}
1164//*************************************************************************************************
1165
1166
1167//*************************************************************************************************
1197template< typename MT1 // Type of the left-hand side dense matrix
1198 , typename MT2 > // Type of the right-hand side sparse matrix
1199inline decltype(auto)
1200 operator%( const DenseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
1201{
1203
1204 if( (*lhs).rows() != (*rhs).rows() || (*lhs).columns() != (*rhs).columns() ) {
1205 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1206 }
1207
1208 return tdmatsmatschur( *lhs, *rhs );
1209}
1210//*************************************************************************************************
1211
1212
1213
1214
1215//=================================================================================================
1216//
1217// SIZE SPECIALIZATIONS
1218//
1219//=================================================================================================
1220
1221//*************************************************************************************************
1223template< typename MT1, typename MT2 >
1224struct Size< DMatSMatSchurExpr<MT1,MT2>, 0UL >
1225 : public Max_t< Size<MT1,0UL>, Size<MT2,0UL> >
1226{};
1227
1228template< typename MT1, typename MT2 >
1229struct Size< DMatSMatSchurExpr<MT1,MT2>, 1UL >
1230 : public Max_t< Size<MT1,1UL>, Size<MT2,1UL> >
1231{};
1233//*************************************************************************************************
1234
1235} // namespace blaze
1236
1237#endif
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:751
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 IsStrictlyLower type trait.
Header file for the IsStrictlyUpper 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 RemoveReference type trait.
Constraints on the storage order of matrix types.
Header file for the Schur product trait.
Header file for the ValueIndexPair class.
Constraint on the data type.
Pointer difference type of the Blaze library.
Constraint on the data type.
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 SchurExpr 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) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9640
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#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_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_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:61
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
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
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
If_t< Less_t< T1, T2 >::value, T2, T1 > Max_t
Compile time value evaluation.
Definition: Max.h:73
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:137
#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
MT::Iterator upperBound(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Returns an iterator to the first index greater than the given index.
Definition: SparseMatrix.h:244
MT::Iterator lowerBound(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Returns an iterator to the first index not less than the given index.
Definition: SparseMatrix.h:194
MT::Iterator find(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Searches for a specific matrix element.
Definition: SparseMatrix.h:144
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
#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 Size type trait.
Header file for the serial shim.
Header file for the IsZero type trait.
Header file for basic type definitions.
Header file for the Max_t alias template.