35 #ifndef _BLAZE_MATH_VIEWS_SUBMATRIX_DENSE_H_ 36 #define _BLAZE_MATH_VIEWS_SUBMATRIX_DENSE_H_ 130 template<
typename MT >
132 :
public View< DenseMatrix< Submatrix<MT,unaligned,false,true>, false > >
137 using Operand = If_< IsExpression<MT>, MT, MT& >;
142 using This = Submatrix<MT,unaligned,false,true>;
143 using BaseType = DenseMatrix<This,false>;
148 using SIMDType = SIMDTrait_<ElementType>;
162 using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer,
ElementType* >;
168 template<
typename IteratorType >
169 class SubmatrixIterator
174 using IteratorCategory =
typename std::iterator_traits<IteratorType>::iterator_category;
177 using ValueType =
typename std::iterator_traits<IteratorType>::value_type;
180 using PointerType =
typename std::iterator_traits<IteratorType>::pointer;
183 using ReferenceType =
typename std::iterator_traits<IteratorType>::reference;
186 using DifferenceType =
typename std::iterator_traits<IteratorType>::difference_type;
189 using iterator_category = IteratorCategory;
190 using value_type = ValueType;
191 using pointer = PointerType;
192 using reference = ReferenceType;
193 using difference_type = DifferenceType;
199 inline SubmatrixIterator()
201 , isAligned_( false )
211 inline SubmatrixIterator( IteratorType iterator,
bool isMemoryAligned )
212 : iterator_ ( iterator )
213 , isAligned_( isMemoryAligned )
222 template<
typename IteratorType2 >
223 inline SubmatrixIterator(
const SubmatrixIterator<IteratorType2>& it )
224 : iterator_ ( it.base() )
225 , isAligned_( it.isAligned() )
235 inline SubmatrixIterator&
operator+=(
size_t inc ) {
247 inline SubmatrixIterator&
operator-=(
size_t dec ) {
258 inline SubmatrixIterator& operator++() {
269 inline const SubmatrixIterator operator++(
int ) {
270 return SubmatrixIterator( iterator_++, isAligned_ );
279 inline SubmatrixIterator& operator--() {
290 inline const SubmatrixIterator operator--(
int ) {
291 return SubmatrixIterator( iterator_--, isAligned_ );
315 inline SIMDType load() const noexcept {
333 inline SIMDType
loada() const noexcept {
334 return iterator_.loada();
348 inline SIMDType
loadu() const noexcept {
349 return iterator_.loadu();
364 inline void store(
const SIMDType& value )
const {
380 inline void storea(
const SIMDType& value )
const {
381 iterator_.storea( value );
396 inline void storeu(
const SIMDType& value )
const {
398 iterator_.storea( value );
401 iterator_.storeu( value );
417 inline void stream(
const SIMDType& value )
const {
418 iterator_.stream( value );
428 inline bool operator==(
const SubmatrixIterator& rhs )
const {
429 return iterator_ == rhs.iterator_;
439 inline bool operator!=(
const SubmatrixIterator& rhs )
const {
440 return iterator_ != rhs.iterator_;
450 inline bool operator<(
const SubmatrixIterator& rhs )
const {
451 return iterator_ < rhs.iterator_;
461 inline bool operator>(
const SubmatrixIterator& rhs )
const {
462 return iterator_ > rhs.iterator_;
472 inline bool operator<=(
const SubmatrixIterator& rhs )
const {
473 return iterator_ <= rhs.iterator_;
483 inline bool operator>=(
const SubmatrixIterator& rhs )
const {
484 return iterator_ >= rhs.iterator_;
494 inline DifferenceType
operator-(
const SubmatrixIterator& rhs )
const {
495 return iterator_ - rhs.iterator_;
506 friend inline const SubmatrixIterator
operator+(
const SubmatrixIterator& it,
size_t inc ) {
507 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
518 friend inline const SubmatrixIterator
operator+(
size_t inc,
const SubmatrixIterator& it ) {
519 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
530 friend inline const SubmatrixIterator
operator-(
const SubmatrixIterator& it,
size_t dec ) {
531 return SubmatrixIterator( it.iterator_ - dec, it.isAligned_ );
540 inline IteratorType base()
const {
550 inline bool isAligned() const noexcept {
557 IteratorType iterator_;
565 using ConstIterator = SubmatrixIterator< ConstIterator_<MT> >;
573 enum :
bool { simdEnabled = MT::simdEnabled };
576 enum :
bool { smpAssignable = MT::smpAssignable };
582 explicit inline Submatrix( Operand matrix,
size_t rindex,
size_t cindex,
size_t m,
size_t n );
594 inline Reference operator()(
size_t i,
size_t j );
595 inline ConstReference operator()(
size_t i,
size_t j )
const;
596 inline Reference at(
size_t i,
size_t j );
597 inline ConstReference at(
size_t i,
size_t j )
const;
598 inline Pointer data () noexcept;
599 inline ConstPointer data () const noexcept;
600 inline Pointer data (
size_t i ) noexcept;
601 inline ConstPointer data (
size_t i ) const noexcept;
603 inline ConstIterator
begin (
size_t i ) const;
604 inline ConstIterator
cbegin(
size_t i ) const;
606 inline ConstIterator
end (
size_t i ) const;
607 inline ConstIterator
cend (
size_t i ) const;
614 inline Submatrix& operator=( const ElementType& rhs );
615 inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
616 inline Submatrix& operator=( const Submatrix& rhs );
618 template< typename MT2,
bool SO2 >
619 inline Submatrix& operator=( const Matrix<MT2,SO2>& rhs );
621 template< typename MT2,
bool SO2 >
622 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
623 operator+=( const Matrix<MT2,SO2>& rhs );
625 template< typename MT2,
bool SO2 >
626 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
627 operator+=( const Matrix<MT2,SO2>& rhs );
629 template< typename MT2,
bool SO2 >
630 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
631 operator-=( const Matrix<MT2,SO2>& rhs );
633 template< typename MT2,
bool SO2 >
634 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
635 operator-=( const Matrix<MT2,SO2>& rhs );
637 template< typename MT2,
bool SO2 >
638 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
639 operator%=( const Matrix<MT2,SO2>& rhs );
641 template< typename MT2,
bool SO2 >
642 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
643 operator%=( const Matrix<MT2,SO2>& rhs );
645 template< typename MT2,
bool SO2 >
646 inline Submatrix& operator*=( const Matrix<MT2,SO2>& rhs );
648 template< typename Other >
649 inline
EnableIf_< IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
651 template< typename Other >
652 inline
EnableIf_< IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
659 inline Operand operand() const noexcept;
660 inline
size_t row() const noexcept;
661 inline
size_t column() const noexcept;
662 inline
size_t rows() const noexcept;
663 inline
size_t columns() const noexcept;
664 inline
size_t spacing() const noexcept;
665 inline
size_t capacity() const noexcept;
666 inline
size_t capacity(
size_t i ) const noexcept;
668 inline
size_t nonZeros(
size_t i ) const;
670 inline
void reset(
size_t i );
680 template< typename Other > inline Submatrix& scale( const Other& scalar );
687 template< typename MT2 >
688 struct VectorizedAssign {
689 enum :
bool { value = useOptimizedKernels &&
690 simdEnabled && MT2::simdEnabled &&
691 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value };
697 template<
typename MT2 >
698 struct VectorizedAddAssign {
699 enum :
bool { value = useOptimizedKernels &&
700 simdEnabled && MT2::simdEnabled &&
701 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
702 HasSIMDAdd< ElementType, ElementType_<MT2> >::value &&
703 !IsDiagonal<MT2>::value };
709 template<
typename MT2 >
710 struct VectorizedSubAssign {
711 enum :
bool { value = useOptimizedKernels &&
712 simdEnabled && MT2::simdEnabled &&
713 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
714 HasSIMDSub< ElementType, ElementType_<MT2> >::value &&
715 !IsDiagonal<MT2>::value };
721 template<
typename MT2 >
722 struct VectorizedSchurAssign {
723 enum :
bool { value = useOptimizedKernels &&
724 simdEnabled && MT2::simdEnabled &&
725 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
726 HasSIMDMult< ElementType, ElementType_<MT2> >::value };
739 template<
typename Other >
740 inline bool canAlias(
const Other* alias )
const noexcept;
742 template<
typename MT2,
bool AF2,
bool SO2 >
743 inline bool canAlias(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept;
745 template<
typename Other >
746 inline bool isAliased(
const Other* alias )
const noexcept;
748 template<
typename MT2,
bool AF2,
bool SO2 >
749 inline bool isAliased(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept;
751 inline bool isAligned () const noexcept;
752 inline
bool canSMPAssign() const noexcept;
763 template< typename MT2 >
764 inline
DisableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,false>& rhs );
766 template< typename MT2 >
767 inline
EnableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,false>& rhs );
769 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,true>& rhs );
770 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
771 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
773 template< typename MT2 >
774 inline
DisableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,false>& rhs );
776 template< typename MT2 >
777 inline
EnableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,false>& rhs );
779 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,true>& rhs );
780 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
781 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
783 template< typename MT2 >
784 inline
DisableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,false>& rhs );
786 template< typename MT2 >
787 inline
EnableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,false>& rhs );
789 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,true>& rhs );
790 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
791 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
793 template< typename MT2 >
794 inline
DisableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,false>& rhs );
796 template< typename MT2 >
797 inline
EnableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,false>& rhs );
799 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,true>& rhs );
800 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
801 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
809 inline
bool hasOverlap() const noexcept;
818 const
size_t column_;
821 const
bool isAligned_;
832 template< typename MT2,
bool AF2,
bool SO2,
bool DF2 > friend class Submatrix;
871 template< typename MT >
872 inline Submatrix<MT,
unaligned,false,true>::Submatrix( Operand matrix,
size_t rindex,
size_t cindex,
size_t m,
size_t n )
878 , isAligned_( simdEnabled && matrix.data() !=
nullptr &&
checkAlignment( data() ) &&
879 ( m < 2UL || ( matrix.
spacing() &
size_t(-SIMDSIZE) ) == 0UL ) )
881 if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
908 template<
typename MT >
910 Submatrix<MT,unaligned,false,true>::operator()(
size_t i,
size_t j )
915 return matrix_(row_+i,column_+j);
932 template<
typename MT >
934 Submatrix<MT,unaligned,false,true>::operator()(
size_t i,
size_t j )
const 939 return const_cast<const MT&
>( matrix_ )(row_+i,column_+j);
957 template<
typename MT >
959 Submatrix<MT,unaligned,false,true>::at(
size_t i,
size_t j )
985 template<
typename MT >
987 Submatrix<MT,unaligned,false,true>::at(
size_t i,
size_t j )
const 1011 template<
typename MT >
1012 inline typename Submatrix<MT,unaligned,false,true>::Pointer
1013 Submatrix<MT,unaligned,false,true>::data() noexcept
1015 return matrix_.data() + row_*
spacing() + column_;
1031 template<
typename MT >
1032 inline typename Submatrix<MT,unaligned,false,true>::ConstPointer
1033 Submatrix<MT,unaligned,false,true>::data() const noexcept
1035 return matrix_.data() + row_*
spacing() + column_;
1050 template<
typename MT >
1051 inline typename Submatrix<MT,unaligned,false,true>::Pointer
1052 Submatrix<MT,unaligned,false,true>::data(
size_t i ) noexcept
1054 return matrix_.data() + (row_+i)*
spacing() + column_;
1069 template<
typename MT >
1070 inline typename Submatrix<MT,unaligned,false,true>::ConstPointer
1071 Submatrix<MT,unaligned,false,true>::data(
size_t i )
const noexcept
1073 return matrix_.data() + (row_+i)*
spacing() + column_;
1091 template<
typename MT >
1096 return Iterator( matrix_.begin( row_ + i ) + column_, isAligned_ );
1114 template<
typename MT >
1119 return ConstIterator( matrix_.cbegin( row_ + i ) + column_, isAligned_ );
1137 template<
typename MT >
1142 return ConstIterator( matrix_.cbegin( row_ + i ) + column_, isAligned_ );
1160 template<
typename MT >
1165 return Iterator( matrix_.begin( row_ + i ) + column_ +
n_, isAligned_ );
1183 template<
typename MT >
1188 return ConstIterator( matrix_.cbegin( row_ + i ) + column_ +
n_, isAligned_ );
1206 template<
typename MT >
1211 return ConstIterator( matrix_.cbegin( row_ + i ) + column_ +
n_, isAligned_ );
1236 template<
typename MT >
1237 inline Submatrix<MT,unaligned,false,true>&
1238 Submatrix<MT,unaligned,false,true>::operator=(
const ElementType& rhs )
1240 const size_t iend( row_ + m_ );
1242 for(
size_t i=row_; i<iend; ++i )
1244 const size_t jbegin( ( IsUpper<MT>::value )
1245 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
1246 ?(
max( i+1UL, column_ ) )
1247 :(
max( i, column_ ) ) )
1249 const size_t jend ( ( IsLower<MT>::value )
1250 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
1251 ?(
min( i, column_+n_ ) )
1252 :(
min( i+1UL, column_+n_ ) ) )
1255 for(
size_t j=jbegin; j<jend; ++j )
1278 template<
typename MT >
1279 inline Submatrix<MT,unaligned,false,true>&
1280 Submatrix<MT,unaligned,false,true>::operator=( initializer_list< initializer_list<ElementType> > list )
1288 for(
const auto& rowList : list ) {
1289 std::fill( std::copy( rowList.begin(), rowList.end(),
begin(i) ),
end(i),
ElementType() );
1314 template<
typename MT >
1315 inline Submatrix<MT,unaligned,false,true>&
1316 Submatrix<MT,unaligned,false,true>::operator=(
const Submatrix& rhs )
1321 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1324 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
1328 if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
1332 decltype(
auto) left( derestrict( *this ) );
1334 if( rhs.canAlias( &matrix_ ) ) {
1365 template<
typename MT >
1366 template<
typename MT2
1368 inline Submatrix<MT,unaligned,false,true>&
1369 Submatrix<MT,unaligned,false,true>::operator=(
const Matrix<MT2,SO2>& rhs )
1377 using Right = If_< IsRestricted<MT>, CompositeType_<MT2>,
const MT2& >;
1378 Right right( ~rhs );
1380 if( !tryAssign( matrix_, right, row_, column_ ) ) {
1384 if( IsSparseMatrix<MT2>::value ) {
1388 decltype(
auto) left( derestrict( *this ) );
1390 if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1391 const ResultType_<MT2> tmp( right );
1420 template<
typename MT >
1421 template<
typename MT2
1423 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,false,true>& >
1430 using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
1439 if( !tryAddAssign( matrix_, ~rhs, row_, column_ ) ) {
1443 decltype(
auto) left( derestrict( *this ) );
1445 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
1446 (~rhs).canAlias( &matrix_ ) ) {
1447 const AddType tmp( *
this + (~rhs) );
1476 template<
typename MT >
1477 template<
typename MT2
1479 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,false,true>& >
1486 using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
1495 const AddType tmp( *
this + (~rhs) );
1497 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1501 decltype(
auto) left( derestrict( *this ) );
1527 template< typename MT >
1528 template< typename MT2
1530 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,false,true>& >
1531 Submatrix<MT,unaligned,false,true>::operator-=( const Matrix<MT2,SO2>& rhs )
1537 using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
1546 if( !trySubAssign( matrix_, ~rhs, row_, column_ ) ) {
1550 decltype(
auto) left( derestrict( *this ) );
1552 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
1553 (~rhs).canAlias( &matrix_ ) ) {
1554 const SubType tmp( *
this - (~rhs ) );
1583 template<
typename MT >
1584 template<
typename MT2
1586 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,false,true>& >
1593 using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
1602 const SubType tmp( *
this - (~rhs) );
1604 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1608 decltype(
auto) left( derestrict( *this ) );
1634 template< typename MT >
1635 template< typename MT2
1637 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,false,true>& >
1638 Submatrix<MT,unaligned,false,true>::operator%=( const Matrix<MT2,SO2>& rhs )
1644 using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
1652 if( !trySchurAssign( matrix_, ~rhs, row_, column_ ) ) {
1656 decltype(
auto) left( derestrict( *this ) );
1658 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
1659 (~rhs).canAlias( &matrix_ ) ) {
1660 const SchurType tmp( *
this % (~rhs) );
1661 if( IsSparseMatrix<SchurType>::value )
1691 template<
typename MT >
1692 template<
typename MT2
1694 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,false,true>& >
1695 Submatrix<MT,unaligned,false,true>::operator%=(
const Matrix<MT2,SO2>& rhs )
1701 using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
1709 const SchurType tmp( *
this % (~rhs) );
1711 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1715 if( IsSparseMatrix<SchurType>::value ) {
1719 decltype(
auto) left( derestrict( *this ) );
1745 template< typename MT >
1746 template< typename MT2
1748 inline Submatrix<MT,unaligned,false,true>&
1749 Submatrix<MT,unaligned,false,true>::operator*=( const Matrix<MT2,SO2>& rhs )
1755 using MultType = MultTrait_< ResultType, ResultType_<MT2> >;
1764 const MultType tmp( *
this * (~rhs) );
1766 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1770 decltype(
auto) left( derestrict( *this ) );
1793 template< typename MT >
1794 template< typename Other >
1795 inline
EnableIf_< IsNumeric<Other>, Submatrix<MT,unaligned,false,true> >&
1796 Submatrix<MT,unaligned,false,true>::operator*=( Other rhs )
1800 decltype(
auto) left( derestrict( *this ) );
1822 template< typename MT >
1823 template< typename Other >
1824 inline
EnableIf_< IsNumeric<Other>, Submatrix<MT,unaligned,false,true> >&
1825 Submatrix<MT,unaligned,false,true>::operator/=( Other rhs )
1831 decltype(
auto) left( derestrict( *this ) );
1854 template< typename MT >
1855 inline typename Submatrix<MT,unaligned,false,true>::Operand
1856 Submatrix<MT,unaligned,false,true>::operand() const noexcept
1870 template<
typename MT >
1885 template<
typename MT >
1899 template<
typename MT >
1914 template<
typename MT >
1934 template<
typename MT >
1937 return matrix_.spacing();
1948 template<
typename MT >
1969 template<
typename MT >
1988 template<
typename MT >
1991 const size_t iend( row_ + m_ );
1992 const size_t jend( column_ + n_ );
1993 size_t nonzeros( 0UL );
1995 for(
size_t i=row_; i<iend; ++i )
1996 for(
size_t j=column_; j<jend; ++j )
2018 template<
typename MT >
2023 const size_t jend( column_ + n_ );
2024 size_t nonzeros( 0UL );
2026 for(
size_t j=column_; j<jend; ++j )
2042 template<
typename MT >
2047 for(
size_t i=row_; i<row_+
m_; ++i )
2049 const size_t jbegin( ( IsUpper<MT>::value )
2050 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
2051 ?(
max( i+1UL, column_ ) )
2052 :(
max( i, column_ ) ) )
2054 const size_t jend ( ( IsLower<MT>::value )
2055 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
2056 ?(
min( i, column_+n_ ) )
2057 :(
min( i+1UL, column_+n_ ) ) )
2060 for(
size_t j=jbegin; j<jend; ++j )
2061 clear( matrix_(i,j) );
2080 template<
typename MT >
2087 const size_t jbegin( ( IsUpper<MT>::value )
2088 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
2089 ?(
max( i+1UL, column_ ) )
2090 :(
max( i, column_ ) ) )
2092 const size_t jend ( ( IsLower<MT>::value )
2093 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
2094 ?(
min( i, column_+n_ ) )
2095 :(
min( i+1UL, column_+n_ ) ) )
2098 for(
size_t j=jbegin; j<jend; ++j )
2099 clear( matrix_(row_+i,j) );
2115 template<
typename MT >
2116 inline bool Submatrix<MT,unaligned,false,true>::hasOverlap() const noexcept
2118 BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value,
"Invalid matrix detected" );
2120 if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
2154 template<
typename MT >
2161 if( !tryAssign( matrix_,
trans( *
this ), row_, column_ ) ) {
2165 decltype(
auto) left( derestrict( *this ) );
2193 template< typename MT >
2194 inline Submatrix<MT,unaligned,false,true>& Submatrix<MT,unaligned,false,true>::
ctranspose()
2200 if( !tryAssign( matrix_,
ctrans( *
this ), row_, column_ ) ) {
2204 decltype(
auto) left( derestrict( *this ) );
2227 template< typename MT >
2228 template< typename Other >
2229 inline Submatrix<MT,unaligned,false,true>&
2230 Submatrix<MT,unaligned,false,true>::scale( const Other& scalar )
2234 const size_t iend( row_ + m_ );
2236 for(
size_t i=row_; i<iend; ++i )
2238 const size_t jbegin( ( IsUpper<MT>::value )
2239 ?( ( IsStrictlyUpper<MT>::value )
2240 ?(
max( i+1UL, column_ ) )
2241 :(
max( i, column_ ) ) )
2243 const size_t jend ( ( IsLower<MT>::value )
2244 ?( ( IsStrictlyLower<MT>::value )
2245 ?(
min( i, column_+n_ ) )
2246 :(
min( i+1UL, column_+n_ ) ) )
2249 for(
size_t j=jbegin; j<jend; ++j )
2250 matrix_(i,j) *= scalar;
2278 template<
typename MT >
2279 template<
typename Other >
2280 inline bool Submatrix<MT,unaligned,false,true>::canAlias(
const Other* alias )
const noexcept
2282 return matrix_.isAliased( alias );
2299 template<
typename MT >
2300 template<
typename MT2
2303 inline bool Submatrix<MT,unaligned,false,true>::canAlias(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept
2305 return ( matrix_.isAliased( &alias->matrix_ ) &&
2306 ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
2307 ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
2324 template<
typename MT >
2325 template<
typename Other >
2326 inline bool Submatrix<MT,unaligned,false,true>::isAliased(
const Other* alias )
const noexcept
2328 return matrix_.isAliased( alias );
2345 template<
typename MT >
2346 template<
typename MT2
2349 inline bool Submatrix<MT,unaligned,false,true>::isAliased(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept
2351 return ( matrix_.isAliased( &alias->matrix_ ) &&
2352 ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
2353 ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
2369 template<
typename MT >
2370 inline bool Submatrix<MT,unaligned,false,true>::isAligned() const noexcept
2389 template<
typename MT >
2390 inline bool Submatrix<MT,unaligned,false,true>::canSMPAssign() const noexcept
2392 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
2414 template<
typename MT >
2416 Submatrix<MT,unaligned,false,true>::load(
size_t i,
size_t j )
const noexcept
2419 return loada( i, j );
2421 return loadu( i, j );
2443 template<
typename MT >
2454 return matrix_.loada( row_+i, column_+j );
2476 template<
typename MT >
2487 return matrix_.loadu( row_+i, column_+j );
2510 template<
typename MT >
2512 Submatrix<MT,unaligned,false,true>::store(
size_t i,
size_t j,
const SIMDType& value ) noexcept
2540 template<
typename MT >
2551 matrix_.storea( row_+i, column_+j, value );
2574 template<
typename MT >
2585 matrix_.storeu( row_+i, column_+j, value );
2608 template<
typename MT >
2620 matrix_.stream( row_+i, column_+j, value );
2622 matrix_.storeu( row_+i, column_+j, value );
2640 template<
typename MT >
2641 template<
typename MT2 >
2642 inline DisableIf_< typename Submatrix<MT,unaligned,false,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
2643 Submatrix<MT,unaligned,false,true>::assign(
const DenseMatrix<MT2,false>& rhs )
2648 const size_t jpos( n_ &
size_t(-2) );
2651 for(
size_t i=0UL; i<
m_; ++i ) {
2652 for(
size_t j=0UL; j<jpos; j+=2UL ) {
2653 matrix_(row_+i,column_+j ) = (~rhs)(i,j );
2654 matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
2657 matrix_(row_+i,column_+jpos) = (~rhs)(i,jpos);
2677 template<
typename MT >
2678 template<
typename MT2 >
2679 inline EnableIf_< typename Submatrix<MT,unaligned,false,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
2680 Submatrix<MT,unaligned,false,true>::assign(
const DenseMatrix<MT2,false>& rhs )
2687 const size_t jpos( n_ &
size_t(-SIMDSIZE) );
2690 if( useStreaming && isAligned_ &&
2691 m_*n_ > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
2692 !(~rhs).isAliased( &matrix_ ) )
2694 for(
size_t i=0UL; i<
m_; ++i )
2698 ConstIterator_<MT2> right( (~rhs).
begin(i) );
2700 for( ; j<jpos; j+=SIMDSIZE ) {
2701 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2703 for( ; j<
n_; ++j ) {
2710 for(
size_t i=0UL; i<
m_; ++i )
2714 ConstIterator_<MT2> right( (~rhs).
begin(i) );
2716 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2717 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2718 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2719 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2720 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2722 for( ; j<jpos; j+=SIMDSIZE ) {
2723 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2725 for( ; j<
n_; ++j ) {
2726 *left = *right; ++left; ++right;
2747 template<
typename MT >
2748 template<
typename MT2 >
2749 inline void Submatrix<MT,unaligned,false,true>::assign(
const DenseMatrix<MT2,true>& rhs )
2756 constexpr
size_t block( BLOCK_SIZE );
2758 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
2759 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2760 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
2761 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2762 for(
size_t i=ii; i<iend; ++i ) {
2763 for(
size_t j=jj; j<jend; ++j ) {
2764 matrix_(row_+i,column_+j) = (~rhs)(i,j);
2786 template<
typename MT >
2787 template<
typename MT2 >
2788 inline void Submatrix<MT,unaligned,false,true>::assign(
const SparseMatrix<MT2,false>& rhs )
2793 for(
size_t i=0UL; i<
m_; ++i )
2794 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
2795 matrix_(row_+i,column_+element->index()) = element->value();
2813 template<
typename MT >
2814 template<
typename MT2 >
2815 inline void Submatrix<MT,unaligned,false,true>::assign(
const SparseMatrix<MT2,true>& rhs )
2822 for(
size_t j=0UL; j<
n_; ++j )
2823 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
2824 matrix_(row_+element->index(),column_+j) = element->value();
2842 template<
typename MT >
2843 template<
typename MT2 >
2844 inline DisableIf_< typename Submatrix<MT,unaligned,false,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
2845 Submatrix<MT,unaligned,false,true>::addAssign(
const DenseMatrix<MT2,false>& rhs )
2850 const size_t jpos( n_ &
size_t(-2) );
2853 for(
size_t i=0UL; i<
m_; ++i )
2855 if( IsDiagonal<MT2>::value ) {
2856 matrix_(row_+i,column_+i) += (~rhs)(i,i);
2859 for(
size_t j=0UL; j<jpos; j+=2UL ) {
2860 matrix_(row_+i,column_+j ) += (~rhs)(i,j );
2861 matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
2864 matrix_(row_+i,column_+jpos) += (~rhs)(i,jpos);
2885 template<
typename MT >
2886 template<
typename MT2 >
2887 inline EnableIf_< typename Submatrix<MT,unaligned,false,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
2888 Submatrix<MT,unaligned,false,true>::addAssign(
const DenseMatrix<MT2,false>& rhs )
2895 for(
size_t i=0UL; i<
m_; ++i )
2897 const size_t jbegin( ( IsUpper<MT2>::value )
2898 ?( ( IsStrictlyUpper<MT2>::value ? i+1UL : i ) &
size_t(-SIMDSIZE) )
2900 const size_t jend ( ( IsLower<MT2>::value )
2901 ?( IsStrictlyLower<MT2>::value ? i : i+1UL )
2905 const size_t jpos( jend &
size_t(-SIMDSIZE) );
2910 ConstIterator_<MT2> right( (~rhs).
begin(i) + jbegin );
2912 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2913 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2914 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2915 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2916 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2918 for( ; j<jpos; j+=SIMDSIZE ) {
2919 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2921 for( ; j<jend; ++j ) {
2922 *left += *right; ++left; ++right;
2942 template<
typename MT >
2943 template<
typename MT2 >
2944 inline void Submatrix<MT,unaligned,false,true>::addAssign(
const DenseMatrix<MT2,true>& rhs )
2951 constexpr
size_t block( BLOCK_SIZE );
2953 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
2954 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2955 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
2956 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2957 for(
size_t i=ii; i<iend; ++i ) {
2958 for(
size_t j=jj; j<jend; ++j ) {
2959 matrix_(row_+i,column_+j) += (~rhs)(i,j);
2981 template<
typename MT >
2982 template<
typename MT2 >
2983 inline void Submatrix<MT,unaligned,false,true>::addAssign(
const SparseMatrix<MT2,false>& rhs )
2988 for(
size_t i=0UL; i<
m_; ++i )
2989 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
2990 matrix_(row_+i,column_+element->index()) += element->value();
3008 template<
typename MT >
3009 template<
typename MT2 >
3010 inline void Submatrix<MT,unaligned,false,true>::addAssign(
const SparseMatrix<MT2,true>& rhs )
3017 for(
size_t j=0UL; j<
n_; ++j )
3018 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
3019 matrix_(row_+element->index(),column_+j) += element->value();
3037 template<
typename MT >
3038 template<
typename MT2 >
3039 inline DisableIf_< typename Submatrix<MT,unaligned,false,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
3040 Submatrix<MT,unaligned,false,true>::subAssign(
const DenseMatrix<MT2,false>& rhs )
3045 const size_t jpos( n_ &
size_t(-2) );
3048 for(
size_t i=0UL; i<
m_; ++i )
3050 if( IsDiagonal<MT2>::value ) {
3051 matrix_(row_+i,column_+i) -= (~rhs)(i,i);
3054 for(
size_t j=0UL; j<jpos; j+=2UL ) {
3055 matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
3056 matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
3059 matrix_(row_+i,column_+jpos) -= (~rhs)(i,jpos);
3080 template<
typename MT >
3081 template<
typename MT2 >
3082 inline EnableIf_< typename Submatrix<MT,unaligned,false,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
3083 Submatrix<MT,unaligned,false,true>::subAssign(
const DenseMatrix<MT2,false>& rhs )
3090 for(
size_t i=0UL; i<
m_; ++i )
3092 const size_t jbegin( ( IsUpper<MT2>::value )
3093 ?( ( IsStrictlyUpper<MT2>::value ? i+1UL : i ) &
size_t(-SIMDSIZE) )
3095 const size_t jend ( ( IsLower<MT2>::value )
3096 ?( IsStrictlyLower<MT2>::value ? i : i+1UL )
3100 const size_t jpos( jend &
size_t(-SIMDSIZE) );
3105 ConstIterator_<MT2> right( (~rhs).
begin(i) + jbegin );
3107 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3108 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3109 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3110 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3111 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3113 for( ; j<jpos; j+=SIMDSIZE ) {
3114 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3116 for( ; j<jend; ++j ) {
3117 *left -= *right; ++left; ++right;
3137 template<
typename MT >
3138 template<
typename MT2 >
3139 inline void Submatrix<MT,unaligned,false,true>::subAssign(
const DenseMatrix<MT2,true>& rhs )
3146 constexpr
size_t block( BLOCK_SIZE );
3148 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
3149 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3150 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
3151 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3152 for(
size_t i=ii; i<iend; ++i ) {
3153 for(
size_t j=jj; j<jend; ++j ) {
3154 matrix_(row_+i,column_+j) -= (~rhs)(i,j);
3176 template<
typename MT >
3177 template<
typename MT2 >
3178 inline void Submatrix<MT,unaligned,false,true>::subAssign(
const SparseMatrix<MT2,false>& rhs )
3183 for(
size_t i=0UL; i<
m_; ++i )
3184 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
3185 matrix_(row_+i,column_+element->index()) -= element->value();
3203 template<
typename MT >
3204 template<
typename MT2 >
3205 inline void Submatrix<MT,unaligned,false,true>::subAssign(
const SparseMatrix<MT2,true>& rhs )
3212 for(
size_t j=0UL; j<
n_; ++j )
3213 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
3214 matrix_(row_+element->index(),column_+j) -= element->value();
3232 template<
typename MT >
3233 template<
typename MT2 >
3234 inline DisableIf_< typename Submatrix<MT,unaligned,false,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
3235 Submatrix<MT,unaligned,false,true>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
3240 const size_t jpos( n_ &
size_t(-2) );
3243 for(
size_t i=0UL; i<
m_; ++i ) {
3244 for(
size_t j=0UL; j<jpos; j+=2UL ) {
3245 matrix_(row_+i,column_+j ) *= (~rhs)(i,j );
3246 matrix_(row_+i,column_+j+1UL) *= (~rhs)(i,j+1UL);
3249 matrix_(row_+i,column_+jpos) *= (~rhs)(i,jpos);
3269 template<
typename MT >
3270 template<
typename MT2 >
3271 inline EnableIf_< typename Submatrix<MT,unaligned,false,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
3272 Submatrix<MT,unaligned,false,true>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
3279 for(
size_t i=0UL; i<
m_; ++i )
3281 const size_t jpos( n_ &
size_t(-SIMDSIZE) );
3286 ConstIterator_<MT2> right( (~rhs).
begin(i) );
3288 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3289 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3290 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3291 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3292 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3294 for( ; j<jpos; j+=SIMDSIZE ) {
3295 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3297 for( ; j<
n_; ++j ) {
3298 *left *= *right; ++left; ++right;
3318 template<
typename MT >
3319 template<
typename MT2 >
3320 inline void Submatrix<MT,unaligned,false,true>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
3327 constexpr
size_t block( BLOCK_SIZE );
3329 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
3330 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3331 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
3332 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3333 for(
size_t i=ii; i<iend; ++i ) {
3334 for(
size_t j=jj; j<jend; ++j ) {
3335 matrix_(row_+i,column_+j) *= (~rhs)(i,j);
3357 template<
typename MT >
3358 template<
typename MT2 >
3359 inline void Submatrix<MT,unaligned,false,true>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
3366 for(
size_t i=0UL; i<
m_; ++i )
3370 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element ) {
3371 for( ; j<element->index(); ++j )
3372 reset( matrix_(row_+i,column_+j) );
3373 matrix_(row_+i,column_+j) *= element->value();
3377 for( ; j<
n_; ++j ) {
3378 reset( matrix_(row_+i,column_+j) );
3398 template<
typename MT >
3399 template<
typename MT2 >
3400 inline void Submatrix<MT,unaligned,false,true>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
3409 for(
size_t j=0UL; j<
n_; ++j )
3413 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element ) {
3414 for( ; i<element->index(); ++i )
3415 reset( matrix_(row_+i,column_+j) );
3416 matrix_(row_+i,column_+j) *= element->value();
3420 for( ; i<
m_; ++i ) {
3421 reset( matrix_(row_+i,column_+j) );
3449 template<
typename MT >
3450 class Submatrix<MT,unaligned,true,true>
3451 :
public View< DenseMatrix< Submatrix<MT,unaligned,true,true>, true > >
3456 using Operand = If_< IsExpression<MT>, MT, MT& >;
3461 using This = Submatrix<MT,unaligned,true,true>;
3462 using BaseType = DenseMatrix<This,true>;
3466 using ElementType = ElementType_<MT>;
3467 using SIMDType = SIMDTrait_<ElementType>;
3472 using ConstReference = ConstReference_<MT>;
3478 using ConstPointer =
const ElementType*;
3481 using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
3487 template<
typename IteratorType >
3488 class SubmatrixIterator
3493 using IteratorCategory =
typename std::iterator_traits<IteratorType>::iterator_category;
3496 using ValueType =
typename std::iterator_traits<IteratorType>::value_type;
3499 using PointerType =
typename std::iterator_traits<IteratorType>::pointer;
3502 using ReferenceType =
typename std::iterator_traits<IteratorType>::reference;
3505 using DifferenceType =
typename std::iterator_traits<IteratorType>::difference_type;
3508 using iterator_category = IteratorCategory;
3509 using value_type = ValueType;
3510 using pointer = PointerType;
3511 using reference = ReferenceType;
3512 using difference_type = DifferenceType;
3518 inline SubmatrixIterator()
3520 , isAligned_( false )
3532 inline SubmatrixIterator( IteratorType iterator,
bool isMemoryAligned )
3533 : iterator_ ( iterator )
3534 , isAligned_( isMemoryAligned )
3543 template<
typename IteratorType2 >
3544 inline SubmatrixIterator(
const SubmatrixIterator<IteratorType2>& it )
3545 : iterator_ ( it.base() )
3546 , isAligned_( it.isAligned() )
3556 inline SubmatrixIterator&
operator+=(
size_t inc ) {
3568 inline SubmatrixIterator&
operator-=(
size_t dec ) {
3579 inline SubmatrixIterator& operator++() {
3590 inline const SubmatrixIterator operator++(
int ) {
3591 return SubmatrixIterator( iterator_++, isAligned_ );
3600 inline SubmatrixIterator& operator--() {
3611 inline const SubmatrixIterator operator--(
int ) {
3612 return SubmatrixIterator( iterator_--, isAligned_ );
3621 inline ReferenceType
operator*()
const {
3636 inline SIMDType load() const noexcept {
3654 inline SIMDType
loada() const noexcept {
3655 return iterator_.loada();
3669 inline SIMDType
loadu() const noexcept {
3670 return iterator_.loadu();
3685 inline void store(
const SIMDType& value )
const {
3701 inline void storea(
const SIMDType& value )
const {
3702 iterator_.storea( value );
3717 inline void storeu(
const SIMDType& value )
const {
3719 iterator_.storea( value );
3722 iterator_.storeu( value );
3738 inline void stream(
const SIMDType& value )
const {
3739 iterator_.stream( value );
3749 inline bool operator==(
const SubmatrixIterator& rhs )
const {
3750 return iterator_ == rhs.iterator_;
3760 inline bool operator!=(
const SubmatrixIterator& rhs )
const {
3761 return iterator_ != rhs.iterator_;
3771 inline bool operator<(
const SubmatrixIterator& rhs )
const {
3772 return iterator_ < rhs.iterator_;
3782 inline bool operator>(
const SubmatrixIterator& rhs )
const {
3783 return iterator_ > rhs.iterator_;
3793 inline bool operator<=(
const SubmatrixIterator& rhs )
const {
3794 return iterator_ <= rhs.iterator_;
3804 inline bool operator>=(
const SubmatrixIterator& rhs )
const {
3805 return iterator_ >= rhs.iterator_;
3815 inline DifferenceType
operator-(
const SubmatrixIterator& rhs )
const {
3816 return iterator_ - rhs.iterator_;
3827 friend inline const SubmatrixIterator
operator+(
const SubmatrixIterator& it,
size_t inc ) {
3828 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
3839 friend inline const SubmatrixIterator
operator+(
size_t inc,
const SubmatrixIterator& it ) {
3840 return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
3851 friend inline const SubmatrixIterator
operator-(
const SubmatrixIterator& it,
size_t dec ) {
3852 return SubmatrixIterator( it.iterator_ - dec, it.isAligned_ );
3861 inline IteratorType base()
const {
3871 inline bool isAligned() const noexcept {
3878 IteratorType iterator_;
3886 using ConstIterator = SubmatrixIterator< ConstIterator_<MT> >;
3894 enum :
bool { simdEnabled = MT::simdEnabled };
3897 enum :
bool { smpAssignable = MT::smpAssignable };
3903 explicit inline Submatrix( Operand matrix,
size_t rindex,
size_t cindex,
size_t m,
size_t n );
3915 inline Reference operator()(
size_t i,
size_t j );
3916 inline ConstReference operator()(
size_t i,
size_t j )
const;
3917 inline Reference at(
size_t i,
size_t j );
3918 inline ConstReference at(
size_t i,
size_t j )
const;
3919 inline Pointer data () noexcept;
3920 inline ConstPointer data () const noexcept;
3921 inline Pointer data (
size_t j ) noexcept;
3922 inline ConstPointer data (
size_t j ) const noexcept;
3924 inline ConstIterator
begin (
size_t j ) const;
3925 inline ConstIterator
cbegin(
size_t j ) const;
3927 inline ConstIterator
end (
size_t j ) const;
3928 inline ConstIterator
cend (
size_t j ) const;
3935 inline Submatrix& operator=( const ElementType& rhs );
3936 inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
3937 inline Submatrix& operator=( const Submatrix& rhs );
3939 template< typename MT2,
bool SO >
3940 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
3942 template< typename MT2,
bool SO >
3943 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
3944 operator+=( const Matrix<MT2,SO>& rhs );
3946 template< typename MT2,
bool SO >
3947 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
3948 operator+=( const Matrix<MT2,SO>& rhs );
3950 template< typename MT2,
bool SO >
3951 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
3952 operator-=( const Matrix<MT2,SO>& rhs );
3954 template< typename MT2,
bool SO >
3955 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
3956 operator-=( const Matrix<MT2,SO>& rhs );
3958 template< typename MT2,
bool SO >
3959 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
3960 operator%=( const Matrix<MT2,SO>& rhs );
3962 template< typename MT2,
bool SO >
3963 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
3964 operator%=( const Matrix<MT2,SO>& rhs );
3966 template< typename MT2,
bool SO >
3967 inline Submatrix& operator*=( const Matrix<MT2,SO>& rhs );
3969 template< typename Other >
3970 inline
EnableIf_< IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
3972 template< typename Other >
3973 inline
EnableIf_< IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
3980 inline Operand operand() const noexcept;
3981 inline
size_t row() const noexcept;
3982 inline
size_t column() const noexcept;
3983 inline
size_t rows() const noexcept;
3984 inline
size_t columns() const noexcept;
3985 inline
size_t spacing() const noexcept;
3986 inline
size_t capacity() const noexcept;
3987 inline
size_t capacity(
size_t i ) const noexcept;
3989 inline
size_t nonZeros(
size_t i ) const;
3990 inline
void reset();
3991 inline
void reset(
size_t i );
3999 inline Submatrix& ctranspose();
4001 template< typename Other > inline Submatrix& scale( const Other& scalar );
4008 template< typename MT2 >
4009 struct VectorizedAssign {
4010 enum :
bool { value = useOptimizedKernels &&
4011 simdEnabled && MT2::simdEnabled &&
4012 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value };
4018 template<
typename MT2 >
4019 struct VectorizedAddAssign {
4020 enum :
bool { value = useOptimizedKernels &&
4021 simdEnabled && MT2::simdEnabled &&
4022 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
4023 HasSIMDAdd< ElementType, ElementType_<MT2> >::value &&
4024 !IsDiagonal<MT2>::value };
4030 template<
typename MT2 >
4031 struct VectorizedSubAssign {
4032 enum :
bool { value = useOptimizedKernels &&
4033 simdEnabled && MT2::simdEnabled &&
4034 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
4035 HasSIMDSub< ElementType, ElementType_<MT2> >::value &&
4036 !IsDiagonal<MT2>::value };
4042 template<
typename MT2 >
4043 struct VectorizedSchurAssign {
4044 enum :
bool { value = useOptimizedKernels &&
4045 simdEnabled && MT2::simdEnabled &&
4046 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
4047 HasSIMDMult< ElementType, ElementType_<MT2> >::value };
4060 template<
typename Other >
4061 inline bool canAlias(
const Other* alias )
const noexcept;
4063 template<
typename MT2,
bool AF2,
bool SO2 >
4064 inline bool canAlias(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept;
4066 template<
typename Other >
4067 inline bool isAliased(
const Other* alias )
const noexcept;
4069 template<
typename MT2,
bool AF2,
bool SO2 >
4070 inline bool isAliased(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept;
4072 inline bool isAligned () const noexcept;
4073 inline
bool canSMPAssign() const noexcept;
4084 template< typename MT2 >
4085 inline
DisableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,true>& rhs );
4087 template< typename MT2 >
4088 inline
EnableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,true>& rhs );
4090 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,false>& rhs );
4091 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
4092 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
4094 template< typename MT2 >
4095 inline
DisableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,true>& rhs );
4097 template< typename MT2 >
4098 inline
EnableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,true>& rhs );
4100 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,false>& rhs );
4101 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
4102 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
4104 template< typename MT2 >
4105 inline
DisableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,true>& rhs );
4107 template< typename MT2 >
4108 inline
EnableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,true>& rhs );
4110 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,false>& rhs );
4111 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
4112 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
4114 template< typename MT2 >
4115 inline
DisableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,true>& rhs );
4117 template< typename MT2 >
4118 inline
EnableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,true>& rhs );
4120 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,false>& rhs );
4121 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
4122 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
4130 inline
bool hasOverlap() const noexcept;
4139 const
size_t column_;
4142 const
bool isAligned_;
4153 template< typename MT2,
bool AF2,
bool SO2,
bool DF2 > friend class Submatrix;
4192 template< typename MT >
4193 inline Submatrix<MT,unaligned,true,true>::Submatrix( Operand matrix,
size_t rindex,
size_t cindex,
size_t m,
size_t n )
4194 : matrix_ ( matrix )
4196 , column_ ( cindex )
4199 , isAligned_( simdEnabled && matrix.data() !=
nullptr &&
checkAlignment( data() ) &&
4200 ( n < 2UL || ( matrix.
spacing() &
size_t(-SIMDSIZE) ) == 0UL ) )
4202 if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
4229 template<
typename MT >
4231 Submatrix<MT,unaligned,true,true>::operator()(
size_t i,
size_t j )
4236 return matrix_(row_+i,column_+j);
4253 template<
typename MT >
4255 Submatrix<MT,unaligned,true,true>::operator()(
size_t i,
size_t j )
const 4260 return const_cast<const MT&
>( matrix_ )(row_+i,column_+j);
4278 template<
typename MT >
4280 Submatrix<MT,unaligned,true,true>::at(
size_t i,
size_t j )
4288 return (*
this)(i,j);
4306 template<
typename MT >
4308 Submatrix<MT,unaligned,true,true>::at(
size_t i,
size_t j )
const 4316 return (*
this)(i,j);
4332 template<
typename MT >
4333 inline typename Submatrix<MT,unaligned,true,true>::Pointer
4334 Submatrix<MT,unaligned,true,true>::data() noexcept
4336 return matrix_.data() + row_ + column_*
spacing();
4352 template<
typename MT >
4353 inline typename Submatrix<MT,unaligned,true,true>::ConstPointer
4354 Submatrix<MT,unaligned,true,true>::data() const noexcept
4356 return matrix_.data() + row_ + column_*
spacing();
4371 template<
typename MT >
4372 inline typename Submatrix<MT,unaligned,true,true>::Pointer
4373 Submatrix<MT,unaligned,true,true>::data(
size_t j ) noexcept
4375 return matrix_.data() + row_ + (column_+j)*
spacing();
4390 template<
typename MT >
4391 inline typename Submatrix<MT,unaligned,true,true>::ConstPointer
4392 Submatrix<MT,unaligned,true,true>::data(
size_t j )
const noexcept
4394 return matrix_.data() + row_ + (column_+j)*
spacing();
4407 template<
typename MT >
4412 return Iterator( matrix_.begin( column_ + j ) + row_, isAligned_ );
4425 template<
typename MT >
4430 return ConstIterator( matrix_.cbegin( column_ + j ) + row_, isAligned_ );
4443 template<
typename MT >
4448 return ConstIterator( matrix_.cbegin( column_ + j ) + row_, isAligned_ );
4461 template<
typename MT >
4466 return Iterator( matrix_.begin( column_ + j ) + row_ +
m_, isAligned_ );
4479 template<
typename MT >
4484 return ConstIterator( matrix_.cbegin( column_ + j ) + row_ +
m_, isAligned_ );
4497 template<
typename MT >
4502 return ConstIterator( matrix_.cbegin( column_ + j ) + row_ +
m_, isAligned_ );
4527 template<
typename MT >
4528 inline Submatrix<MT,unaligned,true,true>&
4529 Submatrix<MT,unaligned,true,true>::operator=(
const ElementType& rhs )
4531 const size_t jend( column_ + n_ );
4533 for(
size_t j=column_; j<jend; ++j )
4535 const size_t ibegin( ( IsLower<MT>::value )
4536 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4537 ?(
max( j+1UL, row_ ) )
4538 :(
max( j, row_ ) ) )
4540 const size_t iend ( ( IsUpper<MT>::value )
4541 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4542 ?(
min( j, row_+m_ ) )
4543 :(
min( j+1UL, row_+m_ ) ) )
4546 for(
size_t i=ibegin; i<iend; ++i )
4569 template<
typename MT >
4570 inline Submatrix<MT,unaligned,true,true>&
4571 Submatrix<MT,unaligned,true,true>::operator=( initializer_list< initializer_list<ElementType> > list )
4579 for(
const auto& rowList : list ) {
4581 for(
const auto& element : rowList ) {
4582 matrix_(row_+i,column_+j) = element;
4585 for( ; j<
n_; ++j ) {
4612 template<
typename MT >
4613 inline Submatrix<MT,unaligned,true,true>&
4614 Submatrix<MT,unaligned,true,true>::operator=(
const Submatrix& rhs )
4619 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
4622 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
4626 if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
4630 decltype(
auto) left( derestrict( *this ) );
4632 if( rhs.canAlias( &matrix_ ) ) {
4663 template<
typename MT >
4664 template<
typename MT2
4666 inline Submatrix<MT,unaligned,true,true>&
4667 Submatrix<MT,unaligned,true,true>::operator=(
const Matrix<MT2,SO>& rhs )
4675 using Right = If_< IsRestricted<MT>, CompositeType_<MT2>,
const MT2& >;
4676 Right right( ~rhs );
4678 if( !tryAssign( matrix_, right, row_, column_ ) ) {
4682 if( IsSparseMatrix<MT2>::value ) {
4686 decltype(
auto) left( derestrict( *this ) );
4688 if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4689 const ResultType_<MT2> tmp( right );
4718 template<
typename MT >
4719 template<
typename MT2
4721 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,true,true>& >
4728 using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
4737 if( !tryAddAssign( matrix_, ~rhs, row_, column_ ) ) {
4741 decltype(
auto) left( derestrict( *this ) );
4743 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
4744 (~rhs).canAlias( &matrix_ ) ) {
4745 const AddType tmp( *
this + (~rhs) );
4774 template<
typename MT >
4775 template<
typename MT2
4777 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,true,true>& >
4784 using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
4793 const AddType tmp( *
this + (~rhs) );
4795 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
4799 decltype(
auto) left( derestrict( *this ) );
4825 template< typename MT >
4826 template< typename MT2
4828 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,true,true>& >
4829 Submatrix<MT,unaligned,true,true>::operator-=( const Matrix<MT2,SO>& rhs )
4835 using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
4844 if( !trySubAssign( matrix_, ~rhs, row_, column_ ) ) {
4848 decltype(
auto) left( derestrict( *this ) );
4850 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
4851 (~rhs).canAlias( &matrix_ ) ) {
4852 const SubType tmp( *
this - (~rhs ) );
4881 template<
typename MT >
4882 template<
typename MT2
4884 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,true,true>& >
4891 using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
4900 const SubType tmp( *
this - (~rhs) );
4902 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
4906 decltype(
auto) left( derestrict( *this ) );
4932 template< typename MT >
4933 template< typename MT2
4935 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,true,true>& >
4936 Submatrix<MT,unaligned,true,true>::operator%=( const Matrix<MT2,SO>& rhs )
4942 using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
4950 if( !trySchurAssign( matrix_, ~rhs, row_, column_ ) ) {
4954 decltype(
auto) left( derestrict( *this ) );
4956 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
4957 (~rhs).canAlias( &matrix_ ) ) {
4958 const SchurType tmp( *
this % (~rhs) );
4959 if( IsSparseMatrix<SchurType>::value )
4989 template<
typename MT >
4990 template<
typename MT2
4992 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,unaligned,true,true>& >
4993 Submatrix<MT,unaligned,true,true>::operator%=(
const Matrix<MT2,SO>& rhs )
4999 using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
5007 const SchurType tmp( *
this % (~rhs) );
5009 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
5013 if( IsSparseMatrix<SchurType>::value ) {
5017 decltype(
auto) left( derestrict( *this ) );
5043 template< typename MT >
5044 template< typename MT2
5046 inline Submatrix<MT,unaligned,true,true>&
5047 Submatrix<MT,unaligned,true,true>::operator*=( const Matrix<MT2,SO>& rhs )
5053 using MultType = MultTrait_< ResultType, ResultType_<MT2> >;
5062 const MultType tmp( *
this * (~rhs) );
5064 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
5068 decltype(
auto) left( derestrict( *this ) );
5091 template< typename MT >
5092 template< typename Other >
5093 inline
EnableIf_< IsNumeric<Other>, Submatrix<MT,unaligned,true,true> >&
5094 Submatrix<MT,unaligned,true,true>::operator*=( Other rhs )
5098 decltype(
auto) left( derestrict( *this ) );
5120 template< typename MT >
5121 template< typename Other >
5122 inline
EnableIf_< IsNumeric<Other>, Submatrix<MT,unaligned,true,true> >&
5123 Submatrix<MT,unaligned,true,true>::operator/=( Other rhs )
5129 decltype(
auto) left( derestrict( *this ) );
5152 template< typename MT >
5153 inline typename Submatrix<MT,unaligned,true,true>::Operand
5154 Submatrix<MT,unaligned,true,true>::operand() const noexcept
5168 template<
typename MT >
5183 template<
typename MT >
5198 template<
typename MT >
5213 template<
typename MT >
5231 template<
typename MT >
5234 return matrix_.spacing();
5246 template<
typename MT >
5262 template<
typename MT >
5281 template<
typename MT >
5284 const size_t iend( row_ + m_ );
5285 const size_t jend( column_ + n_ );
5286 size_t nonzeros( 0UL );
5288 for(
size_t j=column_; j<jend; ++j )
5289 for(
size_t i=row_; i<iend; ++i )
5306 template<
typename MT >
5311 const size_t iend( row_ + m_ );
5312 size_t nonzeros( 0UL );
5314 for(
size_t i=row_; i<iend; ++i )
5315 if( !
isDefault( matrix_(i,column_+j) ) )
5330 template<
typename MT >
5335 for(
size_t j=column_; j<column_+
n_; ++j )
5337 const size_t ibegin( ( IsLower<MT>::value )
5338 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
5339 ?(
max( j+1UL, row_ ) )
5340 :(
max( j, row_ ) ) )
5342 const size_t iend ( ( IsUpper<MT>::value )
5343 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
5344 ?(
min( j, row_+m_ ) )
5345 :(
min( j+1UL, row_+m_ ) ) )
5348 for(
size_t i=ibegin; i<iend; ++i )
5349 clear( matrix_(i,j) );
5363 template<
typename MT >
5370 const size_t ibegin( ( IsLower<MT>::value )
5371 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
5372 ?(
max( j+1UL, row_ ) )
5373 :(
max( j, row_ ) ) )
5375 const size_t iend ( ( IsUpper<MT>::value )
5376 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
5377 ?(
min( j, row_+m_ ) )
5378 :(
min( j+1UL, row_+m_ ) ) )
5381 for(
size_t i=ibegin; i<iend; ++i )
5382 clear( matrix_(i,column_+j) );
5398 template<
typename MT >
5399 inline bool Submatrix<MT,unaligned,true,true>::hasOverlap() const noexcept
5401 BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value,
"Invalid matrix detected" );
5403 if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
5437 template<
typename MT >
5444 if( !tryAssign( matrix_,
trans( *
this ), row_, column_ ) ) {
5448 decltype(
auto) left( derestrict( *this ) );
5476 template< typename MT >
5477 inline Submatrix<MT,unaligned,true,true>& Submatrix<MT,unaligned,true,true>::ctranspose()
5483 if( !tryAssign( matrix_,
ctrans( *
this ), row_, column_ ) ) {
5487 decltype(
auto) left( derestrict( *this ) );
5510 template< typename MT >
5511 template< typename Other >
5512 inline Submatrix<MT,unaligned,true,true>& Submatrix<MT,unaligned,true,true>::scale( const Other& scalar )
5516 const size_t jend( column_ + n_ );
5518 for(
size_t j=column_; j<jend; ++j )
5520 const size_t ibegin( ( IsLower<MT>::value )
5521 ?( ( IsStrictlyLower<MT>::value )
5522 ?(
max( j+1UL, row_ ) )
5523 :(
max( j, row_ ) ) )
5525 const size_t iend ( ( IsUpper<MT>::value )
5526 ?( ( IsStrictlyUpper<MT>::value )
5527 ?(
min( j, row_+m_ ) )
5528 :(
min( j+1UL, row_+m_ ) ) )
5531 for(
size_t i=ibegin; i<iend; ++i )
5532 matrix_(i,j) *= scalar;
5560 template<
typename MT >
5561 template<
typename Other >
5562 inline bool Submatrix<MT,unaligned,true,true>::canAlias(
const Other* alias )
const noexcept
5564 return matrix_.isAliased( alias );
5581 template<
typename MT >
5582 template<
typename MT2
5585 inline bool Submatrix<MT,unaligned,true,true>::canAlias(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept
5587 return ( matrix_.isAliased( &alias->matrix_ ) &&
5588 ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
5589 ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
5606 template<
typename MT >
5607 template<
typename Other >
5608 inline bool Submatrix<MT,unaligned,true,true>::isAliased(
const Other* alias )
const noexcept
5610 return matrix_.isAliased( alias );
5627 template<
typename MT >
5628 template<
typename MT2
5631 inline bool Submatrix<MT,unaligned,true,true>::isAliased(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept
5633 return ( matrix_.isAliased( &alias->matrix_ ) &&
5634 ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
5635 ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
5651 template<
typename MT >
5652 inline bool Submatrix<MT,unaligned,true,true>::isAligned() const noexcept
5671 template<
typename MT >
5672 inline bool Submatrix<MT,unaligned,true,true>::canSMPAssign() const noexcept
5674 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
5695 template<
typename MT >
5697 Submatrix<MT,unaligned,true,true>::load(
size_t i,
size_t j )
const noexcept
5700 return loada( i, j );
5702 return loadu( i, j );
5723 template<
typename MT >
5734 return matrix_.loada( row_+i, column_+j );
5755 template<
typename MT >
5766 return matrix_.loadu( row_+i, column_+j );
5788 template<
typename MT >
5790 Submatrix<MT,unaligned,true,true>::store(
size_t i,
size_t j,
const SIMDType& value ) noexcept
5817 template<
typename MT >
5828 matrix_.storea( row_+i, column_+j, value );
5850 template<
typename MT >
5861 matrix_.storeu( row_+i, column_+j, value );
5884 template<
typename MT >
5896 matrix_.stream( row_+i, column_+j, value );
5898 matrix_.storeu( row_+i, column_+j, value );
5916 template<
typename MT >
5917 template<
typename MT2 >
5918 inline DisableIf_< typename Submatrix<MT,unaligned,true,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
5919 Submatrix<MT,unaligned,true,true>::assign(
const DenseMatrix<MT2,true>& rhs )
5924 const size_t ipos( m_ &
size_t(-2) );
5927 for(
size_t j=0UL; j<
n_; ++j ) {
5928 for(
size_t i=0UL; i<ipos; i+=2UL ) {
5929 matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
5930 matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
5933 matrix_(row_+ipos,column_+j) = (~rhs)(ipos,j);
5953 template<
typename MT >
5954 template<
typename MT2 >
5955 inline EnableIf_< typename Submatrix<MT,unaligned,true,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
5956 Submatrix<MT,unaligned,true,true>::assign(
const DenseMatrix<MT2,true>& rhs )
5963 const size_t ipos( m_ &
size_t(-SIMDSIZE) );
5966 if( useStreaming && isAligned_ &&
5967 m_*n_ > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
5968 !(~rhs).isAliased( &matrix_ ) )
5970 for(
size_t j=0UL; j<
n_; ++j )
5974 ConstIterator_<MT2> right( (~rhs).
begin(j) );
5976 for( ; i<ipos; i+=SIMDSIZE ) {
5977 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5979 for( ; i<
m_; ++i ) {
5980 *left = *right; ++left; ++right;
5986 for(
size_t j=0UL; j<
n_; ++j )
5990 ConstIterator_<MT2> right( (~rhs).
begin(j) );
5992 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5993 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5994 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5995 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5996 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5998 for( ; i<ipos; i+=SIMDSIZE ) {
5999 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6001 for( ; i<
m_; ++i ) {
6002 *left = *right; ++left; ++right;
6023 template<
typename MT >
6024 template<
typename MT2 >
6025 inline void Submatrix<MT,unaligned,true,true>::assign(
const DenseMatrix<MT2,false>& rhs )
6032 constexpr
size_t block( BLOCK_SIZE );
6034 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
6035 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6036 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
6037 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6038 for(
size_t j=jj; j<jend; ++j ) {
6039 for(
size_t i=ii; i<iend; ++i ) {
6040 matrix_(row_+i,column_+j) = (~rhs)(i,j);
6062 template<
typename MT >
6063 template<
typename MT2 >
6064 inline void Submatrix<MT,unaligned,true,true>::assign(
const SparseMatrix<MT2,true>& rhs )
6069 for(
size_t j=0UL; j<
n_; ++j )
6070 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
6071 matrix_(row_+element->index(),column_+j) = element->value();
6089 template<
typename MT >
6090 template<
typename MT2 >
6091 inline void Submatrix<MT,unaligned,true,true>::assign(
const SparseMatrix<MT2,false>& rhs )
6098 for(
size_t i=0UL; i<
m_; ++i )
6099 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
6100 matrix_(row_+i,column_+element->index()) = element->value();
6118 template<
typename MT >
6119 template<
typename MT2 >
6120 inline DisableIf_< typename Submatrix<MT,unaligned,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
6121 Submatrix<MT,unaligned,true,true>::addAssign(
const DenseMatrix<MT2,true>& rhs )
6126 const size_t ipos( m_ &
size_t(-2) );
6129 for(
size_t j=0UL; j<
n_; ++j )
6131 if( IsDiagonal<MT2>::value ) {
6132 matrix_(row_+j,column_+j) += (~rhs)(j,j);
6135 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6136 matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
6137 matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
6140 matrix_(row_+ipos,column_+j) += (~rhs)(ipos,j);
6161 template<
typename MT >
6162 template<
typename MT2 >
6163 inline EnableIf_< typename Submatrix<MT,unaligned,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
6164 Submatrix<MT,unaligned,true,true>::addAssign(
const DenseMatrix<MT2,true>& rhs )
6171 for(
size_t j=0UL; j<
n_; ++j )
6173 const size_t ibegin( ( IsLower<MT>::value )
6174 ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) &
size_t(-SIMDSIZE) )
6176 const size_t iend ( ( IsUpper<MT>::value )
6177 ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6181 const size_t ipos( iend &
size_t(-SIMDSIZE) );
6186 ConstIterator_<MT2> right( (~rhs).
begin(j) + ibegin );
6188 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6189 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6190 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6191 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6192 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6194 for( ; i<ipos; i+=SIMDSIZE ) {
6195 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6197 for( ; i<iend; ++i ) {
6198 *left += *right; ++left; ++right;
6218 template<
typename MT >
6219 template<
typename MT2 >
6220 inline void Submatrix<MT,unaligned,true,true>::addAssign(
const DenseMatrix<MT2,false>& rhs )
6227 constexpr
size_t block( BLOCK_SIZE );
6229 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
6230 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6231 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
6232 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6233 for(
size_t j=jj; j<jend; ++j ) {
6234 for(
size_t i=ii; i<iend; ++i ) {
6235 matrix_(row_+i,column_+j) += (~rhs)(i,j);
6257 template<
typename MT >
6258 template<
typename MT2 >
6259 inline void Submatrix<MT,unaligned,true,true>::addAssign(
const SparseMatrix<MT2,true>& rhs )
6264 for(
size_t j=0UL; j<
n_; ++j )
6265 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
6266 matrix_(row_+element->index(),column_+j) += element->value();
6284 template<
typename MT >
6285 template<
typename MT2 >
6286 inline void Submatrix<MT,unaligned,true,true>::addAssign(
const SparseMatrix<MT2,false>& rhs )
6293 for(
size_t i=0UL; i<
m_; ++i )
6294 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
6295 matrix_(row_+i,column_+element->index()) += element->value();
6313 template<
typename MT >
6314 template<
typename MT2 >
6315 inline DisableIf_< typename Submatrix<MT,unaligned,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
6316 Submatrix<MT,unaligned,true,true>::subAssign(
const DenseMatrix<MT2,true>& rhs )
6321 const size_t ipos( m_ &
size_t(-2) );
6324 for(
size_t j=0UL; j<
n_; ++j )
6326 if( IsDiagonal<MT2>::value ) {
6327 matrix_(row_+j,column_+j) -= (~rhs)(j,j);
6330 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6331 matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
6332 matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
6335 matrix_(row_+ipos,column_+j) -= (~rhs)(ipos,j);
6356 template<
typename MT >
6357 template<
typename MT2 >
6358 inline EnableIf_< typename Submatrix<MT,unaligned,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
6359 Submatrix<MT,unaligned,true,true>::subAssign(
const DenseMatrix<MT2,true>& rhs )
6366 for(
size_t j=0UL; j<
n_; ++j )
6368 const size_t ibegin( ( IsLower<MT>::value )
6369 ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) &
size_t(-SIMDSIZE) )
6371 const size_t iend ( ( IsUpper<MT>::value )
6372 ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6376 const size_t ipos( iend &
size_t(-SIMDSIZE) );
6381 ConstIterator_<MT2> right( (~rhs).
begin(j) + ibegin );
6383 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6384 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6385 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6386 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6387 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6389 for( ; i<ipos; i+=SIMDSIZE ) {
6390 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6392 for( ; i<iend; ++i ) {
6393 *left -= *right; ++left; ++right;
6413 template<
typename MT >
6414 template<
typename MT2 >
6415 inline void Submatrix<MT,unaligned,true,true>::subAssign(
const DenseMatrix<MT2,false>& rhs )
6422 constexpr
size_t block( BLOCK_SIZE );
6424 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
6425 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6426 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
6427 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6428 for(
size_t j=jj; j<jend; ++j ) {
6429 for(
size_t i=ii; i<iend; ++i ) {
6430 matrix_(row_+i,column_+j) -= (~rhs)(i,j);
6452 template<
typename MT >
6453 template<
typename MT2 >
6454 inline void Submatrix<MT,unaligned,true,true>::subAssign(
const SparseMatrix<MT2,true>& rhs )
6459 for(
size_t j=0UL; j<
n_; ++j )
6460 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
6461 matrix_(row_+element->index(),column_+j) -= element->value();
6479 template<
typename MT >
6480 template<
typename MT2 >
6481 inline void Submatrix<MT,unaligned,true,true>::subAssign(
const SparseMatrix<MT2,false>& rhs )
6488 for(
size_t i=0UL; i<
m_; ++i )
6489 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
6490 matrix_(row_+i,column_+element->index()) -= element->value();
6508 template<
typename MT >
6509 template<
typename MT2 >
6510 inline DisableIf_< typename Submatrix<MT,unaligned,true,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
6511 Submatrix<MT,unaligned,true,true>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
6516 const size_t ipos( m_ &
size_t(-2) );
6519 for(
size_t j=0UL; j<
n_; ++j ) {
6520 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6521 matrix_(row_+i ,column_+j) *= (~rhs)(i ,j);
6522 matrix_(row_+i+1UL,column_+j) *= (~rhs)(i+1UL,j);
6525 matrix_(row_+ipos,column_+j) *= (~rhs)(ipos,j);
6546 template<
typename MT >
6547 template<
typename MT2 >
6548 inline EnableIf_< typename Submatrix<MT,unaligned,true,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
6549 Submatrix<MT,unaligned,true,true>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
6556 for(
size_t j=0UL; j<
n_; ++j )
6558 const size_t ipos( m_ &
size_t(-SIMDSIZE) );
6563 ConstIterator_<MT2> right( (~rhs).
begin(j) );
6565 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6566 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6567 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6568 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6569 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6571 for( ; i<ipos; i+=SIMDSIZE ) {
6572 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6574 for( ; i<
m_; ++i ) {
6575 *left *= *right; ++left; ++right;
6595 template<
typename MT >
6596 template<
typename MT2 >
6597 inline void Submatrix<MT,unaligned,true,true>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
6604 constexpr
size_t block( BLOCK_SIZE );
6606 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
6607 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6608 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
6609 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6610 for(
size_t j=jj; j<jend; ++j ) {
6611 for(
size_t i=ii; i<iend; ++i ) {
6612 matrix_(row_+i,column_+j) *= (~rhs)(i,j);
6634 template<
typename MT >
6635 template<
typename MT2 >
6636 inline void Submatrix<MT,unaligned,true,true>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
6643 for(
size_t j=0UL; j<
n_; ++j )
6647 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element ) {
6648 for( ; i<element->index(); ++i )
6649 reset( matrix_(row_+i,column_+j) );
6650 matrix_(row_+i,column_+j) *= element->value();
6654 for( ; i<
m_; ++i ) {
6655 reset( matrix_(row_+i,column_+j) );
6675 template<
typename MT >
6676 template<
typename MT2 >
6677 inline void Submatrix<MT,unaligned,true,true>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
6686 for(
size_t i=0UL; i<
m_; ++i )
6690 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element ) {
6691 for( ; j<element->index(); ++j )
6692 reset( matrix_(row_+i,column_+j) );
6693 matrix_(row_+i,column_+j) *= element->value();
6697 for( ; j<
n_; ++j ) {
6698 reset( matrix_(row_+i,column_+j) );
6726 template<
typename MT >
6727 class Submatrix<MT,
aligned,false,true>
6728 :
public View< DenseMatrix< Submatrix<MT,aligned,false,true>, false > >
6733 using Operand = If_< IsExpression<MT>, MT, MT& >;
6738 using This = Submatrix<MT,aligned,false,true>;
6739 using BaseType = DenseMatrix<This,false>;
6743 using ElementType = ElementType_<MT>;
6744 using SIMDType = SIMDTrait_<ElementType>;
6749 using ConstReference = ConstReference_<MT>;
6755 using ConstPointer =
const ElementType*;
6758 using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
6761 using ConstIterator = ConstIterator_<MT>;
6769 enum :
bool { simdEnabled = MT::simdEnabled };
6772 enum :
bool { smpAssignable = MT::smpAssignable };
6778 explicit inline Submatrix( Operand matrix,
size_t rindex,
size_t cindex,
size_t m,
size_t n );
6790 inline Reference operator()(
size_t i,
size_t j );
6791 inline ConstReference operator()(
size_t i,
size_t j )
const;
6792 inline Reference at(
size_t i,
size_t j );
6793 inline ConstReference at(
size_t i,
size_t j )
const;
6794 inline Pointer data () noexcept;
6795 inline ConstPointer data () const noexcept;
6796 inline Pointer data (
size_t i ) noexcept;
6797 inline ConstPointer data (
size_t i ) const noexcept;
6799 inline ConstIterator
begin (
size_t i ) const;
6800 inline ConstIterator
cbegin(
size_t i ) const;
6802 inline ConstIterator
end (
size_t i ) const;
6803 inline ConstIterator
cend (
size_t i ) const;
6810 inline Submatrix& operator=( const ElementType& rhs );
6811 inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
6812 inline Submatrix& operator=( const Submatrix& rhs );
6814 template< typename MT2,
bool SO >
6815 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
6817 template< typename MT2,
bool SO >
6818 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
6819 operator+=( const Matrix<MT2,SO>& rhs );
6821 template< typename MT2,
bool SO >
6822 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
6823 operator+=( const Matrix<MT2,SO>& rhs );
6825 template< typename MT2,
bool SO >
6826 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
6827 operator-=( const Matrix<MT2,SO>& rhs );
6829 template< typename MT2,
bool SO >
6830 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
6831 operator-=( const Matrix<MT2,SO>& rhs );
6833 template< typename MT2,
bool SO >
6834 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
6835 operator%=( const Matrix<MT2,SO>& rhs );
6837 template< typename MT2,
bool SO >
6838 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
6839 operator%=( const Matrix<MT2,SO>& rhs );
6841 template< typename MT2,
bool SO >
6842 inline Submatrix& operator*=( const Matrix<MT2,SO>& rhs );
6844 template< typename Other >
6845 inline
EnableIf_< IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
6847 template< typename Other >
6848 inline
EnableIf_< IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
6855 inline Operand operand() const noexcept;
6856 inline
size_t row() const noexcept;
6857 inline
size_t column() const noexcept;
6858 inline
size_t rows() const noexcept;
6859 inline
size_t columns() const noexcept;
6860 inline
size_t spacing() const noexcept;
6861 inline
size_t capacity() const noexcept;
6862 inline
size_t capacity(
size_t i ) const noexcept;
6864 inline
size_t nonZeros(
size_t i ) const;
6865 inline
void reset();
6866 inline
void reset(
size_t i );
6874 inline Submatrix& ctranspose();
6876 template< typename Other > inline Submatrix& scale( const Other& scalar );
6883 template< typename MT2 >
6884 struct VectorizedAssign {
6885 enum :
bool { value = useOptimizedKernels &&
6886 simdEnabled && MT2::simdEnabled &&
6887 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value };
6893 template<
typename MT2 >
6894 struct VectorizedAddAssign {
6895 enum :
bool { value = useOptimizedKernels &&
6896 simdEnabled && MT2::simdEnabled &&
6897 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
6898 HasSIMDAdd< ElementType, ElementType_<MT2> >::value &&
6899 !IsDiagonal<MT2>::value };
6905 template<
typename MT2 >
6906 struct VectorizedSubAssign {
6907 enum :
bool { value = useOptimizedKernels &&
6908 simdEnabled && MT2::simdEnabled &&
6909 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
6910 HasSIMDSub< ElementType, ElementType_<MT2> >::value &&
6911 !IsDiagonal<MT2>::value };
6917 template<
typename MT2 >
6918 struct VectorizedSchurAssign {
6919 enum :
bool { value = useOptimizedKernels &&
6920 simdEnabled && MT2::simdEnabled &&
6921 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
6922 HasSIMDMult< ElementType, ElementType_<MT2> >::value };
6935 template<
typename Other >
6936 inline bool canAlias(
const Other* alias )
const noexcept;
6938 template<
typename MT2,
bool AF2,
bool SO2 >
6939 inline bool canAlias(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept;
6941 template<
typename Other >
6942 inline bool isAliased(
const Other* alias )
const noexcept;
6944 template<
typename MT2,
bool AF2,
bool SO2 >
6945 inline bool isAliased(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept;
6947 inline bool isAligned () const noexcept;
6948 inline
bool canSMPAssign() const noexcept;
6959 template< typename MT2 >
6960 inline
DisableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,false>& rhs );
6962 template< typename MT2 >
6963 inline
EnableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,false>& rhs );
6965 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,true>& rhs );
6966 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
6967 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
6969 template< typename MT2 >
6970 inline
DisableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,false>& rhs );
6972 template< typename MT2 >
6973 inline
EnableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,false>& rhs );
6975 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,true>& rhs );
6976 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
6977 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
6979 template< typename MT2 >
6980 inline
DisableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,false>& rhs );
6982 template< typename MT2 >
6983 inline
EnableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,false>& rhs );
6985 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,true>& rhs );
6986 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
6987 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
6989 template< typename MT2 >
6990 inline
DisableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,false>& rhs );
6992 template< typename MT2 >
6993 inline
EnableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,false>& rhs );
6995 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,true>& rhs );
6996 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
6997 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
7005 inline
bool hasOverlap() const noexcept;
7014 const
size_t column_;
7021 template< typename MT2,
bool AF2,
bool SO2,
bool DF2 > friend class Submatrix;
7060 template< typename MT >
7061 inline Submatrix<MT,
aligned,false,true>::Submatrix( Operand matrix,
size_t rindex,
size_t cindex,
size_t m,
size_t n )
7068 if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
7072 if( ( simdEnabled && matrix_.data() !=
nullptr && !
checkAlignment( data() ) ) ||
7073 ( m_ > 1UL && matrix_.spacing() % SIMDSIZE != 0UL ) ) {
7100 template<
typename MT >
7102 Submatrix<MT,aligned,false,true>::operator()(
size_t i,
size_t j )
7107 return matrix_(row_+i,column_+j);
7124 template<
typename MT >
7126 Submatrix<MT,aligned,false,true>::operator()(
size_t i,
size_t j )
const 7131 return const_cast<const MT&
>( matrix_ )(row_+i,column_+j);
7149 template<
typename MT >
7151 Submatrix<MT,aligned,false,true>::at(
size_t i,
size_t j )
7159 return (*
this)(i,j);
7177 template<
typename MT >
7179 Submatrix<MT,aligned,false,true>::at(
size_t i,
size_t j )
const 7187 return (*
this)(i,j);
7203 template<
typename MT >
7204 inline typename Submatrix<MT,aligned,false,true>::Pointer
7205 Submatrix<MT,aligned,false,true>::data() noexcept
7207 return matrix_.data() + row_*
spacing() + column_;
7223 template<
typename MT >
7224 inline typename Submatrix<MT,aligned,false,true>::ConstPointer
7225 Submatrix<MT,aligned,false,true>::data() const noexcept
7227 return matrix_.data() + row_*
spacing() + column_;
7242 template<
typename MT >
7243 inline typename Submatrix<MT,aligned,false,true>::Pointer
7244 Submatrix<MT,aligned,false,true>::data(
size_t i ) noexcept
7246 return matrix_.data() + (row_+i)*
spacing() + column_;
7261 template<
typename MT >
7262 inline typename Submatrix<MT,aligned,false,true>::ConstPointer
7263 Submatrix<MT,aligned,false,true>::data(
size_t i )
const noexcept
7265 return matrix_.data() + (row_+i)*
spacing() + column_;
7283 template<
typename MT >
7288 return ( matrix_.begin( row_ + i ) + column_ );
7306 template<
typename MT >
7311 return ( matrix_.cbegin( row_ + i ) + column_ );
7329 template<
typename MT >
7334 return ( matrix_.cbegin( row_ + i ) + column_ );
7352 template<
typename MT >
7357 return ( matrix_.begin( row_ + i ) + column_ +
n_ );
7375 template<
typename MT >
7380 return ( matrix_.cbegin( row_ + i ) + column_ +
n_ );
7398 template<
typename MT >
7403 return ( matrix_.cbegin( row_ + i ) + column_ +
n_ );
7428 template<
typename MT >
7429 inline Submatrix<MT,aligned,false,true>&
7430 Submatrix<MT,aligned,false,true>::operator=(
const ElementType& rhs )
7432 const size_t iend( row_ + m_ );
7434 for(
size_t i=row_; i<iend; ++i )
7436 const size_t jbegin( ( IsUpper<MT>::value )
7437 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
7438 ?(
max( i+1UL, column_ ) )
7439 :(
max( i, column_ ) ) )
7441 const size_t jend ( ( IsLower<MT>::value )
7442 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
7443 ?(
min( i, column_+n_ ) )
7444 :(
min( i+1UL, column_+n_ ) ) )
7447 for(
size_t j=jbegin; j<jend; ++j )
7470 template<
typename MT >
7471 inline Submatrix<MT,aligned,false,true>&
7472 Submatrix<MT,aligned,false,true>::operator=( initializer_list< initializer_list<ElementType> > list )
7480 for(
const auto& rowList : list ) {
7481 std::fill( std::copy( rowList.begin(), rowList.end(),
begin(i) ),
end(i),
ElementType() );
7506 template<
typename MT >
7507 inline Submatrix<MT,aligned,false,true>&
7508 Submatrix<MT,aligned,false,true>::operator=(
const Submatrix& rhs )
7513 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
7516 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
7520 if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
7524 decltype(
auto) left( derestrict( *this ) );
7526 if( rhs.canAlias( &matrix_ ) ) {
7557 template<
typename MT >
7558 template<
typename MT2
7560 inline Submatrix<MT,aligned,false,true>&
7561 Submatrix<MT,aligned,false,true>::operator=(
const Matrix<MT2,SO>& rhs )
7569 using Right = If_< IsRestricted<MT>, CompositeType_<MT2>,
const MT2& >;
7570 Right right( ~rhs );
7572 if( !tryAssign( matrix_, right, row_, column_ ) ) {
7576 if( IsSparseMatrix<MT2>::value ) {
7580 decltype(
auto) left( derestrict( *this ) );
7582 if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
7583 const ResultType_<MT2> tmp( right );
7612 template<
typename MT >
7613 template<
typename MT2
7615 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,false,true>& >
7622 using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
7631 if( !tryAddAssign( matrix_, ~rhs, row_, column_ ) ) {
7635 decltype(
auto) left( derestrict( *this ) );
7637 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
7638 (~rhs).canAlias( &matrix_ ) ) {
7639 const AddType tmp( *
this + (~rhs) );
7668 template<
typename MT >
7669 template<
typename MT2
7671 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,false,true>& >
7678 using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
7687 const AddType tmp( *
this + (~rhs) );
7689 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
7693 decltype(
auto) left( derestrict( *this ) );
7719 template< typename MT >
7720 template< typename MT2
7722 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,false,true>& >
7723 Submatrix<MT,aligned,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
7729 using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
7738 if( !trySubAssign( matrix_, ~rhs, row_, column_ ) ) {
7742 decltype(
auto) left( derestrict( *this ) );
7744 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
7745 (~rhs).canAlias( &matrix_ ) ) {
7746 const SubType tmp( *
this - (~rhs ) );
7775 template<
typename MT >
7776 template<
typename MT2
7778 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,false,true>& >
7785 using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
7794 const SubType tmp( *
this - (~rhs) );
7796 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
7800 decltype(
auto) left( derestrict( *this ) );
7826 template< typename MT >
7827 template< typename MT2
7829 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,false,true>& >
7830 Submatrix<MT,aligned,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
7836 using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
7844 if( !trySchurAssign( matrix_, ~rhs, row_, column_ ) ) {
7848 decltype(
auto) left( derestrict( *this ) );
7850 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
7851 (~rhs).canAlias( &matrix_ ) ) {
7852 const SchurType tmp( *
this % (~rhs) );
7853 if( IsSparseMatrix<SchurType>::value )
7883 template<
typename MT >
7884 template<
typename MT2
7886 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,false,true>& >
7887 Submatrix<MT,aligned,false,true>::operator%=(
const Matrix<MT2,SO>& rhs )
7893 using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
7901 const SchurType tmp( *
this % (~rhs) );
7903 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
7907 if( IsSparseMatrix<SchurType>::value ) {
7911 decltype(
auto) left( derestrict( *this ) );
7937 template< typename MT >
7938 template< typename MT2
7940 inline Submatrix<MT,aligned,false,true>&
7941 Submatrix<MT,aligned,false,true>::operator*=( const Matrix<MT2,SO>& rhs )
7947 using MultType = MultTrait_< ResultType, ResultType_<MT2> >;
7956 const MultType tmp( *
this * (~rhs) );
7958 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
7962 decltype(
auto) left( derestrict( *this ) );
7985 template< typename MT >
7986 template< typename Other >
7987 inline
EnableIf_< IsNumeric<Other>, Submatrix<MT,aligned,false,true> >&
7988 Submatrix<MT,aligned,false,true>::operator*=( Other rhs )
7992 decltype(
auto) left( derestrict( *this ) );
8014 template< typename MT >
8015 template< typename Other >
8016 inline
EnableIf_< IsNumeric<Other>, Submatrix<MT,aligned,false,true> >&
8017 Submatrix<MT,aligned,false,true>::operator/=( Other rhs )
8023 decltype(
auto) left( derestrict( *this ) );
8046 template< typename MT >
8047 inline typename Submatrix<MT,aligned,false,true>::Operand
8048 Submatrix<MT,aligned,false,true>::operand() const noexcept
8062 template<
typename MT >
8077 template<
typename MT >
8092 template<
typename MT >
8107 template<
typename MT >
8127 template<
typename MT >
8130 return matrix_.spacing();
8142 template<
typename MT >
8163 template<
typename MT >
8182 template<
typename MT >
8185 const size_t iend( row_ + m_ );
8186 const size_t jend( column_ + n_ );
8187 size_t nonzeros( 0UL );
8189 for(
size_t i=row_; i<iend; ++i )
8190 for(
size_t j=column_; j<jend; ++j )
8212 template<
typename MT >
8217 const size_t jend( column_ + n_ );
8218 size_t nonzeros( 0UL );
8220 for(
size_t j=column_; j<jend; ++j )
8236 template<
typename MT >
8241 for(
size_t i=row_; i<row_+
m_; ++i )
8243 const size_t jbegin( ( IsUpper<MT>::value )
8244 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
8245 ?(
max( i+1UL, column_ ) )
8246 :(
max( i, column_ ) ) )
8248 const size_t jend ( ( IsLower<MT>::value )
8249 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
8250 ?(
min( i, column_+n_ ) )
8251 :(
min( i+1UL, column_+n_ ) ) )
8254 for(
size_t j=jbegin; j<jend; ++j )
8255 clear( matrix_(i,j) );
8274 template<
typename MT >
8281 const size_t jbegin( ( IsUpper<MT>::value )
8282 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
8283 ?(
max( i+1UL, column_ ) )
8284 :(
max( i, column_ ) ) )
8286 const size_t jend ( ( IsLower<MT>::value )
8287 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
8288 ?(
min( i, column_+n_ ) )
8289 :(
min( i+1UL, column_+n_ ) ) )
8292 for(
size_t j=jbegin; j<jend; ++j )
8293 clear( matrix_(row_+i,j) );
8309 template<
typename MT >
8310 inline bool Submatrix<MT,aligned,false,true>::hasOverlap() const noexcept
8312 BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value,
"Invalid matrix detected" );
8314 if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
8348 template<
typename MT >
8355 if( !tryAssign( matrix_,
trans( *
this ), row_, column_ ) ) {
8359 decltype(
auto) left( derestrict( *this ) );
8387 template< typename MT >
8388 inline Submatrix<MT,aligned,false,true>& Submatrix<MT,aligned,false,true>::ctranspose()
8394 if( !tryAssign( matrix_,
ctrans( *
this ), row_, column_ ) ) {
8398 decltype(
auto) left( derestrict( *this ) );
8421 template< typename MT >
8422 template< typename Other >
8423 inline Submatrix<MT,aligned,false,true>& Submatrix<MT,aligned,false,true>::scale( const Other& scalar )
8427 const size_t iend( row_ + m_ );
8429 for(
size_t i=row_; i<iend; ++i )
8431 const size_t jbegin( ( IsUpper<MT>::value )
8432 ?( ( IsStrictlyUpper<MT>::value )
8433 ?(
max( i+1UL, column_ ) )
8434 :(
max( i, column_ ) ) )
8436 const size_t jend ( ( IsLower<MT>::value )
8437 ?( ( IsStrictlyLower<MT>::value )
8438 ?(
min( i, column_+n_ ) )
8439 :(
min( i+1UL, column_+n_ ) ) )
8442 for(
size_t j=jbegin; j<jend; ++j )
8443 matrix_(i,j) *= scalar;
8471 template<
typename MT >
8472 template<
typename Other >
8473 inline bool Submatrix<MT,aligned,false,true>::canAlias(
const Other* alias )
const noexcept
8475 return matrix_.isAliased( alias );
8492 template<
typename MT >
8493 template<
typename MT2
8496 inline bool Submatrix<MT,aligned,false,true>::canAlias(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept
8498 return ( matrix_.isAliased( &alias->matrix_ ) &&
8499 ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
8500 ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
8517 template<
typename MT >
8518 template<
typename Other >
8519 inline bool Submatrix<MT,aligned,false,true>::isAliased(
const Other* alias )
const noexcept
8521 return matrix_.isAliased( alias );
8538 template<
typename MT >
8539 template<
typename MT2
8542 inline bool Submatrix<MT,aligned,false,true>::isAliased(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept
8544 return ( matrix_.isAliased( &alias->matrix_ ) &&
8545 ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
8546 ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
8562 template<
typename MT >
8563 inline bool Submatrix<MT,aligned,false,true>::isAligned() const noexcept
8582 template<
typename MT >
8583 inline bool Submatrix<MT,aligned,false,true>::canSMPAssign() const noexcept
8585 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
8607 template<
typename MT >
8609 Submatrix<MT,aligned,false,true>::load(
size_t i,
size_t j )
const noexcept
8611 return loada( i, j );
8633 template<
typename MT >
8644 return matrix_.loada( row_+i, column_+j );
8666 template<
typename MT >
8677 return matrix_.loadu( row_+i, column_+j );
8700 template<
typename MT >
8702 Submatrix<MT,aligned,false,true>::store(
size_t i,
size_t j,
const SIMDType& value ) noexcept
8704 return storea( i, j, value );
8727 template<
typename MT >
8738 return matrix_.storea( row_+i, column_+j, value );
8761 template<
typename MT >
8772 matrix_.storeu( row_+i, column_+j, value );
8796 template<
typename MT >
8807 matrix_.stream( row_+i, column_+j, value );
8825 template<
typename MT >
8826 template<
typename MT2 >
8827 inline DisableIf_< typename Submatrix<MT,aligned,false,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
8828 Submatrix<MT,aligned,false,true>::assign(
const DenseMatrix<MT2,false>& rhs )
8833 const size_t jpos( n_ &
size_t(-2) );
8836 for(
size_t i=0UL; i<
m_; ++i ) {
8837 for(
size_t j=0UL; j<jpos; j+=2UL ) {
8838 matrix_(row_+i,column_+j ) = (~rhs)(i,j );
8839 matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
8842 matrix_(row_+i,column_+jpos) = (~rhs)(i,jpos);
8862 template<
typename MT >
8863 template<
typename MT2 >
8864 inline EnableIf_< typename Submatrix<MT,aligned,false,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
8865 Submatrix<MT,aligned,false,true>::assign(
const DenseMatrix<MT2,false>& rhs )
8872 const size_t jpos( n_ &
size_t(-SIMDSIZE) );
8876 m_*n_ > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
8877 !(~rhs).isAliased( &matrix_ ) )
8879 for(
size_t i=0UL; i<
m_; ++i )
8883 ConstIterator_<MT2> right( (~rhs).
begin(i) );
8885 for( ; j<jpos; j+=SIMDSIZE ) {
8886 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8888 for( ; j<
n_; ++j ) {
8889 *left = *right; ++left; ++right;
8895 for(
size_t i=0UL; i<
m_; ++i )
8899 ConstIterator_<MT2> right( (~rhs).
begin(i) );
8901 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
8902 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8903 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8904 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8905 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8907 for( ; j<jpos; j+=SIMDSIZE ) {
8908 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
8910 for( ; j<
n_; ++j ) {
8911 *left = *right; ++left; ++right;
8932 template<
typename MT >
8933 template<
typename MT2 >
8934 inline void Submatrix<MT,aligned,false,true>::assign(
const DenseMatrix<MT2,true>& rhs )
8941 constexpr
size_t block( BLOCK_SIZE );
8943 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
8944 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8945 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
8946 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8947 for(
size_t i=ii; i<iend; ++i ) {
8948 for(
size_t j=jj; j<jend; ++j ) {
8949 matrix_(row_+i,column_+j) = (~rhs)(i,j);
8971 template<
typename MT >
8972 template<
typename MT2 >
8973 inline void Submatrix<MT,aligned,false,true>::assign(
const SparseMatrix<MT2,false>& rhs )
8978 for(
size_t i=0UL; i<
m_; ++i )
8979 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
8980 matrix_(row_+i,column_+element->index()) = element->value();
8998 template<
typename MT >
8999 template<
typename MT2 >
9000 inline void Submatrix<MT,aligned,false,true>::assign(
const SparseMatrix<MT2,true>& rhs )
9007 for(
size_t j=0UL; j<
n_; ++j )
9008 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
9009 matrix_(row_+element->index(),column_+j) = element->value();
9027 template<
typename MT >
9028 template<
typename MT2 >
9029 inline DisableIf_< typename Submatrix<MT,aligned,false,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
9030 Submatrix<MT,aligned,false,true>::addAssign(
const DenseMatrix<MT2,false>& rhs )
9035 const size_t jpos( n_ &
size_t(-2) );
9038 for(
size_t i=0UL; i<
m_; ++i )
9040 if( IsDiagonal<MT2>::value ) {
9041 matrix_(row_+i,column_+i) += (~rhs)(i,i);
9044 for(
size_t j=0UL; j<jpos; j+=2UL ) {
9045 matrix_(row_+i,column_+j ) += (~rhs)(i,j );
9046 matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
9049 matrix_(row_+i,column_+jpos) += (~rhs)(i,jpos);
9070 template<
typename MT >
9071 template<
typename MT2 >
9072 inline EnableIf_< typename Submatrix<MT,aligned,false,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
9073 Submatrix<MT,aligned,false,true>::addAssign(
const DenseMatrix<MT2,false>& rhs )
9080 for(
size_t i=0UL; i<
m_; ++i )
9082 const size_t jbegin( ( IsUpper<MT2>::value )
9083 ?( ( IsStrictlyUpper<MT2>::value ? i+1UL : i ) &
size_t(-SIMDSIZE) )
9085 const size_t jend ( ( IsLower<MT2>::value )
9086 ?( IsStrictlyLower<MT2>::value ? i : i+1UL )
9090 const size_t jpos( jend &
size_t(-SIMDSIZE) );
9095 ConstIterator_<MT2> right( (~rhs).
begin(i) + jbegin );
9097 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
9098 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9099 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9100 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9101 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9103 for( ; j<jpos; j+=SIMDSIZE ) {
9104 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9106 for( ; j<jend; ++j ) {
9107 *left += *right; ++left; ++right;
9127 template<
typename MT >
9128 template<
typename MT2 >
9129 inline void Submatrix<MT,aligned,false,true>::addAssign(
const DenseMatrix<MT2,true>& rhs )
9136 constexpr
size_t block( BLOCK_SIZE );
9138 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
9139 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
9140 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
9141 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
9142 for(
size_t i=ii; i<iend; ++i ) {
9143 for(
size_t j=jj; j<jend; ++j ) {
9144 matrix_(row_+i,column_+j) += (~rhs)(i,j);
9166 template<
typename MT >
9167 template<
typename MT2 >
9168 inline void Submatrix<MT,aligned,false,true>::addAssign(
const SparseMatrix<MT2,false>& rhs )
9173 for(
size_t i=0UL; i<
m_; ++i )
9174 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
9175 matrix_(row_+i,column_+element->index()) += element->value();
9193 template<
typename MT >
9194 template<
typename MT2 >
9195 inline void Submatrix<MT,aligned,false,true>::addAssign(
const SparseMatrix<MT2,true>& rhs )
9202 for(
size_t j=0UL; j<
n_; ++j )
9203 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
9204 matrix_(row_+element->index(),column_+j) += element->value();
9222 template<
typename MT >
9223 template<
typename MT2 >
9224 inline DisableIf_< typename Submatrix<MT,aligned,false,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
9225 Submatrix<MT,aligned,false,true>::subAssign(
const DenseMatrix<MT2,false>& rhs )
9230 const size_t jpos( n_ &
size_t(-2) );
9233 for(
size_t i=0UL; i<
m_; ++i )
9235 if( IsDiagonal<MT2>::value ) {
9236 matrix_(row_+i,column_+i) -= (~rhs)(i,i);
9239 for(
size_t j=0UL; j<jpos; j+=2UL ) {
9240 matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
9241 matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
9244 matrix_(row_+i,column_+jpos) -= (~rhs)(i,jpos);
9265 template<
typename MT >
9266 template<
typename MT2 >
9267 inline EnableIf_< typename Submatrix<MT,aligned,false,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
9268 Submatrix<MT,aligned,false,true>::subAssign(
const DenseMatrix<MT2,false>& rhs )
9275 for(
size_t i=0UL; i<
m_; ++i )
9277 const size_t jbegin( ( IsUpper<MT2>::value )
9278 ?( ( IsStrictlyUpper<MT2>::value ? i+1UL : i ) &
size_t(-SIMDSIZE) )
9280 const size_t jend ( ( IsLower<MT2>::value )
9281 ?( IsStrictlyLower<MT2>::value ? i : i+1UL )
9285 const size_t jpos( jend &
size_t(-SIMDSIZE) );
9290 ConstIterator_<MT2> right( (~rhs).
begin(i) + jbegin );
9292 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
9293 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9294 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9295 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9296 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9298 for( ; j<jpos; j+=SIMDSIZE ) {
9299 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9301 for( ; j<jend; ++j ) {
9302 *left -= *right; ++left; ++right;
9322 template<
typename MT >
9323 template<
typename MT2 >
9324 inline void Submatrix<MT,aligned,false,true>::subAssign(
const DenseMatrix<MT2,true>& rhs )
9331 constexpr
size_t block( BLOCK_SIZE );
9333 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
9334 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
9335 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
9336 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
9337 for(
size_t i=ii; i<iend; ++i ) {
9338 for(
size_t j=jj; j<jend; ++j ) {
9339 matrix_(row_+i,column_+j) -= (~rhs)(i,j);
9361 template<
typename MT >
9362 template<
typename MT2 >
9363 inline void Submatrix<MT,aligned,false,true>::subAssign(
const SparseMatrix<MT2,false>& rhs )
9368 for(
size_t i=0UL; i<
m_; ++i )
9369 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
9370 matrix_(row_+i,column_+element->index()) -= element->value();
9388 template<
typename MT >
9389 template<
typename MT2 >
9390 inline void Submatrix<MT,aligned,false,true>::subAssign(
const SparseMatrix<MT2,true>& rhs )
9397 for(
size_t j=0UL; j<
n_; ++j )
9398 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
9399 matrix_(row_+element->index(),column_+j) -= element->value();
9417 template<
typename MT >
9418 template<
typename MT2 >
9419 inline DisableIf_< typename Submatrix<MT,aligned,false,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
9420 Submatrix<MT,aligned,false,true>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
9425 const size_t jpos( n_ &
size_t(-2) );
9428 for(
size_t i=0UL; i<
m_; ++i ) {
9429 for(
size_t j=0UL; j<jpos; j+=2UL ) {
9430 matrix_(row_+i,column_+j ) *= (~rhs)(i,j );
9431 matrix_(row_+i,column_+j+1UL) *= (~rhs)(i,j+1UL);
9434 matrix_(row_+i,column_+jpos) *= (~rhs)(i,jpos);
9454 template<
typename MT >
9455 template<
typename MT2 >
9456 inline EnableIf_< typename Submatrix<MT,aligned,false,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
9457 Submatrix<MT,aligned,false,true>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
9464 for(
size_t i=0UL; i<
m_; ++i )
9466 const size_t jpos( n_ &
size_t(-SIMDSIZE) );
9471 ConstIterator_<MT2> right( (~rhs).
begin(i) );
9473 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
9474 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9475 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9476 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9477 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9479 for( ; j<jpos; j+=SIMDSIZE ) {
9480 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
9482 for( ; j<
n_; ++j ) {
9483 *left *= *right; ++left; ++right;
9503 template<
typename MT >
9504 template<
typename MT2 >
9505 inline void Submatrix<MT,aligned,false,true>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
9512 constexpr
size_t block( BLOCK_SIZE );
9514 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
9515 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
9516 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
9517 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
9518 for(
size_t i=ii; i<iend; ++i ) {
9519 for(
size_t j=jj; j<jend; ++j ) {
9520 matrix_(row_+i,column_+j) *= (~rhs)(i,j);
9542 template<
typename MT >
9543 template<
typename MT2 >
9544 inline void Submatrix<MT,aligned,false,true>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
9551 for(
size_t i=0UL; i<
m_; ++i )
9555 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element ) {
9556 for( ; j<element->index(); ++j )
9557 reset( matrix_(row_+i,column_+j) );
9558 matrix_(row_+i,column_+j) *= element->value();
9562 for( ; j<
n_; ++j ) {
9563 reset( matrix_(row_+i,column_+j) );
9583 template<
typename MT >
9584 template<
typename MT2 >
9585 inline void Submatrix<MT,aligned,false,true>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
9594 for(
size_t j=0UL; j<
n_; ++j )
9598 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element ) {
9599 for( ; i<element->index(); ++i )
9600 reset( matrix_(row_+i,column_+j) );
9601 matrix_(row_+element->index(),column_+j) *= element->value();
9605 for( ; i<
m_; ++i ) {
9606 reset( matrix_(row_+i,column_+j) );
9634 template<
typename MT >
9635 class Submatrix<MT,aligned,true,true>
9636 :
public View< DenseMatrix< Submatrix<MT,aligned,true,true>, true > >
9641 using Operand = If_< IsExpression<MT>, MT, MT& >;
9646 using This = Submatrix<MT,aligned,true,true>;
9647 using BaseType = DenseMatrix<This,true>;
9651 using ElementType = ElementType_<MT>;
9652 using SIMDType = SIMDTrait_<ElementType>;
9657 using ConstReference = ConstReference_<MT>;
9663 using ConstPointer =
const ElementType*;
9666 using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
9669 using ConstIterator = ConstIterator_<MT>;
9677 enum :
bool { simdEnabled = MT::simdEnabled };
9680 enum :
bool { smpAssignable = MT::smpAssignable };
9686 explicit inline Submatrix( Operand matrix,
size_t rindex,
size_t cindex,
size_t m,
size_t n );
9698 inline Reference operator()(
size_t i,
size_t j );
9699 inline ConstReference operator()(
size_t i,
size_t j )
const;
9700 inline Reference at(
size_t i,
size_t j );
9701 inline ConstReference at(
size_t i,
size_t j )
const;
9702 inline Pointer data () noexcept;
9703 inline ConstPointer data () const noexcept;
9704 inline Pointer data (
size_t j ) noexcept;
9705 inline ConstPointer data (
size_t j ) const noexcept;
9707 inline ConstIterator
begin (
size_t j ) const;
9708 inline ConstIterator
cbegin(
size_t j ) const;
9710 inline ConstIterator
end (
size_t j ) const;
9711 inline ConstIterator
cend (
size_t j ) const;
9718 inline Submatrix& operator=( const ElementType& rhs );
9719 inline Submatrix& operator=( initializer_list< initializer_list<ElementType> > list );
9720 inline Submatrix& operator=( const Submatrix& rhs );
9722 template< typename MT2,
bool SO >
9723 inline Submatrix& operator=( const Matrix<MT2,SO>& rhs );
9725 template< typename MT2,
bool SO >
9726 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
9727 operator+=( const Matrix<MT2,SO>& rhs );
9729 template< typename MT2,
bool SO >
9730 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
9731 operator+=( const Matrix<MT2,SO>& rhs );
9733 template< typename MT2,
bool SO >
9734 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
9735 operator-=( const Matrix<MT2,SO>& rhs );
9737 template< typename MT2,
bool SO >
9738 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
9739 operator-=( const Matrix<MT2,SO>& rhs );
9741 template< typename MT2,
bool SO >
9742 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
9743 operator%=( const Matrix<MT2,SO>& rhs );
9745 template< typename MT2,
bool SO >
9746 inline
EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix& >
9747 operator%=( const Matrix<MT2,SO>& rhs );
9749 template< typename MT2,
bool SO >
9750 inline Submatrix& operator*=( const Matrix<MT2,SO>& rhs );
9752 template< typename Other >
9753 inline
EnableIf_< IsNumeric<Other>, Submatrix >& operator*=( Other rhs );
9755 template< typename Other >
9756 inline
EnableIf_< IsNumeric<Other>, Submatrix >& operator/=( Other rhs );
9763 inline Operand operand() const noexcept;
9764 inline
size_t row() const noexcept;
9765 inline
size_t column() const noexcept;
9766 inline
size_t rows() const noexcept;
9767 inline
size_t columns() const noexcept;
9768 inline
size_t spacing() const noexcept;
9769 inline
size_t capacity() const noexcept;
9770 inline
size_t capacity(
size_t i ) const noexcept;
9772 inline
size_t nonZeros(
size_t i ) const;
9773 inline
void reset();
9774 inline
void reset(
size_t i );
9782 inline Submatrix& ctranspose();
9784 template< typename Other > inline Submatrix& scale( const Other& scalar );
9791 template< typename MT2 >
9792 struct VectorizedAssign {
9793 enum :
bool { value = useOptimizedKernels &&
9794 simdEnabled && MT2::simdEnabled &&
9795 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value };
9801 template<
typename MT2 >
9802 struct VectorizedAddAssign {
9803 enum :
bool { value = useOptimizedKernels &&
9804 simdEnabled && MT2::simdEnabled &&
9805 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
9806 HasSIMDAdd< ElementType, ElementType_<MT2> >::value &&
9807 !IsDiagonal<MT2>::value };
9813 template<
typename MT2 >
9814 struct VectorizedSubAssign {
9815 enum :
bool { value = useOptimizedKernels &&
9816 simdEnabled && MT2::simdEnabled &&
9817 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
9818 HasSIMDSub< ElementType, ElementType_<MT2> >::value &&
9819 !IsDiagonal<MT2>::value };
9825 template<
typename MT2 >
9826 struct VectorizedSchurAssign {
9827 enum :
bool { value = useOptimizedKernels &&
9828 simdEnabled && MT2::simdEnabled &&
9829 IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
9830 HasSIMDMult< ElementType, ElementType_<MT2> >::value };
9843 template<
typename Other >
9844 inline bool canAlias(
const Other* alias )
const noexcept;
9846 template<
typename MT2,
bool AF2,
bool SO2 >
9847 inline bool canAlias(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept;
9849 template<
typename Other >
9850 inline bool isAliased(
const Other* alias )
const noexcept;
9852 template<
typename MT2,
bool AF2,
bool SO2 >
9853 inline bool isAliased(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept;
9855 inline bool isAligned () const noexcept;
9856 inline
bool canSMPAssign() const noexcept;
9867 template< typename MT2 >
9868 inline
DisableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,true>& rhs );
9870 template< typename MT2 >
9871 inline
EnableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,true>& rhs );
9873 template< typename MT2 > inline
void assign( const DenseMatrix<MT2,false>& rhs );
9874 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,true>& rhs );
9875 template< typename MT2 > inline
void assign( const SparseMatrix<MT2,false>& rhs );
9877 template< typename MT2 >
9878 inline
DisableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,true>& rhs );
9880 template< typename MT2 >
9881 inline
EnableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,true>& rhs );
9883 template< typename MT2 > inline
void addAssign( const DenseMatrix<MT2,false>& rhs );
9884 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,true>& rhs );
9885 template< typename MT2 > inline
void addAssign( const SparseMatrix<MT2,false>& rhs );
9887 template< typename MT2 >
9888 inline
DisableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,true>& rhs );
9890 template< typename MT2 >
9891 inline
EnableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,true>& rhs );
9893 template< typename MT2 > inline
void subAssign( const DenseMatrix<MT2,false>& rhs );
9894 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,true>& rhs );
9895 template< typename MT2 > inline
void subAssign( const SparseMatrix<MT2,false>& rhs );
9897 template< typename MT2 >
9898 inline
DisableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,true>& rhs );
9900 template< typename MT2 >
9901 inline
EnableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,true>& rhs );
9903 template< typename MT2 > inline
void schurAssign( const DenseMatrix<MT2,false>& rhs );
9904 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,true>& rhs );
9905 template< typename MT2 > inline
void schurAssign( const SparseMatrix<MT2,false>& rhs );
9913 inline
bool hasOverlap() const noexcept;
9922 const
size_t column_;
9929 template< typename MT2,
bool AF2,
bool SO2,
bool DF2 > friend class Submatrix;
9968 template< typename MT >
9969 inline Submatrix<MT,aligned,true,true>::Submatrix( Operand matrix,
size_t rindex,
size_t cindex,
size_t m,
size_t n )
9976 if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
9980 if( ( simdEnabled && matrix_.data() !=
nullptr && !
checkAlignment( data() ) ) ||
9981 ( n_ > 1UL && matrix_.spacing() % SIMDSIZE != 0UL ) ) {
10008 template<
typename MT >
10010 Submatrix<MT,aligned,true,true>::operator()(
size_t i,
size_t j )
10015 return matrix_(row_+i,column_+j);
10032 template<
typename MT >
10034 Submatrix<MT,aligned,true,true>::operator()(
size_t i,
size_t j )
const 10039 return const_cast<const MT&
>( matrix_ )(row_+i,column_+j);
10057 template<
typename MT >
10059 Submatrix<MT,aligned,true,true>::at(
size_t i,
size_t j )
10061 if( i >=
rows() ) {
10067 return (*
this)(i,j);
10085 template<
typename MT >
10087 Submatrix<MT,aligned,true,true>::at(
size_t i,
size_t j )
const 10089 if( i >=
rows() ) {
10095 return (*
this)(i,j);
10111 template<
typename MT >
10112 inline typename Submatrix<MT,aligned,true,true>::Pointer
10113 Submatrix<MT,aligned,true,true>::data() noexcept
10115 return matrix_.data() + row_ + column_*
spacing();
10131 template<
typename MT >
10132 inline typename Submatrix<MT,aligned,true,true>::ConstPointer
10133 Submatrix<MT,aligned,true,true>::data() const noexcept
10135 return matrix_.data() + row_ + column_*
spacing();
10150 template<
typename MT >
10151 inline typename Submatrix<MT,aligned,true,true>::Pointer
10152 Submatrix<MT,aligned,true,true>::data(
size_t j ) noexcept
10154 return matrix_.data() + row_ + (column_+j)*
spacing();
10169 template<
typename MT >
10170 inline typename Submatrix<MT,aligned,true,true>::ConstPointer
10171 Submatrix<MT,aligned,true,true>::data(
size_t j )
const noexcept
10173 return matrix_.data() + row_ + (column_+j)*
spacing();
10186 template<
typename MT >
10191 return ( matrix_.begin( column_ + j ) + row_ );
10204 template<
typename MT >
10209 return ( matrix_.cbegin( column_ + j ) + row_ );
10222 template<
typename MT >
10227 return ( matrix_.cbegin( column_ + j ) + row_ );
10240 template<
typename MT >
10245 return ( matrix_.begin( column_ + j ) + row_ +
m_ );
10258 template<
typename MT >
10263 return ( matrix_.cbegin( column_ + j ) + row_ +
m_ );
10276 template<
typename MT >
10281 return ( matrix_.cbegin( column_ + j ) + row_ +
m_ );
10306 template<
typename MT >
10307 inline Submatrix<MT,aligned,true,true>&
10308 Submatrix<MT,aligned,true,true>::operator=(
const ElementType& rhs )
10310 const size_t jend( column_ + n_ );
10312 for(
size_t j=column_; j<jend; ++j )
10314 const size_t ibegin( ( IsLower<MT>::value )
10315 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
10316 ?(
max( j+1UL, row_ ) )
10317 :(
max( j, row_ ) ) )
10319 const size_t iend ( ( IsUpper<MT>::value )
10320 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
10321 ?(
min( j, row_+m_ ) )
10322 :(
min( j+1UL, row_+m_ ) ) )
10325 for(
size_t i=ibegin; i<iend; ++i )
10326 matrix_(i,j) = rhs;
10348 template<
typename MT >
10349 inline Submatrix<MT,aligned,true,true>&
10350 Submatrix<MT,aligned,true,true>::operator=( initializer_list< initializer_list<ElementType> > list )
10358 for(
const auto& rowList : list ) {
10360 for(
const auto& element : rowList ) {
10361 matrix_(row_+i,column_+j) = element;
10364 for( ; j<
n_; ++j ) {
10391 template<
typename MT >
10392 inline Submatrix<MT,aligned,true,true>&
10393 Submatrix<MT,aligned,true,true>::operator=(
const Submatrix& rhs )
10398 if(
this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
10401 if(
rows() != rhs.rows() ||
columns() != rhs.columns() ) {
10405 if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
10409 decltype(
auto) left( derestrict( *this ) );
10411 if( rhs.canAlias( &matrix_ ) ) {
10441 template<
typename MT >
10442 template<
typename MT2
10444 inline Submatrix<MT,aligned,true,true>&
10445 Submatrix<MT,aligned,true,true>::operator=(
const Matrix<MT2,SO>& rhs )
10453 using Right = If_< IsRestricted<MT>, CompositeType_<MT2>,
const MT2& >;
10454 Right right( ~rhs );
10456 if( !tryAssign( matrix_, right, row_, column_ ) ) {
10460 if( IsSparseMatrix<MT2>::value ) {
10464 decltype(
auto) left( derestrict( *this ) );
10466 if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
10467 const ResultType_<MT2> tmp( right );
10496 template<
typename MT >
10497 template<
typename MT2
10499 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,true,true>& >
10506 using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
10515 if( !tryAddAssign( matrix_, ~rhs, row_, column_ ) ) {
10519 decltype(
auto) left( derestrict( *this ) );
10521 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
10522 (~rhs).canAlias( &matrix_ ) ) {
10523 const AddType tmp( *
this + (~rhs) );
10552 template<
typename MT >
10553 template<
typename MT2
10555 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,true,true>& >
10562 using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
10571 const AddType tmp( *
this + (~rhs) );
10573 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
10577 decltype(
auto) left( derestrict( *this ) );
10603 template< typename MT >
10604 template< typename MT2
10606 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,true,true>& >
10607 Submatrix<MT,aligned,true,true>::operator-=( const Matrix<MT2,SO>& rhs )
10613 using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
10622 if( !trySubAssign( matrix_, ~rhs, row_, column_ ) ) {
10626 decltype(
auto) left( derestrict( *this ) );
10628 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
10629 (~rhs).canAlias( &matrix_ ) ) {
10630 const SubType tmp( *
this - (~rhs ) );
10659 template<
typename MT >
10660 template<
typename MT2
10662 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,true,true>& >
10669 using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
10678 const SubType tmp( *
this - (~rhs) );
10680 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
10684 decltype(
auto) left( derestrict( *this ) );
10710 template< typename MT >
10711 template< typename MT2
10713 inline
DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,true,true>& >
10714 Submatrix<MT,aligned,true,true>::operator%=( const Matrix<MT2,SO>& rhs )
10720 using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
10728 if( !trySchurAssign( matrix_, ~rhs, row_, column_ ) ) {
10732 decltype(
auto) left( derestrict( *this ) );
10734 if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
10735 (~rhs).canAlias( &matrix_ ) ) {
10736 const SchurType tmp( *
this % (~rhs) );
10737 if( IsSparseMatrix<SchurType>::value )
10767 template<
typename MT >
10768 template<
typename MT2
10770 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Submatrix<MT,aligned,true,true>& >
10771 Submatrix<MT,aligned,true,true>::operator%=(
const Matrix<MT2,SO>& rhs )
10777 using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
10785 const SchurType tmp( *
this % (~rhs) );
10787 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
10791 if( IsSparseMatrix<SchurType>::value ) {
10795 decltype(
auto) left( derestrict( *this ) );
10821 template< typename MT >
10822 template< typename MT2
10824 inline Submatrix<MT,aligned,true,true>&
10825 Submatrix<MT,aligned,true,true>::operator*=( const Matrix<MT2,SO>& rhs )
10831 using MultType = MultTrait_< ResultType, ResultType_<MT2> >;
10840 const MultType tmp( *
this * (~rhs) );
10842 if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
10846 decltype(
auto) left( derestrict( *this ) );
10869 template< typename MT >
10870 template< typename Other >
10871 inline
EnableIf_< IsNumeric<Other>, Submatrix<MT,aligned,true,true> >&
10872 Submatrix<MT,aligned,true,true>::operator*=( Other rhs )
10876 decltype(
auto) left( derestrict( *this ) );
10898 template< typename MT >
10899 template< typename Other >
10900 inline
EnableIf_< IsNumeric<Other>, Submatrix<MT,aligned,true,true> >&
10901 Submatrix<MT,aligned,true,true>::operator/=( Other rhs )
10907 decltype(
auto) left( derestrict( *this ) );
10930 template< typename MT >
10931 inline typename Submatrix<MT,aligned,true,true>::Operand
10932 Submatrix<MT,aligned,true,true>::operand() const noexcept
10946 template<
typename MT >
10961 template<
typename MT >
10976 template<
typename MT >
10991 template<
typename MT >
11009 template<
typename MT >
11012 return matrix_.spacing();
11024 template<
typename MT >
11040 template<
typename MT >
11059 template<
typename MT >
11062 const size_t iend( row_ + m_ );
11063 const size_t jend( column_ + n_ );
11064 size_t nonzeros( 0UL );
11066 for(
size_t j=column_; j<jend; ++j )
11067 for(
size_t i=row_; i<iend; ++i )
11084 template<
typename MT >
11089 const size_t iend( row_ + m_ );
11090 size_t nonzeros( 0UL );
11092 for(
size_t i=row_; i<iend; ++i )
11093 if( !
isDefault( matrix_(i,column_+j) ) )
11108 template<
typename MT >
11113 for(
size_t j=column_; j<column_+
n_; ++j )
11115 const size_t ibegin( ( IsLower<MT>::value )
11116 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
11117 ?(
max( j+1UL, row_ ) )
11118 :(
max( j, row_ ) ) )
11120 const size_t iend ( ( IsUpper<MT>::value )
11121 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
11122 ?(
min( j, row_+m_ ) )
11123 :(
min( j+1UL, row_+m_ ) ) )
11126 for(
size_t i=ibegin; i<iend; ++i )
11127 clear( matrix_(i,j) );
11141 template<
typename MT >
11148 const size_t ibegin( ( IsLower<MT>::value )
11149 ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
11150 ?(
max( j+1UL, row_ ) )
11151 :(
max( j, row_ ) ) )
11153 const size_t iend ( ( IsUpper<MT>::value )
11154 ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
11155 ?(
min( j, row_+m_ ) )
11156 :(
min( j+1UL, row_+m_ ) ) )
11159 for(
size_t i=ibegin; i<iend; ++i )
11160 clear( matrix_(i,column_+j) );
11176 template<
typename MT >
11177 inline bool Submatrix<MT,aligned,true,true>::hasOverlap() const noexcept
11179 BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value,
"Invalid matrix detected" );
11181 if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
11215 template<
typename MT >
11222 if( !tryAssign( matrix_,
trans( *
this ), row_, column_ ) ) {
11226 decltype(
auto) left( derestrict( *this ) );
11254 template< typename MT >
11255 inline Submatrix<MT,aligned,true,true>& Submatrix<MT,aligned,true,true>::ctranspose()
11261 if( !tryAssign( matrix_,
ctrans( *
this ), row_, column_ ) ) {
11265 decltype(
auto) left( derestrict( *this ) );
11288 template< typename MT >
11289 template< typename Other >
11290 inline Submatrix<MT,aligned,true,true>& Submatrix<MT,aligned,true,true>::scale( const Other& scalar )
11294 const size_t jend( column_ + n_ );
11296 for(
size_t j=column_; j<jend; ++j )
11298 const size_t ibegin( ( IsLower<MT>::value )
11299 ?( ( IsStrictlyLower<MT>::value )
11300 ?(
max( j+1UL, row_ ) )
11301 :(
max( j, row_ ) ) )
11303 const size_t iend ( ( IsUpper<MT>::value )
11304 ?( ( IsStrictlyUpper<MT>::value )
11305 ?(
min( j, row_+m_ ) )
11306 :(
min( j+1UL, row_+m_ ) ) )
11309 for(
size_t i=ibegin; i<iend; ++i )
11310 matrix_(i,j) *= scalar;
11338 template<
typename MT >
11339 template<
typename Other >
11340 inline bool Submatrix<MT,aligned,true,true>::canAlias(
const Other* alias )
const noexcept
11342 return matrix_.isAliased( alias );
11359 template<
typename MT >
11360 template<
typename MT2
11363 inline bool Submatrix<MT,aligned,true,true>::canAlias(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept
11365 return ( matrix_.isAliased( &alias->matrix_ ) &&
11366 ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
11367 ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
11384 template<
typename MT >
11385 template<
typename Other >
11386 inline bool Submatrix<MT,aligned,true,true>::isAliased(
const Other* alias )
const noexcept
11388 return matrix_.isAliased( alias );
11405 template<
typename MT >
11406 template<
typename MT2
11409 inline bool Submatrix<MT,aligned,true,true>::isAliased(
const Submatrix<MT2,AF2,SO2,true>* alias )
const noexcept
11411 return ( matrix_.isAliased( &alias->matrix_ ) &&
11412 ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
11413 ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
11429 template<
typename MT >
11430 inline bool Submatrix<MT,aligned,true,true>::isAligned() const noexcept
11449 template<
typename MT >
11450 inline bool Submatrix<MT,aligned,true,true>::canSMPAssign() const noexcept
11452 return (
rows() *
columns() >= SMP_DMATASSIGN_THRESHOLD );
11473 template<
typename MT >
11475 Submatrix<MT,aligned,true,true>::load(
size_t i,
size_t j )
const noexcept
11477 return loada( i, j );
11498 template<
typename MT >
11509 return matrix_.loada( row_+i, column_+j );
11530 template<
typename MT >
11541 return matrix_.loadu( row_+i, column_+j );
11563 template<
typename MT >
11565 Submatrix<MT,aligned,true,true>::store(
size_t i,
size_t j,
const SIMDType& value ) noexcept
11589 template<
typename MT >
11600 matrix_.storea( row_+i, column_+j, value );
11622 template<
typename MT >
11633 matrix_.storeu( row_+i, column_+j, value );
11656 template<
typename MT >
11667 matrix_.stream( row_+i, column_+j, value );
11685 template<
typename MT >
11686 template<
typename MT2 >
11687 inline DisableIf_< typename Submatrix<MT,aligned,true,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
11688 Submatrix<MT,aligned,true,true>::assign(
const DenseMatrix<MT2,true>& rhs )
11693 const size_t ipos( m_ &
size_t(-2) );
11696 for(
size_t j=0UL; j<
n_; ++j ) {
11697 for(
size_t i=0UL; i<ipos; i+=2UL ) {
11698 matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
11699 matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
11702 matrix_(row_+ipos,column_+j) = (~rhs)(ipos,j);
11722 template<
typename MT >
11723 template<
typename MT2 >
11724 inline EnableIf_< typename Submatrix<MT,aligned,true,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
11725 Submatrix<MT,aligned,true,true>::assign(
const DenseMatrix<MT2,true>& rhs )
11732 const size_t ipos( m_ &
size_t(-SIMDSIZE) );
11735 if( useStreaming &&
11736 m_*n_ > ( cacheSize / (
sizeof(ElementType) * 3UL ) ) &&
11737 !(~rhs).isAliased( &matrix_ ) )
11739 for(
size_t j=0UL; j<
n_; ++j )
11743 ConstIterator_<MT2> right( (~rhs).
begin(j) );
11745 for( ; i<ipos; i+=SIMDSIZE ) {
11746 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11748 for( ; i<
m_; ++i ) {
11749 *left = *right; ++left; ++right;
11755 for(
size_t j=0UL; j<
n_; ++j )
11759 ConstIterator_<MT2> right( (~rhs).
begin(j) );
11761 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
11762 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11763 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11764 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11765 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11767 for( ; i<ipos; i+=SIMDSIZE ) {
11768 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11770 for( ; i<
m_; ++i ) {
11771 *left = *right; ++left; ++right;
11792 template<
typename MT >
11793 template<
typename MT2 >
11794 inline void Submatrix<MT,aligned,true,true>::assign(
const DenseMatrix<MT2,false>& rhs )
11801 constexpr
size_t block( BLOCK_SIZE );
11803 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
11804 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
11805 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
11806 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
11807 for(
size_t j=jj; j<jend; ++j ) {
11808 for(
size_t i=ii; i<iend; ++i ) {
11809 matrix_(row_+i,column_+j) = (~rhs)(i,j);
11831 template<
typename MT >
11832 template<
typename MT2 >
11833 inline void Submatrix<MT,aligned,true,true>::assign(
const SparseMatrix<MT2,true>& rhs )
11838 for(
size_t j=0UL; j<
n_; ++j )
11839 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
11840 matrix_(row_+element->index(),column_+j) = element->value();
11858 template<
typename MT >
11859 template<
typename MT2 >
11860 inline void Submatrix<MT,aligned,true,true>::assign(
const SparseMatrix<MT2,false>& rhs )
11867 for(
size_t i=0UL; i<
m_; ++i )
11868 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
11869 matrix_(row_+i,column_+element->index()) = element->value();
11887 template<
typename MT >
11888 template<
typename MT2 >
11889 inline DisableIf_< typename Submatrix<MT,aligned,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
11890 Submatrix<MT,aligned,true,true>::addAssign(
const DenseMatrix<MT2,true>& rhs )
11895 const size_t ipos( m_ &
size_t(-2) );
11898 for(
size_t j=0UL; j<
n_; ++j )
11900 if( IsDiagonal<MT2>::value ) {
11901 matrix_(row_+j,column_+j) += (~rhs)(j,j);
11904 for(
size_t i=0UL; i<ipos; i+=2UL ) {
11905 matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
11906 matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
11909 matrix_(row_+ipos,column_+j) += (~rhs)(ipos,j);
11930 template<
typename MT >
11931 template<
typename MT2 >
11932 inline EnableIf_< typename Submatrix<MT,aligned,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
11933 Submatrix<MT,aligned,true,true>::addAssign(
const DenseMatrix<MT2,true>& rhs )
11940 for(
size_t j=0UL; j<
n_; ++j )
11942 const size_t ibegin( ( IsLower<MT>::value )
11943 ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) &
size_t(-SIMDSIZE) )
11945 const size_t iend ( ( IsUpper<MT>::value )
11946 ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
11950 const size_t ipos( iend &
size_t(-SIMDSIZE) );
11953 size_t i( ibegin );
11955 ConstIterator_<MT2> right( (~rhs).
begin(j) + ibegin );
11957 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
11958 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11959 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11960 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11961 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11963 for( ; i<ipos; i+=SIMDSIZE ) {
11964 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
11966 for( ; i<iend; ++i ) {
11967 *left += *right; ++left; ++right;
11987 template<
typename MT >
11988 template<
typename MT2 >
11989 inline void Submatrix<MT,aligned,true,true>::addAssign(
const DenseMatrix<MT2,false>& rhs )
11996 constexpr
size_t block( BLOCK_SIZE );
11998 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
11999 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
12000 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
12001 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
12002 for(
size_t j=jj; j<jend; ++j ) {
12003 for(
size_t i=ii; i<iend; ++i ) {
12004 matrix_(row_+i,column_+j) += (~rhs)(i,j);
12026 template<
typename MT >
12027 template<
typename MT2 >
12028 inline void Submatrix<MT,aligned,true,true>::addAssign(
const SparseMatrix<MT2,true>& rhs )
12033 for(
size_t j=0UL; j<
n_; ++j )
12034 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
12035 matrix_(row_+element->index(),column_+j) += element->value();
12053 template<
typename MT >
12054 template<
typename MT2 >
12055 inline void Submatrix<MT,aligned,true,true>::addAssign(
const SparseMatrix<MT2,false>& rhs )
12062 for(
size_t i=0UL; i<
m_; ++i )
12063 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
12064 matrix_(row_+i,column_+element->index()) += element->value();
12082 template<
typename MT >
12083 template<
typename MT2 >
12084 inline DisableIf_< typename Submatrix<MT,aligned,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
12085 Submatrix<MT,aligned,true,true>::subAssign(
const DenseMatrix<MT2,true>& rhs )
12090 const size_t ipos( m_ &
size_t(-2) );
12093 for(
size_t j=0UL; j<
n_; ++j )
12095 if( IsDiagonal<MT2>::value ) {
12096 matrix_(row_+j,column_+j) -= (~rhs)(j,j);
12099 for(
size_t i=0UL; i<ipos; i+=2UL ) {
12100 matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
12101 matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
12104 matrix_(row_+ipos,column_+j) -= (~rhs)(ipos,j);
12125 template<
typename MT >
12126 template<
typename MT2 >
12127 inline EnableIf_< typename Submatrix<MT,aligned,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
12128 Submatrix<MT,aligned,true,true>::subAssign(
const DenseMatrix<MT2,true>& rhs )
12135 for(
size_t j=0UL; j<
n_; ++j )
12137 const size_t ibegin( ( IsLower<MT>::value )
12138 ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) &
size_t(-SIMDSIZE) )
12140 const size_t iend ( ( IsUpper<MT>::value )
12141 ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
12145 const size_t ipos( iend &
size_t(-SIMDSIZE) );
12148 size_t i( ibegin );
12150 ConstIterator_<MT2> right( (~rhs).
begin(j) + ibegin );
12152 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
12153 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12154 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12155 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12156 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12158 for( ; i<ipos; i+=SIMDSIZE ) {
12159 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12161 for( ; i<iend; ++i ) {
12162 *left -= *right; ++left; ++right;
12182 template<
typename MT >
12183 template<
typename MT2 >
12184 inline void Submatrix<MT,aligned,true,true>::subAssign(
const DenseMatrix<MT2,false>& rhs )
12191 constexpr
size_t block( BLOCK_SIZE );
12193 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
12194 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
12195 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
12196 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
12197 for(
size_t j=jj; j<jend; ++j ) {
12198 for(
size_t i=ii; i<iend; ++i ) {
12199 matrix_(row_+i,column_+j) -= (~rhs)(i,j);
12221 template<
typename MT >
12222 template<
typename MT2 >
12223 inline void Submatrix<MT,aligned,true,true>::subAssign(
const SparseMatrix<MT2,true>& rhs )
12228 for(
size_t j=0UL; j<
n_; ++j )
12229 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element )
12230 matrix_(row_+element->index(),column_+j) -= element->value();
12248 template<
typename MT >
12249 template<
typename MT2 >
12250 inline void Submatrix<MT,aligned,true,true>::subAssign(
const SparseMatrix<MT2,false>& rhs )
12257 for(
size_t i=0UL; i<
m_; ++i )
12258 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element )
12259 matrix_(row_+i,column_+element->index()) -= element->value();
12277 template<
typename MT >
12278 template<
typename MT2 >
12279 inline DisableIf_< typename Submatrix<MT,aligned,true,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
12280 Submatrix<MT,aligned,true,true>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
12285 const size_t ipos( m_ &
size_t(-2) );
12288 for(
size_t j=0UL; j<
n_; ++j ) {
12289 for(
size_t i=0UL; i<ipos; i+=2UL ) {
12290 matrix_(row_+i ,column_+j) *= (~rhs)(i ,j);
12291 matrix_(row_+i+1UL,column_+j) *= (~rhs)(i+1UL,j);
12294 matrix_(row_+ipos,column_+j) *= (~rhs)(ipos,j);
12315 template<
typename MT >
12316 template<
typename MT2 >
12317 inline EnableIf_< typename Submatrix<MT,aligned,true,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
12318 Submatrix<MT,aligned,true,true>::schurAssign(
const DenseMatrix<MT2,true>& rhs )
12325 for(
size_t j=0UL; j<
n_; ++j )
12327 const size_t ipos( m_ &
size_t(-SIMDSIZE) );
12332 ConstIterator_<MT2> right( (~rhs).
begin(j) );
12334 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
12335 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12336 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12337 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12338 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12340 for( ; i<ipos; i+=SIMDSIZE ) {
12341 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
12343 for( ; i<
m_; ++i ) {
12344 *left *= *right; ++left; ++right;
12364 template<
typename MT >
12365 template<
typename MT2 >
12366 inline void Submatrix<MT,aligned,true,true>::schurAssign(
const DenseMatrix<MT2,false>& rhs )
12373 constexpr
size_t block( BLOCK_SIZE );
12375 for(
size_t jj=0UL; jj<
n_; jj+=block ) {
12376 const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
12377 for(
size_t ii=0UL; ii<
m_; ii+=block ) {
12378 const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
12379 for(
size_t j=jj; j<jend; ++j ) {
12380 for(
size_t i=ii; i<iend; ++i ) {
12381 matrix_(row_+i,column_+j) *= (~rhs)(i,j);
12403 template<
typename MT >
12404 template<
typename MT2 >
12405 inline void Submatrix<MT,aligned,true,true>::schurAssign(
const SparseMatrix<MT2,true>& rhs )
12412 for(
size_t j=0UL; j<
n_; ++j )
12416 for( ConstIterator_<MT2> element=(~rhs).
begin(j); element!=(~rhs).
end(j); ++element ) {
12417 for( ; i<element->index(); ++i )
12418 reset( matrix_(row_+i,column_+j) );
12419 matrix_(row_+i,column_+j) *= element->value();
12423 for( ; i<
m_; ++i ) {
12424 reset( matrix_(row_+i,column_+j) );
12444 template<
typename MT >
12445 template<
typename MT2 >
12446 inline void Submatrix<MT,aligned,true,true>::schurAssign(
const SparseMatrix<MT2,false>& rhs )
12455 for(
size_t i=0UL; i<
m_; ++i )
12459 for( ConstIterator_<MT2> element=(~rhs).
begin(i); element!=(~rhs).
end(i); ++element ) {
12460 for( ; j<element->index(); ++j )
12461 reset( matrix_(row_+i,column_+j) );
12462 matrix_(row_+i,column_+j) *= element->value();
12466 for( ; j<
n_; ++j ) {
12467 reset( matrix_(row_+i,column_+j) );
constexpr bool aligned
Alignment flag for aligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:85
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
Header file for kernel specific block sizes.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3079
Header file for the Schur product trait.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
Header file for the subtraction trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:356
Header file for basic type definitions.
Header file for the View base class.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:61
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:329
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3078
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
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:699
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:3287
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1762
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:81
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:661
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:394
Column< MT > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:124
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:731
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
Header file for the RequiresEvaluation type trait.
System settings for performance optimizations.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
Header file for the IsUniLower type trait.
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1809
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
BLAZE_ALWAYS_INLINE 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:308
BLAZE_ALWAYS_INLINE 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:242
Constraint on the data type.
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:110
Header file for the std::initializer_list aliases.
Row< MT > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:124
Header file for the matrix storage order types.
Constraint on the data type.
Headerfile for the generic max algorithm.
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1359
Header file for nested template disabiguation.
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3077
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3081
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the implementation of the Submatrix base template.
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:367
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:443
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for all SIMD functionality.
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:340
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE 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:264
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:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
constexpr bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:580
Constraint on the data type.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< 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:75
Header file for the IsSIMDCombinable type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
Header file for run time assertion macros.
Header file for the addition trait.
Header file for the submatrix trait.
Header file for the reset shim.
Header file for the cache size of the target architecture.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the isDefault shim.
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
Constraints on the storage order of matrix types.
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:405
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:324
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:3288
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3083
Header file for the alignment check function.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the IsHermitian type trait.
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the IsExpression type trait class.
Constraint on the data type.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:635