35#ifndef _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
36#define _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
234template<
typename Type
238 :
public SparseMatrix< CompressedMatrix<Type,SO,Tag>, SO >
258 Element(
const Element& rhs ) =
default;
259 Element( Element&& rhs ) =
default;
263 inline Element&
operator=(
const Element& rhs )
265 this->value_ = rhs.value_;
269 inline Element&
operator=( Element&& rhs )
271 this->value_ = std::move( rhs.value_ );
275 template<
typename Other >
276 inline auto operator=(
const Other& rhs )
279 this->value_ = rhs.value();
283 template<
typename Other >
286 IsRValueReference_v<Other&&>, Element& >
288 this->value_ = std::move( rhs.value() );
292 template<
typename Other >
300 template<
typename Other >
303 IsRValueReference_v<Other&&>, Element& >
305 this->value_ = std::move( v );
321 struct Uninitialized {};
350 template<
typename NewType >
359 template<
size_t NewM
380 CompressedMatrix(
size_t m,
size_t n,
const std::vector<size_t>& nonzeros );
433 inline size_t rows() const noexcept;
434 inline
size_t columns() const noexcept;
435 inline
size_t capacity() const noexcept;
436 inline
size_t capacity(
size_t i ) const noexcept;
438 inline
size_t nonZeros(
size_t i ) const;
440 inline
void reset(
size_t i );
442 void resize (
size_t m,
size_t n,
bool preserve=true );
443 inline
void reserve(
size_t nonzeros );
444 void reserve(
size_t i,
size_t nonzeros );
446 inline
void trim (
size_t i );
455 inline
Iterator set (
size_t i,
size_t j, const Type& value );
457 inline
void append (
size_t i,
size_t j, const Type& value,
bool check=false );
465 inline
void erase(
size_t i,
size_t j );
469 template< typename Pred >
470 inline
void erase( Pred predicate );
472 template< typename Pred >
495 template< typename Other > inline
CompressedMatrix& scale( const Other& scalar );
502 template< typename Other > inline
bool canAlias ( const Other* alias ) const noexcept;
503 template< typename Other > inline
bool isAliased( const Other* alias ) const noexcept;
507 template< typename MT,
bool SO2 > inline
void assign ( const
DenseMatrix<MT,SO2>& rhs );
578template< typename Type
595template<
typename Type
616template<
typename Type
622 for(
size_t i=1UL; i<2UL*
m_+2UL; ++i )
637template<
typename Type
643 begin_[0UL] = allocate<Element>( nonzeros );
644 for(
size_t i=1UL; i<(2UL*
m_+1UL); ++i )
662template<
typename Type
668 BLAZE_USER_ASSERT( nonzeros.size() == m,
"Size of capacity vector and number of rows don't match" );
670 size_t newCapacity( 0UL );
671 for(
auto it=nonzeros.begin(); it!=nonzeros.end(); ++it )
674 begin_[0UL] =
end_[0UL] = allocate<Element>( newCapacity );
675 for(
size_t i=0UL; i<
m_; ++i ) {
702template<
typename Type
710 for(
const auto& rowList : list )
714 for(
const Type& element : rowList ) {
715 if( !isDefault<strict>( element ) )
732template<
typename Type
738 const size_t nonzeros( sm.
nonZeros() );
740 begin_[0UL] = allocate<Element>( nonzeros );
741 for(
size_t i=0UL; i<
m_; ++i ) {
755template<
typename Type
761 , capacity_( sm.capacity_ )
762 , begin_ ( sm.begin_ )
779template<
typename Type
801template<
typename Type
824template<
typename Type
832 , end_ ( begin_+(m+1UL) )
850template<
typename Type
855 if( begin_ !=
nullptr ) {
884template<
typename Type
908template<
typename Type
919 if( pos == end_[i] || pos->index_ != j )
940template<
typename Type
968template<
typename Type
996template<
typename Type
1019template<
typename Type
1042template<
typename Type
1065template<
typename Type
1088template<
typename Type
1111template<
typename Type
1152template<
typename Type
1165 for(
const auto& rowList : list )
1169 for(
const Type& element : rowList ) {
1170 if( !isDefault<strict>( element ) )
1171 append( i, j, element );
1193template<
typename Type
1201 if( &rhs ==
this )
return *
this;
1203 const size_t nonzeros( rhs.nonZeros() );
1205 if( rhs.m_ > capacity_ || nonzeros >
capacity() )
1208 Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
1210 newBegin[0UL] = allocate<Element>( nonzeros );
1211 for(
size_t i=0UL; i<rhs.m_; ++i ) {
1212 newEnd[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( newBegin[i] ) ) );
1213 newBegin[i+1UL] = newEnd[i];
1215 newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
1217 swap( begin_, newBegin );
1221 if( newBegin !=
nullptr ) {
1227 for(
size_t i=0UL; i<rhs.m_; ++i ) {
1228 end_[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( begin_[i] ) ) );
1229 begin_[i+1UL] = end_[i];
1247template<
typename Type
1253 if( begin_ !=
nullptr ) {
1260 capacity_ = rhs.capacity_;
1261 begin_ = rhs.begin_;
1266 rhs.capacity_ = 0UL;
1267 rhs.begin_ =
nullptr;
1284template<
typename Type
1287template<
typename MT
1289inline CompressedMatrix<Type,SO,Tag>&
1292 using blaze::assign;
1296 if( (*rhs).canAlias(
this ) ) {
1301 resize( (*rhs).rows(), (*rhs).columns(),
false );
1302 assign( *
this, *rhs );
1319template<
typename Type
1322template<
typename MT
1327 using blaze::assign;
1331 if( (*rhs).canAlias(
this ) ||
1332 (*rhs).rows() > capacity_ ||
1338 resize( (*rhs).rows(), (*rhs).columns(),
false );
1341 if( !IsZero_v<MT> ) {
1342 assign( *
this, *rhs );
1361template<
typename Type
1364template<
typename MT
1369 using blaze::addAssign;
1373 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1377 if( !IsZero_v<MT> ) {
1378 addAssign( *
this, *rhs );
1396template<
typename Type
1399template<
typename MT
1404 using blaze::subAssign;
1408 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1412 if( !IsZero_v<MT> ) {
1413 subAssign( *
this, *rhs );
1432template<
typename Type
1435template<
typename MT
1440 using blaze::schurAssign;
1444 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1448 if( (*rhs).canAlias(
this ) ) {
1454 schurAssign( *
this, tmp );
1473template<
typename Type
1476template<
typename MT
1483 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1487 if( !IsZero_v<MT> ) {
1513template<
typename Type
1528template<
typename Type
1543template<
typename Type
1548 if( begin_ !=
nullptr )
1549 return end_[m_] - begin_[0UL];
1566template<
typename Type
1572 return begin_[i+1UL] - begin_[i];
1582template<
typename Type
1587 size_t nonzeros( 0UL );
1589 for(
size_t i=0UL; i<m_; ++i )
1608template<
typename Type
1614 return end_[i] - begin_[i];
1624template<
typename Type
1629 for(
size_t i=0UL; i<m_; ++i )
1630 end_[i] = begin_[i];
1646template<
typename Type
1652 end_[i] = begin_[i];
1664template<
typename Type
1669 if( end_ !=
nullptr )
1670 end_[0UL] = end_[m_];
1692template<
typename Type
1700 BLAZE_INTERNAL_ASSERT( begin_ ==
nullptr ||
size_t( end_ - begin_ ) == capacity_ + 1UL,
"Invalid storage setting detected" );
1702 if( m == m_ && n == n_ )
return;
1704 if( begin_ ==
nullptr )
1707 end_ = begin_+m+1UL;
1709 for(
size_t i=0UL; i<2UL*m+2UL; ++i ) {
1710 begin_[i] =
nullptr;
1715 else if( m > capacity_ )
1718 Iterator* newEnd ( newBegin+m+1UL );
1720 newBegin[0UL] = begin_[0UL];
1723 for(
size_t i=0UL; i<m_; ++i ) {
1724 newEnd [i] = end_ [i];
1725 newBegin[i+1UL] = begin_[i+1UL];
1727 for(
size_t i=m_; i<m; ++i ) {
1728 newBegin[i+1UL] = newEnd[i] = begin_[m_];
1732 for(
size_t i=0UL; i<m; ++i ) {
1733 newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1737 newEnd[m] = end_[m_];
1739 swap( newBegin, begin_ );
1749 for(
size_t i=0UL; i<m_; ++i )
1750 end_[i] = begin_[i];
1753 for(
size_t i=m_; i<m; ++i ) {
1754 begin_[i+1UL] = end_[i] = begin_[m_];
1760 for(
size_t i=0UL; i<m; ++i )
1764 for(
size_t i=0UL; i<m; ++i )
1765 end_[i] = begin_[i];
1775 BLAZE_INTERNAL_ASSERT(
size_t( end_ - begin_ ) == capacity_ + 1UL,
"Invalid storage setting detected" );
1790template<
typename Type
1796 reserveElements( nonzeros );
1815template<
typename Type
1825 BLAZE_INTERNAL_ASSERT(
static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL,
"Invalid storage setting detected" );
1827 const size_t current(
capacity(i) );
1829 if( current >= nonzeros )
return;
1831 const ptrdiff_t additional( nonzeros - current );
1833 if( end_[m_] - begin_[m_] < additional )
1835 const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1839 Iterator* newEnd ( newBegin+m_+1UL );
1841 newBegin[0UL] = allocate<Element>( newCapacity );
1842 newEnd [m_ ] = newBegin[0UL]+newCapacity;
1844 for(
size_t k=0UL; k<i; ++k ) {
1845 newEnd [k ] = castDown(
transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1846 newBegin[k+1UL] = newBegin[k] +
capacity(k);
1848 newEnd [i ] = castDown(
transfer( begin_[i], end_[i], castUp( newBegin[i] ) ) );
1849 newBegin[i+1UL] = newBegin[i] + nonzeros;
1850 for(
size_t k=i+1UL; k<m_; ++k ) {
1851 newEnd [k ] = castDown(
transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1852 newBegin[k+1UL] = newBegin[k] +
capacity(k);
1857 swap( newBegin, begin_ );
1865 begin_[m_] += additional;
1866 for(
size_t j=m_-1UL; j>i; --j ) {
1867 begin_[j] = castDown( std::move_backward( begin_[j], end_[j], castUp( end_[j]+additional ) ) );
1868 end_ [j] += additional;
1873 BLAZE_INTERNAL_ASSERT(
static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL,
"Invalid storage setting detected" );
1888template<
typename Type
1893 for(
size_t i=0UL; i<m_; ++i )
1910template<
typename Type
1917 if( i < ( m_ - 1UL ) )
1918 end_[i+1] = castDown( std::move( begin_[i+1], end_[i+1], castUp( end_[i] ) ) );
1919 begin_[i+1] = end_[i];
1933template<
typename Type
1951template<
typename Type
1960 swap( capacity_, sm.capacity_ );
1961 swap( begin_, sm.begin_ );
1962 swap( end_ , sm.end_ );
1975template<
typename Type
1980 size_t nonzeros( 2UL*
capacity()+1UL );
1996template<
typename Type
2004 Iterator* newEnd = newBegin+capacity_+1UL;
2006 newBegin[0UL] = allocate<Element>( nonzeros );
2008 for(
size_t k=0UL; k<m_; ++k ) {
2010 newEnd [k] = castDown(
transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
2011 newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
2014 newEnd[m_] = newBegin[0UL]+nonzeros;
2016 swap( newBegin, begin_ );
2019 if( newBegin !=
nullptr ) {
2035template<
typename Type
2041 return static_cast<Iterator>( it );
2054template<
typename Type
2085template<
typename Type
2096 if( pos != end_[i] && pos->index_ == j ) {
2097 pos->value() = value;
2100 else return insert( pos, i, j, value );
2118template<
typename Type
2129 if( pos != end_[i] && pos->index_ == j ) {
2133 return insert( pos, i, j, value );
2148template<
typename Type
2156 if( begin_[i+1UL] - end_[i] != 0 ) {
2157 std::move_backward( pos, end_[i], castUp( end_[i]+1UL ) );
2158 pos->value_ = value;
2164 else if( end_[m_] - begin_[m_] != 0 ) {
2165 std::move_backward( pos, end_[m_-1UL], castUp( end_[m_-1UL]+1UL ) );
2167 pos->value_ = value;
2170 for(
size_t k=i+1UL; k<m_+1UL; ++k ) {
2178 size_t newCapacity( extendCapacity() );
2181 Iterator* newEnd = newBegin+capacity_+1UL;
2183 newBegin[0UL] = allocate<Element>( newCapacity );
2185 for(
size_t k=0UL; k<i; ++k ) {
2186 const size_t nonzeros( end_[k] - begin_[k] );
2187 const size_t total( begin_[k+1UL] - begin_[k] );
2188 newEnd [k] = newBegin[k] + nonzeros;
2189 newBegin[k+1UL] = newBegin[k] + total;
2191 newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
2192 newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
2193 for(
size_t k=i+1UL; k<m_; ++k ) {
2194 const size_t nonzeros( end_[k] - begin_[k] );
2195 const size_t total( begin_[k+1UL] - begin_[k] );
2196 newEnd [k] = newBegin[k] + nonzeros;
2197 newBegin[k+1UL] = newBegin[k] + total;
2200 newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
2202 Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
2203 tmp->value_ = value;
2205 std::move( pos, end_[m_-1UL], castUp( tmp+1UL ) );
2207 swap( newBegin, begin_ );
2271template<
typename Type
2279 BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_,
"Index is not strictly increasing" );
2281 end_[i]->value_ = value;
2283 if( !check || !isDefault<strict>( end_[i]->value_ ) ) {
2284 end_[i]->index_ = j;
2304template<
typename Type
2311 begin_[i+1UL] = end_[i];
2313 end_[i+1UL] = end_[i];
2335template<
typename Type
2344 if( pos != end_[i] )
2345 end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2361template<
typename Type
2368 BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i],
"Invalid compressed matrix iterator" );
2370 if( pos != end_[i] )
2371 end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2390template<
typename Type
2398 BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i],
"Invalid compressed matrix iterator" );
2399 BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i],
"Invalid compressed matrix iterator" );
2402 end_[i] = castDown( std::move( last, end_[i], castUp( first ) ) );
2430template<
typename Type
2433template<
typename Pred >
2436 for(
size_t i=0UL; i<m_; ++i ) {
2437 end_[i] = castDown( std::remove_if( castUp( begin_[i] ), castUp( end_[i] ),
2438 [predicate=predicate](
const ElementBase& element) {
2439 return predicate( element.
value() );
2473template<
typename Type
2476template<
typename Pred >
2481 BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i],
"Invalid compressed matrix iterator" );
2482 BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i],
"Invalid compressed matrix iterator" );
2484 const auto pos = std::remove_if( castUp( first ), castUp( last ),
2485 [predicate=predicate](
const ElementBase& element ) {
2486 return predicate( element.
value() );
2489 end_[i] = castDown( std::move( last, end_[i], pos ) );
2517template<
typename Type
2523 return const_cast<Iterator>(
const_cast<const This&
>( *this ).
find( i, j ) );
2543template<
typename Type
2550 if( pos != end_[i] && pos->index_ == j )
2552 else return end_[i];
2572template<
typename Type
2598template<
typename Type
2605 return std::lower_bound( begin_[i], end_[i], j,
2606 [](
const Element& element,
size_t index )
2608 return element.index() < index;
2629template<
typename Type
2655template<
typename Type
2662 return std::upper_bound( begin_[i], end_[i], j,
2663 [](
size_t index,
const Element& element )
2665 return index < element.index();
2684template<
typename Type
2701template<
typename Type
2730template<
typename Type
2733template<
typename Other >
2736 for(
size_t i=0UL; i<m_; ++i )
2737 for(
auto element=begin_[i]; element!=end_[i]; ++element )
2738 element->value_ *= scalar;
2763template<
typename Type
2766template<
typename Other >
2769 return static_cast<const void*
>( this ) ==
static_cast<const void*
>( alias );
2784template<
typename Type
2787template<
typename Other >
2790 return static_cast<const void*
>( this ) ==
static_cast<const void*
>( alias );
2805template<
typename Type
2826template<
typename Type
2829template<
typename MT
2836 if( m_ == 0UL || n_ == 0UL )
2839 size_t nonzeros( 0UL );
2841 for(
size_t i=1UL; i<=m_; ++i )
2842 begin_[i] = end_[i] = end_[m_];
2844 for(
size_t i=0UL; i<m_; ++i )
2846 begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2848 const size_t jbegin( ( IsUpper_v<MT> )
2849 ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2851 const size_t jend ( ( IsLower_v<MT> )
2852 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2855 for(
size_t j=jbegin; j<jend; ++j )
2858 reserveElements( extendCapacity() );
2859 for(
size_t k=i+1UL; k<=m_; ++k )
2860 begin_[k] = end_[k] = end_[m_];
2863 end_[i]->value_ = (*rhs)(i,j);
2865 if( !isDefault<strict>( end_[i]->value_ ) ) {
2866 end_[i]->index_ = j;
2873 begin_[m_] = begin_[0UL]+nonzeros;
2889template<
typename Type
2892template<
typename MT >
2900 if( m_ == 0UL || begin_[0] ==
nullptr )
2903 for(
size_t i=0UL; i<m_; ++i ) {
2904 end_[i] = castDown( std::copy( (*rhs).begin(i), (*rhs).end(i), castUp( begin_[i] ) ) );
2905 begin_[i+1UL] = end_[i];
2922template<
typename Type
2925template<
typename MT >
2936 std::vector<size_t> rowLengths( m_, 0UL );
2937 for(
size_t j=0UL; j<n_; ++j ) {
2938 for(
auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2939 ++rowLengths[element->index()];
2943 for(
size_t i=0UL; i<m_; ++i ) {
2944 begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2948 for(
size_t j=0UL; j<n_; ++j ) {
2949 for(
auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2950 append( element->index(), j, element->value() );
2967template<
typename Type
2970template<
typename MT
2994template<
typename Type
2997template<
typename MT
3021template<
typename Type
3024template<
typename MT
3048template<
typename Type
3051template<
typename MT
3075template<
typename Type
3078template<
typename MT
3087 for(
size_t i=0UL; i<m_; ++i ) {
3089 for(
auto element=
begin(i); element!=last; ++element )
3090 element->value_ *= (*rhs)(i,element->index_);
3116template<
typename Type
3119 :
public SparseMatrix< CompressedMatrix<Type,true,Tag>, true >
3137 Element() =
default;
3138 Element(
const Element& rhs ) =
default;
3139 Element( Element&& rhs ) =
default;
3143 inline Element&
operator=(
const Element& rhs )
3145 this->value_ = rhs.value_;
3149 inline Element&
operator=( Element&& rhs )
3151 this->value_ = std::move( rhs.value_ );
3155 template<
typename Other >
3156 inline auto operator=(
const Other& rhs )
3157 -> EnableIf_t< IsSparseElement_v<Other>, Element& >
3159 this->value_ = rhs.value();
3163 template<
typename Other >
3165 -> EnableIf_t< IsSparseElement_v< RemoveReference_t<Other> > &&
3166 IsRValueReference_v<Other&&>, Element& >
3168 this->value_ = std::move( rhs.value() );
3172 template<
typename Other >
3174 -> EnableIf_t< !IsSparseElement_v<Other>, Element& >
3180 template<
typename Other >
3182 -> EnableIf_t< !IsSparseElement_v< RemoveReference_t<Other> > &&
3183 IsRValueReference_v<Other&&>, Element& >
3185 this->value_ = std::move( v );
3199 struct Uninitialized {};
3204 using This = CompressedMatrix<Type,true,Tag>;
3205 using BaseType = SparseMatrix<This,true>;
3218 using Reference = MatrixAccessProxy<This>;
3227 template<
typename NewType >
3229 using Other = CompressedMatrix<NewType,true,Tag>;
3236 template<
size_t NewM
3239 using Other = CompressedMatrix<Type,true,Tag>;
3248 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
3257 CompressedMatrix(
size_t m,
size_t n,
const std::vector<size_t>& nonzeros );
3263 template<
typename MT,
bool SO >
inline CompressedMatrix(
const DenseMatrix<MT,SO>& dm );
3264 template<
typename MT,
bool SO >
inline CompressedMatrix(
const SparseMatrix<MT,SO>& sm );
3300 template<
typename MT,
bool SO >
inline CompressedMatrix& operator+=(
const Matrix<MT,SO>& rhs ) &;
3301 template<
typename MT,
bool SO >
inline CompressedMatrix& operator-=(
const Matrix<MT,SO>& rhs ) &;
3302 template<
typename MT,
bool SO >
inline CompressedMatrix& operator%=(
const DenseMatrix<MT,SO>& rhs ) &;
3303 template<
typename MT,
bool SO >
inline CompressedMatrix& operator%=(
const SparseMatrix<MT,SO>& rhs ) &;
3310 inline size_t rows() const noexcept;
3311 inline
size_t columns() const noexcept;
3312 inline
size_t capacity() const noexcept;
3313 inline
size_t capacity(
size_t j ) const noexcept;
3315 inline
size_t nonZeros(
size_t j ) const;
3316 inline
void reset();
3317 inline
void reset(
size_t j );
3318 inline
void clear();
3319 void resize (
size_t m,
size_t n,
bool preserve=true );
3320 inline
void reserve(
size_t nonzeros );
3321 void reserve(
size_t j,
size_t nonzeros );
3322 inline
void trim ();
3323 inline
void trim (
size_t j );
3332 inline
Iterator set (
size_t i,
size_t j, const Type& value );
3333 inline
Iterator insert (
size_t i,
size_t j, const Type& value );
3334 inline
void append (
size_t i,
size_t j, const Type& value,
bool check=false );
3342 inline
void erase(
size_t i,
size_t j );
3346 template< typename Pred >
3347 inline
void erase( Pred predicate );
3349 template< typename Pred >
3372 template< typename Other > inline
CompressedMatrix& scale( const Other& scalar );
3379 template< typename Other > inline
bool canAlias ( const Other* alias ) const noexcept;
3380 template< typename Other > inline
bool isAliased( const Other* alias ) const noexcept;
3384 template< typename MT,
bool SO > inline
void assign ( const DenseMatrix<MT,SO>& rhs );
3385 template< typename MT > inline
void assign ( const SparseMatrix<MT,true>& rhs );
3386 template< typename MT > inline
void assign ( const SparseMatrix<MT,false>& rhs );
3387 template< typename MT,
bool SO > inline
void addAssign ( const DenseMatrix<MT,SO>& rhs );
3388 template< typename MT,
bool SO > inline
void addAssign ( const SparseMatrix<MT,SO>& rhs );
3389 template< typename MT,
bool SO > inline
void subAssign ( const DenseMatrix<MT,SO>& rhs );
3390 template< typename MT,
bool SO > inline
void subAssign ( const SparseMatrix<MT,SO>& rhs );
3391 template< typename MT,
bool SO > inline
void schurAssign( const DenseMatrix<MT,SO>& rhs );
3430 static const Type
zero_;
3454template< typename Type
3471template<
typename Type
3493template<
typename Type
3496 : CompressedMatrix( m, n, Uninitialized() )
3498 for(
size_t j=1UL; j<2UL*
n_+2UL; ++j )
3515template<
typename Type
3518 : CompressedMatrix( m, n, Uninitialized() )
3520 begin_[0UL] = allocate<Element>( nonzeros );
3521 for(
size_t j=1UL; j<(2UL*
n_+1UL); ++j )
3540template<
typename Type
3543 : CompressedMatrix( m, n, Uninitialized() )
3545 BLAZE_USER_ASSERT( nonzeros.size() == n,
"Size of capacity vector and number of columns don't match" );
3547 size_t newCapacity( 0UL );
3548 for(
auto it=nonzeros.begin(); it!=nonzeros.end(); ++it )
3551 begin_[0UL] =
end_[0UL] = allocate<Element>( newCapacity );
3552 for(
size_t j=0UL; j<
n_; ++j ) {
3581template<
typename Type
3586 for(
size_t j=0UL; j<
n_; ++j )
3590 for(
const auto& rowList : list )
3592 if( rowList.size() <= j ) {
3597 auto pos( rowList.begin() );
3598 std::advance( pos, j );
3599 if( !isDefault<strict>( *pos ) )
3617template<
typename Type
3620 : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
3622 const size_t nonzeros( sm.nonZeros() );
3624 begin_[0UL] = allocate<Element>( nonzeros );
3625 for(
size_t j=0UL; j<
n_; ++j ) {
3641template<
typename Type
3646 , capacity_( sm.capacity_ )
3647 , begin_ ( sm.begin_ )
3653 sm.begin_ =
nullptr;
3666template<
typename Type
3668template<
typename MT
3671 : CompressedMatrix( (*dm).
rows(), (*dm).
columns() )
3673 using blaze::assign;
3689template<
typename Type
3691template<
typename MT
3696 using blaze::assign;
3713template<
typename Type
3719 , begin_( new Iterator[2UL*n+2UL] )
3720 , end_ ( begin_+(n+1UL) )
3740template<
typename Type
3744 if( begin_ !=
nullptr ) {
3775template<
typename Type
3783 return Reference( *
this, i, j );
3800template<
typename Type
3808 const ConstIterator pos(
lowerBound( i, j ) );
3810 if( pos == end_[j] || pos->index_ != i )
3833template<
typename Type
3844 return (*
this)(i,j);
3862template<
typename Type
3873 return (*
this)(i,j);
3886template<
typename Type
3905template<
typename Type
3924template<
typename Type
3943template<
typename Type
3962template<
typename Type
3981template<
typename Type
4023template<
typename Type
4025inline CompressedMatrix<Type,true,Tag>&
4033 for(
size_t j=0UL; j<n_; ++j )
4037 for(
const auto& rowList : list )
4039 if( rowList.size() <= j ) {
4044 auto pos( rowList.begin() );
4045 std::advance( pos, j );
4046 if( !isDefault<strict>( *pos ) )
4047 append( i, j, *pos );
4070template<
typename Type
4072inline CompressedMatrix<Type,true,Tag>&
4077 if( &rhs ==
this )
return *
this;
4079 const size_t nonzeros( rhs.nonZeros() );
4081 if( rhs.n_ > capacity_ || nonzeros >
capacity() )
4083 Iterator* newBegin(
new Iterator[2UL*rhs.n_+2UL] );
4084 Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
4086 newBegin[0UL] = allocate<Element>( nonzeros );
4087 for(
size_t j=0UL; j<rhs.n_; ++j ) {
4088 newEnd[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( newBegin[j] ) ) );
4089 newBegin[j+1UL] = newEnd[j];
4091 newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
4093 swap( begin_, newBegin );
4097 if( newBegin !=
nullptr ) {
4103 for(
size_t j=0UL; j<rhs.n_; ++j ) {
4104 end_[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( begin_[j] ) ) );
4105 begin_[j+1UL] = end_[j];
4125template<
typename Type
4127inline CompressedMatrix<Type,true,Tag>&
4130 if( begin_ !=
nullptr ) {
4137 capacity_ = rhs.capacity_;
4138 begin_ = rhs.begin_;
4143 rhs.capacity_ = 0UL;
4144 rhs.begin_ =
nullptr;
4163template<
typename Type
4165template<
typename MT
4167inline CompressedMatrix<Type,true,Tag>&
4170 using blaze::assign;
4174 if( (*rhs).canAlias(
this ) ) {
4175 CompressedMatrix tmp( *rhs );
4179 resize( (*rhs).rows(), (*rhs).columns(),
false );
4180 assign( *
this, *rhs );
4199template<
typename Type
4201template<
typename MT
4203inline CompressedMatrix<Type,true,Tag>&
4206 using blaze::assign;
4210 if( (*rhs).canAlias(
this ) ||
4211 (*rhs).columns() > capacity_ ||
4213 CompressedMatrix tmp( *rhs );
4217 resize( (*rhs).rows(), (*rhs).columns(),
false );
4220 if( !IsZero_v<MT> ) {
4221 assign( *
this, *rhs );
4242template<
typename Type
4244template<
typename MT
4246inline CompressedMatrix<Type,true,Tag>&
4247 CompressedMatrix<Type,true,Tag>::operator+=(
const Matrix<MT,SO>& rhs ) &
4249 using blaze::addAssign;
4253 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4257 if( !IsZero_v<MT> ) {
4258 addAssign( *
this, *rhs );
4278template<
typename Type
4280template<
typename MT
4282inline CompressedMatrix<Type,true,Tag>&
4283 CompressedMatrix<Type,true,Tag>::operator-=(
const Matrix<MT,SO>& rhs ) &
4285 using blaze::subAssign;
4289 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4293 if( !IsZero_v<MT> ) {
4294 subAssign( *
this, *rhs );
4315template<
typename Type
4317template<
typename MT
4319inline CompressedMatrix<Type,true,Tag>&
4320 CompressedMatrix<Type,true,Tag>::operator%=(
const DenseMatrix<MT,SO>& rhs ) &
4322 using blaze::schurAssign;
4326 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4330 if( (*rhs).canAlias(
this ) ) {
4331 CompressedMatrix tmp( *
this % (*rhs) );
4335 CompositeType_t<MT> tmp( *rhs );
4336 schurAssign( *
this, tmp );
4357template<
typename Type
4359template<
typename MT
4361inline CompressedMatrix<Type,true,Tag>&
4362 CompressedMatrix<Type,true,Tag>::operator%=(
const SparseMatrix<MT,SO>& rhs ) &
4366 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4370 if( !IsZero_v<MT> ) {
4371 CompressedMatrix tmp( *
this % (*rhs) );
4398template<
typename Type
4414template<
typename Type
4430template<
typename Type
4434 if( begin_ !=
nullptr )
4435 return end_[n_] - begin_[0UL];
4449template<
typename Type
4454 return begin_[j+1UL] - begin_[j];
4466template<
typename Type
4470 size_t nonzeros( 0UL );
4472 for(
size_t j=0UL; j<n_; ++j )
4488template<
typename Type
4493 return end_[j] - begin_[j];
4505template<
typename Type
4509 for(
size_t j=0UL; j<n_; ++j )
4510 end_[j] = begin_[j];
4526template<
typename Type
4531 end_[j] = begin_[j];
4545template<
typename Type
4549 if( end_ !=
nullptr )
4550 end_[0UL] = end_[n_];
4574template<
typename Type
4581 BLAZE_INTERNAL_ASSERT( begin_ ==
nullptr ||
size_t( end_ - begin_ ) == capacity_ + 1UL,
"Invalid storage setting detected" );
4583 if( m == m_ && n == n_ )
return;
4585 if( begin_ ==
nullptr )
4587 begin_ =
new Iterator[2UL*n+2UL];
4588 end_ = begin_+n+1UL;
4590 for(
size_t j=0UL; j<2UL*n+2UL; ++j ) {
4591 begin_[j] =
nullptr;
4596 else if( n > capacity_ )
4598 Iterator* newBegin(
new Iterator[2UL*n+2UL] );
4599 Iterator* newEnd ( newBegin+n+1UL );
4601 newBegin[0UL] = begin_[0UL];
4604 for(
size_t j=0UL; j<n_; ++j ) {
4605 newEnd [j] = end_ [j];
4606 newBegin[j+1UL] = begin_[j+1UL];
4608 for(
size_t j=n_; j<n; ++j ) {
4609 newBegin[j+1UL] = newEnd[j] = begin_[n_];
4613 for(
size_t j=0UL; j<n; ++j ) {
4614 newBegin[j+1UL] = newEnd[j] = begin_[0UL];
4618 newEnd[n] = end_[n_];
4620 swap( newBegin, begin_ );
4630 for(
size_t j=0UL; j<n_; ++j )
4631 end_[j] = begin_[j];
4634 for(
size_t j=n_; j<n; ++j ) {
4635 begin_[j+1UL] = end_[j] = begin_[n_];
4641 for(
size_t j=0UL; j<n; ++j )
4645 for(
size_t j=0UL; j<n; ++j )
4646 end_[j] = begin_[j];
4656 BLAZE_INTERNAL_ASSERT(
size_t( end_ - begin_ ) == capacity_ + 1UL,
"Invalid storage setting detected" );
4673template<
typename Type
4678 reserveElements( nonzeros );
4696template<
typename Type
4705 BLAZE_INTERNAL_ASSERT(
static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL,
"Invalid storage setting detected" );
4707 const size_t current(
capacity(j) );
4709 if( current >= nonzeros )
return;
4711 const ptrdiff_t additional( nonzeros - current );
4713 if( end_[n_] - begin_[n_] < additional )
4715 const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
4718 Iterator* newBegin(
new Iterator[2UL*n_+2UL] );
4719 Iterator* newEnd ( newBegin+n_+1UL );
4721 newBegin[0UL] = allocate<Element>( newCapacity );
4722 newEnd [n_ ] = newBegin[0UL]+newCapacity;
4724 for(
size_t k=0UL; k<j; ++k ) {
4725 newEnd [k ] = castDown(
transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4726 newBegin[k+1UL] = newBegin[k] +
capacity(k);
4728 newEnd [j ] = castDown(
transfer( begin_[j], end_[j], castUp( newBegin[j] ) ) );
4729 newBegin[j+1UL] = newBegin[j] + nonzeros;
4730 for(
size_t k=j+1UL; k<n_; ++k ) {
4731 newEnd [k ] = castDown(
transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4732 newBegin[k+1UL] = newBegin[k] +
capacity(k);
4737 swap( newBegin, begin_ );
4745 begin_[n_] += additional;
4746 for(
size_t k=n_-1UL; k>j; --k ) {
4747 begin_[k] = castDown( std::move_backward( begin_[k], end_[k], castUp( end_[k]+additional ) ) );
4748 end_ [k] += additional;
4753 BLAZE_INTERNAL_ASSERT(
static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL,
"Invalid storage setting detected" );
4769template<
typename Type
4773 for(
size_t j=0UL; j<n_; ++j )
4791template<
typename Type
4797 if( j < ( n_ - 1UL ) )
4798 end_[j+1] = castDown( std::move( begin_[j+1], end_[j+1], castUp( end_[j] ) ) );
4799 begin_[j+1] = end_[j];
4815template<
typename Type
4820 CompressedMatrix( *this ).swap( *
this );
4834template<
typename Type
4842 swap( capacity_, sm.capacity_ );
4843 swap( begin_, sm.begin_ );
4844 swap( end_ , sm.end_ );
4859template<
typename Type
4863 size_t nonzeros( 2UL*
capacity()+1UL );
4881template<
typename Type
4887 Iterator* newBegin =
new Iterator[2UL*capacity_+2UL];
4888 Iterator* newEnd = newBegin+capacity_+1UL;
4890 newBegin[0UL] = allocate<Element>( nonzeros );
4892 for(
size_t k=0UL; k<n_; ++k ) {
4894 newEnd [k] = castDown(
transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4895 newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4898 newEnd[n_] = newBegin[0UL]+nonzeros;
4900 swap( newBegin, begin_ );
4903 if( newBegin !=
nullptr ) {
4920template<
typename Type
4925 return static_cast<Iterator
>( it );
4938template<
typename Type
4943 return static_cast<IteratorBase
>( it );
4969template<
typename Type
4979 if( pos != end_[j] && pos->index_ == i ) {
4980 pos->value() = value;
4983 else return insert( pos, i, j, value );
5003template<
typename Type
5013 if( pos != end_[j] && pos->index_ == i ) {
5017 return insert( pos, i, j, value );
5034template<
typename Type
5041 if( begin_[j+1UL] - end_[j] != 0 ) {
5042 std::move_backward( pos, end_[j], castUp( end_[j]+1UL ) );
5043 pos->value_ = value;
5049 else if( end_[n_] - begin_[n_] != 0 ) {
5050 std::move_backward( pos, end_[n_-1UL], castUp( end_[n_-1]+1UL ) );
5052 pos->value_ = value;
5055 for(
size_t k=j+1UL; k<n_+1UL; ++k ) {
5063 size_t newCapacity( extendCapacity() );
5065 Iterator* newBegin =
new Iterator[2UL*capacity_+2UL];
5066 Iterator* newEnd = newBegin+capacity_+1UL;
5068 newBegin[0UL] = allocate<Element>( newCapacity );
5070 for(
size_t k=0UL; k<j; ++k ) {
5071 const size_t nonzeros( end_[k] - begin_[k] );
5072 const size_t total( begin_[k+1UL] - begin_[k] );
5073 newEnd [k] = newBegin[k] + nonzeros;
5074 newBegin[k+1UL] = newBegin[k] + total;
5076 newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
5077 newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
5078 for(
size_t k=j+1UL; k<n_; ++k ) {
5079 const size_t nonzeros( end_[k] - begin_[k] );
5080 const size_t total( begin_[k+1UL] - begin_[k] );
5081 newEnd [k] = newBegin[k] + nonzeros;
5082 newBegin[k+1UL] = newBegin[k] + total;
5085 newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
5087 Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
5088 tmp->value_ = value;
5090 std::move( pos, end_[n_-1UL], castUp( tmp+1UL ) );
5092 swap( newBegin, begin_ );
5157template<
typename Type
5164 BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_,
"Index is not strictly increasing" );
5166 end_[j]->value_ = value;
5168 if( !check || !isDefault<strict>( end_[j]->value_ ) ) {
5169 end_[j]->index_ = i;
5191template<
typename Type
5197 begin_[j+1UL] = end_[j];
5199 end_[j+1UL] = end_[j];
5223template<
typename Type
5230 const Iterator pos(
find( i, j ) );
5231 if( pos != end_[j] )
5232 end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5248template<
typename Type
5254 BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j],
"Invalid compressed matrix iterator" );
5256 if( pos != end_[j] )
5257 end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5276template<
typename Type
5283 BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j],
"Invalid compressed matrix iterator" );
5284 BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j],
"Invalid compressed matrix iterator" );
5287 end_[j] = castDown( std::move( last, end_[j], castUp( first ) ) );
5317template<
typename Type
5319template<
typename Pred >
5322 for(
size_t j=0UL; j<n_; ++j ) {
5323 end_[j] = castDown( std::remove_if( castUp( begin_[j] ), castUp( end_[j] ),
5324 [predicate=predicate](
const ElementBase& element ) {
5325 return predicate( element.value() );
5358template<
typename Type
5360template<
typename Pred >
5365 BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j],
"Invalid compressed matrix iterator" );
5366 BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j],
"Invalid compressed matrix iterator" );
5368 const auto pos = std::remove_if( castUp( first ), castUp( last ),
5369 [predicate=predicate](
const ElementBase& element ) {
5370 return predicate( element.value() );
5373 end_[j] = castDown( std::move( last, end_[j], pos ) );
5402template<
typename Type
5407 return const_cast<Iterator
>(
const_cast<const This&
>( *this ).find( i, j ) );
5428template<
typename Type
5433 const ConstIterator pos(
lowerBound( i, j ) );
5434 if( pos != end_[j] && pos->index_ == i )
5436 else return end_[j];
5456template<
typename Type
5461 return const_cast<Iterator
>(
const_cast<const This&
>( *this ).lowerBound( i, j ) );
5481template<
typename Type
5487 return std::lower_bound( begin_[j], end_[j], i,
5488 [](
const Element& element,
size_t index )
5490 return element.index() < index;
5511template<
typename Type
5516 return const_cast<Iterator
>(
const_cast<const This&
>( *this ).upperBound( i, j ) );
5536template<
typename Type
5542 return std::upper_bound( begin_[j], end_[j], i,
5543 [](
size_t index,
const Element& element )
5545 return index < element.index();
5566template<
typename Type
5570 CompressedMatrix tmp(
trans( *
this ) );
5584template<
typename Type
5588 CompressedMatrix tmp(
ctrans( *
this ) );
5614template<
typename Type
5616template<
typename Other >
5617inline CompressedMatrix<Type,true,Tag>& CompressedMatrix<Type,true,Tag>::scale(
const Other& scalar )
5619 for(
size_t j=0UL; j<n_; ++j )
5620 for(
auto element=begin_[j]; element!=end_[j]; ++element )
5621 element->value_ *= scalar;
5648template<
typename Type
5650template<
typename Other >
5653 return static_cast<const void*
>( this ) ==
static_cast<const void*
>( alias );
5670template<
typename Type
5672template<
typename Other >
5675 return static_cast<const void*
>( this ) ==
static_cast<const void*
>( alias );
5692template<
typename Type
5714template<
typename Type
5716template<
typename MT
5723 if( m_ == 0UL || n_ == 0UL )
5726 size_t nonzeros( 0UL );
5728 for(
size_t j=1UL; j<=n_; ++j )
5729 begin_[j] = end_[j] = end_[n_];
5731 for(
size_t j=0UL; j<n_; ++j )
5733 begin_[j] = end_[j] = begin_[0UL]+nonzeros;
5735 const size_t ibegin( ( IsLower_v<MT> )
5736 ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5738 const size_t iend ( ( IsUpper_v<MT> )
5739 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5742 for(
size_t i=ibegin; i<iend; ++i )
5745 reserveElements( extendCapacity() );
5746 for(
size_t k=j+1UL; k<=n_; ++k )
5747 begin_[k] = end_[k] = end_[n_];
5750 end_[j]->value_ = (*rhs)(i,j);
5752 if( !isDefault<strict>( end_[j]->value_ ) ) {
5753 end_[j]->index_ = i;
5760 begin_[n_] = begin_[0UL]+nonzeros;
5778template<
typename Type
5780template<
typename MT >
5788 if( n_ == 0UL || begin_[0] ==
nullptr )
5791 for(
size_t j=0UL; j<n_; ++j ) {
5792 end_[j] = castDown( std::copy( (*rhs).begin(j), (*rhs).end(j), castUp( begin_[j] ) ) );
5793 begin_[j+1UL] = end_[j];
5812template<
typename Type
5814template<
typename MT >
5825 std::vector<size_t> columnLengths( n_, 0UL );
5826 for(
size_t i=0UL; i<m_; ++i ) {
5827 for(
auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5828 ++columnLengths[element->index()];
5832 for(
size_t j=0UL; j<n_; ++j ) {
5833 begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
5837 for(
size_t i=0UL; i<m_; ++i ) {
5838 for(
auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5839 append( i, element->index(), element->value() );
5858template<
typename Type
5860template<
typename MT
5867 CompressedMatrix tmp(
serial( *
this + (*rhs) ) );
5886template<
typename Type
5888template<
typename MT
5895 CompressedMatrix tmp(
serial( *
this + (*rhs) ) );
5914template<
typename Type
5916template<
typename MT
5923 CompressedMatrix tmp(
serial( *
this - (*rhs) ) );
5942template<
typename Type
5944template<
typename MT
5951 CompressedMatrix tmp(
serial( *
this - (*rhs) ) );
5970template<
typename Type
5972template<
typename MT
5981 for(
size_t j=0UL; j<n_; ++j ) {
5982 const Iterator last(
end(j) );
5983 for(
auto element=
begin(j); element!=last; ++element )
5984 element->value_ *= (*rhs)(element->index_,j);
6006template< RelaxationFlag RF,
typename Type,
bool SO,
typename Tag >
6007bool isDefault(
const CompressedMatrix<Type,SO,Tag>& m );
6009template<
typename Type,
bool SO,
typename Tag >
6010bool isIntact(
const CompressedMatrix<Type,SO,Tag>& m );
6012template<
typename Type,
bool SO,
typename Tag >
6013void swap( CompressedMatrix<Type,SO,Tag>& a, CompressedMatrix<Type,SO,Tag>& b )
noexcept;
6072template<
typename Type
6090template<
typename Type
6110template<
typename T1,
typename T2 >
6111struct AddTraitEval2< T1, T2
6114 using Type = CompressedMatrix< AddTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6115 , ( StorageOrder_v<T1> && StorageOrder_v<T2> )
6116 ,
AddTrait_t< TagType_t<T1>, TagType_t<T2> > >;
6132template<
typename T1,
typename T2 >
6133struct SubTraitEval2< T1, T2
6136 using Type = CompressedMatrix< SubTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6137 , ( StorageOrder_v<T1> && StorageOrder_v<T2> )
6138 ,
SubTrait_t< TagType_t<T1>, TagType_t<T2> > >;
6154template<
typename T1
6156struct SchurTraitEval2< T1, T2
6159 ( IsSparseMatrix_v<T1> || IsSparseMatrix_v<T2> ) > >
6161 static constexpr bool SO = ( IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2>
6162 ? ( StorageOrder_v<T1> && StorageOrder_v<T2> )
6163 : ( IsSparseMatrix_v<T1>
6164 ? StorageOrder_v<T1>
6165 : StorageOrder_v<T2> ) );
6167 using Type = CompressedMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6169 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
6185template<
typename T1,
typename T2 >
6186struct MultTraitEval2< T1, T2
6189 using Type = CompressedMatrix< MultTrait_t< ElementType_t<T1>, T2 >
6190 , StorageOrder_v<T1>
6191 , MultTrait_t< TagType_t<T1>, T2 > >;
6194template<
typename T1,
typename T2 >
6195struct MultTraitEval2< T1, T2
6198 using Type = CompressedMatrix< MultTrait_t< T1, ElementType_t<T2> >
6199 , StorageOrder_v<T2>
6200 , MultTrait_t< T1, TagType_t<T2> > >;
6203template<
typename T1,
typename T2 >
6204struct MultTraitEval2< T1, T2
6207 IsColumnVector_v<T1> &&
6208 IsRowVector_v<T2> > >
6210 using Type = CompressedMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6215template<
typename T1,
typename T2 >
6216struct MultTraitEval2< T1, T2
6218 IsSparseMatrix_v<T2> &&
6219 !( IsIdentity_v<T1> && IsIdentity_v<T2> ) > >
6221 using MultType = MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
6222 using MultTag = MultTrait_t< TagType_t<T1>, TagType_t<T2> >;
6224 using Type = CompressedMatrix< AddTrait_t<MultType,MultType>
6225 , StorageOrder_v<T1>
6226 , AddTrait_t<MultTag,MultTag> >;
6242template<
typename T1
6244struct KronTraitEval2< T1, T2
6247 ( IsSparseMatrix_v<T1> || IsSparseMatrix_v<T2> ) > >
6249 using Type = CompressedMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6250 , ( IsDenseMatrix_v<T2> ? StorageOrder_v<T1> : StorageOrder_v<T2> )
6267template<
typename T1,
typename T2 >
6268struct DivTraitEval2< T1, T2
6271 using Type = CompressedMatrix< DivTrait_t< ElementType_t<T1>, T2 >
6272 , StorageOrder_v<T1>
6273 , DivTrait_t< TagType_t<T1>, T2 > >;
6289template<
typename T,
typename OP >
6290struct UnaryMapTraitEval2< T, OP
6293 using ElementType =
decltype( std::declval<OP>()( std::declval< ElementType_t<T> >() ) );
6295 using Type = CompressedMatrix< EvaluateTrait_t<ElementType>
6297 , MapTrait_t< TagType_t<T>, OP > >;
6315struct ExpandTraitEval2< T, E
6318 using Type = CompressedMatrix< ElementType_t<T>
6336template<
typename T,
size_t R0,
size_t R1 >
6337struct RepeatTraitEval2< T, R0, R1,
inf
6340 using Type = CompressedMatrix< ElementType_t<T>
6358template<
typename T1,
bool SO,
typename Tag,
typename T2 >
6359struct HighType< CompressedMatrix<T1,SO,Tag>, CompressedMatrix<T2,SO,Tag> >
6361 using Type = CompressedMatrix< typename HighType<T1,T2>::Type, SO, Tag >;
6377template<
typename T1,
bool SO,
typename Tag,
typename T2 >
6378struct LowType< CompressedMatrix<T1,SO,Tag>, CompressedMatrix<T2,SO,Tag> >
6380 using Type = CompressedMatrix< typename LowType<T1,T2>::Type, SO, Tag >;
6396template<
typename MT,
size_t I,
size_t J,
size_t M,
size_t N >
6397struct SubmatrixTraitEval2< MT, I, J, M, N
6400 using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >
6401 , StorageOrder_v<MT>
6418template<
typename MT,
size_t M >
6419struct RowsTraitEval2< MT, M
6422 using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >
6440template<
typename MT,
size_t N >
6441struct ColumnsTraitEval2< MT, N
6444 using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >
Header file for the addition trait.
Header file for auxiliary alias declarations.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.
Definition: Aliases.h:110
typename ResultType_t< T >::TagType TagType_t
Alias declaration for nested TagType type definitions.
Definition: Aliases.h:530
Header file for run time assertion macros.
Header file for the columns trait.
Constraint on the data type.
Header file for the division trait.
Header file for the EnableIf class template.
Header file for the EvaluateTrait class template.
Header file for the expand trait.
Header file for the HighType type trait.
Header file for the IntegralConstant class template.
Header file for the IsColumnVector type trait.
Header file for the isDefault shim.
Header file for the IsDenseMatrix type trait.
Header file for the IsFloatingPoint type trait.
Header file for the IsIdentity type trait.
Header file for the IsLower type trait.
Header file for the IsMatrix type trait.
Header file for the IsRowVector type trait.
Header file for the IsSMPAssignable type trait.
Header file for the IsScalar type trait.
Header file for the IsSparseMatrix type trait.
Header file for the IsSparseVector type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsUpper type trait.
Header file for the Kron product trait.
Header file for the LowType type trait.
Header file for the map trait.
Header file for the MatrixAccessProxy class.
Header file for memory allocation and deallocation functionality.
Header file for the multiplication trait.
Constraint on the data type.
Constraint on the data type.
Header file for the relaxation flag enumeration.
Header file for the RemoveConst type trait.
Header file for the repeat trait.
Header file for the rows trait.
Constraint on the size of two data types.
Header file for the Schur product trait.
Header file for the subtraction trait.
Header file for the submatrix trait.
Constraint on the data type.
Header file for the generic transfer algorithm.
Header file for the ValueIndexPair class.
Constraint on the data type.
Efficient implementation of a compressed matrix.
Definition: CompressedMatrix.h:239
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:547
Iterator * end_
Pointers one past the last non-zero element of each row.
Definition: CompressedMatrix.h:551
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2767
size_t capacity() const noexcept
Returns the maximum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1546
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:3026
CompressedMatrix< Type,!SO, Tag > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:332
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater than the given index.
Definition: CompressedMatrix.h:2633
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:329
CompressedMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CompressedMatrix.h:2704
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:548
SparseMatrix< This, SO > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:328
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:340
void erase(size_t i, size_t j)
Erasing an element from the compressed matrix.
Definition: CompressedMatrix.h:2338
size_t rows() const noexcept
Returns the current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:1516
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the compressed matrix.
Definition: CompressedMatrix.h:1695
CompressedMatrix & transpose()
In-place transpose of the matrix.
Definition: CompressedMatrix.h:2687
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2808
MatrixAccessProxy< This > Reference
Reference to a compressed matrix value.
Definition: CompressedMatrix.h:341
void append(size_t i, size_t j, const Type &value, bool check=false)
Appending an element to the specified row/column of the compressed matrix.
Definition: CompressedMatrix.h:2274
void clear()
Clearing the compressed matrix.
Definition: CompressedMatrix.h:1667
Iterator begin(size_t i) noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:1000
Iterator castDown(IteratorBase it) const noexcept
Performs a down-cast of the given iterator.
Definition: CompressedMatrix.h:2039
Iterator set(size_t i, size_t j, const Type &value)
Setting an element of the compressed matrix.
Definition: CompressedMatrix.h:2089
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:553
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: CompressedMatrix.h:1936
Reference operator()(size_t i, size_t j) noexcept
2D-access to the compressed matrix elements.
Definition: CompressedMatrix.h:888
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less than the given index.
Definition: CompressedMatrix.h:2576
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2972
CompressedMatrix< Type,!SO, Tag > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:335
size_t nonZeros() const
Returns the number of non-zero elements in the compressed matrix.
Definition: CompressedMatrix.h:1585
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2788
ValueIndexPair< Type > ElementBase
Base class for the compressed matrix element.
Definition: CompressedMatrix.h:242
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:344
ElementBase * IteratorBase
Iterator over non-constant base elements.
Definition: CompressedMatrix.h:243
void reserve(size_t nonzeros)
Setting the minimum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1793
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:1046
void reserveElements(size_t nonzeros)
Reserving the specified number of compressed matrix elements.
Definition: CompressedMatrix.h:1999
size_t columns() const noexcept
Returns the current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:1531
Tag TagType
Tag type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:338
size_t extendCapacity() const noexcept
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1978
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:371
void swap(CompressedMatrix &sm) noexcept
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1954
~CompressedMatrix()
The destructor for CompressedMatrix.
Definition: CompressedMatrix.h:853
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:343
Iterator end(size_t i) noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1069
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:339
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1627
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CompressedMatrix.h:944
const Type & ConstReference
Reference to a constant compressed matrix value.
Definition: CompressedMatrix.h:342
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1891
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2831
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:550
CompressedMatrix & operator=(initializer_list< initializer_list< Type > > list) &
List assignment to all matrix elements.
Definition: CompressedMatrix.h:1156
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:549
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:2122
IteratorBase castUp(Iterator it) const noexcept
Performs an up-cast of the given iterator.
Definition: CompressedMatrix.h:2058
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1115
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2307
void schurAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the Schur product assignment of a dense matrix.
Definition: CompressedMatrix.h:3080
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:2521
CompressedMatrix< Type, SO, Tag > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:327
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:337
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:598
Base class for dense matrices.
Definition: DenseMatrix.h:82
Access proxy for sparse, matrices.
Definition: MatrixAccessProxy.h:101
Base class for matrices.
Definition: Matrix.h:85
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Index-value-pair for sparse vectors and matrices.
Definition: ValueIndexPair.h:75
constexpr Reference value() noexcept
Access to the current value of the value-index-pair.
Definition: ValueIndexPair.h:370
Initializer list type of the Blaze library.
Pointer difference type of the Blaze library.
Constraint on the data type.
Header file for the SparseMatrix base class.
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Transfer.h:71
bool isDefault(const CompressedMatrix< Type, SO, Tag > &m)
Returns whether the given compressed matrix is in default state.
Definition: CompressedMatrix.h:6047
void swap(CompressedMatrix< Type, SO, Tag > &a, CompressedMatrix< Type, SO, Tag > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:6093
bool isIntact(const CompressedMatrix< Type, SO, Tag > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:6075
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.
Definition: Volatile.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.
Definition: SameSize.h:60
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.
Definition: Const.h:79
#define BLAZE_CONSTRAINT_MUST_BE_SAME_TAG(A, B)
Data type constraint.
Definition: SameTag.h:68
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1501
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
typename AddTrait< T1, T2 >::Type AddTrait_t
Auxiliary alias declaration for the AddTrait class template.
Definition: AddTrait.h:163
typename SubTrait< T1, T2 >::Type SubTrait_t
Auxiliary alias declaration for the SubTrait class template.
Definition: SubTrait.h:163
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.
Definition: MultTrait.h:165
constexpr bool IsScalar_v
Auxiliary variable template for the IsScalar type trait.
Definition: IsScalar.h:104
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.
Definition: IsMatrix.h:124
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.
Definition: IsSparseMatrix.h:124
constexpr bool IsSparseVector_v
Auxiliary variable template for the IsSparseVector type trait.
Definition: IsSparseVector.h:124
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
constexpr Infinity inf
Global Infinity instance.
Definition: Infinity.h:1080
constexpr size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:107
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:584
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
MT::Iterator lowerBound(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Returns an iterator to the first index not less than the given index.
Definition: SparseMatrix.h:194
MT::Iterator find(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Searches for a specific matrix element.
Definition: SparseMatrix.h:144
void deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
Header file for the exception macros of the math module.
Header file for all forward declarations of the math module.
Header file for the extended initializer_list functionality.
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
constexpr bool columnMajor
Storage order flag for column-major matrices.
Definition: StorageOrder.h:99
Header file for all forward declarations for sparse vectors and matrices.
Header file for the StorageOrder type trait.
Header file for the serial shim.
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:351
CompressedMatrix< NewType, SO, Tag > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:352
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:361
CompressedMatrix< Type, SO, Tag > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:362
Header file for the default storage order for all vectors of the Blaze library.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for the default transpose flag for all vectors of the Blaze library.
Header file for the IsZero type trait.
Header file for basic type definitions.
Header file for the generic max algorithm.
Header file for the generic min algorithm.