35#ifndef _BLAZE_MATH_VIEWS_SUBMATRIX_DENSE_H_
36#define _BLAZE_MATH_VIEWS_SUBMATRIX_DENSE_H_
132class Submatrix<MT,
unaligned,false,true,CSAs...>
133 :
public View< DenseMatrix< Submatrix<MT,unaligned,false,true,CSAs...>, false > >
134 ,
private SubmatrixData<CSAs...>
138 using DataType = SubmatrixData<CSAs...>;
139 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
144 template<
typename MT1,
typename MT2 >
145 static constexpr bool EnforceEvaluation_v =
146 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
152 using This = Submatrix<MT,
unaligned,
false,
true,CSAs...>;
155 using BaseType = View< DenseMatrix<This,false> >;
157 using ViewedType = MT;
159 using OppositeType = OppositeType_t<ResultType>;
160 using TransposeType = TransposeType_t<ResultType>;
161 using ElementType = ElementType_t<MT>;
162 using SIMDType = SIMDTrait_t<ElementType>;
163 using ReturnType = ReturnType_t<MT>;
164 using CompositeType =
const Submatrix&;
167 using ConstReference = ConstReference_t<MT>;
170 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
173 using ConstPointer = ConstPointer_t<MT>;
176 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
182 template<
typename IteratorType >
183 class SubmatrixIterator
188 using IteratorCategory =
typename std::iterator_traits<IteratorType>::iterator_category;
191 using ValueType =
typename std::iterator_traits<IteratorType>::value_type;
194 using PointerType =
typename std::iterator_traits<IteratorType>::pointer;
197 using ReferenceType =
typename std::iterator_traits<IteratorType>::reference;
200 using DifferenceType =
typename std::iterator_traits<IteratorType>::difference_type;
203 using iterator_category = IteratorCategory;
204 using value_type = ValueType;
205 using pointer = PointerType;
206 using reference = ReferenceType;
207 using difference_type = DifferenceType;
213 inline SubmatrixIterator()
215 , isAligned_( false )
225 inline SubmatrixIterator( IteratorType iterator,
bool isMemoryAligned )
226 : iterator_ ( iterator )
227 , isAligned_( isMemoryAligned )
236 template<
typename IteratorType2 >
237 inline SubmatrixIterator(
const SubmatrixIterator<IteratorType2>& it )
238 : iterator_ ( it.base() )
239 , isAligned_( it.isAligned() )
249 inline SubmatrixIterator&
operator+=(
size_t inc ) {
261 inline SubmatrixIterator&
operator-=(
size_t dec ) {
272 inline SubmatrixIterator& operator++() {
283 inline const SubmatrixIterator operator++(
int ) {
284 return SubmatrixIterator( iterator_++, isAligned_ );
293 inline SubmatrixIterator& operator--() {
304 inline const SubmatrixIterator operator--(
int ) {
305 return SubmatrixIterator( iterator_--, isAligned_ );
324 inline IteratorType operator->()
const {
339 inline SIMDType load() const noexcept {
357 inline SIMDType
loada() const noexcept {
358 return iterator_.loada();
372 inline SIMDType
loadu() const noexcept {
373 return iterator_.loadu();
388 inline void store(
const SIMDType& value )
const {
409 inline void storea(
const SIMDType& value )
const {
410 iterator_.storea( value );
425 inline void storeu(
const SIMDType& value )
const {
426 iterator_.storeu( value );
441 inline void stream(
const SIMDType& value )
const {
442 iterator_.stream( value );
452 inline bool operator==(
const SubmatrixIterator& rhs )
const {
453 return iterator_ == rhs.iterator_;
463 inline bool operator!=(
const SubmatrixIterator& rhs )
const {
464 return iterator_ != rhs.iterator_;
474 inline bool operator<(
const SubmatrixIterator& rhs )
const {
475 return iterator_ < rhs.iterator_;
485 inline bool operator>(
const SubmatrixIterator& rhs )
const {
486 return iterator_ > rhs.iterator_;
496 inline bool operator<=(
const SubmatrixIterator& rhs )
const {
497 return iterator_ <= rhs.iterator_;
507 inline bool operator>=(
const SubmatrixIterator& rhs )
const {
508 return iterator_ >= rhs.iterator_;
518 inline DifferenceType
operator-(
const SubmatrixIterator& rhs )
const {
519 return iterator_ - rhs.iterator_;
530 friend inline const SubmatrixIterator
operator+(
const SubmatrixIterator& it,
size_t inc ) {
531 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
542 friend inline const SubmatrixIterator
operator+(
size_t inc,
const SubmatrixIterator& it ) {
543 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
554 friend inline const SubmatrixIterator
operator-(
const SubmatrixIterator& it,
size_t dec ) {
555 return SubmatrixIterator( it.iterator_ - dec, it.isAligned_ );
564 inline IteratorType base()
const {
574 inline bool isAligned() const noexcept {
581 IteratorType iterator_;
589 using ConstIterator = SubmatrixIterator< ConstIterator_t<MT> >;
592 using Iterator = If_t< IsConst_v<MT>, ConstIterator, SubmatrixIterator< Iterator_t<MT> > >;
597 static constexpr bool simdEnabled = MT::simdEnabled;
600 static constexpr bool smpAssignable = MT::smpAssignable;
603 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
609 template<
typename... RSAs >
610 explicit inline Submatrix( MT& matrix, RSAs... args );
612 Submatrix(
const Submatrix& ) =
default;
619 ~Submatrix() =
default;
626 inline Reference operator()(
size_t i,
size_t j );
627 inline ConstReference operator()(
size_t i,
size_t j )
const;
628 inline Reference at(
size_t i,
size_t j );
629 inline ConstReference at(
size_t i,
size_t j )
const;
630 inline Pointer
data () noexcept;
631 inline ConstPointer
data () const noexcept;
632 inline Pointer
data (
size_t i ) noexcept;
633 inline ConstPointer
data (
size_t i ) const noexcept;
634 inline Iterator
begin (
size_t i );
635 inline ConstIterator
begin (
size_t i ) const;
636 inline ConstIterator
cbegin(
size_t i ) const;
637 inline Iterator
end (
size_t i );
638 inline ConstIterator
end (
size_t i ) const;
639 inline ConstIterator
cend (
size_t i ) const;
646 inline Submatrix& operator=( const ElementType& rhs );
648 inline Submatrix& operator=( const Submatrix& rhs );
650 template< typename MT2,
bool SO2 >
651 inline Submatrix& operator=( const Matrix<MT2,SO2>& rhs );
653 template< typename MT2,
bool SO2 >
654 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
655 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
657 template< typename MT2,
bool SO2 >
658 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
659 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
661 template< typename MT2,
bool SO2 >
662 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
663 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
665 template< typename MT2,
bool SO2 >
666 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
667 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
669 template< typename MT2,
bool SO2 >
670 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
671 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
673 template< typename MT2,
bool SO2 >
674 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
675 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
684 using DataType::
rows;
687 inline MT& operand() noexcept;
688 inline const MT& operand() const noexcept;
690 inline
size_t spacing() const noexcept;
691 inline
size_t capacity() const noexcept;
692 inline
size_t capacity(
size_t i ) const noexcept;
694 inline
size_t nonZeros(
size_t i ) const;
696 inline
void reset(
size_t i );
706 template< typename Other > inline Submatrix& scale( const Other& scalar );
713 template< typename MT2 >
714 static constexpr
bool VectorizedAssign_v =
715 ( useOptimizedKernels &&
716 simdEnabled && MT2::simdEnabled &&
722 template< typename MT2 >
723 static constexpr
bool VectorizedAddAssign_v =
724 ( VectorizedAssign_v<MT2> &&
731 template< typename MT2 >
732 static constexpr
bool VectorizedSubAssign_v =
733 ( VectorizedAssign_v<MT2> &&
740 template< typename MT2 >
741 static constexpr
bool VectorizedSchurAssign_v =
742 ( VectorizedAssign_v<MT2> &&
748 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
755 template< typename Other >
756 inline
bool canAlias( const Other* alias ) const noexcept;
758 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
759 inline
bool canAlias( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
761 template< typename Other >
762 inline
bool isAliased( const Other* alias ) const noexcept;
764 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
765 inline
bool isAliased( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
767 inline
bool isAligned () const noexcept;
768 inline
bool canSMPAssign() const noexcept;
779 template< typename MT2 >
780 inline auto assign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedAssign_v<MT2> >;
782 template< typename MT2 >
783 inline auto assign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedAssign_v<MT2> >;
785 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,true>& rhs );
786 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
787 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
789 template< typename MT2 >
790 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<MT2> >;
792 template< typename MT2 >
793 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<MT2> >;
795 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,true>& rhs );
796 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
797 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
799 template< typename MT2 >
800 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<MT2> >;
802 template< typename MT2 >
803 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<MT2> >;
805 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,true>& rhs );
806 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
807 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
809 template< typename MT2 >
810 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedSchurAssign_v<MT2> >;
812 template< typename MT2 >
813 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedSchurAssign_v<MT2> >;
815 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,true>& rhs );
816 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
817 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
825 inline
bool hasOverlap() const noexcept;
833 const
bool isAligned_;
844 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
bool DF2,
size_t... CSAs2 > friend class Submatrix;
884template< typename... RSAs >
885inline Submatrix<MT,
unaligned,false,true,CSAs...>::Submatrix( MT& matrix, RSAs... args )
886 : DataType ( args... )
890 (
rows() < 2UL || ( matrix.
spacing() % SIMDSIZE ) == 0UL ) )
927inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Reference
928 Submatrix<MT,unaligned,false,true,CSAs...>::operator()(
size_t i,
size_t j )
952inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstReference
953 Submatrix<MT,unaligned,false,true,CSAs...>::operator()(
size_t i,
size_t j )
const
958 return const_cast<const MT&
>( matrix_ )(
row()+i,
column()+j);
978inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Reference
979 Submatrix<MT,unaligned,false,true,CSAs...>::at(
size_t i,
size_t j )
1005template<
typename MT
1007inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstReference
1008 Submatrix<MT,unaligned,false,true,CSAs...>::at(
size_t i,
size_t j )
const
1016 return (*
this)(i,j);
1032template<
typename MT
1034inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Pointer
1053template<
typename MT
1055inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstPointer
1073template<
typename MT
1075inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Pointer
1093template<
typename MT
1095inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstPointer
1116template<
typename MT
1118inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Iterator
1122 return Iterator( matrix_.begin(
row() + i ) +
column(), isAligned_ );
1140template<
typename MT
1142inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstIterator
1146 return ConstIterator( matrix_.cbegin(
row() + i ) +
column(), isAligned_ );
1164template<
typename MT
1166inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstIterator
1170 return ConstIterator( matrix_.cbegin(
row() + i ) +
column(), isAligned_ );
1188template<
typename MT
1190inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::Iterator
1194 return Iterator( matrix_.begin(
row() + i ) +
column() +
columns(), isAligned_ );
1212template<
typename MT
1214inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstIterator
1218 return ConstIterator( matrix_.cbegin(
row() + i ) +
column() +
columns(), isAligned_ );
1236template<
typename MT
1238inline typename Submatrix<MT,
unaligned,
false,
true,CSAs...>::ConstIterator
1242 return ConstIterator( matrix_.cbegin(
row() + i ) +
column() +
columns(), isAligned_ );
1267template<
typename MT
1269inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
1270 Submatrix<MT,unaligned,false,true,CSAs...>::operator=(
const ElementType& rhs )
1272 const size_t iend(
row() +
rows() );
1273 decltype(
auto) left( derestrict( matrix_ ) );
1275 for(
size_t i=
row(); i<iend; ++i )
1277 const size_t jbegin( ( IsUpper_v<MT> )
1278 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
1282 const size_t jend ( ( IsLower_v<MT> )
1283 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
1288 for(
size_t j=jbegin; j<jend; ++j ) {
1289 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, j, rhs ) )
1316template<
typename MT
1318inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
1321 if( list.size() !=
rows() ) {
1325 if( IsRestricted_v<MT> ) {
1326 const InitializerMatrix<ElementType> tmp( list,
columns() );
1327 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
1332 decltype(
auto) left( derestrict( *
this ) );
1335 for(
const auto& rowList : list ) {
1336 std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
1361template<
typename MT
1363inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
1364 Submatrix<MT,unaligned,false,true,CSAs...>::operator=(
const Submatrix& rhs )
1369 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ &&
row() == rhs.row() &&
column() == rhs.column() ) )
1372 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
1376 if( !tryAssign( matrix_, rhs,
row(),
column() ) ) {
1380 decltype(
auto) left( derestrict( *
this ) );
1382 if( rhs.canAlias(
this ) ) {
1383 const ResultType tmp( rhs );
1413template<
typename MT
1415template<
typename MT2
1417inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
1418 Submatrix<MT,unaligned,false,true,CSAs...>::operator=(
const Matrix<MT2,SO2>& rhs )
1422 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
1426 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>,
const MT2& >;
1427 Right right( *rhs );
1429 if( !tryAssign( matrix_, right,
row(),
column() ) ) {
1433 decltype(
auto) left( derestrict( *
this ) );
1435 if( IsReference_v<Right> && right.canAlias(
this ) ) {
1436 const ResultType_t<MT2> tmp( right );
1437 if( IsSparseMatrix_v<MT2> )
1442 if( IsSparseMatrix_v<MT2> )
1469template<
typename MT
1471template<
typename MT2
1474 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1480 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1485 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
1489 if( !tryAddAssign( matrix_, *rhs,
row(),
column() ) ) {
1493 decltype(
auto) left( derestrict( *
this ) );
1495 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
1496 const AddType tmp( *
this + (*rhs) );
1525template<
typename MT
1527template<
typename MT2
1530 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1536 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1541 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
1545 const AddType tmp( *
this + (*rhs) );
1547 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
1551 decltype(
auto) left( derestrict( *
this ) );
1577template<
typename MT
1579template<
typename MT2
1582 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1588 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1593 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
1597 if( !trySubAssign( matrix_, *rhs,
row(),
column() ) ) {
1601 decltype(
auto) left( derestrict( *
this ) );
1603 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
1604 const SubType tmp( *
this - (*rhs ) );
1633template<
typename MT
1635template<
typename MT2
1638 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1644 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1649 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
1653 const SubType tmp( *
this - (*rhs) );
1655 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
1659 decltype(
auto) left( derestrict( *
this ) );
1685template<
typename MT
1687template<
typename MT2
1689inline auto Submatrix<MT,unaligned,false,true,CSAs...>::operator%=(
const Matrix<MT2,SO2>& rhs )
1690 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1696 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1700 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
1704 if( !trySchurAssign( matrix_, *rhs,
row(),
column() ) ) {
1708 decltype(
auto) left( derestrict( *
this ) );
1710 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
1711 const SchurType tmp( *
this % (*rhs) );
1712 if( IsSparseMatrix_v<SchurType> )
1742template<
typename MT
1744template<
typename MT2
1746inline auto Submatrix<MT,unaligned,false,true,CSAs...>::operator%=(
const Matrix<MT2,SO2>& rhs )
1747 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
1753 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1757 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
1761 const SchurType tmp( *
this % (*rhs) );
1763 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
1767 decltype(
auto) left( derestrict( *
this ) );
1769 if( IsSparseMatrix_v<SchurType> ) {
1797template<
typename MT
1799inline MT& Submatrix<MT,unaligned,false,true,CSAs...>::operand() noexcept
1813template<
typename MT
1815inline const MT& Submatrix<MT,unaligned,false,true,CSAs...>::operand() const noexcept
1834template<
typename MT
1838 return matrix_.spacing();
1850template<
typename MT
1872template<
typename MT
1892template<
typename MT
1896 const size_t iend(
row() +
rows() );
1898 size_t nonzeros( 0UL );
1900 for(
size_t i=
row(); i<iend; ++i )
1901 for(
size_t j=
column(); j<jend; ++j )
1923template<
typename MT
1930 size_t nonzeros( 0UL );
1932 for(
size_t j=
column(); j<jend; ++j )
1948template<
typename MT
1956 const size_t jbegin( ( IsUpper_v<MT> )
1957 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
1961 const size_t jend ( ( IsLower_v<MT> )
1962 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
1967 for(
size_t j=jbegin; j<jend; ++j )
1968 clear( matrix_(i,j) );
1987template<
typename MT
1995 const size_t jbegin( ( IsUpper_v<MT> )
1996 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
2000 const size_t jend ( ( IsLower_v<MT> )
2001 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
2006 for(
size_t j=jbegin; j<jend; ++j )
2023template<
typename MT
2025inline bool Submatrix<MT,unaligned,false,true,CSAs...>::hasOverlap() const noexcept
2063template<
typename MT
2065inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
2076 decltype(
auto) left( derestrict( *
this ) );
2077 const ResultType tmp(
trans( *
this ) );
2105template<
typename MT
2107inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
2118 decltype(
auto) left( derestrict( *
this ) );
2119 const ResultType tmp(
ctrans( *
this ) );
2142template<
typename MT
2144template<
typename Other >
2145inline Submatrix<MT,
unaligned,
false,
true,CSAs...>&
2146 Submatrix<MT,unaligned,false,true,CSAs...>::scale(
const Other& scalar )
2150 const size_t iend(
row() +
rows() );
2152 for(
size_t i=
row(); i<iend; ++i )
2154 const size_t jbegin( ( IsUpper_v<MT> )
2155 ?( ( IsStrictlyUpper_v<MT> )
2159 const size_t jend ( ( IsLower_v<MT> )
2160 ?( ( IsStrictlyLower_v<MT> )
2165 for(
size_t j=jbegin; j<jend; ++j )
2166 matrix_(i,j) *= scalar;
2194template<
typename MT
2196template<
typename Other >
2197inline bool Submatrix<MT,unaligned,false,true,CSAs...>::canAlias(
const Other* alias )
const noexcept
2199 return matrix_.isAliased( &unview( *alias ) );
2216template<
typename MT
2218template<
typename MT2
2223 Submatrix<MT,unaligned,false,true,CSAs...>::canAlias(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
2225 return ( matrix_.isAliased( &alias->matrix_ ) &&
2226 (
row() +
rows() > alias->row() ) &&
2227 (
row() < alias->row() + alias->rows() ) &&
2229 (
column() < alias->column() + alias->columns() ) );
2246template<
typename MT
2248template<
typename Other >
2249inline bool Submatrix<MT,unaligned,false,true,CSAs...>::isAliased(
const Other* alias )
const noexcept
2251 return matrix_.isAliased( &unview( *alias ) );
2268template<
typename MT
2270template<
typename MT2
2275 Submatrix<MT,unaligned,false,true,CSAs...>::isAliased(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
2277 return ( matrix_.isAliased( &alias->matrix_ ) &&
2278 (
row() +
rows() > alias->row() ) &&
2279 (
row() < alias->row() + alias->rows() ) &&
2281 (
column() < alias->column() + alias->columns() ) );
2297template<
typename MT
2299inline bool Submatrix<MT,unaligned,false,true,CSAs...>::isAligned() const noexcept
2318template<
typename MT
2320inline bool Submatrix<MT,unaligned,false,true,CSAs...>::canSMPAssign() const noexcept
2322 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
2344template<
typename MT
2347 Submatrix<MT,unaligned,false,true,CSAs...>::load(
size_t i,
size_t j )
const noexcept
2350 return loada( i, j );
2352 return loadu( i, j );
2374template<
typename MT
2386 return matrix_.loada(
row()+i,
column()+j );
2408template<
typename MT
2419 return matrix_.loadu(
row()+i,
column()+j );
2442template<
typename MT
2445 Submatrix<MT,unaligned,false,true,CSAs...>::store(
size_t i,
size_t j,
const SIMDType& value )
noexcept
2473template<
typename MT
2485 matrix_.storea(
row()+i,
column()+j, value );
2508template<
typename MT
2519 matrix_.storeu(
row()+i,
column()+j, value );
2542template<
typename MT
2555 matrix_.stream(
row()+i,
column()+j, value );
2557 matrix_.storeu(
row()+i,
column()+j, value );
2575template<
typename MT
2577template<
typename MT2 >
2578inline auto Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
2579 -> DisableIf_t< VectorizedAssign_v<MT2> >
2587 for(
size_t i=0UL; i<
rows(); ++i ) {
2588 for(
size_t j=0UL; j<jpos; j+=2UL ) {
2589 matrix_(
row()+i,
column()+j ) = (*rhs)(i,j );
2590 matrix_(
row()+i,
column()+j+1UL) = (*rhs)(i,j+1UL);
2593 matrix_(
row()+i,
column()+jpos) = (*rhs)(i,jpos);
2613template<
typename MT
2615template<
typename MT2 >
2616inline auto Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
2617 -> EnableIf_t< VectorizedAssign_v<MT2> >
2627 if( useStreaming && isAligned_ &&
2628 rows()*
columns() > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
2629 !(*rhs).isAliased(
this ) )
2631 for(
size_t i=0UL; i<
rows(); ++i )
2634 Iterator left(
begin(i) );
2635 ConstIterator_t<MT2> right( (*rhs).begin(i) );
2637 for( ; j<jpos; j+=SIMDSIZE ) {
2638 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2641 *left = *right; ++left; ++right;
2647 for(
size_t i=0UL; i<
rows(); ++i )
2650 Iterator left(
begin(i) );
2651 ConstIterator_t<MT2> right( (*rhs).begin(i) );
2653 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2654 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2655 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2656 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2657 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2659 for( ; j<jpos; j+=SIMDSIZE ) {
2660 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2663 *left = *right; ++left; ++right;
2684template<
typename MT
2686template<
typename MT2 >
2687inline void Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
2694 constexpr size_t block( BLOCK_SIZE );
2696 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
2697 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
2698 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
2699 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
2700 for(
size_t i=ii; i<iend; ++i ) {
2701 for(
size_t j=jj; j<jend; ++j ) {
2702 matrix_(
row()+i,
column()+j) = (*rhs)(i,j);
2724template<
typename MT
2726template<
typename MT2 >
2727inline void Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const SparseMatrix<MT2,false>& rhs )
2732 for(
size_t i=0UL; i<
rows(); ++i )
2733 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2734 matrix_(
row()+i,
column()+element->index()) = element->value();
2752template<
typename MT
2754template<
typename MT2 >
2755inline void Submatrix<MT,unaligned,false,true,CSAs...>::assign(
const SparseMatrix<MT2,true>& rhs )
2762 for(
size_t j=0UL; j<
columns(); ++j )
2763 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2764 matrix_(
row()+element->index(),
column()+j) = element->value();
2782template<
typename MT
2784template<
typename MT2 >
2785inline auto Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
2786 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
2794 for(
size_t i=0UL; i<
rows(); ++i )
2796 if( IsDiagonal_v<MT2> ) {
2797 matrix_(
row()+i,
column()+i) += (*rhs)(i,i);
2800 for(
size_t j=0UL; j<jpos; j+=2UL ) {
2801 matrix_(
row()+i,
column()+j ) += (*rhs)(i,j );
2802 matrix_(
row()+i,
column()+j+1UL) += (*rhs)(i,j+1UL);
2805 matrix_(
row()+i,
column()+jpos) += (*rhs)(i,jpos);
2826template<
typename MT
2828template<
typename MT2 >
2829inline auto Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
2830 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
2837 for(
size_t i=0UL; i<
rows(); ++i )
2839 const size_t jbegin( ( IsUpper_v<MT2> )
2840 ?(
prevMultiple( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ), SIMDSIZE ) )
2842 const size_t jend ( ( IsLower_v<MT2> )
2843 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
2851 Iterator left(
begin(i) + jbegin );
2852 ConstIterator_t<MT2> right( (*rhs).begin(i) + jbegin );
2854 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2855 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2856 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2857 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2858 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2860 for( ; j<jpos; j+=SIMDSIZE ) {
2861 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2863 for( ; j<jend; ++j ) {
2864 *left += *right; ++left; ++right;
2884template<
typename MT
2886template<
typename MT2 >
2887inline void Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
2894 constexpr size_t block( BLOCK_SIZE );
2896 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
2897 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
2898 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
2899 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
2900 for(
size_t i=ii; i<iend; ++i ) {
2901 for(
size_t j=jj; j<jend; ++j ) {
2902 matrix_(
row()+i,
column()+j) += (*rhs)(i,j);
2924template<
typename MT
2926template<
typename MT2 >
2927inline void Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const SparseMatrix<MT2,false>& rhs )
2932 for(
size_t i=0UL; i<
rows(); ++i )
2933 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2934 matrix_(
row()+i,
column()+element->index()) += element->value();
2952template<
typename MT
2954template<
typename MT2 >
2955inline void Submatrix<MT,unaligned,false,true,CSAs...>::addAssign(
const SparseMatrix<MT2,true>& rhs )
2962 for(
size_t j=0UL; j<
columns(); ++j )
2963 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2964 matrix_(
row()+element->index(),
column()+j) += element->value();
2982template<
typename MT
2984template<
typename MT2 >
2985inline auto Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
2986 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
2994 for(
size_t i=0UL; i<
rows(); ++i )
2996 if( IsDiagonal_v<MT2> ) {
2997 matrix_(
row()+i,
column()+i) -= (*rhs)(i,i);
3000 for(
size_t j=0UL; j<jpos; j+=2UL ) {
3001 matrix_(
row()+i,
column()+j ) -= (*rhs)(i,j );
3002 matrix_(
row()+i,
column()+j+1UL) -= (*rhs)(i,j+1UL);
3005 matrix_(
row()+i,
column()+jpos) -= (*rhs)(i,jpos);
3026template<
typename MT
3028template<
typename MT2 >
3029inline auto Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
3030 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
3037 for(
size_t i=0UL; i<
rows(); ++i )
3039 const size_t jbegin( ( IsUpper_v<MT2> )
3040 ?(
prevMultiple( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ), SIMDSIZE ) )
3042 const size_t jend ( ( IsLower_v<MT2> )
3043 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
3051 Iterator left(
begin(i) + jbegin );
3052 ConstIterator_t<MT2> right( (*rhs).begin(i) + jbegin );
3054 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3055 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3056 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3057 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3058 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3060 for( ; j<jpos; j+=SIMDSIZE ) {
3061 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3063 for( ; j<jend; ++j ) {
3064 *left -= *right; ++left; ++right;
3084template<
typename MT
3086template<
typename MT2 >
3087inline void Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
3094 constexpr size_t block( BLOCK_SIZE );
3096 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
3097 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
3098 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
3099 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
3100 for(
size_t i=ii; i<iend; ++i ) {
3101 for(
size_t j=jj; j<jend; ++j ) {
3102 matrix_(
row()+i,
column()+j) -= (*rhs)(i,j);
3124template<
typename MT
3126template<
typename MT2 >
3127inline void Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const SparseMatrix<MT2,false>& rhs )
3132 for(
size_t i=0UL; i<
rows(); ++i )
3133 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3134 matrix_(
row()+i,
column()+element->index()) -= element->value();
3152template<
typename MT
3154template<
typename MT2 >
3155inline void Submatrix<MT,unaligned,false,true,CSAs...>::subAssign(
const SparseMatrix<MT2,true>& rhs )
3162 for(
size_t j=0UL; j<
columns(); ++j )
3163 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3164 matrix_(
row()+element->index(),
column()+j) -= element->value();
3182template<
typename MT
3184template<
typename MT2 >
3185inline auto Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
3186 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
3194 for(
size_t i=0UL; i<
rows(); ++i ) {
3195 for(
size_t j=0UL; j<jpos; j+=2UL ) {
3196 matrix_(
row()+i,
column()+j ) *= (*rhs)(i,j );
3197 matrix_(
row()+i,
column()+j+1UL) *= (*rhs)(i,j+1UL);
3200 matrix_(
row()+i,
column()+jpos) *= (*rhs)(i,jpos);
3220template<
typename MT
3222template<
typename MT2 >
3223inline auto Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
3224 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
3231 for(
size_t i=0UL; i<
rows(); ++i )
3237 Iterator left(
begin(i) );
3238 ConstIterator_t<MT2> right( (*rhs).begin(i) );
3240 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3241 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3242 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3243 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3244 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3246 for( ; j<jpos; j+=SIMDSIZE ) {
3247 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3250 *left *= *right; ++left; ++right;
3270template<
typename MT
3272template<
typename MT2 >
3273inline void Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
3280 constexpr size_t block( BLOCK_SIZE );
3282 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
3283 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
3284 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
3285 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
3286 for(
size_t i=ii; i<iend; ++i ) {
3287 for(
size_t j=jj; j<jend; ++j ) {
3288 matrix_(
row()+i,
column()+j) *= (*rhs)(i,j);
3310template<
typename MT
3312template<
typename MT2 >
3313inline void Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
3320 for(
size_t i=0UL; i<
rows(); ++i )
3324 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
3325 for( ; j<element->index(); ++j )
3327 matrix_(
row()+i,
column()+j) *= element->value();
3352template<
typename MT
3354template<
typename MT2 >
3355inline void Submatrix<MT,unaligned,false,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
3364 for(
size_t j=0UL; j<
columns(); ++j )
3368 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
3369 for( ; i<element->index(); ++i )
3371 matrix_(
row()+i,
column()+j) *= element->value();
3375 for( ; i<
rows(); ++i ) {
3404template<
typename MT
3406class Submatrix<MT,
unaligned,true,true,CSAs...>
3407 :
public View< DenseMatrix< Submatrix<MT,unaligned,true,true,CSAs...>, true > >
3408 ,
private SubmatrixData<CSAs...>
3412 using DataType = SubmatrixData<CSAs...>;
3413 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
3418 template<
typename MT1,
typename MT2 >
3419 static constexpr bool EnforceEvaluation_v =
3420 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
3426 using This = Submatrix<MT,
unaligned,
true,
true,CSAs...>;
3429 using BaseType = View< DenseMatrix<This,true> >;
3431 using ViewedType = MT;
3433 using OppositeType = OppositeType_t<ResultType>;
3434 using TransposeType = TransposeType_t<ResultType>;
3435 using ElementType = ElementType_t<MT>;
3436 using SIMDType = SIMDTrait_t<ElementType>;
3437 using ReturnType = ReturnType_t<MT>;
3438 using CompositeType =
const Submatrix&;
3441 using ConstReference = ConstReference_t<MT>;
3444 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
3447 using ConstPointer = ConstPointer_t<MT>;
3450 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
3456 template<
typename IteratorType >
3457 class SubmatrixIterator
3462 using IteratorCategory =
typename std::iterator_traits<IteratorType>::iterator_category;
3465 using ValueType =
typename std::iterator_traits<IteratorType>::value_type;
3468 using PointerType =
typename std::iterator_traits<IteratorType>::pointer;
3471 using ReferenceType =
typename std::iterator_traits<IteratorType>::reference;
3474 using DifferenceType =
typename std::iterator_traits<IteratorType>::difference_type;
3477 using iterator_category = IteratorCategory;
3478 using value_type = ValueType;
3479 using pointer = PointerType;
3480 using reference = ReferenceType;
3481 using difference_type = DifferenceType;
3487 inline SubmatrixIterator()
3489 , isAligned_( false )
3501 inline SubmatrixIterator( IteratorType iterator,
bool isMemoryAligned )
3502 : iterator_ ( iterator )
3503 , isAligned_( isMemoryAligned )
3512 template<
typename IteratorType2 >
3513 inline SubmatrixIterator(
const SubmatrixIterator<IteratorType2>& it )
3514 : iterator_ ( it.base() )
3515 , isAligned_( it.isAligned() )
3525 inline SubmatrixIterator&
operator+=(
size_t inc ) {
3537 inline SubmatrixIterator&
operator-=(
size_t dec ) {
3548 inline SubmatrixIterator& operator++() {
3559 inline const SubmatrixIterator operator++(
int ) {
3560 return SubmatrixIterator( iterator_++, isAligned_ );
3569 inline SubmatrixIterator& operator--() {
3580 inline const SubmatrixIterator operator--(
int ) {
3581 return SubmatrixIterator( iterator_--, isAligned_ );
3590 inline ReferenceType
operator*()
const {
3600 inline IteratorType operator->()
const {
3615 inline SIMDType load() const noexcept {
3633 inline SIMDType
loada() const noexcept {
3634 return iterator_.loada();
3648 inline SIMDType
loadu() const noexcept {
3649 return iterator_.loadu();
3664 inline void store(
const SIMDType& value )
const {
3685 inline void storea(
const SIMDType& value )
const {
3686 iterator_.storea( value );
3701 inline void storeu(
const SIMDType& value )
const {
3702 iterator_.storeu( value );
3717 inline void stream(
const SIMDType& value )
const {
3718 iterator_.stream( value );
3728 inline bool operator==(
const SubmatrixIterator& rhs )
const {
3729 return iterator_ == rhs.iterator_;
3739 inline bool operator!=(
const SubmatrixIterator& rhs )
const {
3740 return iterator_ != rhs.iterator_;
3750 inline bool operator<(
const SubmatrixIterator& rhs )
const {
3751 return iterator_ < rhs.iterator_;
3761 inline bool operator>(
const SubmatrixIterator& rhs )
const {
3762 return iterator_ > rhs.iterator_;
3772 inline bool operator<=(
const SubmatrixIterator& rhs )
const {
3773 return iterator_ <= rhs.iterator_;
3783 inline bool operator>=(
const SubmatrixIterator& rhs )
const {
3784 return iterator_ >= rhs.iterator_;
3794 inline DifferenceType
operator-(
const SubmatrixIterator& rhs )
const {
3795 return iterator_ - rhs.iterator_;
3806 friend inline const SubmatrixIterator
operator+(
const SubmatrixIterator& it,
size_t inc ) {
3807 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
3818 friend inline const SubmatrixIterator
operator+(
size_t inc,
const SubmatrixIterator& it ) {
3819 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
3830 friend inline const SubmatrixIterator
operator-(
const SubmatrixIterator& it,
size_t dec ) {
3831 return SubmatrixIterator( it.iterator_ - dec, it.isAligned_ );
3840 inline IteratorType base()
const {
3850 inline bool isAligned() const noexcept {
3857 IteratorType iterator_;
3865 using ConstIterator = SubmatrixIterator< ConstIterator_t<MT> >;
3868 using Iterator = If_t< IsConst_v<MT>, ConstIterator, SubmatrixIterator< Iterator_t<MT> > >;
3873 static constexpr bool simdEnabled = MT::simdEnabled;
3876 static constexpr bool smpAssignable = MT::smpAssignable;
3879 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
3885 template<
typename... RSAs >
3886 explicit inline Submatrix( MT& matrix, RSAs... args );
3888 Submatrix(
const Submatrix& ) =
default;
3895 ~Submatrix() =
default;
3902 inline Reference operator()(
size_t i,
size_t j );
3903 inline ConstReference operator()(
size_t i,
size_t j )
const;
3904 inline Reference at(
size_t i,
size_t j );
3905 inline ConstReference at(
size_t i,
size_t j )
const;
3906 inline Pointer
data () noexcept;
3907 inline ConstPointer
data () const noexcept;
3908 inline Pointer
data (
size_t j ) noexcept;
3909 inline ConstPointer
data (
size_t j ) const noexcept;
3910 inline Iterator
begin (
size_t j );
3911 inline ConstIterator
begin (
size_t j ) const;
3912 inline ConstIterator
cbegin(
size_t j ) const;
3913 inline Iterator
end (
size_t j );
3914 inline ConstIterator
end (
size_t j ) const;
3915 inline ConstIterator
cend (
size_t j ) const;
3922 inline Submatrix& operator=( const ElementType& rhs );
3924 inline Submatrix& operator=( const Submatrix& rhs );
3926 template< typename MT2,
bool SO >
3927 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
3929 template< typename MT2,
bool SO >
3930 inline auto operator+=( const Matrix<MT2,SO>& rhs )
3931 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3933 template< typename MT2,
bool SO >
3934 inline auto operator+=( const Matrix<MT2,SO>& rhs )
3935 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3937 template< typename MT2,
bool SO >
3938 inline auto operator-=( const Matrix<MT2,SO>& rhs )
3939 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3941 template< typename MT2,
bool SO >
3942 inline auto operator-=( const Matrix<MT2,SO>& rhs )
3943 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3945 template< typename MT2,
bool SO >
3946 inline auto operator%=( const Matrix<MT2,SO>& rhs )
3947 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3949 template< typename MT2,
bool SO >
3950 inline auto operator%=( const Matrix<MT2,SO>& rhs )
3951 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
3958 using DataType::
row;
3960 using DataType::
rows;
3963 inline MT& operand() noexcept;
3964 inline const MT& operand() const noexcept;
3966 inline
size_t spacing() const noexcept;
3967 inline
size_t capacity() const noexcept;
3968 inline
size_t capacity(
size_t i ) const noexcept;
3970 inline
size_t nonZeros(
size_t i ) const;
3971 inline
void reset();
3972 inline
void reset(
size_t i );
3982 template< typename Other > inline Submatrix& scale( const Other& scalar );
3989 template< typename MT2 >
3990 static constexpr
bool VectorizedAssign_v =
3991 ( useOptimizedKernels &&
3992 simdEnabled && MT2::simdEnabled &&
3998 template< typename MT2 >
3999 static constexpr
bool VectorizedAddAssign_v =
4000 ( VectorizedAssign_v<MT2> &&
4007 template< typename MT2 >
4008 static constexpr
bool VectorizedSubAssign_v =
4009 ( VectorizedAssign_v<MT2> &&
4016 template< typename MT2 >
4017 static constexpr
bool VectorizedSchurAssign_v =
4018 ( VectorizedAssign_v<MT2> &&
4024 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
4031 template< typename Other >
4032 inline
bool canAlias( const Other* alias ) const noexcept;
4034 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
4035 inline
bool canAlias( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
4037 template< typename Other >
4038 inline
bool isAliased( const Other* alias ) const noexcept;
4040 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
4041 inline
bool isAliased( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
4043 inline
bool isAligned () const noexcept;
4044 inline
bool canSMPAssign() const noexcept;
4055 template< typename MT2 >
4056 inline auto assign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedAssign_v<MT2> >;
4058 template< typename MT2 >
4059 inline auto assign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedAssign_v<MT2> >;
4061 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,false>& rhs );
4062 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
4063 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
4065 template< typename MT2 >
4066 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<MT2> >;
4068 template< typename MT2 >
4069 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<MT2> >;
4071 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,false>& rhs );
4072 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
4073 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
4075 template< typename MT2 >
4076 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<MT2> >;
4078 template< typename MT2 >
4079 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<MT2> >;
4081 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,false>& rhs );
4082 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
4083 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
4085 template< typename MT2 >
4086 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedSchurAssign_v<MT2> >;
4088 template< typename MT2 >
4089 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedSchurAssign_v<MT2> >;
4091 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,false>& rhs );
4092 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
4093 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
4101 inline
bool hasOverlap() const noexcept;
4109 const
bool isAligned_;
4120 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
bool DF2,
size_t... CSAs2 > friend class Submatrix;
4158template< typename MT
4160template< typename... RSAs >
4161inline Submatrix<MT,
unaligned,true,true,CSAs...>::Submatrix( MT& matrix, RSAs... args )
4162 : DataType ( args... )
4163 , matrix_ ( matrix )
4201template<
typename MT
4203inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Reference
4204 Submatrix<MT,unaligned,true,true,CSAs...>::operator()(
size_t i,
size_t j )
4226template<
typename MT
4228inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstReference
4229 Submatrix<MT,unaligned,true,true,CSAs...>::operator()(
size_t i,
size_t j )
const
4234 return const_cast<const MT&
>( matrix_ )(
row()+i,
column()+j);
4252template<
typename MT
4254inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Reference
4255 Submatrix<MT,unaligned,true,true,CSAs...>::at(
size_t i,
size_t j )
4263 return (*
this)(i,j);
4281template<
typename MT
4283inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstReference
4284 Submatrix<MT,unaligned,true,true,CSAs...>::at(
size_t i,
size_t j )
const
4292 return (*
this)(i,j);
4308template<
typename MT
4310inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Pointer
4329template<
typename MT
4331inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstPointer
4349template<
typename MT
4351inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Pointer
4369template<
typename MT
4371inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstPointer
4387template<
typename MT
4389inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Iterator
4393 return Iterator( matrix_.begin(
column() + j ) +
row(), isAligned_ );
4406template<
typename MT
4408inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstIterator
4412 return ConstIterator( matrix_.cbegin(
column() + j ) +
row(), isAligned_ );
4425template<
typename MT
4427inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstIterator
4431 return ConstIterator( matrix_.cbegin(
column() + j ) +
row(), isAligned_ );
4444template<
typename MT
4446inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::Iterator
4450 return Iterator( matrix_.begin(
column() + j ) +
row() +
rows(), isAligned_ );
4463template<
typename MT
4465inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstIterator
4469 return ConstIterator( matrix_.cbegin(
column() + j ) +
row() +
rows(), isAligned_ );
4482template<
typename MT
4484inline typename Submatrix<MT,
unaligned,
true,
true,CSAs...>::ConstIterator
4488 return ConstIterator( matrix_.cbegin(
column() + j ) +
row() +
rows(), isAligned_ );
4513template<
typename MT
4515inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
4516 Submatrix<MT,unaligned,true,true,CSAs...>::operator=(
const ElementType& rhs )
4519 decltype(
auto) left( derestrict( matrix_ ) );
4521 for(
size_t j=
column(); j<jend; ++j )
4523 const size_t ibegin( ( IsLower_v<MT> )
4524 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
4528 const size_t iend ( ( IsUpper_v<MT> )
4529 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
4534 for(
size_t i=ibegin; i<iend; ++i ) {
4535 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, j, rhs ) )
4562template<
typename MT
4564inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
4569 if( list.size() !=
rows() ) {
4573 if( IsRestricted_v<MT> ) {
4574 const InitializerMatrix<ElementType> tmp( list,
columns() );
4575 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
4580 decltype(
auto) left( derestrict( *
this ) );
4583 for(
const auto& rowList : list ) {
4585 for(
const auto& element : rowList ) {
4586 left(i,j) = element;
4616template<
typename MT
4618inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
4619 Submatrix<MT,unaligned,true,true,CSAs...>::operator=(
const Submatrix& rhs )
4624 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ &&
row() == rhs.row() &&
column() == rhs.column() ) )
4627 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
4631 if( !tryAssign( matrix_, rhs,
row(),
column() ) ) {
4635 decltype(
auto) left( derestrict( *
this ) );
4637 if( rhs.canAlias(
this ) ) {
4638 const ResultType tmp( rhs );
4668template<
typename MT
4670template<
typename MT2
4672inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
4673 Submatrix<MT,unaligned,true,true,CSAs...>::operator=(
const Matrix<MT2,SO>& rhs )
4677 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
4681 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>,
const MT2& >;
4682 Right right( *rhs );
4684 if( !tryAssign( matrix_, right,
row(),
column() ) ) {
4688 decltype(
auto) left( derestrict( *
this ) );
4690 if( IsReference_v<Right> && right.canAlias(
this ) ) {
4691 const ResultType_t<MT2> tmp( right );
4692 if( IsSparseMatrix_v<MT2> )
4697 if( IsSparseMatrix_v<MT2> )
4724template<
typename MT
4726template<
typename MT2
4729 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4735 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4740 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
4744 if( !tryAddAssign( matrix_, *rhs,
row(),
column() ) ) {
4748 decltype(
auto) left( derestrict( *
this ) );
4750 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
4751 const AddType tmp( *
this + (*rhs) );
4780template<
typename MT
4782template<
typename MT2
4785 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4791 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4796 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
4800 const AddType tmp( *
this + (*rhs) );
4802 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
4806 decltype(
auto) left( derestrict( *
this ) );
4832template<
typename MT
4834template<
typename MT2
4837 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4843 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4848 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
4852 if( !trySubAssign( matrix_, *rhs,
row(),
column() ) ) {
4856 decltype(
auto) left( derestrict( *
this ) );
4858 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
4859 const SubType tmp( *
this - (*rhs ) );
4888template<
typename MT
4890template<
typename MT2
4893 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4899 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4904 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
4908 const SubType tmp( *
this - (*rhs) );
4910 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
4914 decltype(
auto) left( derestrict( *
this ) );
4940template<
typename MT
4942template<
typename MT2
4944inline auto Submatrix<MT,unaligned,true,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
4945 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
4951 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4955 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
4959 if( !trySchurAssign( matrix_, *rhs,
row(),
column() ) ) {
4963 decltype(
auto) left( derestrict( *
this ) );
4965 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
4966 const SchurType tmp( *
this % (*rhs) );
4967 if( IsSparseMatrix_v<SchurType> )
4997template<
typename MT
4999template<
typename MT2
5001inline auto Submatrix<MT,unaligned,true,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
5002 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
5008 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
5012 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
5016 const SchurType tmp( *
this % (*rhs) );
5018 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
5022 decltype(
auto) left( derestrict( *
this ) );
5024 if( IsSparseMatrix_v<SchurType> ) {
5052template<
typename MT
5054inline MT& Submatrix<MT,unaligned,true,true,CSAs...>::operand() noexcept
5068template<
typename MT
5070inline const MT& Submatrix<MT,unaligned,true,true,CSAs...>::operand() const noexcept
5087template<
typename MT
5091 return matrix_.spacing();
5103template<
typename MT
5120template<
typename MT
5140template<
typename MT
5144 const size_t iend(
row() +
rows() );
5146 size_t nonzeros( 0UL );
5148 for(
size_t j=
column(); j<jend; ++j )
5149 for(
size_t i=
row(); i<iend; ++i )
5166template<
typename MT
5172 const size_t iend(
row() +
rows() );
5173 size_t nonzeros( 0UL );
5175 for(
size_t i=
row(); i<iend; ++i )
5191template<
typename MT
5199 const size_t ibegin( ( IsLower_v<MT> )
5200 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
5204 const size_t iend ( ( IsUpper_v<MT> )
5205 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
5210 for(
size_t i=ibegin; i<iend; ++i )
5211 clear( matrix_(i,j) );
5225template<
typename MT
5233 const size_t ibegin( ( IsLower_v<MT> )
5234 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
5238 const size_t iend ( ( IsUpper_v<MT> )
5239 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
5244 for(
size_t i=ibegin; i<iend; ++i )
5261template<
typename MT
5263inline bool Submatrix<MT,unaligned,true,true,CSAs...>::hasOverlap() const noexcept
5301template<
typename MT
5303inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
5314 decltype(
auto) left( derestrict( *
this ) );
5315 const ResultType tmp(
trans( *
this ) );
5343template<
typename MT
5345inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
5356 decltype(
auto) left( derestrict( *
this ) );
5357 const ResultType tmp(
ctrans( *
this ) );
5380template<
typename MT
5382template<
typename Other >
5383inline Submatrix<MT,
unaligned,
true,
true,CSAs...>&
5384 Submatrix<MT,unaligned,true,true,CSAs...>::scale(
const Other& scalar )
5390 for(
size_t j=
column(); j<jend; ++j )
5392 const size_t ibegin( ( IsLower_v<MT> )
5393 ?( ( IsStrictlyLower_v<MT> )
5397 const size_t iend ( ( IsUpper_v<MT> )
5398 ?( ( IsStrictlyUpper_v<MT> )
5403 for(
size_t i=ibegin; i<iend; ++i )
5404 matrix_(i,j) *= scalar;
5432template<
typename MT
5434template<
typename Other >
5435inline bool Submatrix<MT,unaligned,true,true,CSAs...>::canAlias(
const Other* alias )
const noexcept
5437 return matrix_.isAliased( &unview( *alias ) );
5454template<
typename MT
5456template<
typename MT2
5461 Submatrix<MT,unaligned,true,true,CSAs...>::canAlias(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
5463 return ( matrix_.isAliased( &alias->matrix_ ) &&
5464 (
row() +
rows() > alias->row() ) &&
5465 (
row() < alias->row() + alias->rows() ) &&
5467 (
column() < alias->column() + alias->columns() ) );
5484template<
typename MT
5486template<
typename Other >
5487inline bool Submatrix<MT,unaligned,true,true,CSAs...>::isAliased(
const Other* alias )
const noexcept
5489 return matrix_.isAliased( &unview( *alias ) );
5506template<
typename MT
5508template<
typename MT2
5513 Submatrix<MT,unaligned,true,true,CSAs...>::isAliased(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
5515 return ( matrix_.isAliased( &alias->matrix_ ) &&
5516 (
row() +
rows() > alias->row() ) &&
5517 (
row() < alias->row() + alias->rows() ) &&
5519 (
column() < alias->column() + alias->columns() ) );
5535template<
typename MT
5537inline bool Submatrix<MT,unaligned,true,true,CSAs...>::isAligned() const noexcept
5556template<
typename MT
5558inline bool Submatrix<MT,unaligned,true,true,CSAs...>::canSMPAssign() const noexcept
5560 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
5581template<
typename MT
5584 Submatrix<MT,unaligned,true,true,CSAs...>::load(
size_t i,
size_t j )
const noexcept
5587 return loada( i, j );
5589 return loadu( i, j );
5610template<
typename MT
5622 return matrix_.loada(
row()+i,
column()+j );
5643template<
typename MT
5654 return matrix_.loadu(
row()+i,
column()+j );
5676template<
typename MT
5679 Submatrix<MT,unaligned,true,true,CSAs...>::store(
size_t i,
size_t j,
const SIMDType& value )
noexcept
5706template<
typename MT
5718 matrix_.storea(
row()+i,
column()+j, value );
5740template<
typename MT
5751 matrix_.storeu(
row()+i,
column()+j, value );
5774template<
typename MT
5787 matrix_.stream(
row()+i,
column()+j, value );
5789 matrix_.storeu(
row()+i,
column()+j, value );
5807template<
typename MT
5809template<
typename MT2 >
5810inline auto Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
5811 -> DisableIf_t< VectorizedAssign_v<MT2> >
5819 for(
size_t j=0UL; j<
columns(); ++j ) {
5820 for(
size_t i=0UL; i<ipos; i+=2UL ) {
5821 matrix_(
row()+i ,
column()+j) = (*rhs)(i ,j);
5822 matrix_(
row()+i+1UL,
column()+j) = (*rhs)(i+1UL,j);
5824 if( ipos <
rows() ) {
5825 matrix_(
row()+ipos,
column()+j) = (*rhs)(ipos,j);
5845template<
typename MT
5847template<
typename MT2 >
5848inline auto Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
5849 -> EnableIf_t< VectorizedAssign_v<MT2> >
5859 if( useStreaming && isAligned_ &&
5860 rows()*
columns() > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
5861 !(*rhs).isAliased(
this ) )
5863 for(
size_t j=0UL; j<
columns(); ++j )
5866 Iterator left(
begin(j) );
5867 ConstIterator_t<MT2> right( (*rhs).begin(j) );
5869 for( ; i<ipos; i+=SIMDSIZE ) {
5870 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5872 for( ; i<
rows(); ++i ) {
5873 *left = *right; ++left; ++right;
5879 for(
size_t j=0UL; j<
columns(); ++j )
5882 Iterator left(
begin(j) );
5883 ConstIterator_t<MT2> right( (*rhs).begin(j) );
5885 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5886 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5887 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5888 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5889 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5891 for( ; i<ipos; i+=SIMDSIZE ) {
5892 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5894 for( ; i<
rows(); ++i ) {
5895 *left = *right; ++left; ++right;
5916template<
typename MT
5918template<
typename MT2 >
5919inline void Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
5926 constexpr size_t block( BLOCK_SIZE );
5928 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
5929 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
5930 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
5931 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
5932 for(
size_t j=jj; j<jend; ++j ) {
5933 for(
size_t i=ii; i<iend; ++i ) {
5934 matrix_(
row()+i,
column()+j) = (*rhs)(i,j);
5956template<
typename MT
5958template<
typename MT2 >
5959inline void Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const SparseMatrix<MT2,true>& rhs )
5964 for(
size_t j=0UL; j<
columns(); ++j )
5965 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
5966 matrix_(
row()+element->index(),
column()+j) = element->value();
5984template<
typename MT
5986template<
typename MT2 >
5987inline void Submatrix<MT,unaligned,true,true,CSAs...>::assign(
const SparseMatrix<MT2,false>& rhs )
5994 for(
size_t i=0UL; i<
rows(); ++i )
5995 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5996 matrix_(
row()+i,
column()+element->index()) = element->value();
6014template<
typename MT
6016template<
typename MT2 >
6017inline auto Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
6018 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
6026 for(
size_t j=0UL; j<
columns(); ++j )
6028 if( IsDiagonal_v<MT2> ) {
6029 matrix_(
row()+j,
column()+j) += (*rhs)(j,j);
6032 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6033 matrix_(
row()+i ,
column()+j) += (*rhs)(i ,j);
6034 matrix_(
row()+i+1UL,
column()+j) += (*rhs)(i+1UL,j);
6036 if( ipos <
rows() ) {
6037 matrix_(
row()+ipos,
column()+j) += (*rhs)(ipos,j);
6058template<
typename MT
6060template<
typename MT2 >
6061inline auto Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
6062 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
6069 for(
size_t j=0UL; j<
columns(); ++j )
6071 const size_t ibegin( ( IsLower_v<MT> )
6072 ?(
prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
6074 const size_t iend ( ( IsUpper_v<MT> )
6075 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6083 Iterator left(
begin(j) + ibegin );
6084 ConstIterator_t<MT2> right( (*rhs).begin(j) + ibegin );
6086 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6087 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6088 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6089 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6090 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6092 for( ; i<ipos; i+=SIMDSIZE ) {
6093 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6095 for( ; i<iend; ++i ) {
6096 *left += *right; ++left; ++right;
6116template<
typename MT
6118template<
typename MT2 >
6119inline void Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
6126 constexpr size_t block( BLOCK_SIZE );
6128 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
6129 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
6130 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
6131 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
6132 for(
size_t j=jj; j<jend; ++j ) {
6133 for(
size_t i=ii; i<iend; ++i ) {
6134 matrix_(
row()+i,
column()+j) += (*rhs)(i,j);
6156template<
typename MT
6158template<
typename MT2 >
6159inline void Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const SparseMatrix<MT2,true>& rhs )
6164 for(
size_t j=0UL; j<
columns(); ++j )
6165 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6166 matrix_(
row()+element->index(),
column()+j) += element->value();
6184template<
typename MT
6186template<
typename MT2 >
6187inline void Submatrix<MT,unaligned,true,true,CSAs...>::addAssign(
const SparseMatrix<MT2,false>& rhs )
6194 for(
size_t i=0UL; i<
rows(); ++i )
6195 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6196 matrix_(
row()+i,
column()+element->index()) += element->value();
6214template<
typename MT
6216template<
typename MT2 >
6217inline auto Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
6218 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
6226 for(
size_t j=0UL; j<
columns(); ++j )
6228 if( IsDiagonal_v<MT2> ) {
6229 matrix_(
row()+j,
column()+j) -= (*rhs)(j,j);
6232 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6233 matrix_(
row()+i ,
column()+j) -= (*rhs)(i ,j);
6234 matrix_(
row()+i+1UL,
column()+j) -= (*rhs)(i+1UL,j);
6236 if( ipos <
rows() ) {
6237 matrix_(
row()+ipos,
column()+j) -= (*rhs)(ipos,j);
6258template<
typename MT
6260template<
typename MT2 >
6261inline auto Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
6262 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
6269 for(
size_t j=0UL; j<
columns(); ++j )
6271 const size_t ibegin( ( IsLower_v<MT> )
6272 ?(
prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
6274 const size_t iend ( ( IsUpper_v<MT> )
6275 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6283 Iterator left(
begin(j) + ibegin );
6284 ConstIterator_t<MT2> right( (*rhs).begin(j) + ibegin );
6286 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6287 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6288 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6289 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6290 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6292 for( ; i<ipos; i+=SIMDSIZE ) {
6293 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6295 for( ; i<iend; ++i ) {
6296 *left -= *right; ++left; ++right;
6316template<
typename MT
6318template<
typename MT2 >
6319inline void Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
6326 constexpr size_t block( BLOCK_SIZE );
6328 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
6329 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
6330 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
6331 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
6332 for(
size_t j=jj; j<jend; ++j ) {
6333 for(
size_t i=ii; i<iend; ++i ) {
6334 matrix_(
row()+i,
column()+j) -= (*rhs)(i,j);
6356template<
typename MT
6358template<
typename MT2 >
6359inline void Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const SparseMatrix<MT2,true>& rhs )
6364 for(
size_t j=0UL; j<
columns(); ++j )
6365 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6366 matrix_(
row()+element->index(),
column()+j) -= element->value();
6384template<
typename MT
6386template<
typename MT2 >
6387inline void Submatrix<MT,unaligned,true,true,CSAs...>::subAssign(
const SparseMatrix<MT2,false>& rhs )
6394 for(
size_t i=0UL; i<
rows(); ++i )
6395 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6396 matrix_(
row()+i,
column()+element->index()) -= element->value();
6414template<
typename MT
6416template<
typename MT2 >
6417inline auto Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
6418 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
6426 for(
size_t j=0UL; j<
columns(); ++j ) {
6427 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6428 matrix_(
row()+i ,
column()+j) *= (*rhs)(i ,j);
6429 matrix_(
row()+i+1UL,
column()+j) *= (*rhs)(i+1UL,j);
6431 if( ipos <
rows() ) {
6432 matrix_(
row()+ipos,
column()+j) *= (*rhs)(ipos,j);
6453template<
typename MT
6455template<
typename MT2 >
6456inline auto Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
6457 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
6464 for(
size_t j=0UL; j<
columns(); ++j )
6470 Iterator left(
begin(j) );
6471 ConstIterator_t<MT2> right( (*rhs).begin(j) );
6473 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6474 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6475 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6476 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6477 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6479 for( ; i<ipos; i+=SIMDSIZE ) {
6480 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6482 for( ; i<
rows(); ++i ) {
6483 *left *= *right; ++left; ++right;
6503template<
typename MT
6505template<
typename MT2 >
6506inline void Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
6513 constexpr size_t block( BLOCK_SIZE );
6515 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
6516 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
6517 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
6518 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
6519 for(
size_t j=jj; j<jend; ++j ) {
6520 for(
size_t i=ii; i<iend; ++i ) {
6521 matrix_(
row()+i,
column()+j) *= (*rhs)(i,j);
6543template<
typename MT
6545template<
typename MT2 >
6546inline void Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
6553 for(
size_t j=0UL; j<
columns(); ++j )
6557 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
6558 for( ; i<element->index(); ++i )
6560 matrix_(
row()+i,
column()+j) *= element->value();
6564 for( ; i<
rows(); ++i ) {
6585template<
typename MT
6587template<
typename MT2 >
6588inline void Submatrix<MT,unaligned,true,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
6597 for(
size_t i=0UL; i<
rows(); ++i )
6601 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
6602 for( ; j<element->index(); ++j )
6604 matrix_(
row()+i,
column()+j) *= element->value();
6637template<
typename MT
6639class Submatrix<MT,
aligned,false,true,CSAs...>
6640 :
public View< DenseMatrix< Submatrix<MT,aligned,false,true,CSAs...>, false > >
6641 ,
private SubmatrixData<CSAs...>
6645 using DataType = SubmatrixData<CSAs...>;
6646 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
6651 template<
typename MT1,
typename MT2 >
6652 static constexpr bool EnforceEvaluation_v =
6653 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
6659 using This = Submatrix<MT,
aligned,
false,
true,CSAs...>;
6662 using BaseType = View< DenseMatrix<This,false> >;
6664 using ViewedType = MT;
6666 using OppositeType = OppositeType_t<ResultType>;
6667 using TransposeType = TransposeType_t<ResultType>;
6668 using ElementType = ElementType_t<MT>;
6669 using SIMDType = SIMDTrait_t<ElementType>;
6670 using ReturnType = ReturnType_t<MT>;
6671 using CompositeType =
const Submatrix&;
6674 using ConstReference = ConstReference_t<MT>;
6677 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
6680 using ConstPointer = ConstPointer_t<MT>;
6683 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
6686 using ConstIterator = ConstIterator_t<MT>;
6689 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
6694 static constexpr bool simdEnabled = MT::simdEnabled;
6697 static constexpr bool smpAssignable = MT::smpAssignable;
6700 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
6706 template<
typename... RSAs >
6707 explicit inline Submatrix( MT& matrix, RSAs... args );
6709 Submatrix(
const Submatrix& ) =
default;
6716 ~Submatrix() =
default;
6723 inline Reference operator()(
size_t i,
size_t j );
6724 inline ConstReference operator()(
size_t i,
size_t j )
const;
6725 inline Reference at(
size_t i,
size_t j );
6726 inline ConstReference at(
size_t i,
size_t j )
const;
6727 inline Pointer
data () noexcept;
6728 inline ConstPointer
data () const noexcept;
6729 inline Pointer
data (
size_t i ) noexcept;
6730 inline ConstPointer
data (
size_t i ) const noexcept;
6731 inline Iterator
begin (
size_t i );
6732 inline ConstIterator
begin (
size_t i ) const;
6733 inline ConstIterator
cbegin(
size_t i ) const;
6734 inline Iterator
end (
size_t i );
6735 inline ConstIterator
end (
size_t i ) const;
6736 inline ConstIterator
cend (
size_t i ) const;
6743 inline Submatrix& operator=( const ElementType& rhs );
6745 inline Submatrix& operator=( const Submatrix& rhs );
6747 template< typename MT2,
bool SO >
6748 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
6750 template< typename MT2,
bool SO >
6751 inline auto operator+=( const Matrix<MT2,SO>& rhs )
6752 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6754 template< typename MT2,
bool SO >
6755 inline auto operator+=( const Matrix<MT2,SO>& rhs )
6756 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6758 template< typename MT2,
bool SO >
6759 inline auto operator-=( const Matrix<MT2,SO>& rhs )
6760 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6762 template< typename MT2,
bool SO >
6763 inline auto operator-=( const Matrix<MT2,SO>& rhs )
6764 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6766 template< typename MT2,
bool SO >
6767 inline auto operator%=( const Matrix<MT2,SO>& rhs )
6768 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6770 template< typename MT2,
bool SO >
6771 inline auto operator%=( const Matrix<MT2,SO>& rhs )
6772 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
6779 using DataType::
row;
6781 using DataType::
rows;
6784 inline MT& operand() noexcept;
6785 inline const MT& operand() const noexcept;
6787 inline
size_t spacing() const noexcept;
6788 inline
size_t capacity() const noexcept;
6789 inline
size_t capacity(
size_t i ) const noexcept;
6791 inline
size_t nonZeros(
size_t i ) const;
6792 inline
void reset();
6793 inline
void reset(
size_t i );
6803 template< typename Other > inline Submatrix& scale( const Other& scalar );
6810 template< typename MT2 >
6811 static constexpr
bool VectorizedAssign_v =
6812 ( useOptimizedKernels &&
6813 simdEnabled && MT2::simdEnabled &&
6819 template< typename MT2 >
6820 static constexpr
bool VectorizedAddAssign_v =
6821 ( VectorizedAssign_v<MT2> &&
6828 template< typename MT2 >
6829 static constexpr
bool VectorizedSubAssign_v =
6830 ( VectorizedAssign_v<MT2> &&
6837 template< typename MT2 >
6838 static constexpr
bool VectorizedSchurAssign_v =
6839 ( VectorizedAssign_v<MT2> &&
6845 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
6852 template< typename Other >
6853 inline
bool canAlias( const Other* alias ) const noexcept;
6855 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
6856 inline
bool canAlias( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
6858 template< typename Other >
6859 inline
bool isAliased( const Other* alias ) const noexcept;
6861 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
6862 inline
bool isAliased( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
6864 inline
bool isAligned () const noexcept;
6865 inline
bool canSMPAssign() const noexcept;
6876 template< typename MT2 >
6877 inline auto assign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedAssign_v<MT2> >;
6879 template< typename MT2 >
6880 inline auto assign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedAssign_v<MT2> >;
6882 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,true>& rhs );
6883 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
6884 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
6886 template< typename MT2 >
6887 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<MT2> >;
6889 template< typename MT2 >
6890 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<MT2> >;
6892 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,true>& rhs );
6893 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
6894 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
6896 template< typename MT2 >
6897 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<MT2> >;
6899 template< typename MT2 >
6900 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<MT2> >;
6902 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,true>& rhs );
6903 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
6904 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
6906 template< typename MT2 >
6907 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) ->
DisableIf_t< VectorizedSchurAssign_v<MT2> >;
6909 template< typename MT2 >
6910 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) ->
EnableIf_t< VectorizedSchurAssign_v<MT2> >;
6912 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,true>& rhs );
6913 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
6914 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
6922 inline
bool hasOverlap() const noexcept;
6934 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
bool DF2,
size_t... CSAs2 > friend class Submatrix;
6972template< typename MT
6974template< typename... RSAs >
6975inline Submatrix<MT,
aligned,false,true,CSAs...>::Submatrix( MT& matrix, RSAs... args )
6976 : DataType( args... )
6977 , matrix_ ( matrix )
6985 if( simdEnabled && IsContiguous_v<MT> &&
6987 (
rows() > 1UL && matrix_.spacing() % SIMDSIZE != 0UL ) ) ) {
6997 BLAZE_USER_ASSERT( !simdEnabled || !IsContiguous_v<MT> ||
rows() <= 1UL || matrix_.spacing() % SIMDSIZE == 0UL,
"Invalid submatrix alignment" );
7023template<
typename MT
7025inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Reference
7026 Submatrix<MT,aligned,false,true,CSAs...>::operator()(
size_t i,
size_t j )
7048template<
typename MT
7050inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstReference
7051 Submatrix<MT,aligned,false,true,CSAs...>::operator()(
size_t i,
size_t j )
const
7056 return const_cast<const MT&
>( matrix_ )(
row()+i,
column()+j);
7074template<
typename MT
7076inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Reference
7077 Submatrix<MT,aligned,false,true,CSAs...>::at(
size_t i,
size_t j )
7085 return (*
this)(i,j);
7103template<
typename MT
7105inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstReference
7106 Submatrix<MT,aligned,false,true,CSAs...>::at(
size_t i,
size_t j )
const
7114 return (*
this)(i,j);
7130template<
typename MT
7132inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Pointer
7151template<
typename MT
7153inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstPointer
7171template<
typename MT
7173inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Pointer
7191template<
typename MT
7193inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstPointer
7214template<
typename MT
7216inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Iterator
7220 return ( matrix_.begin(
row() + i ) +
column() );
7238template<
typename MT
7240inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstIterator
7244 return ( matrix_.cbegin(
row() + i ) +
column() );
7262template<
typename MT
7264inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstIterator
7268 return ( matrix_.cbegin(
row() + i ) +
column() );
7286template<
typename MT
7288inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::Iterator
7310template<
typename MT
7312inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstIterator
7334template<
typename MT
7336inline typename Submatrix<MT,
aligned,
false,
true,CSAs...>::ConstIterator
7365template<
typename MT
7367inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
7368 Submatrix<MT,aligned,false,true,CSAs...>::operator=(
const ElementType& rhs )
7370 const size_t iend(
row() +
rows() );
7371 decltype(
auto) left( derestrict( matrix_ ) );
7373 for(
size_t i=
row(); i<iend; ++i )
7375 const size_t jbegin( ( IsUpper_v<MT> )
7376 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
7380 const size_t jend ( ( IsLower_v<MT> )
7381 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
7386 for(
size_t j=jbegin; j<jend; ++j ) {
7387 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, j, rhs ) )
7414template<
typename MT
7416inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
7419 if( list.size() !=
rows() ) {
7423 if( IsRestricted_v<MT> ) {
7424 const InitializerMatrix<ElementType> tmp( list,
columns() );
7425 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
7430 decltype(
auto) left( derestrict( *
this ) );
7433 for(
const auto& rowList : list ) {
7434 std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
7459template<
typename MT
7461inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
7462 Submatrix<MT,aligned,false,true,CSAs...>::operator=(
const Submatrix& rhs )
7467 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ &&
row() == rhs.row() &&
column() == rhs.column() ) )
7470 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
7474 if( !tryAssign( matrix_, rhs,
row(),
column() ) ) {
7478 decltype(
auto) left( derestrict( *
this ) );
7480 if( rhs.canAlias(
this ) ) {
7481 const ResultType tmp( rhs );
7511template<
typename MT
7513template<
typename MT2
7515inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
7516 Submatrix<MT,aligned,false,true,CSAs...>::operator=(
const Matrix<MT2,SO>& rhs )
7520 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
7524 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>,
const MT2& >;
7525 Right right( *rhs );
7527 if( !tryAssign( matrix_, right,
row(),
column() ) ) {
7531 decltype(
auto) left( derestrict( *
this ) );
7533 if( IsReference_v<Right> && right.canAlias(
this ) ) {
7534 const ResultType_t<MT2> tmp( right );
7535 if( IsSparseMatrix_v<MT2> )
7540 if( IsSparseMatrix_v<MT2> )
7567template<
typename MT
7569template<
typename MT2
7572 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7578 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
7583 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
7587 if( !tryAddAssign( matrix_, *rhs,
row(),
column() ) ) {
7591 decltype(
auto) left( derestrict( *
this ) );
7593 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
7594 const AddType tmp( *
this + (*rhs) );
7623template<
typename MT
7625template<
typename MT2
7628 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7634 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
7639 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
7643 const AddType tmp( *
this + (*rhs) );
7645 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
7649 decltype(
auto) left( derestrict( *
this ) );
7675template<
typename MT
7677template<
typename MT2
7680 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7686 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
7691 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
7695 if( !trySubAssign( matrix_, *rhs,
row(),
column() ) ) {
7699 decltype(
auto) left( derestrict( *
this ) );
7701 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
7702 const SubType tmp( *
this - (*rhs ) );
7731template<
typename MT
7733template<
typename MT2
7736 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7742 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
7747 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
7751 const SubType tmp( *
this - (*rhs) );
7753 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
7757 decltype(
auto) left( derestrict( *
this ) );
7783template<
typename MT
7785template<
typename MT2
7787inline auto Submatrix<MT,aligned,false,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
7788 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7794 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
7798 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
7802 if( !trySchurAssign( matrix_, *rhs,
row(),
column() ) ) {
7806 decltype(
auto) left( derestrict( *
this ) );
7808 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
7809 const SchurType tmp( *
this % (*rhs) );
7810 if( IsSparseMatrix_v<SchurType> )
7840template<
typename MT
7842template<
typename MT2
7844inline auto Submatrix<MT,aligned,false,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
7845 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
7851 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
7855 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
7859 const SchurType tmp( *
this % (*rhs) );
7861 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
7865 decltype(
auto) left( derestrict( *
this ) );
7867 if( IsSparseMatrix_v<SchurType> ) {
7895template<
typename MT
7897inline MT& Submatrix<MT,aligned,false,true,CSAs...>::operand() noexcept
7911template<
typename MT
7913inline const MT& Submatrix<MT,aligned,false,true,CSAs...>::operand() const noexcept
7932template<
typename MT
7936 return matrix_.spacing();
7948template<
typename MT
7970template<
typename MT
7990template<
typename MT
7994 const size_t iend(
row() +
rows() );
7996 size_t nonzeros( 0UL );
7998 for(
size_t i=
row(); i<iend; ++i )
7999 for(
size_t j=
column(); j<jend; ++j )
8021template<
typename MT
8028 size_t nonzeros( 0UL );
8030 for(
size_t j=
column(); j<jend; ++j )
8046template<
typename MT
8054 const size_t jbegin( ( IsUpper_v<MT> )
8055 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
8059 const size_t jend ( ( IsLower_v<MT> )
8060 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
8065 for(
size_t j=jbegin; j<jend; ++j )
8066 clear( matrix_(i,j) );
8085template<
typename MT
8093 const size_t jbegin( ( IsUpper_v<MT> )
8094 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
8098 const size_t jend ( ( IsLower_v<MT> )
8099 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
8104 for(
size_t j=jbegin; j<jend; ++j )
8121template<
typename MT
8123inline bool Submatrix<MT,aligned,false,true,CSAs...>::hasOverlap() const noexcept
8161template<
typename MT
8163inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
8174 decltype(
auto) left( derestrict( *
this ) );
8175 const ResultType tmp(
trans( *
this ) );
8203template<
typename MT
8205inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
8216 decltype(
auto) left( derestrict( *
this ) );
8217 const ResultType tmp(
ctrans( *
this ) );
8240template<
typename MT
8242template<
typename Other >
8243inline Submatrix<MT,
aligned,
false,
true,CSAs...>&
8244 Submatrix<MT,aligned,false,true,CSAs...>::scale(
const Other& scalar )
8248 const size_t iend(
row() +
rows() );
8250 for(
size_t i=
row(); i<iend; ++i )
8252 const size_t jbegin( ( IsUpper_v<MT> )
8253 ?( ( IsStrictlyUpper_v<MT> )
8257 const size_t jend ( ( IsLower_v<MT> )
8258 ?( ( IsStrictlyLower_v<MT> )
8263 for(
size_t j=jbegin; j<jend; ++j )
8264 matrix_(i,j) *= scalar;
8292template<
typename MT
8294template<
typename Other >
8295inline bool Submatrix<MT,aligned,false,true,CSAs...>::canAlias(
const Other* alias )
const noexcept
8297 return matrix_.isAliased( &unview( *alias ) );
8314template<
typename MT
8316template<
typename MT2
8321 Submatrix<MT,aligned,false,true,CSAs...>::canAlias(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
8323 return ( matrix_.isAliased( &alias->matrix_ ) &&
8324 (
row() +
rows() > alias->row() ) &&
8325 (
row() < alias->row() + alias->rows() ) &&
8327 (
column() < alias->column() + alias->columns() ) );
8344template<
typename MT
8346template<
typename Other >
8347inline bool Submatrix<MT,aligned,false,true,CSAs...>::isAliased(
const Other* alias )
const noexcept
8349 return matrix_.isAliased( &unview( *alias ) );
8366template<
typename MT
8368template<
typename MT2
8373 Submatrix<MT,aligned,false,true,CSAs...>::isAliased(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
8375 return ( matrix_.isAliased( &alias->matrix_ ) &&
8376 (
row() +
rows() > alias->row() ) &&
8377 (
row() < alias->row() + alias->rows() ) &&
8379 (
column() < alias->column() + alias->columns() ) );
8395template<
typename MT
8397inline bool Submatrix<MT,aligned,false,true,CSAs...>::isAligned() const noexcept
8416template<
typename MT
8418inline bool Submatrix<MT,aligned,false,true,CSAs...>::canSMPAssign() const noexcept
8420 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
8442template<
typename MT
8445 Submatrix<MT,aligned,false,true,CSAs...>::load(
size_t i,
size_t j )
const noexcept
8447 return loada( i, j );
8469template<
typename MT
8481 return matrix_.loada(
row()+i,
column()+j );
8503template<
typename MT
8514 return matrix_.loadu(
row()+i,
column()+j );
8537template<
typename MT
8540 Submatrix<MT,aligned,false,true,CSAs...>::store(
size_t i,
size_t j,
const SIMDType& value )
noexcept
8542 return storea( i, j, value );
8565template<
typename MT
8577 return matrix_.storea(
row()+i,
column()+j, value );
8600template<
typename MT
8611 matrix_.storeu(
row()+i,
column()+j, value );
8635template<
typename MT
8647 matrix_.stream(
row()+i,
column()+j, value );
8665template<
typename MT
8667template<
typename MT2 >
8668inline auto Submatrix<MT,aligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
8669 -> DisableIf_t< VectorizedAssign_v<MT2> >
8677 for(
size_t i=0UL; i<
rows(); ++i ) {
8678 for(
size_t j=0UL; j<jpos; j+=2UL ) {
8679 matrix_(
row()+i,
column()+j ) = (*rhs)(i,j );
8680 matrix_(
row()+i,
column()+j+1UL) = (*rhs)(i,j+1UL);
8683 matrix_(
row()+i,
column()+jpos) = (*rhs)(i,jpos);
8703template<
typename MT
8705template<
typename MT2 >
8706inline auto Submatrix<MT,aligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
8707 -> EnableIf_t< VectorizedAssign_v<MT2> >
8718 rows()*
columns() > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
8719 !(*rhs).isAliased(
this ) )
8721 for(
size_t i=0UL; i<
rows(); ++i )
8724 Iterator left(
begin(i) );
8725 ConstIterator_t<MT2> right( (*rhs).begin(i) );
8727 for( ; j<jpos; j+=SIMDSIZE ) {
8728 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8731 *left = *right; ++left; ++right;
8737 for(
size_t i=0UL; i<
rows(); ++i )
8740 Iterator left(
begin(i) );
8741 ConstIterator_t<MT2> right( (*rhs).begin(i) );
8743 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
8744 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8745 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8746 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8747 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8749 for( ; j<jpos; j+=SIMDSIZE ) {
8750 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8753 *left = *right; ++left; ++right;
8774template<
typename MT
8776template<
typename MT2 >
8777inline void Submatrix<MT,aligned,false,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
8784 constexpr size_t block( BLOCK_SIZE );
8786 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
8787 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
8788 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
8789 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
8790 for(
size_t i=ii; i<iend; ++i ) {
8791 for(
size_t j=jj; j<jend; ++j ) {
8792 matrix_(
row()+i,
column()+j) = (*rhs)(i,j);
8814template<
typename MT
8816template<
typename MT2 >
8817inline void Submatrix<MT,aligned,false,true,CSAs...>::assign(
const SparseMatrix<MT2,false>& rhs )
8822 for(
size_t i=0UL; i<
rows(); ++i )
8823 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
8824 matrix_(
row()+i,
column()+element->index()) = element->value();
8842template<
typename MT
8844template<
typename MT2 >
8845inline void Submatrix<MT,aligned,false,true,CSAs...>::assign(
const SparseMatrix<MT2,true>& rhs )
8852 for(
size_t j=0UL; j<
columns(); ++j )
8853 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
8854 matrix_(
row()+element->index(),
column()+j) = element->value();
8872template<
typename MT
8874template<
typename MT2 >
8875inline auto Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
8876 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
8884 for(
size_t i=0UL; i<
rows(); ++i )
8886 if( IsDiagonal_v<MT2> ) {
8887 matrix_(
row()+i,
column()+i) += (*rhs)(i,i);
8890 for(
size_t j=0UL; j<jpos; j+=2UL ) {
8891 matrix_(
row()+i,
column()+j ) += (*rhs)(i,j );
8892 matrix_(
row()+i,
column()+j+1UL) += (*rhs)(i,j+1UL);
8895 matrix_(
row()+i,
column()+jpos) += (*rhs)(i,jpos);
8916template<
typename MT
8918template<
typename MT2 >
8919inline auto Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
8920 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
8927 for(
size_t i=0UL; i<
rows(); ++i )
8929 const size_t jbegin( ( IsUpper_v<MT2> )
8930 ?(
prevMultiple( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ), SIMDSIZE ) )
8932 const size_t jend ( ( IsLower_v<MT2> )
8933 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
8941 Iterator left(
begin(i) + jbegin );
8942 ConstIterator_t<MT2> right( (*rhs).begin(i) + jbegin );
8944 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
8945 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8946 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8947 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8948 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8950 for( ; j<jpos; j+=SIMDSIZE ) {
8951 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8953 for( ; j<jend; ++j ) {
8954 *left += *right; ++left; ++right;
8974template<
typename MT
8976template<
typename MT2 >
8977inline void Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
8984 constexpr size_t block( BLOCK_SIZE );
8986 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
8987 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
8988 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
8989 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
8990 for(
size_t i=ii; i<iend; ++i ) {
8991 for(
size_t j=jj; j<jend; ++j ) {
8992 matrix_(
row()+i,
column()+j) += (*rhs)(i,j);
9014template<
typename MT
9016template<
typename MT2 >
9017inline void Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const SparseMatrix<MT2,false>& rhs )
9022 for(
size_t i=0UL; i<
rows(); ++i )
9023 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
9024 matrix_(
row()+i,
column()+element->index()) += element->value();
9042template<
typename MT
9044template<
typename MT2 >
9045inline void Submatrix<MT,aligned,false,true,CSAs...>::addAssign(
const SparseMatrix<MT2,true>& rhs )
9052 for(
size_t j=0UL; j<
columns(); ++j )
9053 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
9054 matrix_(
row()+element->index(),
column()+j) += element->value();
9072template<
typename MT
9074template<
typename MT2 >
9075inline auto Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
9076 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
9084 for(
size_t i=0UL; i<
rows(); ++i )
9086 if( IsDiagonal_v<MT2> ) {
9087 matrix_(
row()+i,
column()+i) -= (*rhs)(i,i);
9090 for(
size_t j=0UL; j<jpos; j+=2UL ) {
9091 matrix_(
row()+i,
column()+j ) -= (*rhs)(i,j );
9092 matrix_(
row()+i,
column()+j+1UL) -= (*rhs)(i,j+1UL);
9095 matrix_(
row()+i,
column()+jpos) -= (*rhs)(i,jpos);
9116template<
typename MT
9118template<
typename MT2 >
9119inline auto Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
9120 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
9127 for(
size_t i=0UL; i<
rows(); ++i )
9129 const size_t jbegin( ( IsUpper_v<MT2> )
9130 ?(
prevMultiple( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ), SIMDSIZE ) )
9132 const size_t jend ( ( IsLower_v<MT2> )
9133 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
9141 Iterator left(
begin(i) + jbegin );
9142 ConstIterator_t<MT2> right( (*rhs).begin(i) + jbegin );
9144 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
9145 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9146 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9147 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9148 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9150 for( ; j<jpos; j+=SIMDSIZE ) {
9151 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9153 for( ; j<jend; ++j ) {
9154 *left -= *right; ++left; ++right;
9174template<
typename MT
9176template<
typename MT2 >
9177inline void Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
9184 constexpr size_t block( BLOCK_SIZE );
9186 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
9187 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
9188 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
9189 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
9190 for(
size_t i=ii; i<iend; ++i ) {
9191 for(
size_t j=jj; j<jend; ++j ) {
9192 matrix_(
row()+i,
column()+j) -= (*rhs)(i,j);
9214template<
typename MT
9216template<
typename MT2 >
9217inline void Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const SparseMatrix<MT2,false>& rhs )
9222 for(
size_t i=0UL; i<
rows(); ++i )
9223 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
9224 matrix_(
row()+i,
column()+element->index()) -= element->value();
9242template<
typename MT
9244template<
typename MT2 >
9245inline void Submatrix<MT,aligned,false,true,CSAs...>::subAssign(
const SparseMatrix<MT2,true>& rhs )
9252 for(
size_t j=0UL; j<
columns(); ++j )
9253 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
9254 matrix_(
row()+element->index(),
column()+j) -= element->value();
9272template<
typename MT
9274template<
typename MT2 >
9275inline auto Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
9276 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
9284 for(
size_t i=0UL; i<
rows(); ++i ) {
9285 for(
size_t j=0UL; j<jpos; j+=2UL ) {
9286 matrix_(
row()+i,
column()+j ) *= (*rhs)(i,j );
9287 matrix_(
row()+i,
column()+j+1UL) *= (*rhs)(i,j+1UL);
9290 matrix_(
row()+i,
column()+jpos) *= (*rhs)(i,jpos);
9310template<
typename MT
9312template<
typename MT2 >
9313inline auto Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
9314 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
9321 for(
size_t i=0UL; i<
rows(); ++i )
9327 Iterator left(
begin(i) );
9328 ConstIterator_t<MT2> right( (*rhs).begin(i) );
9330 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
9331 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9332 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9333 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9334 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9336 for( ; j<jpos; j+=SIMDSIZE ) {
9337 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9340 *left *= *right; ++left; ++right;
9360template<
typename MT
9362template<
typename MT2 >
9363inline void Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
9370 constexpr size_t block( BLOCK_SIZE );
9372 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
9373 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
9374 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
9375 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
9376 for(
size_t i=ii; i<iend; ++i ) {
9377 for(
size_t j=jj; j<jend; ++j ) {
9378 matrix_(
row()+i,
column()+j) *= (*rhs)(i,j);
9400template<
typename MT
9402template<
typename MT2 >
9403inline void Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
9410 for(
size_t i=0UL; i<
rows(); ++i )
9414 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
9415 for( ; j<element->index(); ++j )
9417 matrix_(
row()+i,
column()+j) *= element->value();
9442template<
typename MT
9444template<
typename MT2 >
9445inline void Submatrix<MT,aligned,false,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
9454 for(
size_t j=0UL; j<
columns(); ++j )
9458 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
9459 for( ; i<element->index(); ++i )
9461 matrix_(
row()+element->index(),
column()+j) *= element->value();
9465 for( ; i<
rows(); ++i ) {
9494template<
typename MT
9496class Submatrix<MT,
aligned,true,true,CSAs...>
9497 :
public View< DenseMatrix< Submatrix<MT,aligned,true,true,CSAs...>, true > >
9498 ,
private SubmatrixData<CSAs...>
9502 using DataType = SubmatrixData<CSAs...>;
9503 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
9508 template<
typename MT1,
typename MT2 >
9509 static constexpr bool EnforceEvaluation_v =
9510 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
9516 using This = Submatrix<MT,
aligned,
true,
true,CSAs...>;
9519 using BaseType = View< DenseMatrix<This,true> >;
9521 using ViewedType = MT;
9523 using OppositeType = OppositeType_t<ResultType>;
9524 using TransposeType = TransposeType_t<ResultType>;
9525 using ElementType = ElementType_t<MT>;
9526 using SIMDType = SIMDTrait_t<ElementType>;
9527 using ReturnType = ReturnType_t<MT>;
9528 using CompositeType =
const Submatrix&;
9531 using ConstReference = ConstReference_t<MT>;
9534 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
9537 using ConstPointer = ConstPointer_t<MT>;
9540 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
9543 using ConstIterator = ConstIterator_t<MT>;
9546 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
9551 static constexpr bool simdEnabled = MT::simdEnabled;
9554 static constexpr bool smpAssignable = MT::smpAssignable;
9557 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
9563 template<
typename... RSAs >
9564 explicit inline Submatrix( MT& matrix, RSAs... args );
9566 Submatrix(
const Submatrix& ) =
default;
9573 ~Submatrix() =
default;
9580 inline Reference operator()(
size_t i,
size_t j );
9581 inline ConstReference operator()(
size_t i,
size_t j )
const;
9582 inline Reference at(
size_t i,
size_t j );
9583 inline ConstReference at(
size_t i,
size_t j )
const;
9584 inline Pointer
data () noexcept;
9585 inline ConstPointer
data () const noexcept;
9586 inline Pointer
data (
size_t j ) noexcept;
9587 inline ConstPointer
data (
size_t j ) const noexcept;
9588 inline Iterator
begin (
size_t j );
9589 inline ConstIterator
begin (
size_t j ) const;
9590 inline ConstIterator
cbegin(
size_t j ) const;
9591 inline Iterator
end (
size_t j );
9592 inline ConstIterator
end (
size_t j ) const;
9593 inline ConstIterator
cend (
size_t j ) const;
9600 inline Submatrix& operator=( const ElementType& rhs );
9602 inline Submatrix& operator=( const Submatrix& rhs );
9604 template< typename MT2,
bool SO >
9605 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
9607 template< typename MT2,
bool SO >
9608 inline auto operator+=( const Matrix<MT2,SO>& rhs )
9609 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9611 template< typename MT2,
bool SO >
9612 inline auto operator+=( const Matrix<MT2,SO>& rhs )
9613 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9615 template< typename MT2,
bool SO >
9616 inline auto operator-=( const Matrix<MT2,SO>& rhs )
9617 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9619 template< typename MT2,
bool SO >
9620 inline auto operator-=( const Matrix<MT2,SO>& rhs )
9621 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9623 template< typename MT2,
bool SO >
9624 inline auto operator%=( const Matrix<MT2,SO>& rhs )
9625 ->
DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9627 template< typename MT2,
bool SO >
9628 inline auto operator%=( const Matrix<MT2,SO>& rhs )
9629 ->
EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >;
9636 using DataType::
row;
9638 using DataType::
rows;
9641 inline MT& operand() noexcept;
9642 inline const MT& operand() const noexcept;
9644 inline
size_t spacing() const noexcept;
9645 inline
size_t capacity() const noexcept;
9646 inline
size_t capacity(
size_t i ) const noexcept;
9648 inline
size_t nonZeros(
size_t i ) const;
9649 inline
void reset();
9650 inline
void reset(
size_t i );
9660 template< typename Other > inline Submatrix& scale( const Other& scalar );
9667 template< typename MT2 >
9668 static constexpr
bool VectorizedAssign_v =
9669 ( useOptimizedKernels &&
9670 simdEnabled && MT2::simdEnabled &&
9676 template< typename MT2 >
9677 static constexpr
bool VectorizedAddAssign_v =
9678 ( VectorizedAssign_v<MT2> &&
9685 template< typename MT2 >
9686 static constexpr
bool VectorizedSubAssign_v =
9687 ( VectorizedAssign_v<MT2> &&
9694 template< typename MT2 >
9695 static constexpr
bool VectorizedSchurAssign_v =
9696 ( VectorizedAssign_v<MT2> &&
9702 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
9709 template< typename Other >
9710 inline
bool canAlias( const Other* alias ) const noexcept;
9712 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
9713 inline
bool canAlias( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
9715 template< typename Other >
9716 inline
bool isAliased( const Other* alias ) const noexcept;
9718 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
size_t... CSAs2 >
9719 inline
bool isAliased( const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias ) const noexcept;
9721 inline
bool isAligned () const noexcept;
9722 inline
bool canSMPAssign() const noexcept;
9733 template< typename MT2 >
9734 inline auto assign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedAssign_v<MT2> >;
9736 template< typename MT2 >
9737 inline auto assign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedAssign_v<MT2> >;
9739 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,false>& rhs );
9740 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
9741 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
9743 template< typename MT2 >
9744 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<MT2> >;
9746 template< typename MT2 >
9747 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<MT2> >;
9749 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,false>& rhs );
9750 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
9751 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
9753 template< typename MT2 >
9754 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<MT2> >;
9756 template< typename MT2 >
9757 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<MT2> >;
9759 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,false>& rhs );
9760 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
9761 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
9763 template< typename MT2 >
9764 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) ->
DisableIf_t< VectorizedSchurAssign_v<MT2> >;
9766 template< typename MT2 >
9767 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) ->
EnableIf_t< VectorizedSchurAssign_v<MT2> >;
9769 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,false>& rhs );
9770 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
9771 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
9779 inline
bool hasOverlap() const noexcept;
9791 template< typename MT2,
AlignmentFlag AF2,
bool SO2,
bool DF2,
size_t... CSAs2 > friend class Submatrix;
9829template< typename MT
9831template< typename... RSAs >
9832inline Submatrix<MT,
aligned,true,true,CSAs...>::Submatrix( MT& matrix, RSAs... args )
9833 : DataType( args... )
9834 , matrix_ ( matrix )
9842 if( simdEnabled && IsContiguous_v<MT> &&
9844 (
columns() > 1UL && matrix_.spacing() % SIMDSIZE != 0UL ) ) ) {
9854 BLAZE_USER_ASSERT( !simdEnabled || !IsContiguous_v<MT> ||
columns() <= 1UL || matrix_.spacing() % SIMDSIZE == 0UL,
"Invalid submatrix alignment" );
9880template<
typename MT
9882inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Reference
9883 Submatrix<MT,aligned,true,true,CSAs...>::operator()(
size_t i,
size_t j )
9905template<
typename MT
9907inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstReference
9908 Submatrix<MT,aligned,true,true,CSAs...>::operator()(
size_t i,
size_t j )
const
9913 return const_cast<const MT&
>( matrix_ )(
row()+i,
column()+j);
9931template<
typename MT
9933inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Reference
9934 Submatrix<MT,aligned,true,true,CSAs...>::at(
size_t i,
size_t j )
9942 return (*
this)(i,j);
9960template<
typename MT
9962inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstReference
9963 Submatrix<MT,aligned,true,true,CSAs...>::at(
size_t i,
size_t j )
const
9971 return (*
this)(i,j);
9987template<
typename MT
9989inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Pointer
10008template<
typename MT
10010inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstPointer
10028template<
typename MT
10030inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Pointer
10048template<
typename MT
10050inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstPointer
10066template<
typename MT
10068inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Iterator
10072 return ( matrix_.begin(
column() + j ) +
row() );
10085template<
typename MT
10087inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstIterator
10091 return ( matrix_.cbegin(
column() + j ) +
row() );
10104template<
typename MT
10106inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstIterator
10110 return ( matrix_.cbegin(
column() + j ) +
row() );
10123template<
typename MT
10125inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::Iterator
10142template<
typename MT
10144inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstIterator
10148 return ( matrix_.cbegin(
column() + j ) +
row() +
rows() );
10161template<
typename MT
10163inline typename Submatrix<MT,
aligned,
true,
true,CSAs...>::ConstIterator
10167 return ( matrix_.cbegin(
column() + j ) +
row() +
rows() );
10192template<
typename MT
10194inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10195 Submatrix<MT,aligned,true,true,CSAs...>::operator=(
const ElementType& rhs )
10198 decltype(
auto) left( derestrict( matrix_ ) );
10200 for(
size_t j=
column(); j<jend; ++j )
10202 const size_t ibegin( ( IsLower_v<MT> )
10203 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
10204 ?(
max( j+1UL,
row() ) )
10207 const size_t iend ( ( IsUpper_v<MT> )
10208 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
10213 for(
size_t i=ibegin; i<iend; ++i ) {
10214 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, j, rhs ) )
10241template<
typename MT
10243inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10248 if( list.size() !=
rows() ) {
10252 if( IsRestricted_v<MT> ) {
10253 const InitializerMatrix<ElementType> tmp( list,
columns() );
10254 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
10259 decltype(
auto) left( derestrict( *
this ) );
10262 for(
const auto& rowList : list ) {
10264 for(
const auto& element : rowList ) {
10265 left(i,j) = element;
10269 reset( left(i,j) );
10295template<
typename MT
10297inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10298 Submatrix<MT,aligned,true,true,CSAs...>::operator=(
const Submatrix& rhs )
10303 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ &&
row() == rhs.row() &&
column() == rhs.column() ) )
10306 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
10310 if( !tryAssign( matrix_, rhs,
row(),
column() ) ) {
10314 decltype(
auto) left( derestrict( *
this ) );
10316 if( rhs.canAlias(
this ) ) {
10317 const ResultType tmp( rhs );
10346template<
typename MT
10348template<
typename MT2
10350inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10351 Submatrix<MT,aligned,true,true,CSAs...>::operator=(
const Matrix<MT2,SO>& rhs )
10355 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
10359 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>,
const MT2& >;
10360 Right right( *rhs );
10362 if( !tryAssign( matrix_, right,
row(),
column() ) ) {
10366 decltype(
auto) left( derestrict( *
this ) );
10368 if( IsReference_v<Right> && right.canAlias(
this ) ) {
10369 const ResultType_t<MT2> tmp( right );
10370 if( IsSparseMatrix_v<MT2> )
10375 if( IsSparseMatrix_v<MT2> )
10402template<
typename MT
10404template<
typename MT2
10407 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10413 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
10418 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
10422 if( !tryAddAssign( matrix_, *rhs,
row(),
column() ) ) {
10426 decltype(
auto) left( derestrict( *
this ) );
10428 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
10429 const AddType tmp( *
this + (*rhs) );
10458template<
typename MT
10460template<
typename MT2
10463 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10469 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
10474 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
10478 const AddType tmp( *
this + (*rhs) );
10480 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
10484 decltype(
auto) left( derestrict( *
this ) );
10510template<
typename MT
10512template<
typename MT2
10515 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10521 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
10526 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
10530 if( !trySubAssign( matrix_, *rhs,
row(),
column() ) ) {
10534 decltype(
auto) left( derestrict( *
this ) );
10536 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
10537 const SubType tmp( *
this - (*rhs ) );
10566template<
typename MT
10568template<
typename MT2
10571 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10577 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
10582 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
10586 const SubType tmp( *
this - (*rhs) );
10588 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
10592 decltype(
auto) left( derestrict( *
this ) );
10618template<
typename MT
10620template<
typename MT2
10622inline auto Submatrix<MT,aligned,true,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
10623 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10629 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
10633 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
10637 if( !trySchurAssign( matrix_, *rhs,
row(),
column() ) ) {
10641 decltype(
auto) left( derestrict( *
this ) );
10643 if( ( ( IsSymmetric_v<MT> || IsHermitian_v<MT> ) && hasOverlap() ) || (*rhs).canAlias(
this ) ) {
10644 const SchurType tmp( *
this % (*rhs) );
10645 if( IsSparseMatrix_v<SchurType> )
10675template<
typename MT
10677template<
typename MT2
10679inline auto Submatrix<MT,aligned,true,true,CSAs...>::operator%=(
const Matrix<MT2,SO>& rhs )
10680 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Submatrix& >
10686 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
10690 if(
rows() != (*rhs).rows() ||
columns() != (*rhs).columns() ) {
10694 const SchurType tmp( *
this % (*rhs) );
10696 if( !tryAssign( matrix_, tmp,
row(),
column() ) ) {
10700 decltype(
auto) left( derestrict( *
this ) );
10702 if( IsSparseMatrix_v<SchurType> ) {
10730template<
typename MT
10732inline MT& Submatrix<MT,aligned,true,true,CSAs...>::operand() noexcept
10746template<
typename MT
10748inline const MT& Submatrix<MT,aligned,true,true,CSAs...>::operand() const noexcept
10765template<
typename MT
10769 return matrix_.spacing();
10781template<
typename MT
10798template<
typename MT
10818template<
typename MT
10822 const size_t iend(
row() +
rows() );
10824 size_t nonzeros( 0UL );
10826 for(
size_t j=
column(); j<jend; ++j )
10827 for(
size_t i=
row(); i<iend; ++i )
10844template<
typename MT
10850 const size_t iend(
row() +
rows() );
10851 size_t nonzeros( 0UL );
10853 for(
size_t i=
row(); i<iend; ++i )
10869template<
typename MT
10877 const size_t ibegin( ( IsLower_v<MT> )
10878 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
10879 ?(
max( j+1UL,
row() ) )
10882 const size_t iend ( ( IsUpper_v<MT> )
10883 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
10888 for(
size_t i=ibegin; i<iend; ++i )
10889 clear( matrix_(i,j) );
10903template<
typename MT
10911 const size_t ibegin( ( IsLower_v<MT> )
10912 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
10913 ?(
max( j+1UL,
row() ) )
10916 const size_t iend ( ( IsUpper_v<MT> )
10917 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
10922 for(
size_t i=ibegin; i<iend; ++i )
10939template<
typename MT
10941inline bool Submatrix<MT,aligned,true,true,CSAs...>::hasOverlap() const noexcept
10979template<
typename MT
10981inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
10992 decltype(
auto) left( derestrict( *
this ) );
10993 const ResultType tmp(
trans( *
this ) );
11021template<
typename MT
11023inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
11034 decltype(
auto) left( derestrict( *
this ) );
11035 const ResultType tmp(
ctrans( *
this ) );
11058template<
typename MT
11060template<
typename Other >
11061inline Submatrix<MT,
aligned,
true,
true,CSAs...>&
11062 Submatrix<MT,aligned,true,true,CSAs...>::scale(
const Other& scalar )
11068 for(
size_t j=
column(); j<jend; ++j )
11070 const size_t ibegin( ( IsLower_v<MT> )
11071 ?( ( IsStrictlyLower_v<MT> )
11072 ?(
max( j+1UL,
row() ) )
11075 const size_t iend ( ( IsUpper_v<MT> )
11076 ?( ( IsStrictlyUpper_v<MT> )
11081 for(
size_t i=ibegin; i<iend; ++i )
11082 matrix_(i,j) *= scalar;
11110template<
typename MT
11112template<
typename Other >
11113inline bool Submatrix<MT,aligned,true,true,CSAs...>::canAlias(
const Other* alias )
const noexcept
11115 return matrix_.isAliased( &unview( *alias ) );
11132template<
typename MT
11134template<
typename MT2
11137 ,
size_t... CSAs2 >
11139 Submatrix<MT,aligned,true,true,CSAs...>::canAlias(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
11141 return ( matrix_.isAliased( &alias->matrix_ ) &&
11142 (
row() +
rows() > alias->row() ) &&
11143 (
row() < alias->row() + alias->rows() ) &&
11145 (
column() < alias->column() + alias->columns() ) );
11162template<
typename MT
11164template<
typename Other >
11165inline bool Submatrix<MT,aligned,true,true,CSAs...>::isAliased(
const Other* alias )
const noexcept
11167 return matrix_.isAliased( &unview( *alias ) );
11184template<
typename MT
11186template<
typename MT2
11189 ,
size_t... CSAs2 >
11191 Submatrix<MT,aligned,true,true,CSAs...>::isAliased(
const Submatrix<MT2,AF2,SO2,true,CSAs2...>* alias )
const noexcept
11193 return ( matrix_.isAliased( &alias->matrix_ ) &&
11194 (
row() +
rows() > alias->row() ) &&
11195 (
row() < alias->row() + alias->rows() ) &&
11197 (
column() < alias->column() + alias->columns() ) );
11213template<
typename MT
11215inline bool Submatrix<MT,aligned,true,true,CSAs...>::isAligned() const noexcept
11234template<
typename MT
11236inline bool Submatrix<MT,aligned,true,true,CSAs...>::canSMPAssign() const noexcept
11238 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
11259template<
typename MT
11262 Submatrix<MT,aligned,true,true,CSAs...>::load(
size_t i,
size_t j )
const noexcept
11264 return loada( i, j );
11285template<
typename MT
11297 return matrix_.loada(
row()+i,
column()+j );
11318template<
typename MT
11329 return matrix_.loadu(
row()+i,
column()+j );
11351template<
typename MT
11354 Submatrix<MT,aligned,true,true,CSAs...>::store(
size_t i,
size_t j,
const SIMDType& value )
noexcept
11378template<
typename MT
11390 matrix_.storea(
row()+i,
column()+j, value );
11412template<
typename MT
11423 matrix_.storeu(
row()+i,
column()+j, value );
11446template<
typename MT
11458 matrix_.stream(
row()+i,
column()+j, value );
11476template<
typename MT
11478template<
typename MT2 >
11479inline auto Submatrix<MT,aligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
11480 -> DisableIf_t< VectorizedAssign_v<MT2> >
11488 for(
size_t j=0UL; j<
columns(); ++j ) {
11489 for(
size_t i=0UL; i<ipos; i+=2UL ) {
11490 matrix_(
row()+i ,
column()+j) = (*rhs)(i ,j);
11491 matrix_(
row()+i+1UL,
column()+j) = (*rhs)(i+1UL,j);
11493 if( ipos <
rows() ) {
11494 matrix_(
row()+ipos,
column()+j) = (*rhs)(ipos,j);
11514template<
typename MT
11516template<
typename MT2 >
11517inline auto Submatrix<MT,aligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,true>& rhs )
11518 -> EnableIf_t< VectorizedAssign_v<MT2> >
11528 if( useStreaming &&
11529 rows()*
columns() > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
11530 !(*rhs).isAliased(
this ) )
11532 for(
size_t j=0UL; j<
columns(); ++j )
11535 Iterator left(
begin(j) );
11536 ConstIterator_t<MT2> right( (*rhs).begin(j) );
11538 for( ; i<ipos; i+=SIMDSIZE ) {
11539 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11541 for( ; i<
rows(); ++i ) {
11542 *left = *right; ++left; ++right;
11548 for(
size_t j=0UL; j<
columns(); ++j )
11551 Iterator left(
begin(j) );
11552 ConstIterator_t<MT2> right( (*rhs).begin(j) );
11554 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
11555 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11556 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11557 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11558 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11560 for( ; i<ipos; i+=SIMDSIZE ) {
11561 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11563 for( ; i<
rows(); ++i ) {
11564 *left = *right; ++left; ++right;
11585template<
typename MT
11587template<
typename MT2 >
11588inline void Submatrix<MT,aligned,true,true,CSAs...>::assign(
const DenseMatrix<MT2,false>& rhs )
11595 constexpr size_t block( BLOCK_SIZE );
11597 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
11598 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
11599 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
11600 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
11601 for(
size_t j=jj; j<jend; ++j ) {
11602 for(
size_t i=ii; i<iend; ++i ) {
11603 matrix_(
row()+i,
column()+j) = (*rhs)(i,j);
11625template<
typename MT
11627template<
typename MT2 >
11628inline void Submatrix<MT,aligned,true,true,CSAs...>::assign(
const SparseMatrix<MT2,true>& rhs )
11633 for(
size_t j=0UL; j<
columns(); ++j )
11634 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
11635 matrix_(
row()+element->index(),
column()+j) = element->value();
11653template<
typename MT
11655template<
typename MT2 >
11656inline void Submatrix<MT,aligned,true,true,CSAs...>::assign(
const SparseMatrix<MT2,false>& rhs )
11663 for(
size_t i=0UL; i<
rows(); ++i )
11664 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
11665 matrix_(
row()+i,
column()+element->index()) = element->value();
11683template<
typename MT
11685template<
typename MT2 >
11686inline auto Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
11687 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
11695 for(
size_t j=0UL; j<
columns(); ++j )
11697 if( IsDiagonal_v<MT2> ) {
11698 matrix_(
row()+j,
column()+j) += (*rhs)(j,j);
11701 for(
size_t i=0UL; i<ipos; i+=2UL ) {
11702 matrix_(
row()+i ,
column()+j) += (*rhs)(i ,j);
11703 matrix_(
row()+i+1UL,
column()+j) += (*rhs)(i+1UL,j);
11705 if( ipos <
rows() ) {
11706 matrix_(
row()+ipos,
column()+j) += (*rhs)(ipos,j);
11727template<
typename MT
11729template<
typename MT2 >
11730inline auto Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,true>& rhs )
11731 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
11738 for(
size_t j=0UL; j<
columns(); ++j )
11740 const size_t ibegin( ( IsLower_v<MT> )
11741 ?(
prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
11743 const size_t iend ( ( IsUpper_v<MT> )
11744 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
11751 size_t i( ibegin );
11752 Iterator left(
begin(j) + ibegin );
11753 ConstIterator_t<MT2> right( (*rhs).begin(j) + ibegin );
11755 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
11756 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11757 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11758 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11759 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11761 for( ; i<ipos; i+=SIMDSIZE ) {
11762 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11764 for( ; i<iend; ++i ) {
11765 *left += *right; ++left; ++right;
11785template<
typename MT
11787template<
typename MT2 >
11788inline void Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const DenseMatrix<MT2,false>& rhs )
11795 constexpr size_t block( BLOCK_SIZE );
11797 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
11798 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
11799 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
11800 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
11801 for(
size_t j=jj; j<jend; ++j ) {
11802 for(
size_t i=ii; i<iend; ++i ) {
11803 matrix_(
row()+i,
column()+j) += (*rhs)(i,j);
11825template<
typename MT
11827template<
typename MT2 >
11828inline void Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const SparseMatrix<MT2,true>& rhs )
11833 for(
size_t j=0UL; j<
columns(); ++j )
11834 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
11835 matrix_(
row()+element->index(),
column()+j) += element->value();
11853template<
typename MT
11855template<
typename MT2 >
11856inline void Submatrix<MT,aligned,true,true,CSAs...>::addAssign(
const SparseMatrix<MT2,false>& rhs )
11863 for(
size_t i=0UL; i<
rows(); ++i )
11864 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
11865 matrix_(
row()+i,
column()+element->index()) += element->value();
11883template<
typename MT
11885template<
typename MT2 >
11886inline auto Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
11887 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
11895 for(
size_t j=0UL; j<
columns(); ++j )
11897 if( IsDiagonal_v<MT2> ) {
11898 matrix_(
row()+j,
column()+j) -= (*rhs)(j,j);
11901 for(
size_t i=0UL; i<ipos; i+=2UL ) {
11902 matrix_(
row()+i ,
column()+j) -= (*rhs)(i ,j);
11903 matrix_(
row()+i+1UL,
column()+j) -= (*rhs)(i+1UL,j);
11905 if( ipos <
rows() ) {
11906 matrix_(
row()+ipos,
column()+j) -= (*rhs)(ipos,j);
11927template<
typename MT
11929template<
typename MT2 >
11930inline auto Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,true>& rhs )
11931 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
11938 for(
size_t j=0UL; j<
columns(); ++j )
11940 const size_t ibegin( ( IsLower_v<MT> )
11941 ?(
prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
11943 const size_t iend ( ( IsUpper_v<MT> )
11944 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
11951 size_t i( ibegin );
11952 Iterator left(
begin(j) + ibegin );
11953 ConstIterator_t<MT2> right( (*rhs).begin(j) + ibegin );
11955 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
11956 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11957 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11958 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11959 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11961 for( ; i<ipos; i+=SIMDSIZE ) {
11962 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11964 for( ; i<iend; ++i ) {
11965 *left -= *right; ++left; ++right;
11985template<
typename MT
11987template<
typename MT2 >
11988inline void Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const DenseMatrix<MT2,false>& rhs )
11995 constexpr size_t block( BLOCK_SIZE );
11997 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
11998 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
11999 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
12000 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
12001 for(
size_t j=jj; j<jend; ++j ) {
12002 for(
size_t i=ii; i<iend; ++i ) {
12003 matrix_(
row()+i,
column()+j) -= (*rhs)(i,j);
12025template<
typename MT
12027template<
typename MT2 >
12028inline void Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const SparseMatrix<MT2,true>& rhs )
12033 for(
size_t j=0UL; j<
columns(); ++j )
12034 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
12035 matrix_(
row()+element->index(),
column()+j) -= element->value();
12053template<
typename MT
12055template<
typename MT2 >
12056inline void Submatrix<MT,aligned,true,true,CSAs...>::subAssign(
const SparseMatrix<MT2,false>& rhs )
12063 for(
size_t i=0UL; i<
rows(); ++i )
12064 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
12065 matrix_(
row()+i,
column()+element->index()) -= element->value();
12083template<
typename MT
12085template<
typename MT2 >
12086inline auto Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
12087 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
12095 for(
size_t j=0UL; j<
columns(); ++j ) {
12096 for(
size_t i=0UL; i<ipos; i+=2UL ) {
12097 matrix_(
row()+i ,
column()+j) *= (*rhs)(i ,j);
12098 matrix_(
row()+i+1UL,
column()+j) *= (*rhs)(i+1UL,j);
12100 if( ipos <
rows() ) {
12101 matrix_(
row()+ipos,
column()+j) *= (*rhs)(ipos,j);
12122template<
typename MT
12124template<
typename MT2 >
12125inline auto Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
12126 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
12133 for(
size_t j=0UL; j<
columns(); ++j )
12139 Iterator left(
begin(j) );
12140 ConstIterator_t<MT2> right( (*rhs).begin(j) );
12142 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
12143 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12144 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12145 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12146 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12148 for( ; i<ipos; i+=SIMDSIZE ) {
12149 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12151 for( ; i<
rows(); ++i ) {
12152 *left *= *right; ++left; ++right;
12172template<
typename MT
12174template<
typename MT2 >
12175inline void Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
12182 constexpr size_t block( BLOCK_SIZE );
12184 for(
size_t jj=0UL; jj<
columns(); jj+=block ) {
12185 const size_t jend( (
columns()<(jj+block) )?(
columns() ):( jj+block ) );
12186 for(
size_t ii=0UL; ii<
rows(); ii+=block ) {
12187 const size_t iend( (
rows()<(ii+block) )?(
rows() ):( ii+block ) );
12188 for(
size_t j=jj; j<jend; ++j ) {
12189 for(
size_t i=ii; i<iend; ++i ) {
12190 matrix_(
row()+i,
column()+j) *= (*rhs)(i,j);
12212template<
typename MT
12214template<
typename MT2 >
12215inline void Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
12222 for(
size_t j=0UL; j<
columns(); ++j )
12226 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
12227 for( ; i<element->index(); ++i )
12229 matrix_(
row()+i,
column()+j) *= element->value();
12233 for( ; i<
rows(); ++i ) {
12254template<
typename MT
12256template<
typename MT2 >
12257inline void Submatrix<MT,aligned,true,true,CSAs...>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
12266 for(
size_t i=0UL; i<
rows(); ++i )
12270 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
12271 for( ; j<element->index(); ++j )
12273 matrix_(
row()+i,
column()+j) *= element->value();
Header file for the addition trait.
Header file for auxiliary alias declarations.
Header file for the alignment check function.
Header file for the alignment flag enumeration.
Header file for run time assertion macros.
Header file for kernel specific block sizes.
Header file for the blaze::checked and blaze::unchecked instances.
Constraints on the storage order of matrix types.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:751
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:719
Header file for the EnableIf class template.
Header file for the HasMutableDataAccess type trait.
Header file for the HasSIMDAdd type trait.
Header file for the HasSIMDMult type trait.
Header file for the HasSIMDSub type trait.
Header file for the If class template.
Header file for the IsConst type trait.
Header file for the IsContiguous type trait.
Header file for the isDefault shim.
Header file for the IsDiagonal type trait.
Header file for the IsExpression type trait class.
Header file for the IsHermitian type trait.
Header file for the IsLower type trait.
Header file for the IsReference type trait.
Header file for the IsRestricted type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseMatrix type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Header file for the IsTriangular type trait.
Header file for the IsUniLower type trait.
Header file for the IsUniUpper type trait.
Header file for the IsUpper type trait.
Header file for the MAYBE_UNUSED function template.
Constraint on the data type.
Header file for the prevMultiple shim.
Constraint on the data type.
Constraints on the storage order of matrix types.
Header file for all SIMD functionality.
Header file for the Schur product trait.
Header file for the subtraction trait.
Header file for the implementation of the SubmatrixData class template.
Header file for the submatrix trait.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Initializer list type of the Blaze library.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
Header file for the DenseMatrix base class.
Header file for the View base class.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.
Definition: Vectorizable.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
decltype(auto) transIf(const DenseMatrix< MT, SO > &dm)
Conditional calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:832
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:1339
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:1375
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1501
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:182
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:386
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:265
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9640
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:448
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
bool isDefault(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the given diagonal matrix is in default state.
Definition: DiagonalMatrix.h:169
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.
Definition: TransExpr.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.
Definition: Submatrix.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: UniTriangular.h:81
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
typename SubmatrixTrait< MT, CSAs... >::Type SubmatrixTrait_t
Auxiliary alias declaration for the SubmatrixTrait type trait.
Definition: SubmatrixTrait.h:145
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.
Definition: HasSIMDSub.h:187
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.
Definition: IsDiagonal.h:148
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.
Definition: HasSIMDMult.h:188
constexpr bool IsContiguous_v
Auxiliary variable template for the IsContiguous type trait.
Definition: IsContiguous.h:144
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
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 > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.
Definition: AlignmentFlag.h:63
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
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
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
constexpr 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
@ unaligned
Flag for unaligned vectors and matrices.
Definition: AlignmentFlag.h:64
@ aligned
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
constexpr void clear(Matrix< MT, SO > &matrix)
Clearing the given matrix.
Definition: Matrix.h:960
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:628
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
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:562
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:584
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:1221
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:1195
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:137
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
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
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
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 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
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
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
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
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
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
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.
Definition: Exception.h:187
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
constexpr bool isChecked(const Ts &... args)
Extracting blaze::Check arguments from a given list of arguments.
Definition: Check.h:225
Header file for the exception macros of the math module.
Header file for the extended initializer_list functionality.
Header file for the matrix storage order types.
Header file for the clear shim.
Header file for the reset shim.
Header file for the cache size of the target architecture.
System settings for the inline keywords.
System settings for performance optimizations.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for the RequiresEvaluation type trait.
Header file for basic type definitions.
Header file for the generic max algorithm.
Header file for the generic min algorithm.
Header file for the implementation of the Submatrix base template.