35#ifndef _BLAZE_MATH_EXPRESSIONS_DMATTSMATSCHUREXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_DMATTSMATSCHUREXPR_H_
100class DMatTSMatSchurExpr
101 :
public SchurExpr< SparseMatrix< DMatTSMatSchurExpr<MT1,MT2>, true > >
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 = DMatTSMatSchurExpr<MT1,MT2>;
150 using BaseType = SchurExpr< SparseMatrix<This,true> >;
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 DMatTSMatSchurExpr& >;
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 column )
216 inline ConstIterator& operator++() {
228 return Element( left_(right_->index(),col_) * right_->value(), right_->index() );
237 inline const ConstIterator* operator->()
const {
247 inline ReturnType value()
const {
248 return left_(right_->index(),col_) * 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 DMatTSMatSchurExpr(
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 j )
const {
364 return ConstIterator( lhs_, rhs_.begin(j), j );
374 inline ConstIterator
end(
size_t j )
const {
375 return ConstIterator( lhs_, rhs_.end(j), j );
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 j )
const {
416 return rhs_.nonZeros(j);
427 inline ConstIterator
find(
size_t i,
size_t j )
const {
429 return ConstIterator( lhs_, rhs_.find( i, j ), j );
440 inline ConstIterator
lowerBound(
size_t i,
size_t j )
const {
442 return ConstIterator( lhs_, rhs_.lowerBound( i, j ), j );
453 inline ConstIterator
upperBound(
size_t i,
size_t j )
const {
455 return ConstIterator( lhs_, rhs_.upperBound( i, j ), j );
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 DMatTSMatSchurExpr& rhs )
524 -> EnableIf_t< UseAssign_v<MT> >
531 CT1 A(
serial( rhs.lhs_ ) );
532 CT2 B(
serial( rhs.rhs_ ) );
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();
562 template<
typename MT >
563 friend inline auto assign( SparseMatrix<MT,false>& lhs,
const DMatTSMatSchurExpr& rhs )
564 -> EnableIf_t< UseAssign_v<MT> >
571 CT1 A(
serial( rhs.lhs_ ) );
572 CT2 B(
serial( rhs.rhs_ ) );
581 const size_t m( rhs.rows() );
582 const size_t n( rhs.columns() );
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()];
594 for(
size_t i=0UL; i<m; ++i ) {
595 (*lhs).reserve( i, nonzeros[i] );
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() );
620 template<
typename MT >
621 friend inline auto assign( SparseMatrix<MT,true>& lhs,
const DMatTSMatSchurExpr& rhs )
622 -> EnableIf_t< UseAssign_v<MT> >
629 CT1 A(
serial( rhs.lhs_ ) );
630 CT2 B(
serial( rhs.rhs_ ) );
640 (*lhs).reserve( B.nonZeros() );
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 );
665 template<
typename MT
667 friend inline auto addAssign( DenseMatrix<MT,SO2>& lhs,
const DMatTSMatSchurExpr& rhs )
668 -> EnableIf_t< UseAssign_v<MT> >
675 CT1 A(
serial( rhs.lhs_ ) );
676 CT2 B(
serial( rhs.rhs_ ) );
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();
710 template<
typename MT
712 friend inline auto subAssign( DenseMatrix<MT,SO2>& lhs,
const DMatTSMatSchurExpr& rhs )
713 -> EnableIf_t< UseAssign_v<MT> >
720 CT1 A(
serial( rhs.lhs_ ) );
721 CT2 B(
serial( rhs.rhs_ ) );
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();
755 template<
typename MT
757 friend inline void schurAssign( DenseMatrix<MT,SO2>& lhs,
const DMatTSMatSchurExpr& rhs )
764 CT1 A(
serial( rhs.lhs_ ) );
765 CT2 B(
serial( rhs.rhs_ ) );
774 for(
size_t j=0UL; j<(*lhs).columns(); ++j )
776 const auto end( B.end(j) );
777 auto begin( B.begin(j) );
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();
788 for( ; i<(*lhs).rows(); ++i )
789 reset( (*lhs)(i,j) );
844 template<
typename MT
846 friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs,
const DMatTSMatSchurExpr& rhs )
905template<
typename MT1
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 )
922 return DMatTSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
942template<
typename MT1
944 ,
EnableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
945 ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) >* =
nullptr >
947 dmattsmatschur(
const DenseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,true>& rhs )
956 using ReturnType =
const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
961 return ReturnType( (*lhs).rows() );
981template<
typename MT1
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 >
989 dmattsmatschur(
const DenseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,true>& rhs )
998 using ReturnType =
const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1003 return ReturnType( (*lhs).rows(), (*lhs).columns() );
1039template<
typename MT1
1041inline decltype(
auto)
1042 operator%(
const DenseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,true>& rhs )
1046 if( (*lhs).rows() != (*rhs).rows() || (*lhs).columns() != (*rhs).columns() ) {
1050 return dmattsmatschur( *lhs, *rhs );
1068template<
typename MT1
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 )
1085 return DMatTSMatSchurExpr<MT1,MT2>( *lhs, *rhs );
1104template<
typename MT1
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 )
1118 using ReturnType =
const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1123 return ReturnType( (*lhs).rows() );
1143template<
typename MT1
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 )
1160 using ReturnType =
const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1165 return ReturnType( (*lhs).rows(), (*lhs).columns() );
1200template<
typename MT1
1202inline decltype(
auto)
1203 operator%(
const DenseMatrix<MT1,true>& lhs,
const SparseMatrix<MT2,true>& rhs )
1207 if( (*lhs).rows() != (*rhs).rows() || (*lhs).columns() != (*rhs).columns() ) {
1211 return tdmattsmatschur( *lhs, *rhs );
1226template<
typename MT1,
typename MT2 >
1227struct Size< DMatTSMatSchurExpr<MT1,MT2>, 0UL >
1228 :
public Max_t< Size<MT1,0UL>, Size<MT2,0UL> >
1231template<
typename MT1,
typename MT2 >
1232struct Size< DMatTSMatSchurExpr<MT1,MT2>, 1UL >
1233 :
public Max_t< Size<MT1,1UL>, Size<MT2,1UL> >
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.