35 #ifndef _BLAZE_MATH_VIEWS_SUBMATRIX_DENSE_H_ 36 #define _BLAZE_MATH_VIEWS_SUBMATRIX_DENSE_H_ 131 template<
typename MT
133 class Submatrix<MT,
unaligned,false,true,CSAs...>
134 :
public View< DenseMatrix< Submatrix<MT,unaligned,false,true,CSAs...>, false > >
135 ,
private SubmatrixData<CSAs...>
139 using DataType = SubmatrixData<CSAs...>;
140 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
145 template<
typename MT1,
typename MT2 >
146 static constexpr
bool EnforceEvaluation_v =
147 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
153 using This = Submatrix<MT,
unaligned,
false,
true,CSAs...>;
155 using BaseType = DenseMatrix<This,false>;
156 using ViewedType = MT;
158 using OppositeType = OppositeType_t<ResultType>;
159 using TransposeType = TransposeType_t<ResultType>;
160 using ElementType = ElementType_t<MT>;
161 using SIMDType = SIMDTrait_t<ElementType>;
162 using ReturnType = ReturnType_t<MT>;
163 using CompositeType =
const Submatrix&;
166 using ConstReference = ConstReference_t<MT>;
169 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
172 using ConstPointer = ConstPointer_t<MT>;
175 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
181 template<
typename IteratorType >
182 class SubmatrixIterator
187 using IteratorCategory =
typename std::iterator_traits<IteratorType>::iterator_category;
190 using ValueType =
typename std::iterator_traits<IteratorType>::value_type;
193 using PointerType =
typename std::iterator_traits<IteratorType>::pointer;
196 using ReferenceType =
typename std::iterator_traits<IteratorType>::reference;
199 using DifferenceType =
typename std::iterator_traits<IteratorType>::difference_type;
202 using iterator_category = IteratorCategory;
203 using value_type = ValueType;
204 using pointer = PointerType;
205 using reference = ReferenceType;
206 using difference_type = DifferenceType;
212 inline SubmatrixIterator()
214 , isAligned_( false )
224 inline SubmatrixIterator( IteratorType iterator,
bool isMemoryAligned )
225 : iterator_ ( iterator )
226 , isAligned_( isMemoryAligned )
235 template<
typename IteratorType2 >
236 inline SubmatrixIterator(
const SubmatrixIterator<IteratorType2>& it )
237 : iterator_ ( it.base() )
238 , isAligned_( it.isAligned() )
248 inline SubmatrixIterator&
operator+=(
size_t inc ) {
260 inline SubmatrixIterator&
operator-=(
size_t dec ) {
271 inline SubmatrixIterator& operator++() {
282 inline const SubmatrixIterator operator++(
int ) {
283 return SubmatrixIterator( iterator_++, isAligned_ );
292 inline SubmatrixIterator& operator--() {
303 inline const SubmatrixIterator operator--(
int ) {
304 return SubmatrixIterator( iterator_--, isAligned_ );
323 inline IteratorType operator->()
const {
338 inline SIMDType load() const noexcept {
356 inline SIMDType
loada() const noexcept {
357 return iterator_.loada();
371 inline SIMDType
loadu() const noexcept {
372 return iterator_.loadu();
387 inline void store(
const SIMDType& value )
const {
408 inline void storea(
const SIMDType& value )
const {
409 iterator_.storea( value );
424 inline void storeu(
const SIMDType& value )
const {
425 iterator_.storeu( value );
440 inline void stream(
const SIMDType& value )
const {
441 iterator_.stream( value );
451 inline bool operator==(
const SubmatrixIterator& rhs )
const {
452 return iterator_ == rhs.iterator_;
462 inline bool operator!=(
const SubmatrixIterator& rhs )
const {
463 return iterator_ != rhs.iterator_;
473 inline bool operator<(
const SubmatrixIterator& rhs )
const {
474 return iterator_ < rhs.iterator_;
484 inline bool operator>(
const SubmatrixIterator& rhs )
const {
485 return iterator_ > rhs.iterator_;
495 inline bool operator<=(
const SubmatrixIterator& rhs )
const {
496 return iterator_ <= rhs.iterator_;
506 inline bool operator>=(
const SubmatrixIterator& rhs )
const {
507 return iterator_ >= rhs.iterator_;
517 inline DifferenceType
operator-(
const SubmatrixIterator& rhs )
const {
518 return iterator_ - rhs.iterator_;
529 friend inline const SubmatrixIterator
operator+(
const SubmatrixIterator& it,
size_t inc ) {
530 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
541 friend inline const SubmatrixIterator
operator+(
size_t inc,
const SubmatrixIterator& it ) {
542 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
553 friend inline const SubmatrixIterator
operator-(
const SubmatrixIterator& it,
size_t dec ) {
554 return SubmatrixIterator( it.iterator_ - dec, it.isAligned_ );
563 inline IteratorType base()
const {
573 inline bool isAligned() const noexcept {
580 IteratorType iterator_;
588 using ConstIterator = SubmatrixIterator< ConstIterator_t<MT> >;
591 using Iterator = If_t< IsConst_v<MT>, ConstIterator, SubmatrixIterator< Iterator_t<MT> > >;
596 static constexpr
bool simdEnabled = MT::simdEnabled;
599 static constexpr
bool smpAssignable = MT::smpAssignable;
602 static constexpr
bool compileTimeArgs = DataType::compileTimeArgs;
608 template<
typename... RSAs >
609 explicit inline Submatrix( MT& matrix, RSAs... args );
611 Submatrix(
const Submatrix& ) =
default;
618 ~Submatrix() =
default;
625 inline Reference operator()(
size_t i,
size_t j );
626 inline ConstReference operator()(
size_t i,
size_t j )
const;
627 inline Reference at(
size_t i,
size_t j );
628 inline ConstReference at(
size_t i,
size_t j )
const;
629 inline Pointer
data () noexcept;
630 inline ConstPointer
data () const noexcept;
631 inline Pointer
data (
size_t i ) noexcept;
632 inline ConstPointer
data (
size_t i ) const noexcept;
633 inline Iterator
begin (
size_t i );
634 inline ConstIterator
begin (
size_t i ) const;
635 inline ConstIterator
cbegin(
size_t i ) const;
636 inline Iterator
end (
size_t i );
637 inline ConstIterator
end (
size_t i ) const;
638 inline ConstIterator
cend (
size_t i ) const;
645 inline Submatrix& operator=( const ElementType& rhs );
646 inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
647 inline Submatrix& operator=( const Submatrix& rhs );
649 template< typename MT2,
bool SO2 >
650 inline Submatrix& operator=( const Matrix<MT2,SO2>& rhs );
652 template< typename MT2,
bool SO2 >
653 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
654 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
656 template< typename MT2,
bool SO2 >
657 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
658 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
660 template< typename MT2,
bool SO2 >
661 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
662 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
664 template< typename MT2,
bool SO2 >
665 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
666 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
668 template< typename MT2,
bool SO2 >
669 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
670 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
672 template< typename MT2,
bool SO2 >
673 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
674 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
683 using DataType::
rows;
686 inline MT& operand() noexcept;
687 inline const MT& operand() const noexcept;
689 inline
size_t spacing() const noexcept;
690 inline
size_t capacity() const noexcept;
691 inline
size_t capacity(
size_t i ) const noexcept;
693 inline
size_t nonZeros(
size_t i ) const;
695 inline
void reset(
size_t i );
705 template< typename Other > inline Submatrix& scale( const Other& scalar );
712 template< typename MT2 >
713 static constexpr
bool VectorizedAssign_v =
714 ( useOptimizedKernels &&
715 simdEnabled && MT2::simdEnabled &&
721 template< typename MT2 >
722 static constexpr
bool VectorizedAddAssign_v =
723 ( useOptimizedKernels &&
724 simdEnabled && MT2::simdEnabled &&
732 template< typename MT2 >
733 static constexpr
bool VectorizedSubAssign_v =
734 ( useOptimizedKernels &&
735 simdEnabled && MT2::simdEnabled &&
743 template< typename MT2 >
744 static constexpr
bool VectorizedSchurAssign_v =
745 ( useOptimizedKernels &&
746 simdEnabled && MT2::simdEnabled &&
753 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
760 template< typename Other >
761 inline
bool canAlias( const Other* alias ) const noexcept;
763 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
764 inline
bool canAlias( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
766 template< typename Other >
767 inline
bool isAliased( const Other* alias ) const noexcept;
769 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
770 inline
bool isAliased( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
772 inline
bool isAligned () const noexcept;
773 inline
bool canSMPAssign() const noexcept;
784 template< typename MT2 >
785 inline auto assign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedAssign_v<MT2> >;
787 template< typename MT2 >
788 inline auto assign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedAssign_v<MT2> >;
790 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,true>& rhs );
791 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
792 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
794 template< typename MT2 >
795 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<MT2> >;
797 template< typename MT2 >
798 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<MT2> >;
800 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,true>& rhs );
801 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
802 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
804 template< typename MT2 >
805 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<MT2> >;
807 template< typename MT2 >
808 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<MT2> >;
810 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,true>& rhs );
811 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
812 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
814 template< typename MT2 >
815 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedSchurAssign_v<MT2> >;
817 template< typename MT2 >
818 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedSchurAssign_v<MT2> >;
820 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,true>& rhs );
821 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
822 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
830 inline
bool hasOverlap() const noexcept;
838 const
bool isAligned_;
849 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
bool DF2,
size_t... CSAs2 > friend class Submatrix;
887 template< typename MT
889 template< typename... RSAs >
890 inline Submatrix<MT,
unaligned,false,true,CSAs...>::Submatrix( MT& matrix, RSAs... args )
891 : DataType ( args... )
895 (
rows() < 2UL || ( matrix.
spacing() &
size_t(-SIMDSIZE) ) == 0UL ) )
930 template<
typename MT
932 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Reference
933 Submatrix<MT,unaligned,false,true,CSAs...>::operator()(
size_t i,
size_t j )
955 template<
typename MT
957 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstReference
958 Submatrix<MT,unaligned,false,true,CSAs...>::operator()(
size_t i,
size_t j )
const 963 return const_cast<const MT&>( matrix_ )(
row()+i,
column()+j);
981 template<
typename MT
983 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Reference
984 Submatrix<MT,unaligned,false,true,CSAs...>::at(
size_t i,
size_t j )
1010 template<
typename MT
1012 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstReference
1013 Submatrix<MT,unaligned,false,true,CSAs...>::at(
size_t i,
size_t j )
const 1021 return (*
this)(i,j);
1037 template<
typename MT
1039 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Pointer
1058 template<
typename MT
1060 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstPointer
1078 template<
typename MT
1080 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Pointer
1098 template<
typename MT
1100 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstPointer
1121 template<
typename MT
1123 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Iterator
1127 return Iterator( matrix_.begin(
row() + i ) +
column(), isAligned_ );
1145 template<
typename MT
1147 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstIterator
1151 return ConstIterator( matrix_.cbegin(
row() + i ) +
column(), isAligned_ );
1169 template<
typename MT
1171 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstIterator
1175 return ConstIterator( matrix_.cbegin(
row() + i ) +
column(), isAligned_ );
1193 template<
typename MT
1195 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Iterator
1199 return Iterator( matrix_.begin(
row() + i ) +
column() +
columns(), isAligned_ );
1217 template<
typename MT
1219 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstIterator
1223 return ConstIterator( matrix_.cbegin(
row() + i ) +
column() +
columns(), isAligned_ );
1241 template<
typename MT
1243 inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstIterator
1247 return ConstIterator( matrix_.cbegin(
row() + i ) +
column() +
columns(), isAligned_ );
1272 template<
typename MT
1274 inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
1275 Submatrix<MT,unaligned,false,true,CSAs...>::operator=(
const ElementType& rhs )
1277 const size_t iend(
row() +
rows() );
1278 decltype(
auto) left( derestrict( matrix_ ) );
1280 for(
size_t i=
row(); i<iend; ++i )
1282 const size_t jbegin( ( IsUpper_v<MT> )
1283 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
1287 const size_t jend ( ( IsLower_v<MT> )
1288 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
1293 for(
size_t j=jbegin; j<jend; ++j ) {
1294 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, j, rhs ) )
1321 template<
typename MT
1323 inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
1324 Submatrix<MT,unaligned,false,true,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
1326 if( list.size() !=
rows() ) {
1330 if( IsRestricted_v<MT> ) {
1331 const InitializerMatrix<ElementType> tmp( list,
columns() );
1332 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
1337 decltype(
auto) left( derestrict( *this ) );
1340 for( const auto& rowList : list ) {
1341 std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
1366 template<
typename MT
1368 inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
1369 Submatrix<MT,unaligned,false,true,CSAs...>::operator=(
const Submatrix& rhs )
1374 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ &&
row() == rhs.row() &&
column() == rhs.column() ) )
1377 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
1381 if( !tryAssign( matrix_, rhs,
row(),
column() ) ) {
1385 decltype(
auto) left( derestrict( *this ) );
1387 if( rhs.canAlias( &matrix_ ) ) {
1388 const ResultType tmp( rhs );
1418 template<
typename MT
1420 template<
typename MT2
1422 inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
1423 Submatrix<MT,unaligned,false,true,CSAs...>::operator=(
const Matrix<MT2,SO2>& rhs )
1431 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>,
const MT2& >;
1432 Right right( ~rhs );
1434 if( !tryAssign( matrix_, right,
row(),
column() ) ) {
1438 decltype(
auto) left( derestrict( *this ) );
1441 const ResultType_t<MT2> tmp( right );
1442 if( IsSparseMatrix_v<MT2> )
1447 if( IsSparseMatrix_v<MT2> )
1474 template<
typename MT
1476 template<
typename MT2
1479 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1485 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1494 if( !tryAddAssign( matrix_, ~rhs,
row(),
column() ) ) {
1498 decltype(
auto) left( derestrict( *this ) );
1501 (~rhs).canAlias( &matrix_ ) ) {
1502 const AddType tmp( *
this + (~rhs) );
1531 template<
typename MT
1533 template<
typename MT2
1536 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1542 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1551 const AddType tmp( *
this + (~rhs) );
1553 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
1557 decltype(
auto) left( derestrict( *this ) );
1583 template< typename MT
1585 template< typename MT2
1587 inline auto Submatrix<MT,
unaligned,false,true,CSAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1588 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1594 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1603 if( !trySubAssign( matrix_, ~rhs,
row(),
column() ) ) {
1607 decltype(
auto) left( derestrict( *this ) );
1610 (~rhs).canAlias( &matrix_ ) ) {
1611 const SubType tmp( *
this - (~rhs ) );
1640 template<
typename MT
1642 template<
typename MT2
1645 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1651 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1660 const SubType tmp( *
this - (~rhs) );
1662 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
1666 decltype(
auto) left( derestrict( *this ) );
1692 template< typename MT
1694 template< typename MT2
1696 inline auto Submatrix<MT,
unaligned,false,true,CSAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1697 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1703 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1711 if( !trySchurAssign( matrix_, ~rhs,
row(),
column() ) ) {
1715 decltype(
auto) left( derestrict( *this ) );
1718 (~rhs).canAlias( &matrix_ ) ) {
1719 const SchurType tmp( *
this % (~rhs) );
1720 if( IsSparseMatrix_v<SchurType> )
1750 template<
typename MT
1752 template<
typename MT2
1754 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::operator%=(
const Matrix<MT2,SO2>& rhs )
1755 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1761 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1769 const SchurType tmp( *
this % (~rhs) );
1771 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
1775 decltype(
auto) left( derestrict( *this ) );
1805 template<
typename MT
1807 inline MT& Submatrix<MT,unaligned,false,true,CSAs...>::operand() noexcept
1821 template<
typename MT
1823 inline const MT& Submatrix<MT,unaligned,false,true,CSAs...>::operand() const noexcept
1842 template<
typename MT
1846 return matrix_.spacing();
1858 template<
typename MT
1880 template<
typename MT
1900 template<
typename MT
1904 const size_t iend(
row() +
rows() );
1906 size_t nonzeros( 0UL );
1908 for(
size_t i=
row(); i<iend; ++i )
1909 for(
size_t j=
column(); j<jend; ++j )
1931 template<
typename MT
1938 size_t nonzeros( 0UL );
1940 for(
size_t j=
column(); j<jend; ++j )
1956 template<
typename MT
1964 const size_t jbegin( ( IsUpper_v<MT> )
1965 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
1969 const size_t jend ( ( IsLower_v<MT> )
1970 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
1975 for(
size_t j=jbegin; j<jend; ++j )
1976 clear( matrix_(i,j) );
1995 template<
typename MT
2003 const size_t jbegin( ( IsUpper_v<MT> )
2004 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
2008 const size_t jend ( ( IsLower_v<MT> )
2009 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
2014 for(
size_t j=jbegin; j<jend; ++j )
2031 template<
typename MT
2033 inline bool Submatrix<MT,unaligned,false,true,CSAs...>::hasOverlap() const noexcept
2071 template<
typename MT
2073 inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
2084 decltype(
auto) left( derestrict( *this ) );
2085 const ResultType tmp(
trans( *this ) );
2113 template< typename MT
2115 inline Submatrix<MT,
unaligned,false,true,CSAs...>&
2126 decltype(
auto) left( derestrict( *this ) );
2127 const ResultType tmp(
ctrans( *this ) );
2150 template< typename MT
2152 template< typename Other >
2153 inline Submatrix<MT,
unaligned,false,true,CSAs...>&
2154 Submatrix<MT,
unaligned,false,true,CSAs...>::scale( const Other& scalar )
2158 const size_t iend(
row() +
rows() );
2160 for(
size_t i=
row(); i<iend; ++i )
2162 const size_t jbegin( ( IsUpper_v<MT> )
2163 ?( ( IsStrictlyUpper_v<MT> )
2167 const size_t jend ( ( IsLower_v<MT> )
2168 ?( ( IsStrictlyLower_v<MT> )
2173 for(
size_t j=jbegin; j<jend; ++j )
2174 matrix_(i,j) *= scalar;
2202 template<
typename MT
2204 template<
typename Other >
2205 inline bool Submatrix<MT,unaligned,false,true,CSAs...>::canAlias(
const Other* alias )
const noexcept
2207 return matrix_.isAliased( alias );
2224 template<
typename MT
2226 template<
typename MT2
2231 Submatrix<MT,unaligned,false,true,CSAs...>::canAlias(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
2233 return ( matrix_.isAliased( &alias->matrix_ ) &&
2234 (
row() +
rows() > alias->row() ) &&
2235 (
row() < alias->row() + alias->rows() ) &&
2237 (
column() < alias->column() + alias->columns() ) );
2254 template<
typename MT
2256 template<
typename Other >
2257 inline bool Submatrix<MT,unaligned,false,true,CSAs...>::isAliased(
const Other* alias )
const noexcept
2259 return matrix_.isAliased( alias );
2276 template<
typename MT
2278 template<
typename MT2
2283 Submatrix<MT,unaligned,false,true,CSAs...>::isAliased(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
2285 return ( matrix_.isAliased( &alias->matrix_ ) &&
2286 (
row() +
rows() > alias->row() ) &&
2287 (
row() < alias->row() + alias->rows() ) &&
2289 (
column() < alias->column() + alias->columns() ) );
2305 template<
typename MT
2307 inline bool Submatrix<MT,unaligned,false,true,CSAs...>::isAligned() const noexcept
2326 template<
typename MT
2328 inline bool Submatrix<MT,unaligned,false,true,CSAs...>::canSMPAssign() const noexcept
2330 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
2352 template<
typename MT
2355 Submatrix<MT,unaligned,false,true,CSAs...>::load(
size_t i,
size_t j )
const noexcept
2358 return loada( i, j );
2360 return loadu( i, j );
2382 template<
typename MT
2394 return matrix_.loada(
row()+i,
column()+j );
2416 template<
typename MT
2427 return matrix_.loadu(
row()+i,
column()+j );
2450 template<
typename MT
2453 Submatrix<MT,unaligned,false,true,CSAs...>::store(
size_t i,
size_t j,
const SIMDType& value ) noexcept
2481 template<
typename MT
2493 matrix_.storea(
row()+i,
column()+j, value );
2516 template<
typename MT
2527 matrix_.storeu(
row()+i,
column()+j, value );
2550 template<
typename MT
2563 matrix_.stream(
row()+i,
column()+j, value );
2565 matrix_.storeu(
row()+i,
column()+j, value );
2583 template<
typename MT
2585 template<
typename MT2 >
2586 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
2587 -> DisableIf_t< VectorizedAssign_v<MT2> >
2592 const size_t jpos(
columns() &
size_t(-2) );
2595 for(
size_t i=0UL; i<
rows(); ++i ) {
2596 for(
size_t j=0UL; j<jpos; j+=2UL ) {
2597 matrix_(
row()+i,
column()+j ) = (~rhs)(i,j );
2598 matrix_(
row()+i,
column()+j+1UL) = (~rhs)(i,j+1UL);
2601 matrix_(
row()+i,
column()+jpos) = (~rhs)(i,jpos);
2621 template<
typename MT
2623 template<
typename MT2 >
2624 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
2625 -> EnableIf_t< VectorizedAssign_v<MT2> >
2632 const size_t jpos(
columns() &
size_t(-SIMDSIZE) );
2635 if( useStreaming && isAligned_ &&
2636 rows()*
columns() > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
2637 !(~rhs).isAliased( &matrix_ ) )
2639 for(
size_t i=0UL; i<
rows(); ++i )
2642 Iterator left(
begin(i) );
2643 ConstIterator_t<MT2> right( (~rhs).
begin(i) );
2645 for( ; j<jpos; j+=SIMDSIZE ) {
2646 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2655 for(
size_t i=0UL; i<
rows(); ++i )
2658 Iterator left(
begin(i) );
2659 ConstIterator_t<MT2> right( (~rhs).
begin(i) );
2661 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2662 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2663 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2664 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2665 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2667 for( ; j<jpos; j+=SIMDSIZE ) {
2668 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2671 *left = *right; ++left; ++right;
2692 template<
typename MT
2694 template<
typename MT2 >
2695 inline void Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
2702 constexpr
size_t block( BLOCK_SIZE );
2704 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
2705 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
2706 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
2707 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
2708 for(
size_t i=ii; i<iend; ++i ) {
2709 for(
size_t j=jj; j<jend; ++j ) {
2710 matrix_(
row()+i,
column()+j) = (~rhs)(i,j);
2732 template<
typename MT
2734 template<
typename MT2 >
2735 inline void Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const SparseMatrix<MT2,false>& rhs )
2740 for(
size_t i=0UL; i<
rows(); ++i )
2741 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
2742 matrix_(
row()+i,
column()+element->index()) = element->value();
2760 template<
typename MT
2762 template<
typename MT2 >
2763 inline void Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const SparseMatrix<MT2,true>& rhs )
2770 for(
size_t j=0UL; j<
columns(); ++j )
2771 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
2772 matrix_(
row()+element->index(),
column()+j) = element->value();
2790 template<
typename MT
2792 template<
typename MT2 >
2793 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
2794 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
2799 const size_t jpos(
columns() &
size_t(-2) );
2802 for(
size_t i=0UL; i<
rows(); ++i )
2804 if( IsDiagonal_v<MT2> ) {
2805 matrix_(
row()+i,
column()+i) += (~rhs)(i,i);
2808 for(
size_t j=0UL; j<jpos; j+=2UL ) {
2809 matrix_(
row()+i,
column()+j ) += (~rhs)(i,j );
2810 matrix_(
row()+i,
column()+j+1UL) += (~rhs)(i,j+1UL);
2813 matrix_(
row()+i,
column()+jpos) += (~rhs)(i,jpos);
2834 template<
typename MT
2836 template<
typename MT2 >
2837 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
2838 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
2845 for(
size_t i=0UL; i<
rows(); ++i )
2847 const size_t jbegin( ( IsUpper_v<MT2> )
2848 ?( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ) &
size_t(-SIMDSIZE) )
2850 const size_t jend ( ( IsLower_v<MT2> )
2851 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
2855 const size_t jpos( jend &
size_t(-SIMDSIZE) );
2859 Iterator left(
begin(i) + jbegin );
2860 ConstIterator_t<MT2> right( (~rhs).
begin(i) + jbegin );
2862 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2863 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2864 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2865 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2866 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2868 for( ; j<jpos; j+=SIMDSIZE ) {
2869 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2871 for( ; j<jend; ++j ) {
2872 *left += *right; ++left; ++right;
2892 template<
typename MT
2894 template<
typename MT2 >
2895 inline void Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
2902 constexpr
size_t block( BLOCK_SIZE );
2904 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
2905 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
2906 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
2907 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
2908 for(
size_t i=ii; i<iend; ++i ) {
2909 for(
size_t j=jj; j<jend; ++j ) {
2910 matrix_(
row()+i,
column()+j) += (~rhs)(i,j);
2932 template<
typename MT
2934 template<
typename MT2 >
2935 inline void Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const SparseMatrix<MT2,false>& rhs )
2940 for(
size_t i=0UL; i<
rows(); ++i )
2941 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
2942 matrix_(
row()+i,
column()+element->index()) += element->value();
2960 template<
typename MT
2962 template<
typename MT2 >
2963 inline void Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const SparseMatrix<MT2,true>& rhs )
2970 for(
size_t j=0UL; j<
columns(); ++j )
2971 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
2972 matrix_(
row()+element->index(),
column()+j) += element->value();
2990 template<
typename MT
2992 template<
typename MT2 >
2993 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
2994 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
2999 const size_t jpos(
columns() &
size_t(-2) );
3002 for(
size_t i=0UL; i<
rows(); ++i )
3004 if( IsDiagonal_v<MT2> ) {
3005 matrix_(
row()+i,
column()+i) -= (~rhs)(i,i);
3008 for(
size_t j=0UL; j<jpos; j+=2UL ) {
3009 matrix_(
row()+i,
column()+j ) -= (~rhs)(i,j );
3010 matrix_(
row()+i,
column()+j+1UL) -= (~rhs)(i,j+1UL);
3013 matrix_(
row()+i,
column()+jpos) -= (~rhs)(i,jpos);
3034 template<
typename MT
3036 template<
typename MT2 >
3037 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
3038 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
3045 for(
size_t i=0UL; i<
rows(); ++i )
3047 const size_t jbegin( ( IsUpper_v<MT2> )
3048 ?( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ) &
size_t(-SIMDSIZE) )
3050 const size_t jend ( ( IsLower_v<MT2> )
3051 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
3055 const size_t jpos( jend &
size_t(-SIMDSIZE) );
3059 Iterator left(
begin(i) + jbegin );
3060 ConstIterator_t<MT2> right( (~rhs).
begin(i) + jbegin );
3062 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3063 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3064 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3065 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3066 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3068 for( ; j<jpos; j+=SIMDSIZE ) {
3069 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3071 for( ; j<jend; ++j ) {
3072 *left -= *right; ++left; ++right;
3092 template<
typename MT
3094 template<
typename MT2 >
3095 inline void Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
3102 constexpr
size_t block( BLOCK_SIZE );
3104 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
3105 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
3106 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
3107 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
3108 for(
size_t i=ii; i<iend; ++i ) {
3109 for(
size_t j=jj; j<jend; ++j ) {
3110 matrix_(
row()+i,
column()+j) -= (~rhs)(i,j);
3132 template<
typename MT
3134 template<
typename MT2 >
3135 inline void Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const SparseMatrix<MT2,false>& rhs )
3140 for(
size_t i=0UL; i<
rows(); ++i )
3141 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
3142 matrix_(
row()+i,
column()+element->index()) -= element->value();
3160 template<
typename MT
3162 template<
typename MT2 >
3163 inline void Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const SparseMatrix<MT2,true>& rhs )
3170 for(
size_t j=0UL; j<
columns(); ++j )
3171 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
3172 matrix_(
row()+element->index(),
column()+j) -= element->value();
3190 template<
typename MT
3192 template<
typename MT2 >
3193 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
3194 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
3199 const size_t jpos(
columns() &
size_t(-2) );
3202 for(
size_t i=0UL; i<
rows(); ++i ) {
3203 for(
size_t j=0UL; j<jpos; j+=2UL ) {
3204 matrix_(
row()+i,
column()+j ) *= (~rhs)(i,j );
3205 matrix_(
row()+i,
column()+j+1UL) *= (~rhs)(i,j+1UL);
3208 matrix_(
row()+i,
column()+jpos) *= (~rhs)(i,jpos);
3228 template<
typename MT
3230 template<
typename MT2 >
3231 inline auto Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
3232 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
3239 for(
size_t i=0UL; i<
rows(); ++i )
3241 const size_t jpos(
columns() &
size_t(-SIMDSIZE) );
3245 Iterator left(
begin(i) );
3246 ConstIterator_t<MT2> right( (~rhs).
begin(i) );
3248 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3249 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3250 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3251 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3252 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3254 for( ; j<jpos; j+=SIMDSIZE ) {
3255 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3258 *left *= *right; ++left; ++right;
3278 template<
typename MT
3280 template<
typename MT2 >
3281 inline void Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
3288 constexpr
size_t block( BLOCK_SIZE );
3290 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
3291 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
3292 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
3293 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
3294 for(
size_t i=ii; i<iend; ++i ) {
3295 for(
size_t j=jj; j<jend; ++j ) {
3296 matrix_(
row()+i,
column()+j) *= (~rhs)(i,j);
3318 template<
typename MT
3320 template<
typename MT2 >
3321 inline void Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
3328 for(
size_t i=0UL; i<
rows(); ++i )
3332 for( ConstIterator_t<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element ) {
3333 for( ; j<element->index(); ++j )
3335 matrix_(
row()+i,
column()+j) *= element->value();
3360 template<
typename MT
3362 template<
typename MT2 >
3363 inline void Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
3372 for(
size_t j=0UL; j<
columns(); ++j )
3376 for( ConstIterator_t<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element ) {
3377 for( ; i<element->index(); ++i )
3379 matrix_(
row()+i,
column()+j) *= element->value();
3383 for( ; i<
rows(); ++i ) {
3412 template<
typename MT
3414 class Submatrix<MT,
unaligned,true,true,CSAs...>
3415 :
public View< DenseMatrix< Submatrix<MT,unaligned,true,true,CSAs...>, true > >
3416 ,
private SubmatrixData<CSAs...>
3420 using DataType = SubmatrixData<CSAs...>;
3421 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
3426 template<
typename MT1,
typename MT2 >
3427 static constexpr
bool EnforceEvaluation_v =
3428 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
3434 using This = Submatrix<MT,
unaligned,
true,
true,CSAs...>;
3436 using BaseType = DenseMatrix<This,true>;
3437 using ViewedType = MT;
3439 using OppositeType = OppositeType_t<ResultType>;
3440 using TransposeType = TransposeType_t<ResultType>;
3441 using ElementType = ElementType_t<MT>;
3442 using SIMDType = SIMDTrait_t<ElementType>;
3443 using ReturnType = ReturnType_t<MT>;
3444 using CompositeType =
const Submatrix&;
3447 using ConstReference = ConstReference_t<MT>;
3450 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
3453 using ConstPointer = ConstPointer_t<MT>;
3456 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
3462 template<
typename IteratorType >
3463 class SubmatrixIterator
3468 using IteratorCategory =
typename std::iterator_traits<IteratorType>::iterator_category;
3471 using ValueType =
typename std::iterator_traits<IteratorType>::value_type;
3474 using PointerType =
typename std::iterator_traits<IteratorType>::pointer;
3477 using ReferenceType =
typename std::iterator_traits<IteratorType>::reference;
3480 using DifferenceType =
typename std::iterator_traits<IteratorType>::difference_type;
3483 using iterator_category = IteratorCategory;
3484 using value_type = ValueType;
3485 using pointer = PointerType;
3486 using reference = ReferenceType;
3487 using difference_type = DifferenceType;
3493 inline SubmatrixIterator()
3495 , isAligned_( false )
3507 inline SubmatrixIterator( IteratorType iterator,
bool isMemoryAligned )
3508 : iterator_ ( iterator )
3509 , isAligned_( isMemoryAligned )
3518 template<
typename IteratorType2 >
3519 inline SubmatrixIterator(
const SubmatrixIterator<IteratorType2>& it )
3520 : iterator_ ( it.base() )
3521 , isAligned_( it.isAligned() )
3531 inline SubmatrixIterator&
operator+=(
size_t inc ) {
3543 inline SubmatrixIterator&
operator-=(
size_t dec ) {
3554 inline SubmatrixIterator& operator++() {
3565 inline const SubmatrixIterator operator++(
int ) {
3566 return SubmatrixIterator( iterator_++, isAligned_ );
3575 inline SubmatrixIterator& operator--() {
3586 inline const SubmatrixIterator operator--(
int ) {
3587 return SubmatrixIterator( iterator_--, isAligned_ );
3596 inline ReferenceType
operator*()
const {
3606 inline IteratorType operator->()
const {
3621 inline SIMDType load() const noexcept {
3639 inline SIMDType
loada() const noexcept {
3640 return iterator_.loada();
3654 inline SIMDType
loadu() const noexcept {
3655 return iterator_.loadu();
3670 inline void store(
const SIMDType& value )
const {
3691 inline void storea(
const SIMDType& value )
const {
3692 iterator_.storea( value );
3707 inline void storeu(
const SIMDType& value )
const {
3708 iterator_.storeu( value );
3723 inline void stream(
const SIMDType& value )
const {
3724 iterator_.stream( value );
3734 inline bool operator==(
const SubmatrixIterator& rhs )
const {
3735 return iterator_ == rhs.iterator_;
3745 inline bool operator!=(
const SubmatrixIterator& rhs )
const {
3746 return iterator_ != rhs.iterator_;
3756 inline bool operator<(
const SubmatrixIterator& rhs )
const {
3757 return iterator_ < rhs.iterator_;
3767 inline bool operator>(
const SubmatrixIterator& rhs )
const {
3768 return iterator_ > rhs.iterator_;
3778 inline bool operator<=(
const SubmatrixIterator& rhs )
const {
3779 return iterator_ <= rhs.iterator_;
3789 inline bool operator>=(
const SubmatrixIterator& rhs )
const {
3790 return iterator_ >= rhs.iterator_;
3800 inline DifferenceType
operator-(
const SubmatrixIterator& rhs )
const {
3801 return iterator_ - rhs.iterator_;
3812 friend inline const SubmatrixIterator
operator+(
const SubmatrixIterator& it,
size_t inc ) {
3813 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
3824 friend inline const SubmatrixIterator
operator+(
size_t inc,
const SubmatrixIterator& it ) {
3825 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
3836 friend inline const SubmatrixIterator
operator-(
const SubmatrixIterator& it,
size_t dec ) {
3837 return SubmatrixIterator( it.iterator_ - dec, it.isAligned_ );
3846 inline IteratorType base()
const {
3856 inline bool isAligned() const noexcept {
3863 IteratorType iterator_;
3871 using ConstIterator = SubmatrixIterator< ConstIterator_t<MT> >;
3874 using Iterator = If_t< IsConst_v<MT>, ConstIterator, SubmatrixIterator< Iterator_t<MT> > >;
3879 static constexpr
bool simdEnabled = MT::simdEnabled;
3882 static constexpr
bool smpAssignable = MT::smpAssignable;
3885 static constexpr
bool compileTimeArgs = DataType::compileTimeArgs;
3891 template<
typename... RSAs >
3892 explicit inline Submatrix( MT& matrix, RSAs... args );
3894 Submatrix(
const Submatrix& ) =
default;
3901 ~Submatrix() =
default;
3908 inline Reference operator()(
size_t i,
size_t j );
3909 inline ConstReference operator()(
size_t i,
size_t j )
const;
3910 inline Reference at(
size_t i,
size_t j );
3911 inline ConstReference at(
size_t i,
size_t j )
const;
3912 inline Pointer
data () noexcept;
3913 inline ConstPointer
data () const noexcept;
3914 inline Pointer
data (
size_t j ) noexcept;
3915 inline ConstPointer
data (
size_t j ) const noexcept;
3916 inline Iterator
begin (
size_t j );
3917 inline ConstIterator
begin (
size_t j ) const;
3918 inline ConstIterator
cbegin(
size_t j ) const;
3919 inline Iterator
end (
size_t j );
3920 inline ConstIterator
end (
size_t j ) const;
3921 inline ConstIterator
cend (
size_t j ) const;
3928 inline Submatrix& operator=( const ElementType& rhs );
3929 inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
3930 inline Submatrix& operator=( const Submatrix& rhs );
3932 template< typename MT2,
bool SO >
3933 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
3935 template< typename MT2,
bool SO >
3936 inline auto operator+=( const Matrix<MT2,SO>& rhs )
3937 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3939 template< typename MT2,
bool SO >
3940 inline auto operator+=( const Matrix<MT2,SO>& rhs )
3941 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3943 template< typename MT2,
bool SO >
3944 inline auto operator-=( const Matrix<MT2,SO>& rhs )
3945 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3947 template< typename MT2,
bool SO >
3948 inline auto operator-=( const Matrix<MT2,SO>& rhs )
3949 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3951 template< typename MT2,
bool SO >
3952 inline auto operator%=( const Matrix<MT2,SO>& rhs )
3953 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3955 template< typename MT2,
bool SO >
3956 inline auto operator%=( const Matrix<MT2,SO>& rhs )
3957 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3964 using DataType::
row;
3966 using DataType::
rows;
3969 inline MT& operand() noexcept;
3970 inline const MT& operand() const noexcept;
3972 inline
size_t spacing() const noexcept;
3973 inline
size_t capacity() const noexcept;
3974 inline
size_t capacity(
size_t i ) const noexcept;
3976 inline
size_t nonZeros(
size_t i ) const;
3977 inline
void reset();
3978 inline
void reset(
size_t i );
3988 template< typename Other > inline Submatrix& scale( const Other& scalar );
3995 template< typename MT2 >
3996 static constexpr
bool VectorizedAssign_v =
3997 ( useOptimizedKernels &&
3998 simdEnabled && MT2::simdEnabled &&
4004 template< typename MT2 >
4005 static constexpr
bool VectorizedAddAssign_v =
4006 ( useOptimizedKernels &&
4007 simdEnabled && MT2::simdEnabled &&
4015 template< typename MT2 >
4016 static constexpr
bool VectorizedSubAssign_v =
4017 ( useOptimizedKernels &&
4018 simdEnabled && MT2::simdEnabled &&
4026 template< typename MT2 >
4027 static constexpr
bool VectorizedSchurAssign_v =
4028 ( useOptimizedKernels &&
4029 simdEnabled && MT2::simdEnabled &&
4036 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
4043 template< typename Other >
4044 inline
bool canAlias( const Other* alias ) const noexcept;
4046 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
4047 inline
bool canAlias( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
4049 template< typename Other >
4050 inline
bool isAliased( const Other* alias ) const noexcept;
4052 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
4053 inline
bool isAliased( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
4055 inline
bool isAligned () const noexcept;
4056 inline
bool canSMPAssign() const noexcept;
4067 template< typename MT2 >
4068 inline auto assign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedAssign_v<MT2> >;
4070 template< typename MT2 >
4071 inline auto assign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedAssign_v<MT2> >;
4073 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,false>& rhs );
4074 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
4075 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
4077 template< typename MT2 >
4078 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<MT2> >;
4080 template< typename MT2 >
4081 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<MT2> >;
4083 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,false>& rhs );
4084 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
4085 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
4087 template< typename MT2 >
4088 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<MT2> >;
4090 template< typename MT2 >
4091 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<MT2> >;
4093 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,false>& rhs );
4094 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
4095 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
4097 template< typename MT2 >
4098 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedSchurAssign_v<MT2> >;
4100 template< typename MT2 >
4101 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedSchurAssign_v<MT2> >;
4103 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,false>& rhs );
4104 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
4105 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
4113 inline
bool hasOverlap() const noexcept;
4121 const
bool isAligned_;
4132 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
bool DF2,
size_t... CSAs2 > friend class Submatrix;
4170 template< typename MT
4172 template< typename... RSAs >
4173 inline Submatrix<MT,
unaligned,true,true,CSAs...>::Submatrix( MT& matrix, RSAs... args )
4174 : DataType ( args... )
4175 , matrix_ ( matrix )
4178 (
columns() < 2UL || ( matrix.
spacing() &
size_t(-SIMDSIZE) ) == 0UL ) )
4213 template<
typename MT
4215 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Reference
4216 Submatrix<MT,unaligned,true,true,CSAs...>::operator()(
size_t i,
size_t j )
4238 template<
typename MT
4240 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstReference
4241 Submatrix<MT,unaligned,true,true,CSAs...>::operator()(
size_t i,
size_t j )
const 4246 return const_cast<const MT&>( matrix_ )(
row()+i,
column()+j);
4264 template<
typename MT
4266 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Reference
4267 Submatrix<MT,unaligned,true,true,CSAs...>::at(
size_t i,
size_t j )
4275 return (*
this)(i,j);
4293 template<
typename MT
4295 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstReference
4296 Submatrix<MT,unaligned,true,true,CSAs...>::at(
size_t i,
size_t j )
const 4304 return (*
this)(i,j);
4320 template<
typename MT
4322 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Pointer
4341 template<
typename MT
4343 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstPointer
4361 template<
typename MT
4363 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Pointer
4381 template<
typename MT
4383 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstPointer
4399 template<
typename MT
4401 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Iterator
4405 return Iterator( matrix_.begin(
column() + j ) +
row(), isAligned_ );
4418 template<
typename MT
4420 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstIterator
4424 return ConstIterator( matrix_.cbegin(
column() + j ) +
row(), isAligned_ );
4437 template<
typename MT
4439 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstIterator
4443 return ConstIterator( matrix_.cbegin(
column() + j ) +
row(), isAligned_ );
4456 template<
typename MT
4458 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Iterator
4462 return Iterator( matrix_.begin(
column() + j ) +
row() +
rows(), isAligned_ );
4475 template<
typename MT
4477 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstIterator
4481 return ConstIterator( matrix_.cbegin(
column() + j ) +
row() +
rows(), isAligned_ );
4494 template<
typename MT
4496 inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstIterator
4500 return ConstIterator( matrix_.cbegin(
column() + j ) +
row() +
rows(), isAligned_ );
4525 template<
typename MT
4527 inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
4528 Submatrix<MT,unaligned,true,true,CSAs...>::operator=(
const ElementType& rhs )
4531 decltype(
auto) left( derestrict( matrix_ ) );
4533 for(
size_t j=
column(); j<jend; ++j )
4535 const size_t ibegin( ( IsLower_v<MT> )
4536 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
4540 const size_t iend ( ( IsUpper_v<MT> )
4541 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
4546 for(
size_t i=ibegin; i<iend; ++i ) {
4547 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, j, rhs ) )
4574 template<
typename MT
4576 inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
4577 Submatrix<MT,unaligned,true,true,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
4581 if( list.size() !=
rows() ) {
4585 if( IsRestricted_v<MT> ) {
4586 const InitializerMatrix<ElementType> tmp( list,
columns() );
4587 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
4592 decltype(
auto) left( derestrict( *this ) );
4595 for( const auto& rowList : list ) {
4597 for(
const auto& element : rowList ) {
4598 left(i,j) = element;
4628 template<
typename MT
4630 inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
4631 Submatrix<MT,unaligned,true,true,CSAs...>::operator=(
const Submatrix& rhs )
4636 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ &&
row() == rhs.row() &&
column() == rhs.column() ) )
4639 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
4643 if( !tryAssign( matrix_, rhs,
row(),
column() ) ) {
4647 decltype(
auto) left( derestrict( *this ) );
4649 if( rhs.canAlias( &matrix_ ) ) {
4650 const ResultType tmp( rhs );
4680 template<
typename MT
4682 template<
typename MT2
4684 inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
4685 Submatrix<MT,unaligned,true,true,CSAs...>::operator=(
const Matrix<MT2,SO>& rhs )
4693 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>,
const MT2& >;
4694 Right right( ~rhs );
4696 if( !tryAssign( matrix_, right,
row(),
column() ) ) {
4700 decltype(
auto) left( derestrict( *this ) );
4703 const ResultType_t<MT2> tmp( right );
4704 if( IsSparseMatrix_v<MT2> )
4709 if( IsSparseMatrix_v<MT2> )
4736 template<
typename MT
4738 template<
typename MT2
4741 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4747 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4756 if( !tryAddAssign( matrix_, ~rhs,
row(),
column() ) ) {
4760 decltype(
auto) left( derestrict( *this ) );
4763 (~rhs).canAlias( &matrix_ ) ) {
4764 const AddType tmp( *
this + (~rhs) );
4793 template<
typename MT
4795 template<
typename MT2
4798 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4804 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4813 const AddType tmp( *
this + (~rhs) );
4815 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
4819 decltype(
auto) left( derestrict( *this ) );
4845 template< typename MT
4847 template< typename MT2
4849 inline auto Submatrix<MT,
unaligned,true,true,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
4850 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4856 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4865 if( !trySubAssign( matrix_, ~rhs,
row(),
column() ) ) {
4869 decltype(
auto) left( derestrict( *this ) );
4872 (~rhs).canAlias( &matrix_ ) ) {
4873 const SubType tmp( *
this - (~rhs ) );
4902 template<
typename MT
4904 template<
typename MT2
4907 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4913 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4922 const SubType tmp( *
this - (~rhs) );
4924 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
4928 decltype(
auto) left( derestrict( *this ) );
4954 template< typename MT
4956 template< typename MT2
4958 inline auto Submatrix<MT,
unaligned,true,true,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
4959 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4965 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4973 if( !trySchurAssign( matrix_, ~rhs,
row(),
column() ) ) {
4977 decltype(
auto) left( derestrict( *this ) );
4980 (~rhs).canAlias( &matrix_ ) ) {
4981 const SchurType tmp( *
this % (~rhs) );
4982 if( IsSparseMatrix_v<SchurType> )
5012 template<
typename MT
5014 template<
typename MT2
5016 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
5017 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
5023 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
5031 const SchurType tmp( *
this % (~rhs) );
5033 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
5037 decltype(
auto) left( derestrict( *this ) );
5067 template<
typename MT
5069 inline MT& Submatrix<MT,unaligned,true,true,CSAs...>::operand() noexcept
5083 template<
typename MT
5085 inline const MT& Submatrix<MT,unaligned,true,true,CSAs...>::operand() const noexcept
5102 template<
typename MT
5106 return matrix_.spacing();
5118 template<
typename MT
5135 template<
typename MT
5155 template<
typename MT
5159 const size_t iend(
row() +
rows() );
5161 size_t nonzeros( 0UL );
5163 for(
size_t j=
column(); j<jend; ++j )
5164 for(
size_t i=
row(); i<iend; ++i )
5181 template<
typename MT
5187 const size_t iend(
row() +
rows() );
5188 size_t nonzeros( 0UL );
5190 for(
size_t i=
row(); i<iend; ++i )
5206 template<
typename MT
5214 const size_t ibegin( ( IsLower_v<MT> )
5215 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
5219 const size_t iend ( ( IsUpper_v<MT> )
5220 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
5225 for(
size_t i=ibegin; i<iend; ++i )
5226 clear( matrix_(i,j) );
5240 template<
typename MT
5248 const size_t ibegin( ( IsLower_v<MT> )
5249 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
5253 const size_t iend ( ( IsUpper_v<MT> )
5254 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
5259 for(
size_t i=ibegin; i<iend; ++i )
5276 template<
typename MT
5278 inline bool Submatrix<MT,unaligned,true,true,CSAs...>::hasOverlap() const noexcept
5316 template<
typename MT
5318 inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
5329 decltype(
auto) left( derestrict( *this ) );
5330 const ResultType tmp(
trans( *this ) );
5358 template< typename MT
5360 inline Submatrix<MT,
unaligned,true,true,CSAs...>&
5371 decltype(
auto) left( derestrict( *this ) );
5372 const ResultType tmp(
ctrans( *this ) );
5395 template< typename MT
5397 template< typename Other >
5398 inline Submatrix<MT,
unaligned,true,true,CSAs...>&
5399 Submatrix<MT,
unaligned,true,true,CSAs...>::scale( const Other& scalar )
5405 for(
size_t j=
column(); j<jend; ++j )
5407 const size_t ibegin( ( IsLower_v<MT> )
5408 ?( ( IsStrictlyLower_v<MT> )
5412 const size_t iend ( ( IsUpper_v<MT> )
5413 ?( ( IsStrictlyUpper_v<MT> )
5418 for(
size_t i=ibegin; i<iend; ++i )
5419 matrix_(i,j) *= scalar;
5447 template<
typename MT
5449 template<
typename Other >
5450 inline bool Submatrix<MT,unaligned,true,true,CSAs...>::canAlias(
const Other* alias )
const noexcept
5452 return matrix_.isAliased( alias );
5469 template<
typename MT
5471 template<
typename MT2
5476 Submatrix<MT,unaligned,true,true,CSAs...>::canAlias(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
5478 return ( matrix_.isAliased( &alias->matrix_ ) &&
5479 (
row() +
rows() > alias->row() ) &&
5480 (
row() < alias->row() + alias->rows() ) &&
5482 (
column() < alias->column() + alias->columns() ) );
5499 template<
typename MT
5501 template<
typename Other >
5502 inline bool Submatrix<MT,unaligned,true,true,CSAs...>::isAliased(
const Other* alias )
const noexcept
5504 return matrix_.isAliased( alias );
5521 template<
typename MT
5523 template<
typename MT2
5528 Submatrix<MT,unaligned,true,true,CSAs...>::isAliased(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
5530 return ( matrix_.isAliased( &alias->matrix_ ) &&
5531 (
row() +
rows() > alias->row() ) &&
5532 (
row() < alias->row() + alias->rows() ) &&
5534 (
column() < alias->column() + alias->columns() ) );
5550 template<
typename MT
5552 inline bool Submatrix<MT,unaligned,true,true,CSAs...>::isAligned() const noexcept
5571 template<
typename MT
5573 inline bool Submatrix<MT,unaligned,true,true,CSAs...>::canSMPAssign() const noexcept
5575 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
5596 template<
typename MT
5599 Submatrix<MT,unaligned,true,true,CSAs...>::load(
size_t i,
size_t j )
const noexcept
5602 return loada( i, j );
5604 return loadu( i, j );
5625 template<
typename MT
5637 return matrix_.loada(
row()+i,
column()+j );
5658 template<
typename MT
5669 return matrix_.loadu(
row()+i,
column()+j );
5691 template<
typename MT
5694 Submatrix<MT,unaligned,true,true,CSAs...>::store(
size_t i,
size_t j,
const SIMDType& value ) noexcept
5721 template<
typename MT
5733 matrix_.storea(
row()+i,
column()+j, value );
5755 template<
typename MT
5766 matrix_.storeu(
row()+i,
column()+j, value );
5789 template<
typename MT
5802 matrix_.stream(
row()+i,
column()+j, value );
5804 matrix_.storeu(
row()+i,
column()+j, value );
5822 template<
typename MT
5824 template<
typename MT2 >
5825 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
5826 -> DisableIf_t< VectorizedAssign_v<MT2> >
5831 const size_t ipos(
rows() &
size_t(-2) );
5834 for(
size_t j=0UL; j<
columns(); ++j ) {
5835 for(
size_t i=0UL; i<ipos; i+=2UL ) {
5836 matrix_(
row()+i ,
column()+j) = (~rhs)(i ,j);
5837 matrix_(
row()+i+1UL,
column()+j) = (~rhs)(i+1UL,j);
5839 if( ipos <
rows() ) {
5840 matrix_(
row()+ipos,
column()+j) = (~rhs)(ipos,j);
5860 template<
typename MT
5862 template<
typename MT2 >
5863 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
5864 -> EnableIf_t< VectorizedAssign_v<MT2> >
5871 const size_t ipos(
rows() &
size_t(-SIMDSIZE) );
5874 if( useStreaming && isAligned_ &&
5875 rows()*
columns() > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
5876 !(~rhs).isAliased( &matrix_ ) )
5878 for(
size_t j=0UL; j<
columns(); ++j )
5881 Iterator left(
begin(j) );
5882 ConstIterator_t<MT2> right( (~rhs).
begin(j) );
5884 for( ; i<ipos; i+=SIMDSIZE ) {
5885 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5887 for( ; i<
rows(); ++i ) {
5888 *left = *right; ++left; ++right;
5894 for(
size_t j=0UL; j<
columns(); ++j )
5897 Iterator left(
begin(j) );
5898 ConstIterator_t<MT2> right( (~rhs).
begin(j) );
5900 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5901 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5902 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5903 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5904 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5906 for( ; i<ipos; i+=SIMDSIZE ) {
5907 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5909 for( ; i<
rows(); ++i ) {
5910 *left = *right; ++left; ++right;
5931 template<
typename MT
5933 template<
typename MT2 >
5934 inline void Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
5941 constexpr
size_t block( BLOCK_SIZE );
5943 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
5944 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
5945 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
5946 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
5947 for(
size_t j=jj; j<jend; ++j ) {
5948 for(
size_t i=ii; i<iend; ++i ) {
5949 matrix_(
row()+i,
column()+j) = (~rhs)(i,j);
5971 template<
typename MT
5973 template<
typename MT2 >
5974 inline void Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const SparseMatrix<MT2,true>& rhs )
5979 for(
size_t j=0UL; j<
columns(); ++j )
5980 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
5981 matrix_(
row()+element->index(),
column()+j) = element->value();
5999 template<
typename MT
6001 template<
typename MT2 >
6002 inline void Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const SparseMatrix<MT2,false>& rhs )
6009 for(
size_t i=0UL; i<
rows(); ++i )
6010 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
6011 matrix_(
row()+i,
column()+element->index()) = element->value();
6029 template<
typename MT
6031 template<
typename MT2 >
6032 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
6033 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
6038 const size_t ipos(
rows() &
size_t(-2) );
6041 for(
size_t j=0UL; j<
columns(); ++j )
6043 if( IsDiagonal_v<MT2> ) {
6044 matrix_(
row()+j,
column()+j) += (~rhs)(j,j);
6047 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6048 matrix_(
row()+i ,
column()+j) += (~rhs)(i ,j);
6049 matrix_(
row()+i+1UL,
column()+j) += (~rhs)(i+1UL,j);
6051 if( ipos <
rows() ) {
6052 matrix_(
row()+ipos,
column()+j) += (~rhs)(ipos,j);
6073 template<
typename MT
6075 template<
typename MT2 >
6076 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
6077 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
6084 for(
size_t j=0UL; j<
columns(); ++j )
6086 const size_t ibegin( ( IsLower_v<MT> )
6087 ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) &
size_t(-SIMDSIZE) )
6089 const size_t iend ( ( IsUpper_v<MT> )
6090 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6094 const size_t ipos( iend &
size_t(-SIMDSIZE) );
6098 Iterator left(
begin(j) + ibegin );
6099 ConstIterator_t<MT2> right( (~rhs).
begin(j) + ibegin );
6101 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6102 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6103 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6104 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6105 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6107 for( ; i<ipos; i+=SIMDSIZE ) {
6108 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6110 for( ; i<iend; ++i ) {
6111 *left += *right; ++left; ++right;
6131 template<
typename MT
6133 template<
typename MT2 >
6134 inline void Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
6141 constexpr
size_t block( BLOCK_SIZE );
6143 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
6144 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
6145 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
6146 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
6147 for(
size_t j=jj; j<jend; ++j ) {
6148 for(
size_t i=ii; i<iend; ++i ) {
6149 matrix_(
row()+i,
column()+j) += (~rhs)(i,j);
6171 template<
typename MT
6173 template<
typename MT2 >
6174 inline void Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const SparseMatrix<MT2,true>& rhs )
6179 for(
size_t j=0UL; j<
columns(); ++j )
6180 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
6181 matrix_(
row()+element->index(),
column()+j) += element->value();
6199 template<
typename MT
6201 template<
typename MT2 >
6202 inline void Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const SparseMatrix<MT2,false>& rhs )
6209 for(
size_t i=0UL; i<
rows(); ++i )
6210 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
6211 matrix_(
row()+i,
column()+element->index()) += element->value();
6229 template<
typename MT
6231 template<
typename MT2 >
6232 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
6233 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
6238 const size_t ipos(
rows() &
size_t(-2) );
6241 for(
size_t j=0UL; j<
columns(); ++j )
6243 if( IsDiagonal_v<MT2> ) {
6244 matrix_(
row()+j,
column()+j) -= (~rhs)(j,j);
6247 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6248 matrix_(
row()+i ,
column()+j) -= (~rhs)(i ,j);
6249 matrix_(
row()+i+1UL,
column()+j) -= (~rhs)(i+1UL,j);
6251 if( ipos <
rows() ) {
6252 matrix_(
row()+ipos,
column()+j) -= (~rhs)(ipos,j);
6273 template<
typename MT
6275 template<
typename MT2 >
6276 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
6277 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
6284 for(
size_t j=0UL; j<
columns(); ++j )
6286 const size_t ibegin( ( IsLower_v<MT> )
6287 ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) &
size_t(-SIMDSIZE) )
6289 const size_t iend ( ( IsUpper_v<MT> )
6290 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6294 const size_t ipos( iend &
size_t(-SIMDSIZE) );
6298 Iterator left(
begin(j) + ibegin );
6299 ConstIterator_t<MT2> right( (~rhs).
begin(j) + ibegin );
6301 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6302 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6303 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6304 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6305 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6307 for( ; i<ipos; i+=SIMDSIZE ) {
6308 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6310 for( ; i<iend; ++i ) {
6311 *left -= *right; ++left; ++right;
6331 template<
typename MT
6333 template<
typename MT2 >
6334 inline void Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
6341 constexpr
size_t block( BLOCK_SIZE );
6343 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
6344 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
6345 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
6346 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
6347 for(
size_t j=jj; j<jend; ++j ) {
6348 for(
size_t i=ii; i<iend; ++i ) {
6349 matrix_(
row()+i,
column()+j) -= (~rhs)(i,j);
6371 template<
typename MT
6373 template<
typename MT2 >
6374 inline void Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const SparseMatrix<MT2,true>& rhs )
6379 for(
size_t j=0UL; j<
columns(); ++j )
6380 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
6381 matrix_(
row()+element->index(),
column()+j) -= element->value();
6399 template<
typename MT
6401 template<
typename MT2 >
6402 inline void Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const SparseMatrix<MT2,false>& rhs )
6409 for(
size_t i=0UL; i<
rows(); ++i )
6410 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
6411 matrix_(
row()+i,
column()+element->index()) -= element->value();
6429 template<
typename MT
6431 template<
typename MT2 >
6432 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
6433 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
6438 const size_t ipos(
rows() &
size_t(-2) );
6441 for(
size_t j=0UL; j<
columns(); ++j ) {
6442 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6443 matrix_(
row()+i ,
column()+j) *= (~rhs)(i ,j);
6444 matrix_(
row()+i+1UL,
column()+j) *= (~rhs)(i+1UL,j);
6446 if( ipos <
rows() ) {
6447 matrix_(
row()+ipos,
column()+j) *= (~rhs)(ipos,j);
6468 template<
typename MT
6470 template<
typename MT2 >
6471 inline auto Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
6472 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
6479 for(
size_t j=0UL; j<
columns(); ++j )
6481 const size_t ipos(
rows() &
size_t(-SIMDSIZE) );
6485 Iterator left(
begin(j) );
6486 ConstIterator_t<MT2> right( (~rhs).
begin(j) );
6488 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6489 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6490 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6491 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6492 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6494 for( ; i<ipos; i+=SIMDSIZE ) {
6495 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6497 for( ; i<
rows(); ++i ) {
6498 *left *= *right; ++left; ++right;
6518 template<
typename MT
6520 template<
typename MT2 >
6521 inline void Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
6528 constexpr
size_t block( BLOCK_SIZE );
6530 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
6531 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
6532 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
6533 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
6534 for(
size_t j=jj; j<jend; ++j ) {
6535 for(
size_t i=ii; i<iend; ++i ) {
6536 matrix_(
row()+i,
column()+j) *= (~rhs)(i,j);
6558 template<
typename MT
6560 template<
typename MT2 >
6561 inline void Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
6568 for(
size_t j=0UL; j<
columns(); ++j )
6572 for( ConstIterator_t<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element ) {
6573 for( ; i<element->index(); ++i )
6575 matrix_(
row()+i,
column()+j) *= element->value();
6579 for( ; i<
rows(); ++i ) {
6600 template<
typename MT
6602 template<
typename MT2 >
6603 inline void Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
6612 for(
size_t i=0UL; i<
rows(); ++i )
6616 for( ConstIterator_t<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element ) {
6617 for( ; j<element->index(); ++j )
6619 matrix_(
row()+i,
column()+j) *= element->value();
6652 template<
typename MT
6654 class Submatrix<MT,
aligned,false,true,CSAs...>
6655 :
public View< DenseMatrix< Submatrix<MT,aligned,false,true,CSAs...>, false > >
6656 ,
private SubmatrixData<CSAs...>
6660 using DataType = SubmatrixData<CSAs...>;
6661 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
6666 template<
typename MT1,
typename MT2 >
6667 static constexpr
bool EnforceEvaluation_v =
6668 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
6674 using This = Submatrix<MT,
aligned,
false,
true,CSAs...>;
6676 using BaseType = DenseMatrix<This,false>;
6677 using ViewedType = MT;
6679 using OppositeType = OppositeType_t<ResultType>;
6680 using TransposeType = TransposeType_t<ResultType>;
6681 using ElementType = ElementType_t<MT>;
6682 using SIMDType = SIMDTrait_t<ElementType>;
6683 using ReturnType = ReturnType_t<MT>;
6684 using CompositeType =
const Submatrix&;
6687 using ConstReference = ConstReference_t<MT>;
6690 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
6693 using ConstPointer = ConstPointer_t<MT>;
6696 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
6699 using ConstIterator = ConstIterator_t<MT>;
6702 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
6707 static constexpr
bool simdEnabled = MT::simdEnabled;
6710 static constexpr
bool smpAssignable = MT::smpAssignable;
6713 static constexpr
bool compileTimeArgs = DataType::compileTimeArgs;
6719 template<
typename... RSAs >
6720 explicit inline Submatrix( MT& matrix, RSAs... args );
6722 Submatrix(
const Submatrix& ) =
default;
6729 ~Submatrix() =
default;
6736 inline Reference operator()(
size_t i,
size_t j );
6737 inline ConstReference operator()(
size_t i,
size_t j )
const;
6738 inline Reference at(
size_t i,
size_t j );
6739 inline ConstReference at(
size_t i,
size_t j )
const;
6740 inline Pointer
data () noexcept;
6741 inline ConstPointer
data () const noexcept;
6742 inline Pointer
data (
size_t i ) noexcept;
6743 inline ConstPointer
data (
size_t i ) const noexcept;
6744 inline Iterator
begin (
size_t i );
6745 inline ConstIterator
begin (
size_t i ) const;
6746 inline ConstIterator
cbegin(
size_t i ) const;
6747 inline Iterator
end (
size_t i );
6748 inline ConstIterator
end (
size_t i ) const;
6749 inline ConstIterator
cend (
size_t i ) const;
6756 inline Submatrix& operator=( const ElementType& rhs );
6757 inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
6758 inline Submatrix& operator=( const Submatrix& rhs );
6760 template< typename MT2,
bool SO >
6761 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
6763 template< typename MT2,
bool SO >
6764 inline auto operator+=( const Matrix<MT2,SO>& rhs )
6765 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6767 template< typename MT2,
bool SO >
6768 inline auto operator+=( const Matrix<MT2,SO>& rhs )
6769 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6771 template< typename MT2,
bool SO >
6772 inline auto operator-=( const Matrix<MT2,SO>& rhs )
6773 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6775 template< typename MT2,
bool SO >
6776 inline auto operator-=( const Matrix<MT2,SO>& rhs )
6777 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6779 template< typename MT2,
bool SO >
6780 inline auto operator%=( const Matrix<MT2,SO>& rhs )
6781 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6783 template< typename MT2,
bool SO >
6784 inline auto operator%=( const Matrix<MT2,SO>& rhs )
6785 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6792 using DataType::
row;
6794 using DataType::
rows;
6797 inline MT& operand() noexcept;
6798 inline const MT& operand() const noexcept;
6800 inline
size_t spacing() const noexcept;
6801 inline
size_t capacity() const noexcept;
6802 inline
size_t capacity(
size_t i ) const noexcept;
6804 inline
size_t nonZeros(
size_t i ) const;
6805 inline
void reset();
6806 inline
void reset(
size_t i );
6816 template< typename Other > inline Submatrix& scale( const Other& scalar );
6823 template< typename MT2 >
6824 static constexpr
bool VectorizedAssign_v =
6825 ( useOptimizedKernels &&
6826 simdEnabled && MT2::simdEnabled &&
6832 template< typename MT2 >
6833 static constexpr
bool VectorizedAddAssign_v =
6834 ( useOptimizedKernels &&
6835 simdEnabled && MT2::simdEnabled &&
6843 template< typename MT2 >
6844 static constexpr
bool VectorizedSubAssign_v =
6845 ( useOptimizedKernels &&
6846 simdEnabled && MT2::simdEnabled &&
6854 template< typename MT2 >
6855 static constexpr
bool VectorizedSchurAssign_v =
6856 ( useOptimizedKernels &&
6857 simdEnabled && MT2::simdEnabled &&
6864 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
6871 template< typename Other >
6872 inline
bool canAlias( const Other* alias ) const noexcept;
6874 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
6875 inline
bool canAlias( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
6877 template< typename Other >
6878 inline
bool isAliased( const Other* alias ) const noexcept;
6880 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
6881 inline
bool isAliased( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
6883 inline
bool isAligned () const noexcept;
6884 inline
bool canSMPAssign() const noexcept;
6895 template< typename MT2 >
6896 inline auto assign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedAssign_v<MT2> >;
6898 template< typename MT2 >
6899 inline auto assign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedAssign_v<MT2> >;
6901 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,true>& rhs );
6902 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
6903 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
6905 template< typename MT2 >
6906 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<MT2> >;
6908 template< typename MT2 >
6909 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<MT2> >;
6911 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,true>& rhs );
6912 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
6913 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
6915 template< typename MT2 >
6916 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<MT2> >;
6918 template< typename MT2 >
6919 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<MT2> >;
6921 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,true>& rhs );
6922 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
6923 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
6925 template< typename MT2 >
6926 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedSchurAssign_v<MT2> >;
6928 template< typename MT2 >
6929 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedSchurAssign_v<MT2> >;
6931 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,true>& rhs );
6932 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
6933 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
6941 inline
bool hasOverlap() const noexcept;
6953 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
bool DF2,
size_t... CSAs2 > friend class Submatrix;
6991 template< typename MT
6993 template< typename... RSAs >
6994 inline Submatrix<MT,
aligned,false,true,CSAs...>::Submatrix( MT& matrix, RSAs... args )
6995 : DataType( args... )
6996 , matrix_ ( matrix )
7004 if( simdEnabled && IsContiguous_v<MT> &&
7006 (
rows() > 1UL && matrix_.spacing() % SIMDSIZE != 0UL ) ) ) {
7016 BLAZE_USER_ASSERT( !simdEnabled || !IsContiguous_v<MT> ||
rows() <= 1UL || matrix_.spacing() % SIMDSIZE == 0UL,
"Invalid submatrix alignment" );
7042 template<
typename MT
7044 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Reference
7045 Submatrix<MT,aligned,false,true,CSAs...>::operator()(
size_t i,
size_t j )
7067 template<
typename MT
7069 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstReference
7070 Submatrix<MT,aligned,false,true,CSAs...>::operator()(
size_t i,
size_t j )
const 7075 return const_cast<const MT&>( matrix_ )(
row()+i,
column()+j);
7093 template<
typename MT
7095 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Reference
7096 Submatrix<MT,aligned,false,true,CSAs...>::at(
size_t i,
size_t j )
7104 return (*
this)(i,j);
7122 template<
typename MT
7124 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstReference
7125 Submatrix<MT,aligned,false,true,CSAs...>::at(
size_t i,
size_t j )
const 7133 return (*
this)(i,j);
7149 template<
typename MT
7151 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Pointer
7170 template<
typename MT
7172 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstPointer
7190 template<
typename MT
7192 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Pointer
7210 template<
typename MT
7212 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstPointer
7233 template<
typename MT
7235 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Iterator
7239 return ( matrix_.begin(
row() + i ) +
column() );
7257 template<
typename MT
7259 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstIterator
7263 return ( matrix_.cbegin(
row() + i ) +
column() );
7281 template<
typename MT
7283 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstIterator
7287 return ( matrix_.cbegin(
row() + i ) +
column() );
7305 template<
typename MT
7307 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Iterator
7329 template<
typename MT
7331 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstIterator
7353 template<
typename MT
7355 inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstIterator
7384 template<
typename MT
7386 inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
7387 Submatrix<MT,aligned,false,true,CSAs...>::operator=(
const ElementType& rhs )
7389 const size_t iend(
row() +
rows() );
7390 decltype(
auto) left( derestrict( matrix_ ) );
7392 for(
size_t i=
row(); i<iend; ++i )
7394 const size_t jbegin( ( IsUpper_v<MT> )
7395 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
7399 const size_t jend ( ( IsLower_v<MT> )
7400 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
7405 for(
size_t j=jbegin; j<jend; ++j ) {
7406 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, j, rhs ) )
7433 template<
typename MT
7435 inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
7436 Submatrix<MT,aligned,false,true,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
7438 if( list.size() !=
rows() ) {
7442 if( IsRestricted_v<MT> ) {
7443 const InitializerMatrix<ElementType> tmp( list,
columns() );
7444 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
7449 decltype(
auto) left( derestrict( *this ) );
7452 for( const auto& rowList : list ) {
7453 std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
7478 template<
typename MT
7480 inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
7481 Submatrix<MT,aligned,false,true,CSAs...>::operator=(
const Submatrix& rhs )
7486 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ &&
row() == rhs.row() &&
column() == rhs.column() ) )
7489 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
7493 if( !tryAssign( matrix_, rhs,
row(),
column() ) ) {
7497 decltype(
auto) left( derestrict( *this ) );
7499 if( rhs.canAlias( &matrix_ ) ) {
7500 const ResultType tmp( rhs );
7530 template<
typename MT
7532 template<
typename MT2
7534 inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
7535 Submatrix<MT,aligned,false,true,CSAs...>::operator=(
const Matrix<MT2,SO>& rhs )
7543 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>,
const MT2& >;
7544 Right right( ~rhs );
7546 if( !tryAssign( matrix_, right,
row(),
column() ) ) {
7550 decltype(
auto) left( derestrict( *this ) );
7553 const ResultType_t<MT2> tmp( right );
7554 if( IsSparseMatrix_v<MT2> )
7559 if( IsSparseMatrix_v<MT2> )
7586 template<
typename MT
7588 template<
typename MT2
7591 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7597 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
7606 if( !tryAddAssign( matrix_, ~rhs,
row(),
column() ) ) {
7610 decltype(
auto) left( derestrict( *this ) );
7613 (~rhs).canAlias( &matrix_ ) ) {
7614 const AddType tmp( *
this + (~rhs) );
7643 template<
typename MT
7645 template<
typename MT2
7648 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7654 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
7663 const AddType tmp( *
this + (~rhs) );
7665 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
7669 decltype(
auto) left( derestrict( *this ) );
7695 template< typename MT
7697 template< typename MT2
7699 inline auto Submatrix<MT,
aligned,false,true,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
7700 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7706 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
7715 if( !trySubAssign( matrix_, ~rhs,
row(),
column() ) ) {
7719 decltype(
auto) left( derestrict( *this ) );
7722 (~rhs).canAlias( &matrix_ ) ) {
7723 const SubType tmp( *
this - (~rhs ) );
7752 template<
typename MT
7754 template<
typename MT2
7757 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7763 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
7772 const SubType tmp( *
this - (~rhs) );
7774 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
7778 decltype(
auto) left( derestrict( *this ) );
7804 template< typename MT
7806 template< typename MT2
7808 inline auto Submatrix<MT,
aligned,false,true,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
7809 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7815 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
7823 if( !trySchurAssign( matrix_, ~rhs,
row(),
column() ) ) {
7827 decltype(
auto) left( derestrict( *this ) );
7830 (~rhs).canAlias( &matrix_ ) ) {
7831 const SchurType tmp( *
this % (~rhs) );
7832 if( IsSparseMatrix_v<SchurType> )
7862 template<
typename MT
7864 template<
typename MT2
7866 inline auto Submatrix<MT,aligned,false,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
7867 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7873 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
7881 const SchurType tmp( *
this % (~rhs) );
7883 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
7887 decltype(
auto) left( derestrict( *this ) );
7917 template<
typename MT
7919 inline MT& Submatrix<MT,aligned,false,true,CSAs...>::operand() noexcept
7933 template<
typename MT
7935 inline const MT& Submatrix<MT,aligned,false,true,CSAs...>::operand() const noexcept
7954 template<
typename MT
7958 return matrix_.spacing();
7970 template<
typename MT
7992 template<
typename MT
8012 template<
typename MT
8016 const size_t iend(
row() +
rows() );
8018 size_t nonzeros( 0UL );
8020 for(
size_t i=
row(); i<iend; ++i )
8021 for(
size_t j=
column(); j<jend; ++j )
8043 template<
typename MT
8050 size_t nonzeros( 0UL );
8052 for(
size_t j=
column(); j<jend; ++j )
8068 template<
typename MT
8076 const size_t jbegin( ( IsUpper_v<MT> )
8077 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
8081 const size_t jend ( ( IsLower_v<MT> )
8082 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
8087 for(
size_t j=jbegin; j<jend; ++j )
8088 clear( matrix_(i,j) );
8107 template<
typename MT
8115 const size_t jbegin( ( IsUpper_v<MT> )
8116 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
8120 const size_t jend ( ( IsLower_v<MT> )
8121 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
8126 for(
size_t j=jbegin; j<jend; ++j )
8143 template<
typename MT
8145 inline bool Submatrix<MT,aligned,false,true,CSAs...>::hasOverlap() const noexcept
8183 template<
typename MT
8185 inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
8196 decltype(
auto) left( derestrict( *this ) );
8197 const ResultType tmp(
trans( *this ) );
8225 template< typename MT
8227 inline Submatrix<MT,
aligned,false,true,CSAs...>&
8238 decltype(
auto) left( derestrict( *this ) );
8239 const ResultType tmp(
ctrans( *this ) );
8262 template< typename MT
8264 template< typename Other >
8265 inline Submatrix<MT,
aligned,false,true,CSAs...>&
8266 Submatrix<MT,
aligned,false,true,CSAs...>::scale( const Other& scalar )
8270 const size_t iend(
row() +
rows() );
8272 for(
size_t i=
row(); i<iend; ++i )
8274 const size_t jbegin( ( IsUpper_v<MT> )
8275 ?( ( IsStrictlyUpper_v<MT> )
8279 const size_t jend ( ( IsLower_v<MT> )
8280 ?( ( IsStrictlyLower_v<MT> )
8285 for(
size_t j=jbegin; j<jend; ++j )
8286 matrix_(i,j) *= scalar;
8314 template<
typename MT
8316 template<
typename Other >
8317 inline bool Submatrix<MT,aligned,false,true,CSAs...>::canAlias(
const Other* alias )
const noexcept
8319 return matrix_.isAliased( alias );
8336 template<
typename MT
8338 template<
typename MT2
8343 Submatrix<MT,aligned,false,true,CSAs...>::canAlias(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
8345 return ( matrix_.isAliased( &alias->matrix_ ) &&
8346 (
row() +
rows() > alias->row() ) &&
8347 (
row() < alias->row() + alias->rows() ) &&
8349 (
column() < alias->column() + alias->columns() ) );
8366 template<
typename MT
8368 template<
typename Other >
8369 inline bool Submatrix<MT,aligned,false,true,CSAs...>::isAliased(
const Other* alias )
const noexcept
8371 return matrix_.isAliased( alias );
8388 template<
typename MT
8390 template<
typename MT2
8395 Submatrix<MT,aligned,false,true,CSAs...>::isAliased(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
8397 return ( matrix_.isAliased( &alias->matrix_ ) &&
8398 (
row() +
rows() > alias->row() ) &&
8399 (
row() < alias->row() + alias->rows() ) &&
8401 (
column() < alias->column() + alias->columns() ) );
8417 template<
typename MT
8419 inline bool Submatrix<MT,aligned,false,true,CSAs...>::isAligned() const noexcept
8438 template<
typename MT
8440 inline bool Submatrix<MT,aligned,false,true,CSAs...>::canSMPAssign() const noexcept
8442 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
8464 template<
typename MT
8467 Submatrix<MT,aligned,false,true,CSAs...>::load(
size_t i,
size_t j )
const noexcept
8469 return loada( i, j );
8491 template<
typename MT
8503 return matrix_.loada(
row()+i,
column()+j );
8525 template<
typename MT
8536 return matrix_.loadu(
row()+i,
column()+j );
8559 template<
typename MT
8562 Submatrix<MT,aligned,false,true,CSAs...>::store(
size_t i,
size_t j,
const SIMDType& value ) noexcept
8564 return storea( i, j, value );
8587 template<
typename MT
8599 return matrix_.storea(
row()+i,
column()+j, value );
8622 template<
typename MT
8633 matrix_.storeu(
row()+i,
column()+j, value );
8657 template<
typename MT
8669 matrix_.stream(
row()+i,
column()+j, value );
8687 template<
typename MT
8689 template<
typename MT2 >
8690 inline auto Submatrix<MT,aligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
8691 -> DisableIf_t< VectorizedAssign_v<MT2> >
8696 const size_t jpos(
columns() &
size_t(-2) );
8699 for(
size_t i=0UL; i<
rows(); ++i ) {
8700 for(
size_t j=0UL; j<jpos; j+=2UL ) {
8701 matrix_(
row()+i,
column()+j ) = (~rhs)(i,j );
8702 matrix_(
row()+i,
column()+j+1UL) = (~rhs)(i,j+1UL);
8705 matrix_(
row()+i,
column()+jpos) = (~rhs)(i,jpos);
8725 template<
typename MT
8727 template<
typename MT2 >
8728 inline auto Submatrix<MT,aligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
8729 -> EnableIf_t< VectorizedAssign_v<MT2> >
8736 const size_t jpos(
columns() &
size_t(-SIMDSIZE) );
8740 rows()*
columns() > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
8741 !(~rhs).isAliased( &matrix_ ) )
8743 for(
size_t i=0UL; i<
rows(); ++i )
8746 Iterator left(
begin(i) );
8747 ConstIterator_t<MT2> right( (~rhs).
begin(i) );
8749 for( ; j<jpos; j+=SIMDSIZE ) {
8750 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8753 *left = *right; ++left; ++right;
8759 for(
size_t i=0UL; i<
rows(); ++i )
8762 Iterator left(
begin(i) );
8763 ConstIterator_t<MT2> right( (~rhs).
begin(i) );
8765 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
8766 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8767 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8768 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8769 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8771 for( ; j<jpos; j+=SIMDSIZE ) {
8772 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8775 *left = *right; ++left; ++right;
8796 template<
typename MT
8798 template<
typename MT2 >
8799 inline void Submatrix<MT,aligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
8806 constexpr
size_t block( BLOCK_SIZE );
8808 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
8809 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
8810 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
8811 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
8812 for(
size_t i=ii; i<iend; ++i ) {
8813 for(
size_t j=jj; j<jend; ++j ) {
8814 matrix_(
row()+i,
column()+j) = (~rhs)(i,j);
8836 template<
typename MT
8838 template<
typename MT2 >
8839 inline void Submatrix<MT,aligned,false,true,CSAs...>::assign(
const SparseMatrix<MT2,false>& rhs )
8844 for(
size_t i=0UL; i<
rows(); ++i )
8845 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
8846 matrix_(
row()+i,
column()+element->index()) = element->value();
8864 template<
typename MT
8866 template<
typename MT2 >
8867 inline void Submatrix<MT,aligned,false,true,CSAs...>::assign(
const SparseMatrix<MT2,true>& rhs )
8874 for(
size_t j=0UL; j<
columns(); ++j )
8875 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
8876 matrix_(
row()+element->index(),
column()+j) = element->value();
8894 template<
typename MT
8896 template<
typename MT2 >
8897 inline auto Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
8898 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
8903 const size_t jpos(
columns() &
size_t(-2) );
8906 for(
size_t i=0UL; i<
rows(); ++i )
8908 if( IsDiagonal_v<MT2> ) {
8909 matrix_(
row()+i,
column()+i) += (~rhs)(i,i);
8912 for(
size_t j=0UL; j<jpos; j+=2UL ) {
8913 matrix_(
row()+i,
column()+j ) += (~rhs)(i,j );
8914 matrix_(
row()+i,
column()+j+1UL) += (~rhs)(i,j+1UL);
8917 matrix_(
row()+i,
column()+jpos) += (~rhs)(i,jpos);
8938 template<
typename MT
8940 template<
typename MT2 >
8941 inline auto Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
8942 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
8949 for(
size_t i=0UL; i<
rows(); ++i )
8951 const size_t jbegin( ( IsUpper_v<MT2> )
8952 ?( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ) &
size_t(-SIMDSIZE) )
8954 const size_t jend ( ( IsLower_v<MT2> )
8955 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
8959 const size_t jpos( jend &
size_t(-SIMDSIZE) );
8963 Iterator left(
begin(i) + jbegin );
8964 ConstIterator_t<MT2> right( (~rhs).
begin(i) + jbegin );
8966 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
8967 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8968 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8969 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8970 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8972 for( ; j<jpos; j+=SIMDSIZE ) {
8973 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8975 for( ; j<jend; ++j ) {
8976 *left += *right; ++left; ++right;
8996 template<
typename MT
8998 template<
typename MT2 >
8999 inline void Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
9006 constexpr
size_t block( BLOCK_SIZE );
9008 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
9009 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
9010 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
9011 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
9012 for(
size_t i=ii; i<iend; ++i ) {
9013 for(
size_t j=jj; j<jend; ++j ) {
9014 matrix_(
row()+i,
column()+j) += (~rhs)(i,j);
9036 template<
typename MT
9038 template<
typename MT2 >
9039 inline void Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const SparseMatrix<MT2,false>& rhs )
9044 for(
size_t i=0UL; i<
rows(); ++i )
9045 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
9046 matrix_(
row()+i,
column()+element->index()) += element->value();
9064 template<
typename MT
9066 template<
typename MT2 >
9067 inline void Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const SparseMatrix<MT2,true>& rhs )
9074 for(
size_t j=0UL; j<
columns(); ++j )
9075 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
9076 matrix_(
row()+element->index(),
column()+j) += element->value();
9094 template<
typename MT
9096 template<
typename MT2 >
9097 inline auto Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
9098 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
9103 const size_t jpos(
columns() &
size_t(-2) );
9106 for(
size_t i=0UL; i<
rows(); ++i )
9108 if( IsDiagonal_v<MT2> ) {
9109 matrix_(
row()+i,
column()+i) -= (~rhs)(i,i);
9112 for(
size_t j=0UL; j<jpos; j+=2UL ) {
9113 matrix_(
row()+i,
column()+j ) -= (~rhs)(i,j );
9114 matrix_(
row()+i,
column()+j+1UL) -= (~rhs)(i,j+1UL);
9117 matrix_(
row()+i,
column()+jpos) -= (~rhs)(i,jpos);
9138 template<
typename MT
9140 template<
typename MT2 >
9141 inline auto Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
9142 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
9149 for(
size_t i=0UL; i<
rows(); ++i )
9151 const size_t jbegin( ( IsUpper_v<MT2> )
9152 ?( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ) &
size_t(-SIMDSIZE) )
9154 const size_t jend ( ( IsLower_v<MT2> )
9155 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
9159 const size_t jpos( jend &
size_t(-SIMDSIZE) );
9163 Iterator left(
begin(i) + jbegin );
9164 ConstIterator_t<MT2> right( (~rhs).
begin(i) + jbegin );
9166 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
9167 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9168 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9169 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9170 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9172 for( ; j<jpos; j+=SIMDSIZE ) {
9173 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9175 for( ; j<jend; ++j ) {
9176 *left -= *right; ++left; ++right;
9196 template<
typename MT
9198 template<
typename MT2 >
9199 inline void Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
9206 constexpr
size_t block( BLOCK_SIZE );
9208 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
9209 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
9210 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
9211 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
9212 for(
size_t i=ii; i<iend; ++i ) {
9213 for(
size_t j=jj; j<jend; ++j ) {
9214 matrix_(
row()+i,
column()+j) -= (~rhs)(i,j);
9236 template<
typename MT
9238 template<
typename MT2 >
9239 inline void Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const SparseMatrix<MT2,false>& rhs )
9244 for(
size_t i=0UL; i<
rows(); ++i )
9245 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
9246 matrix_(
row()+i,
column()+element->index()) -= element->value();
9264 template<
typename MT
9266 template<
typename MT2 >
9267 inline void Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const SparseMatrix<MT2,true>& rhs )
9274 for(
size_t j=0UL; j<
columns(); ++j )
9275 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
9276 matrix_(
row()+element->index(),
column()+j) -= element->value();
9294 template<
typename MT
9296 template<
typename MT2 >
9297 inline auto Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
9298 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
9303 const size_t jpos(
columns() &
size_t(-2) );
9306 for(
size_t i=0UL; i<
rows(); ++i ) {
9307 for(
size_t j=0UL; j<jpos; j+=2UL ) {
9308 matrix_(
row()+i,
column()+j ) *= (~rhs)(i,j );
9309 matrix_(
row()+i,
column()+j+1UL) *= (~rhs)(i,j+1UL);
9312 matrix_(
row()+i,
column()+jpos) *= (~rhs)(i,jpos);
9332 template<
typename MT
9334 template<
typename MT2 >
9335 inline auto Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
9336 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
9343 for(
size_t i=0UL; i<
rows(); ++i )
9345 const size_t jpos(
columns() &
size_t(-SIMDSIZE) );
9349 Iterator left(
begin(i) );
9350 ConstIterator_t<MT2> right( (~rhs).
begin(i) );
9352 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
9353 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9354 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9355 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9356 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9358 for( ; j<jpos; j+=SIMDSIZE ) {
9359 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9362 *left *= *right; ++left; ++right;
9382 template<
typename MT
9384 template<
typename MT2 >
9385 inline void Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
9392 constexpr
size_t block( BLOCK_SIZE );
9394 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
9395 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
9396 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
9397 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
9398 for(
size_t i=ii; i<iend; ++i ) {
9399 for(
size_t j=jj; j<jend; ++j ) {
9400 matrix_(
row()+i,
column()+j) *= (~rhs)(i,j);
9422 template<
typename MT
9424 template<
typename MT2 >
9425 inline void Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
9432 for(
size_t i=0UL; i<
rows(); ++i )
9436 for( ConstIterator_t<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element ) {
9437 for( ; j<element->index(); ++j )
9439 matrix_(
row()+i,
column()+j) *= element->value();
9464 template<
typename MT
9466 template<
typename MT2 >
9467 inline void Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
9476 for(
size_t j=0UL; j<
columns(); ++j )
9480 for( ConstIterator_t<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element ) {
9481 for( ; i<element->index(); ++i )
9483 matrix_(
row()+element->index(),
column()+j) *= element->value();
9487 for( ; i<
rows(); ++i ) {
9516 template<
typename MT
9518 class Submatrix<MT,
aligned,true,true,CSAs...>
9519 :
public View< DenseMatrix< Submatrix<MT,aligned,true,true,CSAs...>, true > >
9520 ,
private SubmatrixData<CSAs...>
9524 using DataType = SubmatrixData<CSAs...>;
9525 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
9530 template<
typename MT1,
typename MT2 >
9531 static constexpr
bool EnforceEvaluation_v =
9532 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
9538 using This = Submatrix<MT,
aligned,
true,
true,CSAs...>;
9540 using BaseType = DenseMatrix<This,true>;
9541 using ViewedType = MT;
9543 using OppositeType = OppositeType_t<ResultType>;
9544 using TransposeType = TransposeType_t<ResultType>;
9545 using ElementType = ElementType_t<MT>;
9546 using SIMDType = SIMDTrait_t<ElementType>;
9547 using ReturnType = ReturnType_t<MT>;
9548 using CompositeType =
const Submatrix&;
9551 using ConstReference = ConstReference_t<MT>;
9554 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
9557 using ConstPointer = ConstPointer_t<MT>;
9560 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
9563 using ConstIterator = ConstIterator_t<MT>;
9566 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
9571 static constexpr
bool simdEnabled = MT::simdEnabled;
9574 static constexpr
bool smpAssignable = MT::smpAssignable;
9577 static constexpr
bool compileTimeArgs = DataType::compileTimeArgs;
9583 template<
typename... RSAs >
9584 explicit inline Submatrix( MT& matrix, RSAs... args );
9586 Submatrix(
const Submatrix& ) =
default;
9593 ~Submatrix() =
default;
9600 inline Reference operator()(
size_t i,
size_t j );
9601 inline ConstReference operator()(
size_t i,
size_t j )
const;
9602 inline Reference at(
size_t i,
size_t j );
9603 inline ConstReference at(
size_t i,
size_t j )
const;
9604 inline Pointer
data () noexcept;
9605 inline ConstPointer
data () const noexcept;
9606 inline Pointer
data (
size_t j ) noexcept;
9607 inline ConstPointer
data (
size_t j ) const noexcept;
9608 inline Iterator
begin (
size_t j );
9609 inline ConstIterator
begin (
size_t j ) const;
9610 inline ConstIterator
cbegin(
size_t j ) const;
9611 inline Iterator
end (
size_t j );
9612 inline ConstIterator
end (
size_t j ) const;
9613 inline ConstIterator
cend (
size_t j ) const;
9620 inline Submatrix& operator=( const ElementType& rhs );
9621 inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
9622 inline Submatrix& operator=( const Submatrix& rhs );
9624 template< typename MT2,
bool SO >
9625 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
9627 template< typename MT2,
bool SO >
9628 inline auto operator+=( const Matrix<MT2,SO>& rhs )
9629 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9631 template< typename MT2,
bool SO >
9632 inline auto operator+=( const Matrix<MT2,SO>& rhs )
9633 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9635 template< typename MT2,
bool SO >
9636 inline auto operator-=( const Matrix<MT2,SO>& rhs )
9637 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9639 template< typename MT2,
bool SO >
9640 inline auto operator-=( const Matrix<MT2,SO>& rhs )
9641 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9643 template< typename MT2,
bool SO >
9644 inline auto operator%=( const Matrix<MT2,SO>& rhs )
9645 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9647 template< typename MT2,
bool SO >
9648 inline auto operator%=( const Matrix<MT2,SO>& rhs )
9649 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9656 using DataType::
row;
9658 using DataType::
rows;
9661 inline MT& operand() noexcept;
9662 inline const MT& operand() const noexcept;
9664 inline
size_t spacing() const noexcept;
9665 inline
size_t capacity() const noexcept;
9666 inline
size_t capacity(
size_t i ) const noexcept;
9668 inline
size_t nonZeros(
size_t i ) const;
9669 inline
void reset();
9670 inline
void reset(
size_t i );
9680 template< typename Other > inline Submatrix& scale( const Other& scalar );
9687 template< typename MT2 >
9688 static constexpr
bool VectorizedAssign_v =
9689 ( useOptimizedKernels &&
9690 simdEnabled && MT2::simdEnabled &&
9696 template< typename MT2 >
9697 static constexpr
bool VectorizedAddAssign_v =
9698 ( useOptimizedKernels &&
9699 simdEnabled && MT2::simdEnabled &&
9707 template< typename MT2 >
9708 static constexpr
bool VectorizedSubAssign_v =
9709 ( useOptimizedKernels &&
9710 simdEnabled && MT2::simdEnabled &&
9718 template< typename MT2 >
9719 static constexpr
bool VectorizedSchurAssign_v =
9720 ( useOptimizedKernels &&
9721 simdEnabled && MT2::simdEnabled &&
9728 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
9735 template< typename Other >
9736 inline
bool canAlias( const Other* alias ) const noexcept;
9738 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
9739 inline
bool canAlias( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
9741 template< typename Other >
9742 inline
bool isAliased( const Other* alias ) const noexcept;
9744 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
9745 inline
bool isAliased( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
9747 inline
bool isAligned () const noexcept;
9748 inline
bool canSMPAssign() const noexcept;
9759 template< typename MT2 >
9760 inline auto assign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedAssign_v<MT2> >;
9762 template< typename MT2 >
9763 inline auto assign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedAssign_v<MT2> >;
9765 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,false>& rhs );
9766 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
9767 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
9769 template< typename MT2 >
9770 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<MT2> >;
9772 template< typename MT2 >
9773 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<MT2> >;
9775 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,false>& rhs );
9776 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
9777 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
9779 template< typename MT2 >
9780 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<MT2> >;
9782 template< typename MT2 >
9783 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<MT2> >;
9785 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,false>& rhs );
9786 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
9787 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
9789 template< typename MT2 >
9790 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedSchurAssign_v<MT2> >;
9792 template< typename MT2 >
9793 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedSchurAssign_v<MT2> >;
9795 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,false>& rhs );
9796 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
9797 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
9805 inline
bool hasOverlap() const noexcept;
9817 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
bool DF2,
size_t... CSAs2 > friend class Submatrix;
9855 template< typename MT
9857 template< typename... RSAs >
9858 inline Submatrix<MT,
aligned,true,true,CSAs...>::Submatrix( MT& matrix, RSAs... args )
9859 : DataType( args... )
9860 , matrix_ ( matrix )
9868 if( simdEnabled && IsContiguous_v<MT> &&
9870 (
columns() > 1UL && matrix_.spacing() % SIMDSIZE != 0UL ) ) ) {
9880 BLAZE_USER_ASSERT( !simdEnabled || !IsContiguous_v<MT> ||
columns() <= 1UL || matrix_.spacing() % SIMDSIZE == 0UL,
"Invalid submatrix alignment" );
9906 template<
typename MT
9908 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Reference
9909 Submatrix<MT,aligned,true,true,CSAs...>::operator()(
size_t i,
size_t j )
9931 template<
typename MT
9933 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstReference
9934 Submatrix<MT,aligned,true,true,CSAs...>::operator()(
size_t i,
size_t j )
const 9939 return const_cast<const MT&>( matrix_ )(
row()+i,
column()+j);
9957 template<
typename MT
9959 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Reference
9960 Submatrix<MT,aligned,true,true,CSAs...>::at(
size_t i,
size_t j )
9968 return (*
this)(i,j);
9986 template<
typename MT
9988 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstReference
9989 Submatrix<MT,aligned,true,true,CSAs...>::at(
size_t i,
size_t j )
const 9997 return (*
this)(i,j);
10013 template<
typename MT
10015 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Pointer
10034 template<
typename MT
10036 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstPointer
10054 template<
typename MT
10056 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Pointer
10074 template<
typename MT
10076 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstPointer
10092 template<
typename MT
10094 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Iterator
10098 return ( matrix_.begin(
column() + j ) +
row() );
10111 template<
typename MT
10113 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstIterator
10117 return ( matrix_.cbegin(
column() + j ) +
row() );
10130 template<
typename MT
10132 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstIterator
10136 return ( matrix_.cbegin(
column() + j ) +
row() );
10149 template<
typename MT
10151 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Iterator
10168 template<
typename MT
10170 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstIterator
10174 return ( matrix_.cbegin(
column() + j ) +
row() +
rows() );
10187 template<
typename MT
10189 inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstIterator
10193 return ( matrix_.cbegin(
column() + j ) +
row() +
rows() );
10218 template<
typename MT
10220 inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10221 Submatrix<MT,aligned,true,true,CSAs...>::operator=(
const ElementType& rhs )
10224 decltype(
auto) left( derestrict( matrix_ ) );
10226 for(
size_t j=
column(); j<jend; ++j )
10228 const size_t ibegin( ( IsLower_v<MT> )
10229 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
10230 ?(
max( j+1UL,
row() ) )
10233 const size_t iend ( ( IsUpper_v<MT> )
10234 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
10239 for(
size_t i=ibegin; i<iend; ++i ) {
10240 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, j, rhs ) )
10267 template<
typename MT
10269 inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10270 Submatrix<MT,aligned,true,true,CSAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
10274 if( list.size() !=
rows() ) {
10278 if( IsRestricted_v<MT> ) {
10279 const InitializerMatrix<ElementType> tmp( list,
columns() );
10280 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
10285 decltype(
auto) left( derestrict( *this ) );
10288 for( const auto& rowList : list ) {
10290 for(
const auto& element : rowList ) {
10291 left(i,j) = element;
10295 reset( left(i,j) );
10321 template<
typename MT
10323 inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10324 Submatrix<MT,aligned,true,true,CSAs...>::operator=(
const Submatrix& rhs )
10329 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ &&
row() == rhs.row() &&
column() == rhs.column() ) )
10332 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
10336 if( !tryAssign( matrix_, rhs,
row(),
column() ) ) {
10340 decltype(
auto) left( derestrict( *this ) );
10342 if( rhs.canAlias( &matrix_ ) ) {
10343 const ResultType tmp( rhs );
10372 template<
typename MT
10374 template<
typename MT2
10376 inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10377 Submatrix<MT,aligned,true,true,CSAs...>::operator=(
const Matrix<MT2,SO>& rhs )
10385 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>,
const MT2& >;
10386 Right right( ~rhs );
10388 if( !tryAssign( matrix_, right,
row(),
column() ) ) {
10392 decltype(
auto) left( derestrict( *this ) );
10395 const ResultType_t<MT2> tmp( right );
10396 if( IsSparseMatrix_v<MT2> )
10401 if( IsSparseMatrix_v<MT2> )
10428 template<
typename MT
10430 template<
typename MT2
10433 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10439 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
10448 if( !tryAddAssign( matrix_, ~rhs,
row(),
column() ) ) {
10452 decltype(
auto) left( derestrict( *this ) );
10455 (~rhs).canAlias( &matrix_ ) ) {
10456 const AddType tmp( *
this + (~rhs) );
10485 template<
typename MT
10487 template<
typename MT2
10490 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10496 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
10505 const AddType tmp( *
this + (~rhs) );
10507 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
10511 decltype(
auto) left( derestrict( *this ) );
10537 template< typename MT
10539 template< typename MT2
10541 inline auto Submatrix<MT,
aligned,true,true,CSAs...>::operator-=( const Matrix<MT2,SO>& rhs )
10542 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10548 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
10557 if( !trySubAssign( matrix_, ~rhs,
row(),
column() ) ) {
10561 decltype(
auto) left( derestrict( *this ) );
10564 (~rhs).canAlias( &matrix_ ) ) {
10565 const SubType tmp( *
this - (~rhs ) );
10594 template<
typename MT
10596 template<
typename MT2
10599 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10605 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
10614 const SubType tmp( *
this - (~rhs) );
10616 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
10620 decltype(
auto) left( derestrict( *this ) );
10646 template< typename MT
10648 template< typename MT2
10650 inline auto Submatrix<MT,
aligned,true,true,CSAs...>::operator%=( const Matrix<MT2,SO>& rhs )
10651 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10657 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
10665 if( !trySchurAssign( matrix_, ~rhs,
row(),
column() ) ) {
10669 decltype(
auto) left( derestrict( *this ) );
10672 (~rhs).canAlias( &matrix_ ) ) {
10673 const SchurType tmp( *
this % (~rhs) );
10674 if( IsSparseMatrix_v<SchurType> )
10704 template<
typename MT
10706 template<
typename MT2
10708 inline auto Submatrix<MT,aligned,true,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
10709 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10715 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
10723 const SchurType tmp( *
this % (~rhs) );
10725 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
10729 decltype(
auto) left( derestrict( *this ) );
10759 template<
typename MT
10761 inline MT& Submatrix<MT,aligned,true,true,CSAs...>::operand() noexcept
10775 template<
typename MT
10777 inline const MT& Submatrix<MT,aligned,true,true,CSAs...>::operand() const noexcept
10794 template<
typename MT
10798 return matrix_.spacing();
10810 template<
typename MT
10827 template<
typename MT
10847 template<
typename MT
10851 const size_t iend(
row() +
rows() );
10853 size_t nonzeros( 0UL );
10855 for(
size_t j=
column(); j<jend; ++j )
10856 for(
size_t i=
row(); i<iend; ++i )
10873 template<
typename MT
10879 const size_t iend(
row() +
rows() );
10880 size_t nonzeros( 0UL );
10882 for(
size_t i=
row(); i<iend; ++i )
10898 template<
typename MT
10906 const size_t ibegin( ( IsLower_v<MT> )
10907 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
10908 ?(
max( j+1UL,
row() ) )
10911 const size_t iend ( ( IsUpper_v<MT> )
10912 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
10917 for(
size_t i=ibegin; i<iend; ++i )
10918 clear( matrix_(i,j) );
10932 template<
typename MT
10940 const size_t ibegin( ( IsLower_v<MT> )
10941 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
10942 ?(
max( j+1UL,
row() ) )
10945 const size_t iend ( ( IsUpper_v<MT> )
10946 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
10951 for(
size_t i=ibegin; i<iend; ++i )
10968 template<
typename MT
10970 inline bool Submatrix<MT,aligned,true,true,CSAs...>::hasOverlap() const noexcept
11008 template<
typename MT
11010 inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
11021 decltype(
auto) left( derestrict( *this ) );
11022 const ResultType tmp(
trans( *this ) );
11050 template< typename MT
11052 inline Submatrix<MT,
aligned,true,true,CSAs...>&
11063 decltype(
auto) left( derestrict( *this ) );
11064 const ResultType tmp(
ctrans( *this ) );
11087 template< typename MT
11089 template< typename Other >
11090 inline Submatrix<MT,
aligned,true,true,CSAs...>&
11091 Submatrix<MT,
aligned,true,true,CSAs...>::scale( const Other& scalar )
11097 for(
size_t j=
column(); j<jend; ++j )
11099 const size_t ibegin( ( IsLower_v<MT> )
11100 ?( ( IsStrictlyLower_v<MT> )
11101 ?(
max( j+1UL,
row() ) )
11104 const size_t iend ( ( IsUpper_v<MT> )
11105 ?( ( IsStrictlyUpper_v<MT> )
11110 for(
size_t i=ibegin; i<iend; ++i )
11111 matrix_(i,j) *= scalar;
11139 template<
typename MT
11141 template<
typename Other >
11142 inline bool Submatrix<MT,aligned,true,true,CSAs...>::canAlias(
const Other* alias )
const noexcept
11144 return matrix_.isAliased( alias );
11161 template<
typename MT
11163 template<
typename MT2
11166 ,
size_t... CSAs2 >
11168 Submatrix<MT,aligned,true,true,CSAs...>::canAlias(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
11170 return ( matrix_.isAliased( &alias->matrix_ ) &&
11171 (
row() +
rows() > alias->row() ) &&
11172 (
row() < alias->row() + alias->rows() ) &&
11174 (
column() < alias->column() + alias->columns() ) );
11191 template<
typename MT
11193 template<
typename Other >
11194 inline bool Submatrix<MT,aligned,true,true,CSAs...>::isAliased(
const Other* alias )
const noexcept
11196 return matrix_.isAliased( alias );
11213 template<
typename MT
11215 template<
typename MT2
11218 ,
size_t... CSAs2 >
11220 Submatrix<MT,aligned,true,true,CSAs...>::isAliased(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
11222 return ( matrix_.isAliased( &alias->matrix_ ) &&
11223 (
row() +
rows() > alias->row() ) &&
11224 (
row() < alias->row() + alias->rows() ) &&
11226 (
column() < alias->column() + alias->columns() ) );
11242 template<
typename MT
11244 inline bool Submatrix<MT,aligned,true,true,CSAs...>::isAligned() const noexcept
11263 template<
typename MT
11265 inline bool Submatrix<MT,aligned,true,true,CSAs...>::canSMPAssign() const noexcept
11267 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
11288 template<
typename MT
11291 Submatrix<MT,aligned,true,true,CSAs...>::load(
size_t i,
size_t j )
const noexcept
11293 return loada( i, j );
11314 template<
typename MT
11326 return matrix_.loada(
row()+i,
column()+j );
11347 template<
typename MT
11358 return matrix_.loadu(
row()+i,
column()+j );
11380 template<
typename MT
11383 Submatrix<MT,aligned,true,true,CSAs...>::store(
size_t i,
size_t j,
const SIMDType& value ) noexcept
11407 template<
typename MT
11419 matrix_.storea(
row()+i,
column()+j, value );
11441 template<
typename MT
11452 matrix_.storeu(
row()+i,
column()+j, value );
11475 template<
typename MT
11487 matrix_.stream(
row()+i,
column()+j, value );
11505 template<
typename MT
11507 template<
typename MT2 >
11508 inline auto Submatrix<MT,aligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
11509 -> DisableIf_t< VectorizedAssign_v<MT2> >
11514 const size_t ipos(
rows() &
size_t(-2) );
11517 for(
size_t j=0UL; j<
columns(); ++j ) {
11518 for(
size_t i=0UL; i<ipos; i+=2UL ) {
11519 matrix_(
row()+i ,
column()+j) = (~rhs)(i ,j);
11520 matrix_(
row()+i+1UL,
column()+j) = (~rhs)(i+1UL,j);
11522 if( ipos <
rows() ) {
11523 matrix_(
row()+ipos,
column()+j) = (~rhs)(ipos,j);
11543 template<
typename MT
11545 template<
typename MT2 >
11546 inline auto Submatrix<MT,aligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
11547 -> EnableIf_t< VectorizedAssign_v<MT2> >
11554 const size_t ipos(
rows() &
size_t(-SIMDSIZE) );
11557 if( useStreaming &&
11558 rows()*
columns() > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
11559 !(~rhs).isAliased( &matrix_ ) )
11561 for(
size_t j=0UL; j<
columns(); ++j )
11564 Iterator left(
begin(j) );
11565 ConstIterator_t<MT2> right( (~rhs).
begin(j) );
11567 for( ; i<ipos; i+=SIMDSIZE ) {
11568 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11570 for( ; i<
rows(); ++i ) {
11571 *left = *right; ++left; ++right;
11577 for(
size_t j=0UL; j<
columns(); ++j )
11580 Iterator left(
begin(j) );
11581 ConstIterator_t<MT2> right( (~rhs).
begin(j) );
11583 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
11584 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11585 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11586 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11587 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11589 for( ; i<ipos; i+=SIMDSIZE ) {
11590 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11592 for( ; i<
rows(); ++i ) {
11593 *left = *right; ++left; ++right;
11614 template<
typename MT
11616 template<
typename MT2 >
11617 inline void Submatrix<MT,aligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
11624 constexpr
size_t block( BLOCK_SIZE );
11626 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
11627 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
11628 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
11629 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
11630 for(
size_t j=jj; j<jend; ++j ) {
11631 for(
size_t i=ii; i<iend; ++i ) {
11632 matrix_(
row()+i,
column()+j) = (~rhs)(i,j);
11654 template<
typename MT
11656 template<
typename MT2 >
11657 inline void Submatrix<MT,aligned,true,true,CSAs...>::assign(
const SparseMatrix<MT2,true>& rhs )
11662 for(
size_t j=0UL; j<
columns(); ++j )
11663 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
11664 matrix_(
row()+element->index(),
column()+j) = element->value();
11682 template<
typename MT
11684 template<
typename MT2 >
11685 inline void Submatrix<MT,aligned,true,true,CSAs...>::assign(
const SparseMatrix<MT2,false>& rhs )
11692 for(
size_t i=0UL; i<
rows(); ++i )
11693 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
11694 matrix_(
row()+i,
column()+element->index()) = element->value();
11712 template<
typename MT
11714 template<
typename MT2 >
11715 inline auto Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
11716 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
11721 const size_t ipos(
rows() &
size_t(-2) );
11724 for(
size_t j=0UL; j<
columns(); ++j )
11726 if( IsDiagonal_v<MT2> ) {
11727 matrix_(
row()+j,
column()+j) += (~rhs)(j,j);
11730 for(
size_t i=0UL; i<ipos; i+=2UL ) {
11731 matrix_(
row()+i ,
column()+j) += (~rhs)(i ,j);
11732 matrix_(
row()+i+1UL,
column()+j) += (~rhs)(i+1UL,j);
11734 if( ipos <
rows() ) {
11735 matrix_(
row()+ipos,
column()+j) += (~rhs)(ipos,j);
11756 template<
typename MT
11758 template<
typename MT2 >
11759 inline auto Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
11760 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
11767 for(
size_t j=0UL; j<
columns(); ++j )
11769 const size_t ibegin( ( IsLower_v<MT> )
11770 ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) &
size_t(-SIMDSIZE) )
11772 const size_t iend ( ( IsUpper_v<MT> )
11773 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
11777 const size_t ipos( iend &
size_t(-SIMDSIZE) );
11780 size_t i( ibegin );
11781 Iterator left(
begin(j) + ibegin );
11782 ConstIterator_t<MT2> right( (~rhs).
begin(j) + ibegin );
11784 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
11785 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11786 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11787 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11788 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11790 for( ; i<ipos; i+=SIMDSIZE ) {
11791 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11793 for( ; i<iend; ++i ) {
11794 *left += *right; ++left; ++right;
11814 template<
typename MT
11816 template<
typename MT2 >
11817 inline void Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
11824 constexpr
size_t block( BLOCK_SIZE );
11826 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
11827 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
11828 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
11829 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
11830 for(
size_t j=jj; j<jend; ++j ) {
11831 for(
size_t i=ii; i<iend; ++i ) {
11832 matrix_(
row()+i,
column()+j) += (~rhs)(i,j);
11854 template<
typename MT
11856 template<
typename MT2 >
11857 inline void Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const SparseMatrix<MT2,true>& rhs )
11862 for(
size_t j=0UL; j<
columns(); ++j )
11863 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
11864 matrix_(
row()+element->index(),
column()+j) += element->value();
11882 template<
typename MT
11884 template<
typename MT2 >
11885 inline void Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const SparseMatrix<MT2,false>& rhs )
11892 for(
size_t i=0UL; i<
rows(); ++i )
11893 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
11894 matrix_(
row()+i,
column()+element->index()) += element->value();
11912 template<
typename MT
11914 template<
typename MT2 >
11915 inline auto Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
11916 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
11921 const size_t ipos(
rows() &
size_t(-2) );
11924 for(
size_t j=0UL; j<
columns(); ++j )
11926 if( IsDiagonal_v<MT2> ) {
11927 matrix_(
row()+j,
column()+j) -= (~rhs)(j,j);
11930 for(
size_t i=0UL; i<ipos; i+=2UL ) {
11931 matrix_(
row()+i ,
column()+j) -= (~rhs)(i ,j);
11932 matrix_(
row()+i+1UL,
column()+j) -= (~rhs)(i+1UL,j);
11934 if( ipos <
rows() ) {
11935 matrix_(
row()+ipos,
column()+j) -= (~rhs)(ipos,j);
11956 template<
typename MT
11958 template<
typename MT2 >
11959 inline auto Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
11960 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
11967 for(
size_t j=0UL; j<
columns(); ++j )
11969 const size_t ibegin( ( IsLower_v<MT> )
11970 ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) &
size_t(-SIMDSIZE) )
11972 const size_t iend ( ( IsUpper_v<MT> )
11973 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
11977 const size_t ipos( iend &
size_t(-SIMDSIZE) );
11980 size_t i( ibegin );
11981 Iterator left(
begin(j) + ibegin );
11982 ConstIterator_t<MT2> right( (~rhs).
begin(j) + ibegin );
11984 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
11985 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11986 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11987 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11988 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11990 for( ; i<ipos; i+=SIMDSIZE ) {
11991 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11993 for( ; i<iend; ++i ) {
11994 *left -= *right; ++left; ++right;
12014 template<
typename MT
12016 template<
typename MT2 >
12017 inline void Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
12024 constexpr
size_t block( BLOCK_SIZE );
12026 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
12027 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
12028 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
12029 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
12030 for(
size_t j=jj; j<jend; ++j ) {
12031 for(
size_t i=ii; i<iend; ++i ) {
12032 matrix_(
row()+i,
column()+j) -= (~rhs)(i,j);
12054 template<
typename MT
12056 template<
typename MT2 >
12057 inline void Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const SparseMatrix<MT2,true>& rhs )
12062 for(
size_t j=0UL; j<
columns(); ++j )
12063 for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).
end(j); ++element )
12064 matrix_(
row()+element->index(),
column()+j) -= element->value();
12082 template<
typename MT
12084 template<
typename MT2 >
12085 inline void Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const SparseMatrix<MT2,false>& rhs )
12092 for(
size_t i=0UL; i<
rows(); ++i )
12093 for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).
end(i); ++element )
12094 matrix_(
row()+i,
column()+element->index()) -= element->value();
12112 template<
typename MT
12114 template<
typename MT2 >
12115 inline auto Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
12116 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
12121 const size_t ipos(
rows() &
size_t(-2) );
12124 for(
size_t j=0UL; j<
columns(); ++j ) {
12125 for(
size_t i=0UL; i<ipos; i+=2UL ) {
12126 matrix_(
row()+i ,
column()+j) *= (~rhs)(i ,j);
12127 matrix_(
row()+i+1UL,
column()+j) *= (~rhs)(i+1UL,j);
12129 if( ipos <
rows() ) {
12130 matrix_(
row()+ipos,
column()+j) *= (~rhs)(ipos,j);
12151 template<
typename MT
12153 template<
typename MT2 >
12154 inline auto Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
12155 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
12162 for(
size_t j=0UL; j<
columns(); ++j )
12164 const size_t ipos(
rows() &
size_t(-SIMDSIZE) );
12168 Iterator left(
begin(j) );
12169 ConstIterator_t<MT2> right( (~rhs).
begin(j) );
12171 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
12172 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12173 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12174 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12175 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12177 for( ; i<ipos; i+=SIMDSIZE ) {
12178 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12180 for( ; i<
rows(); ++i ) {
12181 *left *= *right; ++left; ++right;
12201 template<
typename MT
12203 template<
typename MT2 >
12204 inline void Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
12211 constexpr
size_t block( BLOCK_SIZE );
12213 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
12214 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
12215 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
12216 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
12217 for(
size_t j=jj; j<jend; ++j ) {
12218 for(
size_t i=ii; i<iend; ++i ) {
12219 matrix_(
row()+i,
column()+j) *= (~rhs)(i,j);
12241 template<
typename MT
12243 template<
typename MT2 >
12244 inline void Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
12251 for(
size_t j=0UL; j<
columns(); ++j )
12255 for( ConstIterator_t<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element ) {
12256 for( ; i<element->index(); ++i )
12258 matrix_(
row()+i,
column()+j) *= element->value();
12262 for( ; i<
rows(); ++i ) {
12283 template<
typename MT
12285 template<
typename MT2 >
12286 inline void Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
12295 for(
size_t i=0UL; i<
rows(); ++i )
12299 for( ConstIterator_t<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element ) {
12300 for( ; j<element->index(); ++j )
12302 matrix_(
row()+i,
column()+j) *= element->value();
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.Via these flags it is possible to specify subvec...
Definition: AlignmentFlag.h:62
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:133
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
Header file for kernel specific block sizes.
Header file for the Schur product trait.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
Header file for the alignment flag values.
Header file for the IsUniUpper type trait.
Header file for the subtraction trait.
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
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:750
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:170
Header file for the View base class.
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i....
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type,...
Definition: DenseMatrix.h:61
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e....
Definition: Submatrix.h:81
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
Header file for the MAYBE_UNUSED function template.
constexpr bool IsReference_v
Auxiliary variable template for the IsReference type trait.The IsReference_v variable template provid...
Definition: IsReference.h:95
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
Header file for the reset shim.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:187
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i....
Definition: TransExpr.h:81
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
Header file for the RequiresEvaluation type trait.
constexpr bool IsHermitian_v
Auxiliary variable template for the IsHermitian type trait.The IsHermitian_v variable template provid...
Definition: IsHermitian.h:172
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
Header file for the IsUniLower type trait.
typename SubmatrixTrait< MT, CSAs... >::Type SubmatrixTrait_t
Auxiliary alias declaration for the SubmatrixTrait type trait.The SubmatrixTrait_t alias declaration ...
Definition: SubmatrixTrait.h:171
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:482
MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:416
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
Constraint on the data type.
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:253
Header file for the matrix storage order types.
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
constexpr bool IsContiguous_v
Auxiliary variable template for the IsContiguous type trait.The IsContiguous_v variable template prov...
Definition: IsContiguous.h:144
Headerfile for the generic max algorithm.
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1361
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
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:9091
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:187
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1162
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the implementation of the Submatrix base template.
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:370
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:446
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
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
Header file for all SIMD functionality.
constexpr bool Contains_v
Auxiliary variable template for the Contains type trait.The Contains_v variable template provides a c...
Definition: Contains.h:138
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
Constraint on the data type.
Header file for the IsTriangular type trait.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type,...
Definition: Vectorizable.h:61
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
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:438
Header file for the implementation of the SubmatrixData class template.
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
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:615
Constraint on the data type.
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
Header file for the IsSIMDCombinable type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
Header file for run time assertion macros.
Header file for the addition trait.
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
Header file for the Unique class template.
Header file for the submatrix trait.
Header file for the IsContiguous type trait.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance,...
Definition: Check.h:96
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
Header file for the cache size of the target architecture.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type,...
Definition: Reference.h:79
Header file for the isDefault shim.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
Constraints on the storage order of matrix types.
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
Header file for the HasMutableDataAccess type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
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
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
constexpr const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:718
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
Flag for unaligned vectors and matrices.
Definition: AlignmentFlag.h:64
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:188
Header file for the alignment check function.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
constexpr bool IsSymmetric_v
Auxiliary variable template for the IsSymmetric type trait.The IsSymmetric_v variable template provid...
Definition: IsSymmetric.h:172
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
Header file for the IsUpper type trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.The IsDiagonal_v variable template provides...
Definition: IsDiagonal.h:148
Header file for the IsHermitian type trait.
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.The IsSparseMatrix_v variable template ...
Definition: IsSparseMatrix.h:138
Header file for the clear shim.
Header file for the IsExpression type trait class.
Constraint on the data type.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825