35#ifndef _BLAZE_MATH_VIEWS_ROW_DENSE_H_
36#define _BLAZE_MATH_VIEWS_ROW_DENSE_H_
123class Row<MT,true,true,SF,CRAs...>
124 :
public View< DenseVector< Row<MT,true,true,SF,CRAs...>, true > >
125 ,
private RowData<CRAs...>
129 using DataType = RowData<CRAs...>;
130 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
136 using This = Row<MT,
true,
true,SF,CRAs...>;
139 using BaseType = View< DenseVector<This,true> >;
141 using ViewedType = MT;
143 using TransposeType = TransposeType_t<ResultType>;
144 using ElementType = ElementType_t<MT>;
145 using SIMDType = SIMDTrait_t<ElementType>;
146 using ReturnType = ReturnType_t<MT>;
147 using CompositeType =
const Row&;
150 using ConstReference = ConstReference_t<MT>;
153 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
156 using ConstPointer = ConstPointer_t<MT>;
159 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
162 using ConstIterator = ConstIterator_t<MT>;
165 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
170 static constexpr bool simdEnabled = MT::simdEnabled;
173 static constexpr bool smpAssignable = MT::smpAssignable;
176 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
182 template<
typename... RRAs >
183 explicit inline Row( MT& matrix, RRAs... args );
185 Row(
const Row& ) =
default;
199 inline Reference operator[](
size_t index );
200 inline ConstReference operator[](
size_t index )
const;
201 inline Reference at(
size_t index );
202 inline ConstReference at(
size_t index )
const;
203 inline Pointer
data () noexcept;
204 inline ConstPointer
data () const noexcept;
205 inline Iterator
begin ();
206 inline ConstIterator
begin () const;
207 inline ConstIterator
cbegin() const;
208 inline Iterator
end ();
209 inline ConstIterator
end () const;
210 inline ConstIterator
cend () const;
217 inline Row& operator=( const ElementType& rhs );
219 inline Row& operator=( const Row& rhs );
221 template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
222 template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
223 template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
224 template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
225 template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
226 template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
235 inline MT& operand() noexcept;
236 inline const MT& operand() const noexcept;
238 inline
size_t size() const noexcept;
239 inline
size_t spacing() const noexcept;
240 inline
size_t capacity() const noexcept;
249 template< typename Other > inline Row& scale( const Other& scalar );
256 template< typename VT >
257 static constexpr
bool VectorizedAssign_v =
258 ( useOptimizedKernels &&
259 simdEnabled && VT::simdEnabled &&
265 template< typename VT >
266 static constexpr
bool VectorizedAddAssign_v =
267 ( VectorizedAssign_v<VT> &&
273 template< typename VT >
274 static constexpr
bool VectorizedSubAssign_v =
275 ( VectorizedAssign_v<VT> &&
281 template< typename VT >
282 static constexpr
bool VectorizedMultAssign_v =
283 ( VectorizedAssign_v<VT> &&
289 template< typename VT >
290 static constexpr
bool VectorizedDivAssign_v =
291 ( VectorizedAssign_v<VT> &&
297 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
304 template< typename Other >
305 inline
bool canAlias( const Other* alias ) const noexcept;
307 template< typename MT2,
bool SO2,
bool SF2,
size_t... CRAs2 >
308 inline
bool canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
310 template< typename Other >
311 inline
bool isAliased( const Other* alias ) const noexcept;
313 template< typename MT2,
bool SO2,
bool SF2,
size_t... CRAs2 >
314 inline
bool isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
316 inline
bool isAligned () const noexcept;
317 inline
bool canSMPAssign() const noexcept;
328 template< typename VT >
329 inline auto assign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedAssign_v<VT> >;
331 template< typename VT >
332 inline auto assign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedAssign_v<VT> >;
334 template< typename VT > inline
void assign( const SparseVector<VT,true>& rhs );
336 template< typename VT >
337 inline auto addAssign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<VT> >;
339 template< typename VT >
340 inline auto addAssign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<VT> >;
342 template< typename VT > inline
void addAssign( const SparseVector<VT,true>& rhs );
344 template< typename VT >
345 inline auto subAssign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<VT> >;
347 template< typename VT >
348 inline auto subAssign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<VT> >;
350 template< typename VT > inline
void subAssign( const SparseVector<VT,true>& rhs );
352 template< typename VT >
353 inline auto multAssign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedMultAssign_v<VT> >;
355 template< typename VT >
356 inline auto multAssign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedMultAssign_v<VT> >;
358 template< typename VT > inline
void multAssign( const SparseVector<VT,true>& rhs );
360 template< typename VT >
361 inline auto divAssign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedDivAssign_v<VT> >;
363 template< typename VT >
364 inline auto divAssign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedDivAssign_v<VT> >;
377 template< typename MT2,
bool SO2,
bool DF2,
bool SF2,
size_t... CRAs2 > friend class Row;
418template< typename... RRAs >
419inline Row<MT,true,true,SF,CRAs...>::Row( MT& matrix, RRAs... args )
420 : DataType( args... )
424 if( matrix_.rows() <=
row() ) {
457inline typename Row<MT,
true,
true,SF,CRAs...>::Reference
458 Row<MT,true,true,SF,CRAs...>::operator[](
size_t index )
461 return matrix_(
row(),index);
480inline typename Row<MT,
true,
true,SF,CRAs...>::ConstReference
481 Row<MT,true,true,SF,CRAs...>::operator[](
size_t index )
const
484 return const_cast<const MT&
>( matrix_ )(
row(),index);
504inline typename Row<MT,
true,
true,SF,CRAs...>::Reference
505 Row<MT,true,true,SF,CRAs...>::at(
size_t index )
507 if( index >=
size() ) {
510 return (*
this)[index];
530inline typename Row<MT,
true,
true,SF,CRAs...>::ConstReference
531 Row<MT,true,true,SF,CRAs...>::at(
size_t index )
const
533 if( index >=
size() ) {
536 return (*
this)[index];
554inline typename Row<MT,
true,
true,SF,CRAs...>::Pointer
557 return matrix_.data(
row() );
575inline typename Row<MT,
true,
true,SF,CRAs...>::ConstPointer
578 return matrix_.data(
row() );
595inline typename Row<MT,
true,
true,SF,CRAs...>::Iterator
598 return matrix_.begin(
row() );
615inline typename Row<MT,
true,
true,SF,CRAs...>::ConstIterator
618 return matrix_.cbegin(
row() );
635inline typename Row<MT,
true,
true,SF,CRAs...>::ConstIterator
638 return matrix_.cbegin(
row() );
655inline typename Row<MT,
true,
true,SF,CRAs...>::Iterator
658 return matrix_.end(
row() );
675inline typename Row<MT,
true,
true,SF,CRAs...>::ConstIterator
678 return matrix_.cend(
row() );
695inline typename Row<MT,
true,
true,SF,CRAs...>::ConstIterator
698 return matrix_.cend(
row() );
726inline Row<MT,
true,
true,SF,CRAs...>&
727 Row<MT,true,true,SF,CRAs...>::operator=(
const ElementType& rhs )
729 decltype(
auto) left( derestrict( matrix_ ) );
731 const size_t jbegin( ( IsUpper_v<MT> )
732 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
736 const size_t jend ( ( IsLower_v<MT> )
737 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
742 for(
size_t j=jbegin; j<jend; ++j ) {
743 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_,
row(), j, rhs ) )
771inline Row<MT,
true,
true,SF,CRAs...>&
774 if( list.size() >
size() ) {
778 if( IsRestricted_v<MT> ) {
779 const InitializerVector<ElementType,true> tmp( list,
size() );
780 if( !tryAssign( matrix_, tmp,
row(), 0UL ) ) {
785 decltype(
auto) left( derestrict( *
this ) );
787 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
814inline Row<MT,
true,
true,SF,CRAs...>&
815 Row<MT,true,true,SF,CRAs...>::operator=(
const Row& rhs )
817 if( &rhs ==
this )
return *
this;
819 if(
size() != rhs.size() ) {
823 if( !tryAssign( matrix_, rhs,
row(), 0UL ) ) {
827 decltype(
auto) left( derestrict( *
this ) );
829 if( IsExpression_v<MT> && rhs.canAlias(
this ) ) {
830 const ResultType tmp( rhs );
862template<
typename VT >
863inline Row<MT,
true,
true,SF,CRAs...>&
864 Row<MT,true,true,SF,CRAs...>::operator=(
const Vector<VT,true>& rhs )
869 if(
size() != (*rhs).size() ) {
873 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
876 if( !tryAssign( matrix_, right,
row(), 0UL ) ) {
880 decltype(
auto) left( derestrict( *
this ) );
882 if( IsReference_v<Right> && right.canAlias(
this ) ) {
883 const ResultType_t<VT> tmp( right );
887 if( IsSparseVector_v<VT> )
917template<
typename VT >
918inline Row<MT,
true,
true,SF,CRAs...>&
924 if(
size() != (*rhs).size() ) {
928 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
931 if( !tryAddAssign( matrix_, right,
row(), 0UL ) ) {
935 decltype(
auto) left( derestrict( *
this ) );
937 if( IsReference_v<Right> && right.canAlias(
this ) ) {
938 const ResultType_t<VT> tmp( right );
970template<
typename VT >
971inline Row<MT,
true,
true,SF,CRAs...>&
977 if(
size() != (*rhs).size() ) {
981 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
984 if( !trySubAssign( matrix_, right,
row(), 0UL ) ) {
988 decltype(
auto) left( derestrict( *
this ) );
990 if( IsReference_v<Right> && right.canAlias(
this ) ) {
991 const ResultType_t<VT> tmp( right );
1019template<
typename MT
1022template<
typename VT >
1023inline Row<MT,
true,
true,SF,CRAs...>&
1029 if(
size() != (*rhs).size() ) {
1033 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
1034 Right right( *rhs );
1036 if( !tryMultAssign( matrix_, right,
row(), 0UL ) ) {
1040 decltype(
auto) left( derestrict( *
this ) );
1042 if( IsReference_v<Right> && right.canAlias(
this ) ) {
1043 const ResultType_t<VT> tmp( right );
1070template<
typename MT
1073template<
typename VT >
1074inline Row<MT,
true,
true,SF,CRAs...>&
1080 if(
size() != (*rhs).size() ) {
1084 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
1085 Right right( *rhs );
1087 if( !tryDivAssign( matrix_, right,
row(), 0UL ) ) {
1091 decltype(
auto) left( derestrict( *
this ) );
1093 if( IsReference_v<Right> && right.canAlias(
this ) ) {
1094 const ResultType_t<VT> tmp( right );
1122template<
typename MT
1125template<
typename VT >
1126inline Row<MT,
true,
true,SF,CRAs...>&
1127 Row<MT,true,true,SF,CRAs...>::operator%=(
const Vector<VT,true>& rhs )
1129 using blaze::assign;
1134 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
1140 if(
size() != 3UL || (*rhs).size() != 3UL ) {
1144 const CrossType right( *
this % (*rhs) );
1146 if( !tryAssign( matrix_, right,
row(), 0UL ) ) {
1150 decltype(
auto) left( derestrict( *
this ) );
1152 assign( left, right );
1176template<
typename MT
1179inline MT& Row<MT,true,true,SF,CRAs...>::operand() noexcept
1193template<
typename MT
1196inline const MT& Row<MT,true,true,SF,CRAs...>::operand() const noexcept
1210template<
typename MT
1215 return matrix_.columns();
1230template<
typename MT
1235 return matrix_.spacing();
1247template<
typename MT
1252 return matrix_.capacity(
row() );
1267template<
typename MT
1272 return matrix_.nonZeros(
row() );
1284template<
typename MT
1289 matrix_.reset(
row() );
1316template<
typename MT
1319template<
typename Other >
1320inline Row<MT,
true,
true,SF,CRAs...>&
1321 Row<MT,true,true,SF,CRAs...>::scale(
const Other& scalar )
1325 const size_t jbegin( ( IsUpper_v<MT> )
1326 ?( ( IsStrictlyUpper_v<MT> )
1330 const size_t jend ( ( IsLower_v<MT> )
1331 ?( ( IsStrictlyLower_v<MT> )
1336 for(
size_t j=jbegin; j<jend; ++j ) {
1337 matrix_(
row(),j) *= scalar;
1365template<
typename MT
1368template<
typename Other >
1369inline bool Row<MT,true,true,SF,CRAs...>::canAlias(
const Other* alias )
const noexcept
1371 return matrix_.isAliased( &unview( *alias ) );
1388template<
typename MT
1391template<
typename MT2
1396 Row<MT,true,true,SF,CRAs...>::canAlias(
const Row<MT2,SO2,true,SF2,CRAs2...>* alias )
const noexcept
1398 return matrix_.isAliased( &alias->matrix_ ) && (
row() == alias->row() );
1415template<
typename MT
1418template<
typename Other >
1419inline bool Row<MT,true,true,SF,CRAs...>::isAliased(
const Other* alias )
const noexcept
1421 return matrix_.isAliased( &unview( *alias ) );
1438template<
typename MT
1441template<
typename MT2
1446 Row<MT,true,true,SF,CRAs...>::isAliased(
const Row<MT2,SO2,true,SF2,CRAs2...>* alias )
const noexcept
1448 return matrix_.isAliased( &alias->matrix_ ) && (
row() == alias->row() );
1464template<
typename MT
1467inline bool Row<MT,true,true,SF,CRAs...>::isAligned() const noexcept
1469 return matrix_.isAligned();
1486template<
typename MT
1489inline bool Row<MT,true,true,SF,CRAs...>::canSMPAssign() const noexcept
1491 return (
size() > SMP_DVECASSIGN_THRESHOLD );
1510template<
typename MT
1514 Row<MT,true,true,SF,CRAs...>::load(
size_t index )
const noexcept
1516 return matrix_.load(
row(), index );
1535template<
typename MT
1541 return matrix_.loada(
row(), index );
1560template<
typename MT
1566 return matrix_.loadu(
row(), index );
1586template<
typename MT
1590 Row<MT,true,true,SF,CRAs...>::store(
size_t index,
const SIMDType& value )
noexcept
1592 matrix_.store(
row(), index, value );
1612template<
typename MT
1618 matrix_.storea(
row(), index, value );
1638template<
typename MT
1644 matrix_.storeu(
row(), index, value );
1664template<
typename MT
1670 matrix_.stream(
row(), index, value );
1688template<
typename MT
1691template<
typename VT >
1692inline auto Row<MT,true,true,SF,CRAs...>::assign(
const DenseVector<VT,true>& rhs )
1693 -> DisableIf_t< VectorizedAssign_v<VT> >
1697 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
1700 for(
size_t j=0UL; j<jpos; j+=2UL ) {
1701 matrix_(
row(),j ) = (*rhs)[j ];
1702 matrix_(
row(),j+1UL) = (*rhs)[j+1UL];
1704 if( jpos < (*rhs).size() )
1705 matrix_(
row(),jpos) = (*rhs)[jpos];
1723template<
typename MT
1726template<
typename VT >
1727inline auto Row<MT,true,true,SF,CRAs...>::assign(
const DenseVector<VT,true>& rhs )
1728 -> EnableIf_t< VectorizedAssign_v<VT> >
1734 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1742 Iterator left(
begin() );
1743 ConstIterator_t<VT> right( (*rhs).begin() );
1745 if( useStreaming &&
columns > ( cacheSize/(
sizeof(ElementType) * 3UL ) ) && !(*rhs).isAliased(
this ) )
1747 for( ; j<jpos; j+=SIMDSIZE ) {
1748 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1750 for( ; remainder && j<
columns; ++j ) {
1751 *left = *right; ++left; ++right;
1756 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1757 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1758 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1759 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1760 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1762 for( ; j<jpos; j+=SIMDSIZE ) {
1763 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1765 for( ; remainder && j<
columns; ++j ) {
1766 *left = *right; ++left; ++right;
1786template<
typename MT
1789template<
typename VT >
1790inline void Row<MT,true,true,SF,CRAs...>::assign(
const SparseVector<VT,true>& rhs )
1794 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
1795 matrix_(
row(),element->index()) = element->value();
1813template<
typename MT
1816template<
typename VT >
1817inline auto Row<MT,true,true,SF,CRAs...>::addAssign(
const DenseVector<VT,true>& rhs )
1818 -> DisableIf_t< VectorizedAddAssign_v<VT> >
1822 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
1825 for(
size_t j=0UL; j<jpos; j+=2UL ) {
1826 matrix_(
row(),j ) += (*rhs)[j ];
1827 matrix_(
row(),j+1UL) += (*rhs)[j+1UL];
1829 if( jpos < (*rhs).size() )
1830 matrix_(
row(),jpos) += (*rhs)[jpos];
1848template<
typename MT
1851template<
typename VT >
1852inline auto Row<MT,true,true,SF,CRAs...>::addAssign(
const DenseVector<VT,true>& rhs )
1853 -> EnableIf_t< VectorizedAddAssign_v<VT> >
1859 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1867 Iterator left(
begin() );
1868 ConstIterator_t<VT> right( (*rhs).begin() );
1870 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1871 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1872 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1873 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1874 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1876 for( ; j<jpos; j+=SIMDSIZE ) {
1877 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1879 for( ; remainder && j<
columns; ++j ) {
1880 *left += *right; ++left; ++right;
1899template<
typename MT
1902template<
typename VT >
1903inline void Row<MT,true,true,SF,CRAs...>::addAssign(
const SparseVector<VT,true>& rhs )
1907 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
1908 matrix_(
row(),element->index()) += element->value();
1926template<
typename MT
1929template<
typename VT >
1930inline auto Row<MT,true,true,SF,CRAs...>::subAssign(
const DenseVector<VT,true>& rhs )
1931 -> DisableIf_t< VectorizedSubAssign_v<VT> >
1935 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
1938 for(
size_t j=0UL; j<jpos; j+=2UL ) {
1939 matrix_(
row(),j ) -= (*rhs)[j ];
1940 matrix_(
row(),j+1UL) -= (*rhs)[j+1UL];
1942 if( jpos < (*rhs).size() )
1943 matrix_(
row(),jpos) -= (*rhs)[jpos];
1961template<
typename MT
1964template<
typename VT >
1965inline auto Row<MT,true,true,SF,CRAs...>::subAssign(
const DenseVector<VT,true>& rhs )
1966 -> EnableIf_t< VectorizedSubAssign_v<VT> >
1972 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1980 Iterator left(
begin() );
1981 ConstIterator_t<VT> right( (*rhs).begin() );
1983 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1984 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1985 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1986 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1987 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1989 for( ; j<jpos; j+=SIMDSIZE ) {
1990 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1992 for( ; remainder && j<
columns; ++j ) {
1993 *left -= *right; ++left; ++right;
2012template<
typename MT
2015template<
typename VT >
2016inline void Row<MT,true,true,SF,CRAs...>::subAssign(
const SparseVector<VT,true>& rhs )
2020 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2021 matrix_(
row(),element->index()) -= element->value();
2039template<
typename MT
2042template<
typename VT >
2043inline auto Row<MT,true,true,SF,CRAs...>::multAssign(
const DenseVector<VT,true>& rhs )
2044 -> DisableIf_t< VectorizedMultAssign_v<VT> >
2048 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
2051 for(
size_t j=0UL; j<jpos; j+=2UL ) {
2052 matrix_(
row(),j ) *= (*rhs)[j ];
2053 matrix_(
row(),j+1UL) *= (*rhs)[j+1UL];
2055 if( jpos < (*rhs).size() )
2056 matrix_(
row(),jpos) *= (*rhs)[jpos];
2074template<
typename MT
2077template<
typename VT >
2078inline auto Row<MT,true,true,SF,CRAs...>::multAssign(
const DenseVector<VT,true>& rhs )
2079 -> EnableIf_t< VectorizedMultAssign_v<VT> >
2085 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
2093 Iterator left(
begin() );
2094 ConstIterator_t<VT> right( (*rhs).begin() );
2096 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2097 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2098 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2099 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2100 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2102 for( ; j<jpos; j+=SIMDSIZE ) {
2103 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2105 for( ; remainder && j<
columns; ++j ) {
2106 *left *= *right; ++left; ++right;
2125template<
typename MT
2128template<
typename VT >
2129inline void Row<MT,true,true,SF,CRAs...>::multAssign(
const SparseVector<VT,true>& rhs )
2137 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
2138 const size_t index( element->index() );
2139 for( ; j<index; ++j )
2141 matrix_(
row(),j) *= element->value();
2145 for( ; j<
size(); ++j ) {
2165template<
typename MT
2168template<
typename VT >
2169inline auto Row<MT,true,true,SF,CRAs...>::divAssign(
const DenseVector<VT,true>& rhs )
2170 -> DisableIf_t< VectorizedDivAssign_v<VT> >
2174 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
2177 for(
size_t j=0UL; j<jpos; j+=2UL ) {
2178 matrix_(
row(),j ) /= (*rhs)[j ];
2179 matrix_(
row(),j+1UL) /= (*rhs)[j+1UL];
2181 if( jpos < (*rhs).size() )
2182 matrix_(
row(),jpos) /= (*rhs)[jpos];
2200template<
typename MT
2203template<
typename VT >
2204inline auto Row<MT,true,true,SF,CRAs...>::divAssign(
const DenseVector<VT,true>& rhs )
2205 -> EnableIf_t< VectorizedDivAssign_v<VT> >
2217 Iterator left(
begin() );
2218 ConstIterator_t<VT> right( (*rhs).begin() );
2220 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2221 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2222 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2223 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2224 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2226 for( ; j<jpos; j+=SIMDSIZE ) {
2227 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2230 *left /= *right; ++left; ++right;
2257template<
typename MT
2259class Row<MT,false,true,false,CRAs...>
2260 :
public View< DenseVector< Row<MT,false,true,false,CRAs...>, true > >
2261 ,
private RowData<CRAs...>
2265 using DataType = RowData<CRAs...>;
2266 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
2272 using This = Row<MT,
false,
true,
false,CRAs...>;
2275 using BaseType = View< DenseVector<This,true> >;
2277 using ViewedType = MT;
2279 using TransposeType = TransposeType_t<ResultType>;
2280 using ElementType = ElementType_t<MT>;
2281 using ReturnType = ElementType_t<MT>;
2282 using CompositeType =
const Row&;
2285 using ConstReference = ConstReference_t<MT>;
2288 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
2291 using ConstPointer = ConstPointer_t<MT>;
2294 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
2300 template<
typename MatrixType
2301 ,
typename IteratorType >
2307 using IteratorCategory =
typename std::iterator_traits<IteratorType>::iterator_category;
2310 using ValueType =
typename std::iterator_traits<IteratorType>::value_type;
2313 using PointerType =
typename std::iterator_traits<IteratorType>::pointer;
2316 using ReferenceType =
typename std::iterator_traits<IteratorType>::reference;
2319 using DifferenceType =
typename std::iterator_traits<IteratorType>::difference_type;
2322 using iterator_category = IteratorCategory;
2323 using value_type = ValueType;
2324 using pointer = PointerType;
2325 using reference = ReferenceType;
2326 using difference_type = DifferenceType;
2332 inline RowIterator() noexcept
2333 : matrix_(
nullptr )
2347 inline RowIterator( MatrixType& matrix,
size_t row,
size_t column ) noexcept
2348 : matrix_( &matrix )
2353 if( column_ != matrix_->columns() )
2354 pos_ = matrix_->begin( column_ ) + row_;
2363 template<
typename MatrixType2,
typename IteratorType2 >
2364 inline RowIterator(
const RowIterator<MatrixType2,IteratorType2>& it ) noexcept
2365 : matrix_( it.matrix_ )
2367 , column_( it.column_ )
2378 inline RowIterator&
operator+=(
size_t inc )
noexcept {
2381 if( column_ != matrix_->columns() )
2382 pos_ = matrix_->begin( column_ ) + row_;
2394 inline RowIterator&
operator-=(
size_t dec )
noexcept {
2397 if( column_ != matrix_->columns() )
2398 pos_ = matrix_->begin( column_ ) + row_;
2409 inline RowIterator& operator++() noexcept {
2412 if( column_ != matrix_->columns() )
2413 pos_ = matrix_->begin( column_ ) + row_;
2424 inline const RowIterator operator++(
int )
noexcept {
2425 const RowIterator tmp( *
this );
2436 inline RowIterator& operator--() noexcept {
2439 if( column_ != matrix_->columns() )
2440 pos_ = matrix_->begin( column_ ) + row_;
2451 inline const RowIterator operator--(
int )
noexcept {
2452 const RowIterator tmp( *
this );
2464 inline ReferenceType operator[](
size_t index )
const {
2466 const IteratorType pos( matrix_->begin( column_+index ) + row_ );
2476 inline ReferenceType
operator*()
const {
2486 inline PointerType operator->()
const {
2497 template<
typename MatrixType2,
typename IteratorType2 >
2498 inline bool operator==(
const RowIterator<MatrixType2,IteratorType2>& rhs )
const noexcept {
2499 return column_ == rhs.column_;
2509 template<
typename MatrixType2,
typename IteratorType2 >
2510 inline bool operator!=(
const RowIterator<MatrixType2,IteratorType2>& rhs )
const noexcept {
2511 return !( *
this == rhs );
2521 template<
typename MatrixType2,
typename IteratorType2 >
2522 inline bool operator<(
const RowIterator<MatrixType2,IteratorType2>& rhs )
const noexcept {
2523 return column_ < rhs.column_;
2533 template<
typename MatrixType2,
typename IteratorType2 >
2534 inline bool operator>(
const RowIterator<MatrixType2,IteratorType2>& rhs )
const noexcept {
2535 return column_ > rhs.column_;
2545 template<
typename MatrixType2,
typename IteratorType2 >
2546 inline bool operator<=(
const RowIterator<MatrixType2,IteratorType2>& rhs )
const noexcept {
2547 return column_ <= rhs.column_;
2557 template<
typename MatrixType2,
typename IteratorType2 >
2558 inline bool operator>=(
const RowIterator<MatrixType2,IteratorType2>& rhs )
const noexcept {
2559 return column_ >= rhs.column_;
2569 inline DifferenceType
operator-(
const RowIterator& rhs )
const noexcept {
2570 return column_ - rhs.column_;
2581 friend inline const RowIterator
operator+(
const RowIterator& it,
size_t inc )
noexcept {
2582 return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2593 friend inline const RowIterator
operator+(
size_t inc,
const RowIterator& it )
noexcept {
2594 return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2605 friend inline const RowIterator
operator-(
const RowIterator& it,
size_t dec )
noexcept {
2606 return RowIterator( *it.matrix_, it.row_, it.column_-dec );
2612 MatrixType* matrix_;
2619 template<
typename MatrixType2,
typename IteratorType2 >
friend class RowIterator;
2626 using ConstIterator = RowIterator< const MT, ConstIterator_t<MT> >;
2629 using Iterator = If_t< IsConst_v<MT>, ConstIterator, RowIterator< MT, Iterator_t<MT> > >;
2634 static constexpr bool simdEnabled =
false;
2637 static constexpr bool smpAssignable = MT::smpAssignable;
2640 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2646 template<
typename... RRAs >
2647 explicit inline Row( MT& matrix, RRAs... args );
2649 Row(
const Row& ) =
default;
2663 inline Reference operator[](
size_t index );
2664 inline ConstReference operator[](
size_t index )
const;
2665 inline Reference at(
size_t index );
2666 inline ConstReference at(
size_t index )
const;
2667 inline Pointer
data () noexcept;
2668 inline ConstPointer
data () const noexcept;
2669 inline Iterator
begin ();
2670 inline ConstIterator
begin () const;
2671 inline ConstIterator
cbegin() const;
2672 inline Iterator
end ();
2673 inline ConstIterator
end () const;
2674 inline ConstIterator
cend () const;
2681 inline Row& operator=( const ElementType& rhs );
2683 inline Row& operator=( const Row& rhs );
2685 template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
2686 template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
2687 template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
2688 template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
2689 template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
2690 template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
2697 using DataType::
row;
2699 inline MT& operand() noexcept;
2700 inline const MT& operand() const noexcept;
2702 inline
size_t size() const noexcept;
2703 inline
size_t spacing() const noexcept;
2704 inline
size_t capacity() const noexcept;
2706 inline
void reset();
2713 template< typename Other > inline Row& scale( const Other& scalar );
2720 template< typename Other >
2721 inline
bool canAlias( const Other* alias ) const noexcept;
2723 template< typename MT2,
bool SO2,
bool SF2,
size_t... CRAs2 >
2724 inline
bool canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
2726 template< typename Other >
2727 inline
bool isAliased( const Other* alias ) const noexcept;
2729 template< typename MT2,
bool SO2,
bool SF2,
size_t... CRAs2 >
2730 inline
bool isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
2732 inline
bool isAligned () const noexcept;
2733 inline
bool canSMPAssign() const noexcept;
2735 template< typename VT > inline
void assign ( const DenseVector <VT,true>& rhs );
2736 template< typename VT > inline
void assign ( const SparseVector<VT,true>& rhs );
2737 template< typename VT > inline
void addAssign ( const DenseVector <VT,true>& rhs );
2738 template< typename VT > inline
void addAssign ( const SparseVector<VT,true>& rhs );
2739 template< typename VT > inline
void subAssign ( const DenseVector <VT,true>& rhs );
2740 template< typename VT > inline
void subAssign ( const SparseVector<VT,true>& rhs );
2741 template< typename VT > inline
void multAssign( const DenseVector <VT,true>& rhs );
2742 template< typename VT > inline
void multAssign( const SparseVector<VT,true>& rhs );
2743 template< typename VT > inline
void divAssign ( const DenseVector <VT,true>& rhs );
2756 template< typename MT2,
bool SO2,
bool DF2,
bool SF2,
size_t... CRAs2 > friend class Row;
2795template< typename MT
2797template< typename... RRAs >
2798inline Row<MT,false,true,false,CRAs...>::Row( MT& matrix, RRAs... args )
2799 : DataType( args... )
2800 , matrix_ ( matrix )
2803 if( matrix_.rows() <=
row() ) {
2833template<
typename MT
2835inline typename Row<MT,
false,
true,
false,CRAs...>::Reference
2836 Row<MT,false,true,false,CRAs...>::operator[](
size_t index )
2839 return matrix_(
row(),index);
2855template<
typename MT
2857inline typename Row<MT,
false,
true,
false,CRAs...>::ConstReference
2858 Row<MT,false,true,false,CRAs...>::operator[](
size_t index )
const
2861 return const_cast<const MT&
>( matrix_ )(
row(),index);
2878template<
typename MT
2880inline typename Row<MT,
false,
true,
false,CRAs...>::Reference
2881 Row<MT,false,true,false,CRAs...>::at(
size_t index )
2883 if( index >=
size() ) {
2886 return (*
this)[index];
2903template<
typename MT
2905inline typename Row<MT,
false,
true,
false,CRAs...>::ConstReference
2906 Row<MT,false,true,false,CRAs...>::at(
size_t index )
const
2908 if( index >=
size() ) {
2911 return (*
this)[index];
2926template<
typename MT
2928inline typename Row<MT,
false,
true,
false,CRAs...>::Pointer
2931 return matrix_.data() +
row();
2946template<
typename MT
2948inline typename Row<MT,
false,
true,
false,CRAs...>::ConstPointer
2951 return matrix_.data() +
row();
2965template<
typename MT
2967inline typename Row<MT,
false,
true,
false,CRAs...>::Iterator
2970 return Iterator( matrix_,
row(), 0UL );
2984template<
typename MT
2986inline typename Row<MT,
false,
true,
false,CRAs...>::ConstIterator
2989 return ConstIterator( matrix_,
row(), 0UL );
3003template<
typename MT
3005inline typename Row<MT,
false,
true,
false,CRAs...>::ConstIterator
3008 return ConstIterator( matrix_,
row(), 0UL );
3022template<
typename MT
3024inline typename Row<MT,
false,
true,
false,CRAs...>::Iterator
3027 return Iterator( matrix_,
row(),
size() );
3041template<
typename MT
3043inline typename Row<MT,
false,
true,
false,CRAs...>::ConstIterator
3046 return ConstIterator( matrix_,
row(),
size() );
3060template<
typename MT
3062inline typename Row<MT,
false,
true,
false,CRAs...>::ConstIterator
3065 return ConstIterator( matrix_,
row(),
size() );
3090template<
typename MT
3092inline Row<MT,
false,
true,
false,CRAs...>&
3093 Row<MT,false,true,false,CRAs...>::operator=(
const ElementType& rhs )
3095 decltype(
auto) left( derestrict( matrix_ ) );
3097 const size_t jbegin( ( IsUpper_v<MT> )
3098 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3102 const size_t jend ( ( IsLower_v<MT> )
3103 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3108 for(
size_t j=jbegin; j<jend; ++j ) {
3109 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_,
row(), j, rhs ) )
3110 left(
row(),j) = rhs;
3134template<
typename MT
3136inline Row<MT,
false,
true,
false,CRAs...>&
3139 if( list.size() >
size() ) {
3143 if( IsRestricted_v<MT> ) {
3144 const InitializerVector<ElementType,true> tmp( list,
size() );
3145 if( !tryAssign( matrix_, tmp,
row(), 0UL ) ) {
3150 decltype(
auto) left( derestrict( *
this ) );
3152 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
3176template<
typename MT
3178inline Row<MT,
false,
true,
false,CRAs...>&
3179 Row<MT,false,true,false,CRAs...>::operator=(
const Row& rhs )
3181 if( &rhs ==
this )
return *
this;
3183 if(
size() != rhs.size() ) {
3187 if( !tryAssign( matrix_, rhs,
row(), 0UL ) ) {
3191 decltype(
auto) left( derestrict( *
this ) );
3193 if( IsExpression_v<MT> && rhs.canAlias(
this ) ) {
3194 const ResultType tmp( rhs );
3223template<
typename MT
3225template<
typename VT >
3226inline Row<MT,
false,
true,
false,CRAs...>&
3227 Row<MT,false,true,false,CRAs...>::operator=(
const Vector<VT,true>& rhs )
3233 if(
size() != (*rhs).size() ) {
3237 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
3238 Right right( *rhs );
3240 if( !tryAssign( matrix_, right,
row(), 0UL ) ) {
3244 decltype(
auto) left( derestrict( *
this ) );
3246 if( IsReference_v<Right> && right.canAlias(
this ) ) {
3247 const ResultType tmp( right );
3251 if( IsSparseVector_v<VT> )
3278template<
typename MT
3280template<
typename VT >
3281inline Row<MT,
false,
true,
false,CRAs...>&
3287 if(
size() != (*rhs).size() ) {
3291 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
3292 Right right( *rhs );
3294 if( !tryAddAssign( matrix_, right,
row(), 0UL ) ) {
3298 decltype(
auto) left( derestrict( *
this ) );
3300 if( IsReference_v<Right> && right.canAlias(
this ) ) {
3301 const ResultType_t<VT> tmp( right );
3330template<
typename MT
3332template<
typename VT >
3333inline Row<MT,
false,
true,
false,CRAs...>&
3339 if(
size() != (*rhs).size() ) {
3343 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
3344 Right right( *rhs );
3346 if( !trySubAssign( matrix_, right,
row(), 0UL ) ) {
3350 decltype(
auto) left( derestrict( *
this ) );
3352 if( IsReference_v<Right> && right.canAlias(
this ) ) {
3353 const ResultType_t<VT> tmp( right );
3381template<
typename MT
3383template<
typename VT >
3384inline Row<MT,
false,
true,
false,CRAs...>&
3390 if(
size() != (*rhs).size() ) {
3394 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
3395 Right right( *rhs );
3397 if( !tryMultAssign( matrix_, right,
row(), 0UL ) ) {
3401 decltype(
auto) left( derestrict( *
this ) );
3403 if( IsReference_v<Right> && right.canAlias(
this ) ) {
3404 const ResultType_t<VT> tmp( right );
3431template<
typename MT
3433template<
typename VT >
3434inline Row<MT,
false,
true,
false,CRAs...>&
3440 if(
size() != (*rhs).size() ) {
3444 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
3445 Right right( *rhs );
3447 if( !tryDivAssign( matrix_, right,
row(), 0UL ) ) {
3451 decltype(
auto) left( derestrict( *
this ) );
3453 if( IsReference_v<Right> && right.canAlias(
this ) ) {
3454 const ResultType_t<VT> tmp( right );
3482template<
typename MT
3484template<
typename VT >
3485inline Row<MT,
false,
true,
false,CRAs...>&
3486 Row<MT,false,true,false,CRAs...>::operator%=(
const Vector<VT,true>& rhs )
3488 using blaze::assign;
3493 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
3499 if(
size() != 3UL || (*rhs).size() != 3UL ) {
3503 const CrossType right( *
this % (*rhs) );
3505 if( !tryAssign( matrix_, right,
row(), 0UL ) ) {
3509 decltype(
auto) left( derestrict( *
this ) );
3511 assign( left, right );
3535template<
typename MT
3537inline MT& Row<MT,false,true,false,CRAs...>::operand() noexcept
3551template<
typename MT
3553inline const MT& Row<MT,false,true,false,CRAs...>::operand() const noexcept
3567template<
typename MT
3571 return matrix_.columns();
3586template<
typename MT
3590 return matrix_.spacing();
3602template<
typename MT
3606 return matrix_.columns();
3621template<
typename MT
3626 size_t nonzeros( 0UL );
3628 for(
size_t j=0UL; j<
columns; ++j )
3644template<
typename MT
3650 const size_t jbegin( ( IsUpper_v<MT> )
3651 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3655 const size_t jend ( ( IsLower_v<MT> )
3656 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3661 for(
size_t j=jbegin; j<jend; ++j )
3689template<
typename MT
3691template<
typename Other >
3692inline Row<MT,
false,
true,
false,CRAs...>&
3693 Row<MT,false,true,false,CRAs...>::scale(
const Other& scalar )
3697 const size_t jbegin( ( IsUpper_v<MT> )
3698 ?( ( IsStrictlyUpper_v<MT> )
3702 const size_t jend ( ( IsLower_v<MT> )
3703 ?( ( IsStrictlyLower_v<MT> )
3708 for(
size_t j=jbegin; j<jend; ++j ) {
3709 matrix_(
row(),j) *= scalar;
3737template<
typename MT
3739template<
typename Other >
3740inline bool Row<MT,false,true,false,CRAs...>::canAlias(
const Other* alias )
const noexcept
3742 return matrix_.isAliased( &unview( *alias ) );
3759template<
typename MT
3761template<
typename MT2
3766 Row<MT,false,true,false,CRAs...>::canAlias(
const Row<MT2,SO2,true,SF2,CRAs2...>* alias )
const noexcept
3768 return matrix_.isAliased( &alias->matrix_ ) && (
row() == alias->row() );
3785template<
typename MT
3787template<
typename Other >
3788inline bool Row<MT,false,true,false,CRAs...>::isAliased(
const Other* alias )
const noexcept
3790 return matrix_.isAliased( &unview( *alias ) );
3807template<
typename MT
3809template<
typename MT2
3814 Row<MT,false,true,false,CRAs...>::isAliased(
const Row<MT2,SO2,true,SF2,CRAs2...>* alias )
const noexcept
3816 return matrix_.isAliased( &alias->matrix_ ) && (
row() == alias->row() );
3832template<
typename MT
3834inline bool Row<MT,false,true,false,CRAs...>::isAligned() const noexcept
3853template<
typename MT
3855inline bool Row<MT,false,true,false,CRAs...>::canSMPAssign() const noexcept
3857 return (
size() > SMP_DVECASSIGN_THRESHOLD );
3875template<
typename MT
3877template<
typename VT >
3878inline void Row<MT,false,true,false,CRAs...>::assign(
const DenseVector<VT,true>& rhs )
3882 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
3885 for(
size_t j=0UL; j<jpos; j+=2UL ) {
3886 matrix_(
row(),j ) = (*rhs)[j ];
3887 matrix_(
row(),j+1UL) = (*rhs)[j+1UL];
3889 if( jpos < (*rhs).size() )
3890 matrix_(
row(),jpos) = (*rhs)[jpos];
3908template<
typename MT
3910template<
typename VT >
3911inline void Row<MT,false,true,false,CRAs...>::assign(
const SparseVector<VT,true>& rhs )
3915 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
3916 matrix_(
row(),element->index()) = element->value();
3934template<
typename MT
3936template<
typename VT >
3937inline void Row<MT,false,true,false,CRAs...>::addAssign(
const DenseVector<VT,true>& rhs )
3941 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
3944 for(
size_t j=0UL; j<jpos; j+=2UL ) {
3945 matrix_(
row(),j ) += (*rhs)[j ];
3946 matrix_(
row(),j+1UL) += (*rhs)[j+1UL];
3948 if( jpos < (*rhs).size() )
3949 matrix_(
row(),jpos) += (*rhs)[jpos];
3967template<
typename MT
3969template<
typename VT >
3970inline void Row<MT,false,true,false,CRAs...>::addAssign(
const SparseVector<VT,true>& rhs )
3974 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
3975 matrix_(
row(),element->index()) += element->value();
3993template<
typename MT
3995template<
typename VT >
3996inline void Row<MT,false,true,false,CRAs...>::subAssign(
const DenseVector<VT,true>& rhs )
4000 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
4003 for(
size_t j=0UL; j<jpos; j+=2UL ) {
4004 matrix_(
row(),j ) -= (*rhs)[j ];
4005 matrix_(
row(),j+1UL) -= (*rhs)[j+1UL];
4007 if( jpos < (*rhs).size() )
4008 matrix_(
row(),jpos) -= (*rhs)[jpos];
4026template<
typename MT
4028template<
typename VT >
4029inline void Row<MT,false,true,false,CRAs...>::subAssign(
const SparseVector<VT,true>& rhs )
4033 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
4034 matrix_(
row(),element->index()) -= element->value();
4052template<
typename MT
4054template<
typename VT >
4055inline void Row<MT,false,true,false,CRAs...>::multAssign(
const DenseVector<VT,true>& rhs )
4059 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
4062 for(
size_t j=0UL; j<jpos; j+=2UL ) {
4063 matrix_(
row(),j ) *= (*rhs)[j ];
4064 matrix_(
row(),j+1UL) *= (*rhs)[j+1UL];
4066 if( jpos < (*rhs).size() )
4067 matrix_(
row(),jpos) *= (*rhs)[jpos];
4085template<
typename MT
4087template<
typename VT >
4088inline void Row<MT,false,true,false,CRAs...>::multAssign(
const SparseVector<VT,true>& rhs )
4096 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
4097 const size_t index( element->index() );
4098 for( ; j<index; ++j )
4100 matrix_(
row(),j) *= element->value();
4104 for( ; j<
size(); ++j ) {
4124template<
typename MT
4126template<
typename VT >
4127inline void Row<MT,false,true,false,CRAs...>::divAssign(
const DenseVector<VT,true>& rhs )
4131 const size_t jpos(
prevMultiple( (*rhs).size(), 2UL ) );
4134 for(
size_t j=0UL; j<jpos; j+=2UL ) {
4135 matrix_(
row(),j ) /= (*rhs)[j ];
4136 matrix_(
row(),j+1UL) /= (*rhs)[j+1UL];
4138 if( jpos < (*rhs).size() )
4139 matrix_(
row(),jpos) /= (*rhs)[jpos];
4165template<
typename MT
4167class Row<MT,false,true,true,CRAs...>
4168 :
public View< DenseVector< Row<MT,false,true,true,CRAs...>, true > >
4169 ,
private RowData<CRAs...>
4173 using DataType = RowData<CRAs...>;
4174 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
4180 using This = Row<MT,
false,
true,
true,CRAs...>;
4183 using BaseType = View< DenseVector<This,true> >;
4185 using ViewedType = MT;
4187 using TransposeType = TransposeType_t<ResultType>;
4188 using ElementType = ElementType_t<MT>;
4189 using SIMDType = SIMDTrait_t<ElementType>;
4190 using ReturnType = ElementType_t<MT>;
4191 using CompositeType =
const Row&;
4194 using ConstReference = ConstReference_t<MT>;
4197 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
4200 using ConstPointer = ConstPointer_t<MT>;
4203 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
4206 using ConstIterator = ConstIterator_t<MT>;
4209 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
4214 static constexpr bool simdEnabled = MT::simdEnabled;
4217 static constexpr bool smpAssignable = MT::smpAssignable;
4220 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4226 template<
typename... RRAs >
4227 explicit inline Row( MT& matrix, RRAs... args );
4229 Row(
const Row& ) =
default;
4243 inline Reference operator[](
size_t index );
4244 inline ConstReference operator[](
size_t index )
const;
4245 inline Reference at(
size_t index );
4246 inline ConstReference at(
size_t index )
const;
4247 inline Pointer
data () noexcept;
4248 inline ConstPointer
data () const noexcept;
4249 inline Iterator
begin ();
4250 inline ConstIterator
begin () const;
4251 inline ConstIterator
cbegin() const;
4252 inline Iterator
end ();
4253 inline ConstIterator
end () const;
4254 inline ConstIterator
cend () const;
4261 inline Row& operator=( const ElementType& rhs );
4263 inline Row& operator=( const Row& rhs );
4265 template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
4266 template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
4267 template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
4268 template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
4269 template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
4270 template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
4277 using DataType::
row;
4279 inline MT& operand() noexcept;
4280 inline const MT& operand() const noexcept;
4282 inline
size_t size() const noexcept;
4283 inline
size_t spacing() const noexcept;
4284 inline
size_t capacity() const noexcept;
4286 inline
void reset();
4293 template< typename Other > inline Row& scale( const Other& scalar );
4300 template< typename VT >
4301 static constexpr
bool VectorizedAssign_v =
4302 ( useOptimizedKernels &&
4303 simdEnabled && VT::simdEnabled &&
4309 template< typename VT >
4310 static constexpr
bool VectorizedAddAssign_v =
4311 ( VectorizedAssign_v<VT> &&
4317 template< typename VT >
4318 static constexpr
bool VectorizedSubAssign_v =
4319 ( VectorizedAssign_v<VT> &&
4325 template< typename VT >
4326 static constexpr
bool VectorizedMultAssign_v =
4327 ( VectorizedAssign_v<VT> &&
4333 template< typename VT >
4334 static constexpr
bool VectorizedDivAssign_v =
4335 ( VectorizedAssign_v<VT> &&
4341 static constexpr
size_t SIMDSIZE = SIMDTrait<ElementType>::
size;
4348 template< typename Other >
4349 inline
bool canAlias( const Other* alias ) const noexcept;
4351 template< typename MT2,
bool SO2,
bool SF2,
size_t... CRAs2 >
4352 inline
bool canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
4354 template< typename Other >
4355 inline
bool isAliased( const Other* alias ) const noexcept;
4357 template< typename MT2,
bool SO2,
bool SF2,
size_t... CRAs2 >
4358 inline
bool isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
4360 inline
bool isAligned () const noexcept;
4361 inline
bool canSMPAssign() const noexcept;
4372 template< typename VT >
4373 inline auto assign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedAssign_v<VT> >;
4375 template< typename VT >
4376 inline auto assign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedAssign_v<VT> >;
4378 template< typename VT > inline
void assign( const SparseVector<VT,true>& rhs );
4380 template< typename VT >
4381 inline auto addAssign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedAddAssign_v<VT> >;
4383 template< typename VT >
4384 inline auto addAssign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedAddAssign_v<VT> >;
4386 template< typename VT > inline
void addAssign( const SparseVector<VT,true>& rhs );
4388 template< typename VT >
4389 inline auto subAssign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedSubAssign_v<VT> >;
4391 template< typename VT >
4392 inline auto subAssign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedSubAssign_v<VT> >;
4394 template< typename VT > inline
void subAssign( const SparseVector<VT,true>& rhs );
4396 template< typename VT >
4397 inline auto multAssign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedMultAssign_v<VT> >;
4399 template< typename VT >
4400 inline auto multAssign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedMultAssign_v<VT> >;
4402 template< typename VT > inline
void multAssign( const SparseVector<VT,true>& rhs );
4404 template< typename VT >
4405 inline auto divAssign( const DenseVector<VT,true>& rhs ) ->
DisableIf_t< VectorizedDivAssign_v<VT> >;
4407 template< typename VT >
4408 inline auto divAssign( const DenseVector<VT,true>& rhs ) ->
EnableIf_t< VectorizedDivAssign_v<VT> >;
4421 template< typename MT2,
bool SO2,
bool DF2,
bool SF2,
size_t... CRAs2 > friend class Row;
4460template< typename MT
4462template< typename... RRAs >
4463inline Row<MT,false,true,true,CRAs...>::Row( MT& matrix, RRAs... args )
4464 : DataType( args... )
4465 , matrix_ ( matrix )
4468 if( matrix_.rows() <=
row() ) {
4498template<
typename MT
4500inline typename Row<MT,
false,
true,
true,CRAs...>::Reference
4501 Row<MT,false,true,true,CRAs...>::operator[](
size_t index )
4504 return matrix_(index,
row());
4520template<
typename MT
4522inline typename Row<MT,
false,
true,
true,CRAs...>::ConstReference
4523 Row<MT,false,true,true,CRAs...>::operator[](
size_t index )
const
4526 return const_cast<const MT&
>( matrix_ )(index,
row());
4543template<
typename MT
4545inline typename Row<MT,
false,
true,
true,CRAs...>::Reference
4546 Row<MT,false,true,true,CRAs...>::at(
size_t index )
4548 if( index >=
size() ) {
4551 return (*
this)[index];
4568template<
typename MT
4570inline typename Row<MT,
false,
true,
true,CRAs...>::ConstReference
4571 Row<MT,false,true,true,CRAs...>::at(
size_t index )
const
4573 if( index >=
size() ) {
4576 return (*
this)[index];
4591template<
typename MT
4593inline typename Row<MT,
false,
true,
true,CRAs...>::Pointer
4596 return matrix_.data(
row() );
4611template<
typename MT
4613inline typename Row<MT,
false,
true,
true,CRAs...>::ConstPointer
4616 return matrix_.data(
row() );
4630template<
typename MT
4632inline typename Row<MT,
false,
true,
true,CRAs...>::Iterator
4635 return matrix_.begin(
row() );
4649template<
typename MT
4651inline typename Row<MT,
false,
true,
true,CRAs...>::ConstIterator
4654 return matrix_.cbegin(
row() );
4668template<
typename MT
4670inline typename Row<MT,
false,
true,
true,CRAs...>::ConstIterator
4673 return matrix_.cbegin(
row() );
4687template<
typename MT
4689inline typename Row<MT,
false,
true,
true,CRAs...>::Iterator
4692 return matrix_.end(
row() );
4706template<
typename MT
4708inline typename Row<MT,
false,
true,
true,CRAs...>::ConstIterator
4711 return matrix_.cend(
row() );
4725template<
typename MT
4727inline typename Row<MT,
false,
true,
true,CRAs...>::ConstIterator
4730 return matrix_.cend(
row() );
4751template<
typename MT
4753inline Row<MT,
false,
true,
true,CRAs...>&
4754 Row<MT,false,true,true,CRAs...>::operator=(
const ElementType& rhs )
4756 decltype(
auto) left( derestrict( matrix_ ) );
4758 const size_t ibegin( ( IsLower_v<MT> )
4759 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
4763 const size_t iend ( ( IsUpper_v<MT> )
4764 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
4769 for(
size_t i=ibegin; i<iend; ++i ) {
4770 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i,
row(), rhs ) )
4771 left(i,
row()) = rhs;
4795template<
typename MT
4797inline Row<MT,
false,
true,
true,CRAs...>&
4800 if( list.size() >
size() ) {
4804 if( IsRestricted_v<MT> ) {
4805 const InitializerVector<ElementType,true> tmp( list,
size() );
4806 if( !tryAssign( matrix_, tmp,
row(), 0UL ) ) {
4811 decltype(
auto) left( derestrict( *
this ) );
4813 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
4837template<
typename MT
4839inline Row<MT,
false,
true,
true,CRAs...>&
4840 Row<MT,false,true,true,CRAs...>::operator=(
const Row& rhs )
4842 if( &rhs ==
this )
return *
this;
4844 if(
size() != rhs.size() ) {
4848 if( !tryAssign( matrix_, rhs,
row(), 0UL ) ) {
4852 decltype(
auto) left( derestrict( *
this ) );
4854 if( IsExpression_v<MT> && rhs.canAlias(
this ) ) {
4855 const ResultType tmp( rhs );
4884template<
typename MT
4886template<
typename VT >
4887inline Row<MT,
false,
true,
true,CRAs...>&
4888 Row<MT,false,true,true,CRAs...>::operator=(
const Vector<VT,true>& rhs )
4893 if(
size() != (*rhs).size() ) {
4897 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
4898 Right right( *rhs );
4900 if( !tryAssign( matrix_, right,
row(), 0UL ) ) {
4904 decltype(
auto) left( derestrict( *
this ) );
4906 if( IsReference_v<Right> && right.canAlias(
this ) ) {
4907 const ResultType_t<VT> tmp( right );
4911 if( IsSparseVector_v<VT> )
4938template<
typename MT
4940template<
typename VT >
4941inline Row<MT,
false,
true,
true,CRAs...>&
4947 if(
size() != (*rhs).size() ) {
4951 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
4952 Right right( *rhs );
4954 if( !tryAddAssign( matrix_, right,
row(), 0UL ) ) {
4958 decltype(
auto) left( derestrict( *
this ) );
4960 if( IsReference_v<Right> && right.canAlias(
this ) ) {
4961 const ResultType_t<VT> tmp( right );
4990template<
typename MT
4992template<
typename VT >
4993inline Row<MT,
false,
true,
true,CRAs...>&
4999 if(
size() != (*rhs).size() ) {
5003 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
5004 Right right( *rhs );
5006 if( !trySubAssign( matrix_, right,
row(), 0UL ) ) {
5010 decltype(
auto) left( derestrict( *
this ) );
5012 if( IsReference_v<Right> && right.canAlias(
this ) ) {
5013 const ResultType_t<VT> tmp( right );
5041template<
typename MT
5043template<
typename VT >
5044inline Row<MT,
false,
true,
true,CRAs...>&
5050 if(
size() != (*rhs).size() ) {
5054 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
5055 Right right( *rhs );
5057 if( !tryMultAssign( matrix_, right,
row(), 0UL ) ) {
5061 decltype(
auto) left( derestrict( *
this ) );
5063 if( IsReference_v<Right> && right.canAlias(
this ) ) {
5064 const ResultType_t<VT> tmp( right );
5091template<
typename MT
5093template<
typename VT >
5094inline Row<MT,
false,
true,
true,CRAs...>&
5100 if(
size() != (*rhs).size() ) {
5104 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>,
const VT& >;
5105 Right right( *rhs );
5107 if( !tryDivAssign( matrix_, right,
row(), 0UL ) ) {
5111 decltype(
auto) left( derestrict( *
this ) );
5113 if( IsReference_v<Right> && right.canAlias(
this ) ) {
5114 const ResultType_t<VT> tmp( right );
5142template<
typename MT
5144template<
typename VT >
5145inline Row<MT,
false,
true,
true,CRAs...>&
5146 Row<MT,false,true,true,CRAs...>::operator%=(
const Vector<VT,true>& rhs )
5148 using blaze::assign;
5153 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
5159 if(
size() != 3UL || (*rhs).size() != 3UL ) {
5163 const CrossType right( *
this % (*rhs) );
5165 if( !tryAssign( matrix_, right,
row(), 0UL ) ) {
5169 decltype(
auto) left( derestrict( *
this ) );
5171 assign( left, right );
5195template<
typename MT
5197inline MT& Row<MT,false,true,true,CRAs...>::operand() noexcept
5211template<
typename MT
5213inline const MT& Row<MT,false,true,true,CRAs...>::operand() const noexcept
5227template<
typename MT
5231 return matrix_.columns();
5246template<
typename MT
5250 return matrix_.spacing();
5262template<
typename MT
5266 return matrix_.capacity(
row() );
5281template<
typename MT
5285 return matrix_.nonZeros(
row() );
5297template<
typename MT
5301 matrix_.reset(
row() );
5328template<
typename MT
5330template<
typename Other >
5331inline Row<MT,
false,
true,
true,CRAs...>&
5332 Row<MT,false,true,true,CRAs...>::scale(
const Other& scalar )
5336 const size_t ibegin( ( IsLower_v<MT> )
5337 ?( ( IsStrictlyLower_v<MT> )
5341 const size_t iend ( ( IsUpper_v<MT> )
5342 ?( ( IsStrictlyUpper_v<MT> )
5347 for(
size_t i=ibegin; i<iend; ++i ) {
5348 matrix_(i,
row()) *= scalar;
5376template<
typename MT
5378template<
typename Other >
5379inline bool Row<MT,false,true,true,CRAs...>::canAlias(
const Other* alias )
const noexcept
5381 return matrix_.isAliased( &unview( *alias ) );
5398template<
typename MT
5400template<
typename MT2
5405 Row<MT,false,true,true,CRAs...>::canAlias(
const Row<MT2,SO2,true,SF2,CRAs2...>* alias )
const noexcept
5407 return matrix_.isAliased( &alias->matrix_ ) && (
row() == alias->row() );
5424template<
typename MT
5426template<
typename Other >
5427inline bool Row<MT,false,true,true,CRAs...>::isAliased(
const Other* alias )
const noexcept
5429 return matrix_.isAliased( &unview( *alias ) );
5446template<
typename MT
5448template<
typename MT2
5453 Row<MT,false,true,true,CRAs...>::isAliased(
const Row<MT2,SO2,true,SF2,CRAs2...>* alias )
const noexcept
5455 return matrix_.isAliased( &alias->matrix_ ) && (
row() == alias->row() );
5471template<
typename MT
5473inline bool Row<MT,false,true,true,CRAs...>::isAligned() const noexcept
5475 return matrix_.isAligned();
5492template<
typename MT
5494inline bool Row<MT,false,true,true,CRAs...>::canSMPAssign() const noexcept
5496 return (
size() > SMP_DVECASSIGN_THRESHOLD );
5515template<
typename MT
5518 Row<MT,false,true,true,CRAs...>::load(
size_t index )
const noexcept
5520 return matrix_.load( index,
row() );
5539template<
typename MT
5544 return matrix_.loada( index,
row() );
5563template<
typename MT
5568 return matrix_.loadu( index,
row() );
5588template<
typename MT
5591 Row<MT,false,true,true,CRAs...>::store(
size_t index,
const SIMDType& value )
noexcept
5593 matrix_.store( index,
row(), value );
5613template<
typename MT
5618 matrix_.storea( index,
row(), value );
5638template<
typename MT
5643 matrix_.storeu( index,
row(), value );
5663template<
typename MT
5668 matrix_.stream( index,
row(), value );
5686template<
typename MT
5688template<
typename VT >
5689inline auto Row<MT,false,true,true,CRAs...>::assign(
const DenseVector<VT,true>& rhs )
5690 -> DisableIf_t< VectorizedAssign_v<VT> >
5694 const size_t ipos(
prevMultiple( (*rhs).size(), 2UL ) );
5697 for(
size_t i=0UL; i<ipos; i+=2UL ) {
5698 matrix_(i ,
row()) = (*rhs)[i ];
5699 matrix_(i+1UL,
row()) = (*rhs)[i+1UL];
5701 if( ipos < (*rhs).size() )
5702 matrix_(ipos,
row()) = (*rhs)[ipos];
5720template<
typename MT
5722template<
typename VT >
5723inline auto Row<MT,false,true,true,CRAs...>::assign(
const DenseVector<VT,true>& rhs )
5724 -> EnableIf_t< VectorizedAssign_v<VT> >
5730 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5738 Iterator left(
begin() );
5739 ConstIterator_t<VT> right( (*rhs).begin() );
5741 if( useStreaming &&
rows > ( cacheSize/(
sizeof(ElementType) * 3UL ) ) && !(*rhs).isAliased(
this ) )
5743 for( ; i<ipos; i+=SIMDSIZE ) {
5744 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5746 for( ; remainder && i<
rows; ++i ) {
5747 *left = *right; ++left; ++right;
5752 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5753 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5754 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5755 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5756 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5758 for( ; i<ipos; i+=SIMDSIZE ) {
5759 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5761 for( ; remainder && i<
rows; ++i ) {
5762 *left = *right; ++left; ++right;
5782template<
typename MT
5784template<
typename VT >
5785inline void Row<MT,false,true,true,CRAs...>::assign(
const SparseVector<VT,true>& rhs )
5789 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
5790 matrix_(element->index(),
row()) = element->value();
5808template<
typename MT
5810template<
typename VT >
5811inline auto Row<MT,false,true,true,CRAs...>::addAssign(
const DenseVector<VT,true>& rhs )
5812 -> DisableIf_t< VectorizedAddAssign_v<VT> >
5816 const size_t ipos(
prevMultiple( (*rhs).size(), 2UL ) );
5819 for(
size_t i=0UL; i<ipos; i+=2UL ) {
5820 matrix_(i ,
row()) += (*rhs)[i ];
5821 matrix_(i+1UL,
row()) += (*rhs)[i+1UL];
5823 if( ipos < (*rhs).size() )
5824 matrix_(ipos,
row()) += (*rhs)[ipos];
5842template<
typename MT
5844template<
typename VT >
5845inline auto Row<MT,false,true,true,CRAs...>::addAssign(
const DenseVector<VT,true>& rhs )
5846 -> EnableIf_t< VectorizedAddAssign_v<VT> >
5852 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5860 Iterator left(
begin() );
5861 ConstIterator_t<VT> right( (*rhs).begin() );
5863 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5864 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5865 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5866 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5867 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5869 for( ; i<ipos; i+=SIMDSIZE ) {
5870 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5872 for( ; remainder && i<
rows; ++i ) {
5873 *left += *right; ++left; ++right;
5892template<
typename MT
5894template<
typename VT >
5895inline void Row<MT,false,true,true,CRAs...>::addAssign(
const SparseVector<VT,true>& rhs )
5899 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
5900 matrix_(element->index(),
row()) += element->value();
5918template<
typename MT
5920template<
typename VT >
5921inline auto Row<MT,false,true,true,CRAs...>::subAssign(
const DenseVector<VT,true>& rhs )
5922 -> DisableIf_t< VectorizedSubAssign_v<VT> >
5926 const size_t ipos(
prevMultiple( (*rhs).size(), 2UL ) );
5929 for(
size_t i=0UL; i<ipos; i+=2UL ) {
5930 matrix_(i ,
row()) -= (*rhs)[i ];
5931 matrix_(i+1UL,
row()) -= (*rhs)[i+1UL];
5933 if( ipos < (*rhs).size() )
5934 matrix_(ipos,
row()) -= (*rhs)[ipos];
5952template<
typename MT
5954template<
typename VT >
5955inline auto Row<MT,false,true,true,CRAs...>::subAssign(
const DenseVector<VT,true>& rhs )
5956 -> EnableIf_t< VectorizedSubAssign_v<VT> >
5962 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5970 Iterator left(
begin() );
5971 ConstIterator_t<VT> right( (*rhs).begin() );
5973 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5974 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5975 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5976 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5977 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5979 for( ; i<ipos; i+=SIMDSIZE ) {
5980 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5982 for( ; remainder && i<
rows; ++i ) {
5983 *left -= *right; ++left; ++right;
6002template<
typename MT
6004template<
typename VT >
6005inline void Row<MT,false,true,true,CRAs...>::subAssign(
const SparseVector<VT,true>& rhs )
6009 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
6010 matrix_(element->index(),
row()) -= element->value();
6028template<
typename MT
6030template<
typename VT >
6031inline auto Row<MT,false,true,true,CRAs...>::multAssign(
const DenseVector<VT,true>& rhs )
6032 -> DisableIf_t< VectorizedMultAssign_v<VT> >
6036 const size_t ipos(
prevMultiple( (*rhs).size(), 2UL ) );
6039 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6040 matrix_(i ,
row()) *= (*rhs)[i ];
6041 matrix_(i+1UL,
row()) *= (*rhs)[i+1UL];
6043 if( ipos < (*rhs).size() )
6044 matrix_(ipos,
row()) *= (*rhs)[ipos];
6062template<
typename MT
6064template<
typename VT >
6065inline auto Row<MT,false,true,true,CRAs...>::multAssign(
const DenseVector<VT,true>& rhs )
6066 -> EnableIf_t< VectorizedMultAssign_v<VT> >
6072 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
6080 Iterator left(
begin() );
6081 ConstIterator_t<VT> right( (*rhs).begin() );
6083 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6084 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6085 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6086 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6087 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6089 for( ; i<ipos; i+=SIMDSIZE ) {
6090 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6092 for( ; remainder && i<
rows; ++i ) {
6093 *left *= *right; ++left; ++right;
6112template<
typename MT
6114template<
typename VT >
6115inline void Row<MT,false,true,true,CRAs...>::multAssign(
const SparseVector<VT,true>& rhs )
6123 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
6124 const size_t index( element->index() );
6125 for( ; i<index; ++i )
6127 matrix_(i,
row()) *= element->value();
6131 for( ; i<
size(); ++i ) {
6151template<
typename MT
6153template<
typename VT >
6154inline auto Row<MT,false,true,true,CRAs...>::divAssign(
const DenseVector<VT,true>& rhs )
6155 -> DisableIf_t< VectorizedDivAssign_v<VT> >
6159 const size_t ipos(
prevMultiple( (*rhs).size(), 2UL ) );
6162 for(
size_t i=0UL; i<ipos; i+=2UL ) {
6163 matrix_(i ,
row()) /= (*rhs)[i ];
6164 matrix_(i+1UL,
row()) /= (*rhs)[i+1UL];
6166 if( ipos < (*rhs).size() )
6167 matrix_(ipos,
row()) /= (*rhs)[ipos];
6185template<
typename MT
6187template<
typename VT >
6188inline auto Row<MT,false,true,true,CRAs...>::divAssign(
const DenseVector<VT,true>& rhs )
6189 -> EnableIf_t< VectorizedDivAssign_v<VT> >
6201 Iterator left(
begin() );
6202 ConstIterator_t<VT> right( (*rhs).begin() );
6204 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6205 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6206 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6207 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6208 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6210 for( ; i<ipos; i+=SIMDSIZE ) {
6211 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6213 for( ; i<
rows; ++i ) {
6214 *left /= *right; ++left; ++right;
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Header file for the blaze::checked and blaze::unchecked instances.
Constraints on the storage order of matrix types.
Header file for the cross product trait.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:751
constexpr const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:719
Header file for the EnableIf class template.
Header file for the HasMutableDataAccess type trait.
Header file for the HasSIMDAdd type trait.
Header file for the HasSIMDDiv type trait.
Header file for the HasSIMDMult type trait.
Header file for the HasSIMDSub type trait.
Header file for the If class template.
Header file for the IsConst type trait.
Header file for the isDefault shim.
Header file for the IsExpression type trait class.
Header file for the IsLower type trait.
Header file for the IsPadded type trait.
Header file for the IsReference type trait.
Header file for the IsRestricted type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsTriangular type trait.
Header file for the IsUniLower type trait.
Header file for the IsUniUpper type trait.
Header file for the IsUpper type trait.
Constraint on the data type.
Header file for the prevMultiple shim.
Constraint on the data type.
Header file for the implementation of the RowData class template.
Constraints on the storage order of matrix types.
Header file for the row trait.
Constraint on the transpose flag of vector types.
Header file for all SIMD functionality.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Initializer list type of the Blaze library.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of a vector representation of an initializer list.
Header file for the DenseVector base class.
Header file for the View base class.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.
Definition: Vectorizable.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:574
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:182
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:386
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:510
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:265
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9640
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:448
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
bool isDefault(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the given diagonal matrix is in default state.
Definition: DiagonalMatrix.h:169
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.
Definition: TransExpr.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.
Definition: Submatrix.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:60
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.
Definition: DenseVector.h:61
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.
Definition: RowVector.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: UniTriangular.h:81
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
typename RowTrait< MT, CRAs... >::Type RowTrait_t
Auxiliary alias declaration for the RowTrait type trait.
Definition: RowTrait.h:144
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.
Definition: HasSIMDSub.h:187
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDDiv_v
Auxiliary variable template for the HasSIMDDiv type trait.
Definition: HasSIMDDiv.h:173
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.
Definition: HasSIMDMult.h:188
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:446
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
constexpr void clear(Matrix< MT, SO > &matrix)
Clearing the given matrix.
Definition: Matrix.h:960
MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:628
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:562
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:584
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
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:137
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
auto smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:221
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector.
Definition: DenseVector.h:192
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
constexpr bool isChecked(const Ts &... args)
Extracting blaze::Check arguments from a given list of arguments.
Definition: Check.h:225
Header file for the exception macros of the math module.
Header file for the extended initializer_list functionality.
Header file for the clear shim.
Header file for the reset shim.
Header file for the cache size of the target architecture.
System settings for the inline keywords.
System settings for performance optimizations.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for basic type definitions.
Header file for the implementation of the Row base template.