35#ifndef _BLAZE_MATH_SPARSE_SPARSEMATRIX_H_
36#define _BLAZE_MATH_SPARSE_SPARSEMATRIX_H_
104template<
typename MT,
bool SO,
typename ST >
105auto operator*=( SparseMatrix<MT,SO>& mat, ST scalar )
106 -> EnableIf_t< IsScalar_v<ST>, MT& >;
108template<
typename MT,
bool SO,
typename ST >
109auto operator*=( SparseMatrix<MT,SO>&& mat, ST scalar )
110 -> EnableIf_t< IsScalar_v<ST>, MT& >;
112template<
typename MT,
bool SO,
typename ST >
113auto operator/=( SparseMatrix<MT,SO>& mat, ST scalar )
114 -> EnableIf_t< IsScalar_v<ST>, MT& >;
116template<
typename MT,
bool SO,
typename ST >
117auto operator/=( SparseMatrix<MT,SO>&& mat, ST scalar )
118 -> EnableIf_t< IsScalar_v<ST>, MT& >;
144 if( IsRestricted_v<MT> ) {
145 if( !tryMult( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
156 decltype(
auto) left( derestrict( *mat ) );
158 const size_t iend( SO ==
rowMajor ? (*mat).rows() : (*mat).columns() );
159 for(
size_t i=0UL; i<iend; ++i ) {
160 const auto last( left.end(i) );
161 for(
auto element=left.begin(i); element!=last; ++element ) {
162 element->value() *= scalar;
223 if( IsRestricted_v<MT> ) {
224 if( !tryDiv( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
230 IsFloatingPoint_v< UnderlyingBuiltin_t<ST> >
236 decltype(
auto) left( derestrict( *mat ) );
238 if( IsInvertible_v<ScalarType> ) {
239 const ScalarType tmp( ScalarType(1)/
static_cast<ScalarType
>( scalar ) );
240 const size_t iend( SO ==
rowMajor ? (*mat).rows() : (*mat).columns() );
241 for(
size_t i=0UL; i<iend; ++i ) {
242 const auto last( left.end(i) );
243 for(
auto element=left.begin(i); element!=last; ++element ) {
244 element->value() *= tmp;
249 const size_t iend( SO ==
rowMajor ? (*mat).rows() : (*mat).columns() );
250 for(
size_t i=0UL; i<iend; ++i ) {
251 const auto last( left.end(i) );
252 for(
auto element=left.begin(i); element!=last; ++element ) {
253 element->value() /= scalar;
302template<
typename MT,
bool SO >
303bool isnan(
const SparseMatrix<MT,SO>& sm );
305template<
typename MT,
bool SO >
306bool isinf(
const SparseMatrix<MT,SO>& sm );
308template<
typename MT,
bool SO >
309bool isfinite(
const SparseMatrix<MT,SO>& sm );
311template< RelaxationFlag RF,
typename MT,
bool SO >
314template< RelaxationFlag RF,
typename MT,
bool SO >
317template< RelaxationFlag RF,
typename MT,
bool SO >
318bool isUniform(
const SparseMatrix<MT,SO>& sm );
320template< RelaxationFlag RF,
typename MT,
bool SO >
321bool isZero(
const SparseMatrix<MT,SO>& sm );
323template< RelaxationFlag RF,
typename MT,
bool SO >
324bool isLower(
const SparseMatrix<MT,SO>& sm );
326template< RelaxationFlag RF,
typename MT,
bool SO >
327bool isUniLower(
const SparseMatrix<MT,SO>& sm );
329template< RelaxationFlag RF,
typename MT,
bool SO >
332template< RelaxationFlag RF,
typename MT,
bool SO >
333bool isUpper(
const SparseMatrix<MT,SO>& sm );
335template< RelaxationFlag RF,
typename MT,
bool SO >
336bool isUniUpper(
const SparseMatrix<MT,SO>& sm );
338template< RelaxationFlag RF,
typename MT,
bool SO >
341template< RelaxationFlag RF,
typename MT,
bool SO >
342bool isDiagonal(
const SparseMatrix<MT,SO>& sm );
344template< RelaxationFlag RF,
typename MT,
bool SO >
345bool isIdentity(
const SparseMatrix<MT,SO>& sm );
377 for(
size_t i=0UL; i<A.rows(); ++i ) {
378 for(
auto element=A.begin(i); element!=A.end(i); ++element )
379 if(
isnan( element->value() ) )
return true;
383 for(
size_t j=0UL; j<A.columns(); ++j ) {
384 for(
auto element=A.begin(j); element!=A.end(j); ++element )
385 if(
isnan( element->value() ) )
return true;
421 for(
size_t i=0UL; i<A.rows(); ++i ) {
422 for(
auto element=A.begin(i); element!=A.end(i); ++element )
423 if(
isinf( element->value() ) )
return true;
427 for(
size_t j=0UL; j<A.columns(); ++j ) {
428 for(
auto element=A.begin(j); element!=A.end(j); ++element )
429 if(
isinf( element->value() ) )
return true;
465 for(
size_t i=0UL; i<A.rows(); ++i ) {
466 for(
auto element=A.begin(i); element!=A.end(i); ++element )
467 if( !
isfinite( element->value() ) )
return false;
471 for(
size_t j=0UL; j<A.columns(); ++j ) {
472 for(
auto element=A.begin(j); element!=A.end(j); ++element )
473 if( !
isfinite( element->value() ) )
return false;
525 if( IsSymmetric_v<MT> )
531 if( IsUniform_v<MT> || (*sm).rows() < 2UL )
537 for(
size_t i=0UL; i<A.rows(); ++i ) {
538 for(
auto element=A.begin(i); element!=A.end(i); ++element )
540 const size_t j( element->index() );
542 if( i == j || isDefault<RF>( element->value() ) )
545 const auto pos( A.find( j, i ) );
546 if( pos == A.end(j) || !equal<RF>( pos->value(), element->value() ) )
552 for(
size_t j=0UL; j<A.columns(); ++j ) {
553 for(
auto element=A.begin(j); element!=A.end(j); ++element )
555 const size_t i( element->index() );
557 if( j == i || isDefault<RF>( element->value() ) )
560 const auto pos( A.find( j, i ) );
561 if( pos == A.end(i) || !equal<RF>( pos->value(), element->value() ) )
618 if( IsHermitian_v<MT> )
621 if( !IsScalar_v<ET> || !
isSquare( *sm ) )
624 if( IsBuiltin_v<ET> && IsUniform_v<MT> )
630 for(
size_t i=0UL; i<A.rows(); ++i ) {
631 for(
auto element=A.begin(i); element!=A.end(i); ++element )
633 const size_t j( element->index() );
635 if( isDefault<RF>( element->value() ) )
638 if( i == j && !isReal<RF>( element->value() ) )
641 const auto pos( A.find( j, i ) );
642 if( pos == A.end(j) || !equal<RF>( pos->value(),
conj( element->value() ) ) )
648 for(
size_t j=0UL; j<A.columns(); ++j ) {
649 for(
auto element=A.begin(j); element!=A.end(j); ++element )
651 const size_t i( element->index() );
653 if( isDefault<RF>( element->value() ) )
656 if( j == i && !isReal<RF>( element->value() ) )
659 const auto pos( A.find( j, i ) );
660 if( pos == A.end(i) || !equal<RF>( pos->value(),
conj( element->value() ) ) )
681bool isUniform_backend(
const SparseMatrix<MT,false>& sm,
TrueType )
689 const size_t ibegin( ( IsStrictlyLower_v<MT> )?( 1UL ):( 0UL ) );
690 const size_t iend ( ( IsStrictlyUpper_v<MT> )?( (*sm).rows()-1UL ):( (*sm).rows() ) );
692 for(
size_t i=ibegin; i<iend; ++i ) {
693 for(
auto element=(*sm).begin(i); element!=(*sm).end(i); ++element ) {
694 if( !isDefault<RF>( element->value() ) )
715bool isUniform_backend(
const SparseMatrix<MT,true>& sm,
TrueType )
723 const size_t jbegin( ( IsStrictlyUpper_v<MT> )?( 1UL ):( 0UL ) );
724 const size_t jend ( ( IsStrictlyLower_v<MT> )?( (*sm).columns()-1UL ):( (*sm).columns() ) );
726 for(
size_t j=jbegin; j<jend; ++j ) {
727 for(
auto element=(*sm).begin(j); element!=(*sm).end(j); ++element ) {
728 if( !isDefault<RF>( element->value() ) )
749bool isUniform_backend(
const SparseMatrix<MT,false>& sm,
FalseType )
757 const size_t maxElements( (*sm).rows() * (*sm).columns() );
759 if( (*sm).nonZeros() != maxElements )
761 for(
size_t i=0UL; i<(*sm).rows(); ++i ) {
762 for(
auto element=(*sm).begin(i); element!=(*sm).end(i); ++element ) {
763 if( !isDefault<RF>( element->value() ) )
772 const auto& cmp( (*sm)(0UL,0UL) );
774 for(
size_t i=0UL; i<(*sm).rows(); ++i ) {
775 for(
auto element=(*sm).begin(i); element!=(*sm).end(i); ++element ) {
776 if( !equal<RF>( element->value(), cmp ) )
798bool isUniform_backend(
const SparseMatrix<MT,true>& sm,
FalseType )
806 const size_t maxElements( (*sm).rows() * (*sm).columns() );
808 if( (*sm).nonZeros() != maxElements )
810 for(
size_t j=0UL; j<(*sm).columns(); ++j ) {
811 for(
auto element=(*sm).begin(j); element!=(*sm).end(j); ++element ) {
812 if( !isDefault<RF>( element->value() ) )
821 const auto& cmp( (*sm)(0UL,0UL) );
823 for(
size_t j=0UL; j<(*sm).columns(); ++j ) {
824 for(
auto element=(*sm).begin(j); element!=(*sm).end(j); ++element ) {
825 if( !equal<RF>( element->value(), cmp ) )
875 if( IsUniform_v<MT> ||
876 (*sm).rows() == 0UL || (*sm).columns() == 0UL ||
877 ( (*sm).rows() == 1UL && (*sm).columns() == 1UL ) )
880 if( IsUniTriangular_v<MT> )
928 const size_t M( (*sm).rows() );
929 const size_t N( (*sm).columns() );
931 if( IsZero_v<MT> || M == 0UL || N == 0UL )
934 if( IsUniTriangular_v<MT> )
939 const size_t iend( SO ==
rowMajor ? A.rows() : A.columns() );
941 for(
size_t i=0UL; i<iend; ++i ) {
942 for(
auto element=A.begin(i); element!=A.end(i); ++element ) {
943 if( !isZero<RF>( element->value() ) ) {
1013 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1019 for(
size_t i=0UL; i<A.rows()-1UL; ++i ) {
1020 for(
auto element=A.lowerBound(i,i+1UL); element!=A.end(i); ++element )
1022 if( !isDefault<RF>( element->value() ) )
1028 for(
size_t j=1UL; j<A.columns(); ++j ) {
1029 for(
auto element=A.begin(j); element!=A.end(j); ++element )
1031 if( element->index() >= j )
1034 if( !isDefault<RF>( element->value() ) )
1097 if( IsUniLower_v<MT> )
1106 for(
size_t i=0UL; i<A.rows(); ++i )
1108 auto element( A.lowerBound(i,i) );
1110 if( element == A.end(i) || element->index() != i || !isOne<RF>( element->value() ) )
1115 for( ; element!=A.end(i); ++element ) {
1116 if( !isZero<RF>( element->value() ) )
1122 for(
size_t j=0UL; j<A.columns(); ++j )
1124 bool hasDiagonalElement(
false );
1126 for(
auto element=A.begin(j); element!=A.end(j); ++element )
1128 if( element->index() >= j ) {
1129 if( element->index() != j || !isOne<RF>( element->value() ) )
1131 hasDiagonalElement =
true;
1135 if( !isZero<RF>( element->value() ) )
1139 if( !hasDiagonalElement ) {
1203 if( IsStrictlyLower_v<MT> )
1209 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1212 if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
1218 for(
size_t i=0UL; i<A.rows(); ++i ) {
1219 for(
auto element=A.lowerBound(i,i); element!=A.end(i); ++element )
1221 if( !isDefault<RF>( element->value() ) )
1227 for(
size_t j=0UL; j<A.columns(); ++j ) {
1228 for(
auto element=A.begin(j); element!=A.end(j); ++element )
1230 if( element->index() > j )
1233 if( !isDefault<RF>( element->value() ) )
1303 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1309 for(
size_t i=1UL; i<A.rows(); ++i ) {
1310 for(
auto element=A.begin(i); element!=A.end(i); ++element )
1312 if( element->index() >= i )
1315 if( !isDefault<RF>( element->value() ) )
1321 for(
size_t j=0UL; j<A.columns()-1UL; ++j ) {
1322 for(
auto element=A.lowerBound(j+1UL,j); element!=A.end(j); ++element )
1324 if( !isDefault<RF>( element->value() ) )
1387 if( IsUniUpper_v<MT> )
1396 for(
size_t i=0UL; i<A.rows(); ++i )
1398 bool hasDiagonalElement(
false );
1400 for(
auto element=A.begin(i); element!=A.end(i); ++element )
1402 if( element->index() >= i ) {
1403 if( element->index() != i || !isOne<RF>( element->value() ) )
1405 hasDiagonalElement =
true;
1408 else if( !isZero<RF>( element->value() ) ) {
1413 if( !hasDiagonalElement ) {
1419 for(
size_t j=0UL; j<A.columns(); ++j )
1421 auto element( A.lowerBound(j,j) );
1423 if( element == A.end(j) || element->index() != j || !isOne<RF>( element->value() ) )
1428 for( ; element!=A.end(j); ++element ) {
1429 if( !isZero<RF>( element->value() ) )
1493 if( IsStrictlyUpper_v<MT> )
1499 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1502 if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
1508 for(
size_t i=0UL; i<A.rows(); ++i ) {
1509 for(
auto element=A.begin(i); element!=A.end(i); ++element )
1511 if( element->index() > i )
1514 if( !isDefault<RF>( element->value() ) )
1520 for(
size_t j=0UL; j<A.columns(); ++j ) {
1521 for(
auto element=A.lowerBound(j,j); element!=A.end(j); ++element )
1523 if( !isDefault<RF>( element->value() ) )
1587 if( IsDiagonal_v<MT> )
1593 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1599 for(
size_t i=0UL; i<A.rows(); ++i ) {
1600 for(
auto element=A.begin(i); element!=A.end(i); ++element )
1601 if( element->index() != i && !isDefault<RF>( element->value() ) )
1606 for(
size_t j=0UL; j<A.columns(); ++j ) {
1607 for(
auto element=A.begin(j); element!=A.end(j); ++element )
1608 if( element->index() != j && !isDefault<RF>( element->value() ) )
1671 if( IsIdentity_v<MT> )
1680 for(
size_t i=0UL; i<A.rows(); ++i )
1682 bool hasDiagonalElement(
false );
1684 for(
auto element=A.begin(i); element!=A.end(i); ++element )
1686 if( element->index() == i ) {
1687 if( !isOne<RF>( element->value() ) )
1689 hasDiagonalElement =
true;
1691 else if( !isZero<RF>( element->value() ) ) {
1696 if( !hasDiagonalElement ) {
1702 for(
size_t j=0UL; j<A.columns(); ++j )
1704 bool hasDiagonalElement(
false );
1706 for(
auto element=A.begin(j); element!=A.end(j); ++element )
1708 if( element->index() == j ) {
1709 if( !isOne<RF>( element->value() ) )
1711 hasDiagonalElement =
true;
1713 else if( !isZero<RF>( element->value() ) ) {
1718 if( !hasDiagonalElement ) {
1743template<
typename MT
1745 ,
typename... Args >
1746auto erase( SparseMatrix<MT,SO>& sm, Args&&... args )
1747 ->
decltype( (*sm).erase( std::forward<Args>( args )... ) )
1749 return (*sm).erase( std::forward<Args>( args )... );
Header file for auxiliary alias declarations.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.
Definition: Aliases.h:110
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.
Definition: Aliases.h:470
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
Header file for run time assertion macros.
Header file for the conjugate shim.
Header file for the division trait.
Header file for the EnableIf class template.
Header file for the If class template.
Header file for the IntegralConstant class template.
Header file for the IsBuiltin type trait.
Header file for the IsComplex type trait.
Header file for the isDefault shim.
Header file for the IsDiagonal type trait.
Header file for the IsExpression type trait class.
Header file for the isfinite shim.
Header file for the IsFloatingPoint type trait.
Header file for the IsHermitian type trait.
Header file for the IsIdentity type trait.
Header file for the isinf shim.
Header file for the IsInvertible type trait.
Header file for the IsLower type trait.
Header file for the isnan shim.
Header file for the isOne shim.
Header file for the isReal shim.
Header file for the IsResizable type trait.
Header file for the IsRestricted type trait.
Header file for the IsScalar type trait.
Header file for the IsSquare type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Header file for the IsTriangular type trait.
Header file for the IsUniLower type trait.
Header file for the IsUniTriangular type trait.
Header file for the IsUniUpper type trait.
Header file for the IsUpper type trait.
Header file for the relaxation flag enumeration.
Constraint on the data type.
Header file for the UnderlyingBuiltin type trait.
Header file for the UnderlyingScalar type trait.
Constraint on the data type.
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Constraint on the data type.
Header file for the SparseMatrix base class.
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1464
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Triangular.h:81
#define BLAZE_CONSTRAINT_MUST_BE_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Triangular.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: UniTriangular.h:81
typename DivTrait< T1, T2 >::Type DivTrait_t
Auxiliary alias declaration for the DivTrait class template.
Definition: DivTrait.h:164
typename UnderlyingBuiltin< T >::Type UnderlyingBuiltin_t
Auxiliary alias declaration for the UnderlyingBuiltin type trait.
Definition: UnderlyingBuiltin.h:117
constexpr bool IsResizable_v
Auxiliary variable template for the IsResizable type trait.
Definition: IsResizable.h:136
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:1383
#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
bool isZero(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a zero matrix.
Definition: SparseMatrix.h:926
bool isUniLower(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a lower unitriangular matrix.
Definition: SparseMatrix.h:1090
auto operator/=(SparseMatrix< MT, SO > &&mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Division assignment operator for the division of a temporary sparse matrix by a scalar value ( ).
Definition: SparseMatrix.h:283
bool isfinite(const SparseMatrix< MT, SO > &sm)
Checks the given sparse matrix for finite elements.
Definition: SparseMatrix.h:457
bool isnan(const SparseMatrix< MT, SO > &sm)
Checks the given sparse matrix for not-a-number elements.
Definition: SparseMatrix.h:369
bool isDiagonal(const SparseMatrix< MT, SO > &sm)
Checks if the give sparse matrix is diagonal.
Definition: SparseMatrix.h:1580
bool isUniUpper(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is an upper unitriangular matrix.
Definition: SparseMatrix.h:1380
bool isIdentity(const SparseMatrix< MT, SO > &sm)
Checks if the give sparse matrix is an identity matrix.
Definition: SparseMatrix.h:1664
auto operator*=(SparseMatrix< MT, SO > &&mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a temporary sparse matrix and a scalar v...
Definition: SparseMatrix.h:190
bool isinf(const SparseMatrix< MT, SO > &sm)
Checks the given sparse matrix for infinite elements.
Definition: SparseMatrix.h:413
bool isHermitian(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is Hermitian.
Definition: SparseMatrix.h:610
bool isUniform(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a uniform matrix.
Definition: SparseMatrix.h:873
bool isLower(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a lower triangular matrix.
Definition: SparseMatrix.h:1000
bool isStrictlyLower(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a strictly lower triangular matrix.
Definition: SparseMatrix.h:1196
bool isStrictlyUpper(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a strictly upper triangular matrix.
Definition: SparseMatrix.h:1486
bool isSymmetric(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is symmetric.
Definition: SparseMatrix.h:518
bool isUpper(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is an upper triangular matrix.
Definition: SparseMatrix.h:1290
constexpr bool IsFloatingPoint_v
Auxiliary variable template for the IsFloatingPoint type trait.
Definition: IsFloatingPoint.h:95
BoolConstant< true > TrueType
Type traits base class.
Definition: IntegralConstant.h:132
BoolConstant< false > FalseType
Type/value traits base class.
Definition: IntegralConstant.h:121
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
typename If< Condition >::template Type< T1, T2 > If_t
Auxiliary alias template for the If class template.
Definition: If.h:108
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
Header file for the matrix storage order types.
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Header file for the equal shim.
Header file for the isZero shim.
Compile time check for triangular matrix types.
Definition: IsTriangular.h:88
Header file for the IsZero type trait.
Header file for basic type definitions.