Blaze 3.9
DMatTSMatSchurExpr.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_EXPRESSIONS_DMATTSMATSCHUREXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_DMATTSMATSCHUREXPR_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 DMATTSMATSCHUREXPR
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 DMatTSMatSchurExpr
101 : public SchurExpr< SparseMatrix< DMatTSMatSchurExpr<MT1,MT2>, true > >
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 = DMatTSMatSchurExpr<MT1,MT2>;
148
150 using BaseType = SchurExpr< SparseMatrix<This,true> >;
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 DMatTSMatSchurExpr& >;
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 column )
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 , col_ ( column ) // The column 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_(right_->index(),col_) * 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_(right_->index(),col_) * 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 col_;
300 //*******************************************************************************************
301 };
302 //**********************************************************************************************
303
304 //**Compilation flags***************************************************************************
306 static constexpr bool smpAssignable = false;
307 //**********************************************************************************************
308
309 //**Constructor*********************************************************************************
315 inline DMatTSMatSchurExpr( 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 j ) const {
364 return ConstIterator( lhs_, rhs_.begin(j), j );
365 }
366 //**********************************************************************************************
367
368 //**End function********************************************************************************
374 inline ConstIterator end( size_t j ) const {
375 return ConstIterator( lhs_, rhs_.end(j), j );
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 j ) const {
416 return rhs_.nonZeros(j);
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 ), j );
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 ), j );
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 ), j );
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 DMatTSMatSchurExpr& 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 j=0UL; j<(*lhs).columns(); ++j ) {
542 for( auto element=B.begin(j); element!=B.end(j); ++element )
543 (*lhs)(element->index(),j) = A(element->index(),j) * element->value();
544 }
545 }
547 //**********************************************************************************************
548
549 //**Assignment to row-major sparse matrices*****************************************************
562 template< typename MT > // Type of the target sparse matrix
563 friend inline auto assign( SparseMatrix<MT,false>& lhs, const DMatTSMatSchurExpr& rhs )
564 -> EnableIf_t< UseAssign_v<MT> >
565 {
567
568 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
569 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
570
571 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
572 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
573
574 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
575 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
576 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
577 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
578 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
579 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
580
581 const size_t m( rhs.rows() );
582 const size_t n( rhs.columns() );
583
584 // Counting the number of elements per column
585 std::vector<size_t> nonzeros( m, 0UL );
586 for( size_t j=0UL; j<n; ++j ) {
587 const auto lend( B.end(j) );
588 for( auto l=B.begin(j); l!=lend; ++l ) {
589 ++nonzeros[l->index()];
590 }
591 }
592
593 // Resizing the left-hand side sparse matrix
594 for( size_t i=0UL; i<m; ++i ) {
595 (*lhs).reserve( i, nonzeros[i] );
596 }
597
598 // Performing the Schur product
599 for( size_t j=0UL; j<(*lhs).columns(); ++j ) {
600 for( auto element=B.begin(j); element!=B.end(j); ++element )
601 (*lhs).append( element->index(), j, A(element->index(),j) * element->value() );
602 }
603 }
605 //**********************************************************************************************
606
607 //**Assignment to column-major sparse matrices**************************************************
620 template< typename MT > // Type of the target sparse matrix
621 friend inline auto assign( SparseMatrix<MT,true>& lhs, const DMatTSMatSchurExpr& rhs )
622 -> EnableIf_t< UseAssign_v<MT> >
623 {
625
626 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
627 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
628
629 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
630 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
631
632 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
633 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
634 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
635 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
636 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
637 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
638
639 // Final memory allocation (based on the evaluated operands)
640 (*lhs).reserve( B.nonZeros() );
641
642 // Performing the Schur product
643 for( size_t j=0UL; j<(*lhs).columns(); ++j ) {
644 for( auto element=B.begin(j); element!=B.end(j); ++element )
645 (*lhs).append( element->index(), j, A(element->index(),j) * element->value() );
646 (*lhs).finalize( j );
647 }
648 }
650 //**********************************************************************************************
651
652 //**Addition assignment to dense matrices*******************************************************
665 template< typename MT // Type of the target dense matrix
666 , bool SO2 > // Storage order of the target dense matrix
667 friend inline auto addAssign( DenseMatrix<MT,SO2>& lhs, const DMatTSMatSchurExpr& rhs )
668 -> EnableIf_t< UseAssign_v<MT> >
669 {
671
672 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
673 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
674
675 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
676 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
677
678 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
679 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
680 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
681 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
682 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
683 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
684
685 for( size_t j=0UL; j<(*lhs).columns(); ++j ) {
686 for( auto element=B.begin(j); element!=B.end(j); ++element )
687 (*lhs)(element->index(),j) += A(element->index(),j) * element->value();
688 }
689 }
691 //**********************************************************************************************
692
693 //**Addition assignment to sparse matrices******************************************************
694 // No special implementation for the addition assignment to sparse matrices.
695 //**********************************************************************************************
696
697 //**Subtraction assignment to dense matrices****************************************************
710 template< typename MT // Type of the target dense matrix
711 , bool SO2 > // Storage order of the target dense matrix
712 friend inline auto subAssign( DenseMatrix<MT,SO2>& lhs, const DMatTSMatSchurExpr& rhs )
713 -> EnableIf_t< UseAssign_v<MT> >
714 {
716
717 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
718 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
719
720 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
721 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
722
723 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
724 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
725 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
726 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
727 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
728 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
729
730 for( size_t j=0UL; j<(*lhs).columns(); ++j ) {
731 for( auto element=B.begin(j); element!=B.end(j); ++element )
732 (*lhs)(element->index(),j) -= A(element->index(),j) * element->value();
733 }
734 }
736 //**********************************************************************************************
737
738 //**Subtraction assignment to sparse matrices***************************************************
739 // No special implementation for the subtraction assignment to sparse matrices.
740 //**********************************************************************************************
741
742 //**Schur product assignment to dense matrices**************************************************
755 template< typename MT // Type of the target dense matrix
756 , bool SO2 > // Storage order of the target dense matrix
757 friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs, const DMatTSMatSchurExpr& rhs )
758 {
760
761 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
762 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
763
764 CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
765 CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
766
767 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
768 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
769 BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
770 BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
771 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).rows() , "Invalid number of rows" );
772 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).columns() , "Invalid number of columns" );
773
774 for( size_t j=0UL; j<(*lhs).columns(); ++j )
775 {
776 const auto end( B.end(j) );
777 auto begin( B.begin(j) );
778 size_t i( 0UL );
779
780 for( ; begin!=end; ++begin ) {
781 const size_t index( begin->index() );
782 for( ; i<index; ++i )
783 reset( (*lhs)(i,j) );
784 (*lhs)(index,j) *= A(index,j) * begin->value();
785 ++i;
786 }
787
788 for( ; i<(*lhs).rows(); ++i )
789 reset( (*lhs)(i,j) );
790 }
791 }
793 //**********************************************************************************************
794
795 //**Schur product assignment to sparse matrices*************************************************
796 // No special implementation for the Schur product assignment to sparse matrices.
797 //**********************************************************************************************
798
799 //**Multiplication assignment to dense matrices*************************************************
800 // No special implementation for the multiplication assignment to dense matrices.
801 //**********************************************************************************************
802
803 //**Multiplication assignment to sparse matrices************************************************
804 // No special implementation for the multiplication assignment to sparse matrices.
805 //**********************************************************************************************
806
807 //**SMP assignment to dense matrices************************************************************
808 // No special implementation for the SMP assignment to dense matrices.
809 //**********************************************************************************************
810
811 //**SMP assignment to sparse matrices***********************************************************
812 // No special implementation for the SMP assignment to sparse matrices.
813 //**********************************************************************************************
814
815 //**SMP addition assignment to dense matrices***************************************************
816 // No special implementation for the SMP addition assignment to dense matrices.
817 //**********************************************************************************************
818
819 //**SMP addition assignment to sparse matrices**************************************************
820 // No special implementation for the SMP addition assignment to sparse matrices.
821 //**********************************************************************************************
822
823 //**SMP subtraction assignment to dense matrices************************************************
824 // No special implementation for the SMP subtraction assignment to dense matrices.
825 //**********************************************************************************************
826
827 //**SMP subtraction assignment to sparse matrices***********************************************
828 // No special implementation for the SMP subtraction assignment to sparse matrices.
829 //**********************************************************************************************
830
831 //**SMP Schur product assignment to dense matrices**********************************************
844 template< typename MT // Type of the target dense matrix
845 , bool SO > // Storage order of the target dense matrix
846 friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs, const DMatTSMatSchurExpr& rhs )
847 {
849
850 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
851 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
852
853 smpSchurAssign( *lhs, rhs.lhs_ );
854 smpSchurAssign( *lhs, rhs.rhs_ );
855 }
857 //**********************************************************************************************
858
859 //**SMP Schur product assignment to sparse matrices*********************************************
860 // No special implementation for the SMP Schur product assignment to sparse matrices.
861 //**********************************************************************************************
862
863 //**SMP multiplication assignment to dense matrices*********************************************
864 // No special implementation for the SMP multiplication assignment to dense matrices.
865 //**********************************************************************************************
866
867 //**SMP multiplication assignment to sparse matrices********************************************
868 // No special implementation for the SMP multiplication assignment to sparse matrices.
869 //**********************************************************************************************
870
871 //**Compile time checks*************************************************************************
879 //**********************************************************************************************
880};
881//*************************************************************************************************
882
883
884
885
886//=================================================================================================
887//
888// GLOBAL BINARY ARITHMETIC OPERATORS
889//
890//=================================================================================================
891
892//*************************************************************************************************
905template< typename MT1 // Type of the left-hand side dense matrix
906 , typename MT2 // Type of the right-hand side sparse matrix
907 , DisableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
908 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) ||
909 ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
910 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
911 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
912 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
913 IsZero_v<MT2> >* = nullptr >
914inline const DMatTSMatSchurExpr<MT1,MT2>
915 dmattsmatschur( const DenseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
916{
918
919 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
920 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
921
922 return DMatTSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
923}
925//*************************************************************************************************
926
927
928//*************************************************************************************************
942template< typename MT1 // Type of the left-hand side dense matrix
943 , typename MT2 // Type of the right-hand side sparse matrix
944 , EnableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
945 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) >* = nullptr >
946inline decltype(auto)
947 dmattsmatschur( const DenseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
948{
950
951 MAYBE_UNUSED( rhs );
952
953 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
954 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
955
956 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
957
960
961 return ReturnType( (*lhs).rows() );
962}
964//*************************************************************************************************
965
966
967//*************************************************************************************************
981template< typename MT1 // Type of the left-hand side dense 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<MT2> >* = nullptr >
988inline decltype(auto)
989 dmattsmatschur( const DenseMatrix<MT1,false>& 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//*************************************************************************************************
1039template< typename MT1 // Type of the left-hand side dense matrix
1040 , typename MT2 > // Type of the right-hand side sparse matrix
1041inline decltype(auto)
1042 operator%( const DenseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
1043{
1045
1046 if( (*lhs).rows() != (*rhs).rows() || (*lhs).columns() != (*rhs).columns() ) {
1047 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1048 }
1049
1050 return dmattsmatschur( *lhs, *rhs );
1051}
1052//*************************************************************************************************
1053
1054
1055//*************************************************************************************************
1068template< typename MT1 // Type of the left-hand side dense matrix
1069 , typename MT2 // Type of the right-hand side sparse matrix
1070 , DisableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
1071 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) ||
1072 ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
1073 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
1074 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
1075 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
1076 IsZero_v<MT2> >* = nullptr >
1077inline const DMatTSMatSchurExpr<MT1,MT2>
1078 tdmattsmatschur( const DenseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
1079{
1081
1082 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
1083 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
1084
1085 return DMatTSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
1086}
1087//*************************************************************************************************
1088
1089
1090//*************************************************************************************************
1104template< typename MT1 // Type of the left-hand side dense matrix
1105 , typename MT2 // Type of the right-hand side sparse matrix
1106 , EnableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
1107 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) >* = nullptr >
1108inline decltype(auto)
1109 tdmattsmatschur( const DenseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
1110{
1112
1113 MAYBE_UNUSED( rhs );
1114
1115 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
1116 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
1117
1118 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1119
1122
1123 return ReturnType( (*lhs).rows() );
1124}
1126//*************************************************************************************************
1127
1128
1129//*************************************************************************************************
1143template< typename MT1 // Type of the left-hand side dense matrix
1144 , typename MT2 // Type of the right-hand side sparse matrix
1145 , EnableIf_t< ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
1146 ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
1147 ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
1148 ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
1149 IsZero_v<MT2> >* = nullptr >
1150inline decltype(auto)
1151 tdmattsmatschur( const DenseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
1152{
1154
1155 MAYBE_UNUSED( rhs );
1156
1157 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == (*rhs).rows() , "Invalid number of rows" );
1158 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == (*rhs).columns(), "Invalid number of columns" );
1159
1160 using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1161
1164
1165 return ReturnType( (*lhs).rows(), (*lhs).columns() );
1166}
1168//*************************************************************************************************
1169
1170
1171//*************************************************************************************************
1200template< typename MT1 // Type of the left-hand side dense matrix
1201 , typename MT2 > // Type of the right-hand side sparse matrix
1202inline decltype(auto)
1203 operator%( const DenseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
1204{
1206
1207 if( (*lhs).rows() != (*rhs).rows() || (*lhs).columns() != (*rhs).columns() ) {
1208 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1209 }
1210
1211 return tdmattsmatschur( *lhs, *rhs );
1212}
1213//*************************************************************************************************
1214
1215
1216
1217
1218//=================================================================================================
1219//
1220// SIZE SPECIALIZATIONS
1221//
1222//=================================================================================================
1223
1224//*************************************************************************************************
1226template< typename MT1, typename MT2 >
1227struct Size< DMatTSMatSchurExpr<MT1,MT2>, 0UL >
1228 : public Max_t< Size<MT1,0UL>, Size<MT2,0UL> >
1229{};
1230
1231template< typename MT1, typename MT2 >
1232struct Size< DMatTSMatSchurExpr<MT1,MT2>, 1UL >
1233 : public Max_t< Size<MT1,1UL>, Size<MT2,1UL> >
1234{};
1236//*************************************************************************************************
1237
1238} // namespace blaze
1239
1240#endif
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Constraints on the storage order of matrix types.
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.
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) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
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_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_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
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
#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.