35#ifndef _BLAZE_MATH_EXPRESSIONS_DMATSMATSCHUREXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_DMATSMATSCHUREXPR_H_
100class DMatSMatSchurExpr
101 :
public SchurExpr< SparseMatrix< DMatSMatSchurExpr<MT1,MT2>, false > >
102 ,
private Computation
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>;
121 static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
124 using ExprReturnType =
decltype( std::declval<RN1>() * std::declval<RN2>() );
135 static constexpr bool useAssign = ( RequiresEvaluation_v<MT1> || RequiresEvaluation_v<MT2> );
139 template<
typename MT >
140 static constexpr bool UseAssign_v = useAssign;
147 using This = DMatSMatSchurExpr<MT1,MT2>;
150 using BaseType = SchurExpr< SparseMatrix<This,false> >;
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>;
158 using ReturnType =
const If_t< returnExpr, ExprReturnType, ElementType >;
161 using CompositeType = If_t< useAssign, const ResultType, const DMatSMatSchurExpr& >;
164 using LeftOperand = If_t< IsExpression_v<MT1>,
const MT1,
const MT1& >;
167 using RightOperand = If_t< IsExpression_v<MT2>,
const MT2,
const MT2& >;
178 using Element = ValueIndexPair<ElementType>;
181 using RightIterator = ConstIterator_t< RemoveReference_t<RightOperand> >;
183 using IteratorCategory = std::forward_iterator_tag;
184 using ValueType = Element;
185 using PointerType = ValueType*;
186 using ReferenceType = ValueType&;
190 using iterator_category = IteratorCategory;
191 using value_type = ValueType;
192 using pointer = PointerType;
193 using reference = ReferenceType;
194 using difference_type = DifferenceType;
204 inline ConstIterator( LeftOperand left, RightIterator right,
size_t row )
216 inline ConstIterator& operator++() {
228 return Element( left_(row_,right_->index()) * right_->value(), right_->index() );
237 inline const ConstIterator* operator->()
const {
247 inline ReturnType value()
const {
248 return left_(row_,right_->index()) * right_->value();
257 inline size_t index()
const {
258 return right_->index();
268 inline bool operator==(
const ConstIterator& rhs )
const {
269 return right_ == rhs.right_;
279 inline bool operator!=(
const ConstIterator& rhs )
const {
280 return right_ != rhs.right_;
290 inline DifferenceType
operator-(
const ConstIterator& rhs )
const {
291 return right_ - rhs.right_;
298 RightIterator right_;
306 static constexpr bool smpAssignable =
false;
315 inline DMatSMatSchurExpr(
const MT1& lhs,
const MT2& rhs ) noexcept
331 inline ReturnType operator()(
size_t i,
size_t j )
const {
334 return lhs_(i,j) * rhs_(i,j);
346 inline ReturnType at(
size_t i,
size_t j )
const {
347 if( i >= lhs_.rows() ) {
350 if( j >= lhs_.columns() ) {
363 inline ConstIterator
begin(
size_t i )
const {
364 return ConstIterator( lhs_, rhs_.begin(i), i );
374 inline ConstIterator
end(
size_t i )
const {
375 return ConstIterator( lhs_, rhs_.end(i), i );
384 inline size_t rows() const noexcept {
394 inline size_t columns() const noexcept {
395 return lhs_.columns();
405 return rhs_.nonZeros();
415 inline size_t nonZeros(
size_t i )
const {
416 return rhs_.nonZeros(i);
427 inline ConstIterator
find(
size_t i,
size_t j )
const {
429 return ConstIterator( lhs_, rhs_.find( i, j ), i );
440 inline ConstIterator
lowerBound(
size_t i,
size_t j )
const {
442 return ConstIterator( lhs_, rhs_.lowerBound( i, j ), i );
453 inline ConstIterator
upperBound(
size_t i,
size_t j )
const {
455 return ConstIterator( lhs_, rhs_.upperBound( i, j ), i );
464 inline LeftOperand leftOperand() const noexcept {
474 inline RightOperand rightOperand() const noexcept {
485 template<
typename T >
486 inline bool canAlias(
const T* alias )
const noexcept {
487 return ( lhs_.isAliased( alias ) || rhs_.canAlias( alias ) );
497 template<
typename T >
498 inline bool isAliased(
const T* alias )
const noexcept {
499 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
521 template<
typename MT
523 friend inline auto assign( DenseMatrix<MT,SO2>& lhs,
const DMatSMatSchurExpr& rhs )
524 -> EnableIf_t< UseAssign_v<MT> >
531 CT1 A(
serial( rhs.lhs_ ) );
532 CT2 B(
serial( rhs.rhs_ ) );
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();
561 template<
typename MT >
562 friend inline auto assign( SparseMatrix<MT,false>& lhs,
const DMatSMatSchurExpr& rhs )
563 -> EnableIf_t< UseAssign_v<MT> >
570 CT1 A(
serial( rhs.lhs_ ) );
571 CT2 B(
serial( rhs.rhs_ ) );
581 (*lhs).reserve( B.nonZeros() );
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 );
606 template<
typename MT >
607 friend inline auto assign( SparseMatrix<MT,true>& lhs,
const DMatSMatSchurExpr& rhs )
608 -> EnableIf_t< UseAssign_v<MT> >
615 CT1 A(
serial( rhs.lhs_ ) );
616 CT2 B(
serial( rhs.rhs_ ) );
625 const size_t m( rhs.rows() );
626 const size_t n( rhs.columns() );
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()];
638 for(
size_t j=0UL; j<n; ++j ) {
639 (*lhs).reserve( j, nonzeros[j] );
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() );
663 template<
typename MT
665 friend inline auto addAssign( DenseMatrix<MT,SO2>& lhs,
const DMatSMatSchurExpr& rhs )
666 -> EnableIf_t< UseAssign_v<MT> >
673 CT1 A(
serial( rhs.lhs_ ) );
674 CT2 B(
serial( rhs.rhs_ ) );
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();
707 template<
typename MT
709 friend inline auto subAssign( DenseMatrix<MT,SO2>& lhs,
const DMatSMatSchurExpr& rhs )
710 -> EnableIf_t< UseAssign_v<MT> >
717 CT1 A(
serial( rhs.lhs_ ) );
718 CT2 B(
serial( rhs.rhs_ ) );
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();
752 template<
typename MT
754 friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs,
const DMatSMatSchurExpr& rhs )
761 CT1 A(
serial( rhs.lhs_ ) );
762 CT2 B(
serial( rhs.rhs_ ) );
771 for(
size_t i=0UL; i<(*lhs).rows(); ++i )
773 const auto end( B.end(i) );
774 auto begin( B.begin(i) );
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();
785 for( ; j<(*lhs).columns(); ++j )
786 reset( (*lhs)(i,j) );
841 template<
typename MT
843 friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs,
const DMatSMatSchurExpr& rhs )
902template<
typename MT1
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 )
919 return DMatSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
939template<
typename MT1
941 ,
EnableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
942 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) >* =
nullptr >
944 dmatsmatschur(
const DenseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,false>& rhs )
953 using ReturnType =
const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
958 return ReturnType( (*lhs).rows() );
978template<
typename MT1
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 >
986 dmatsmatschur(
const DenseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,false>& rhs )
995 using ReturnType =
const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1000 return ReturnType( (*lhs).rows(), (*lhs).columns() );
1035template<
typename MT1
1037inline decltype(
auto)
1038 operator%(
const DenseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,false>& rhs )
1042 if( (*lhs).rows() != (*rhs).rows() || (*lhs).columns() != (*rhs).columns() ) {
1046 return dmatsmatschur( *lhs, *rhs );
1064template<
typename MT1
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 )
1081 return DMatSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
1100template<
typename MT1
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 )
1114 using ReturnType =
const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1119 return ReturnType( (*lhs).rows() );
1139template<
typename MT1
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 )
1156 using ReturnType =
const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1161 return ReturnType( (*lhs).rows(), (*lhs).columns() );
1197template<
typename MT1
1199inline decltype(
auto)
1200 operator%(
const DenseMatrix<MT1,true>& lhs,
const SparseMatrix<MT2,false>& rhs )
1204 if( (*lhs).rows() != (*rhs).rows() || (*lhs).columns() != (*rhs).columns() ) {
1208 return tdmatsmatschur( *lhs, *rhs );
1223template<
typename MT1,
typename MT2 >
1224struct Size< DMatSMatSchurExpr<MT1,MT2>, 0UL >
1225 :
public Max_t< Size<MT1,0UL>, Size<MT2,0UL> >
1228template<
typename MT1,
typename MT2 >
1229struct Size< DMatSMatSchurExpr<MT1,MT2>, 1UL >
1230 :
public Max_t< Size<MT1,1UL>, Size<MT2,1UL> >
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.