SparseVector.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SPARSE_SPARSEVECTOR_H_
36 #define _BLAZE_MATH_SPARSE_SPARSEVECTOR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
45 #include <blaze/math/Exception.h>
47 #include <blaze/math/shims/Equal.h>
49 #include <blaze/math/shims/IsNaN.h>
51 #include <blaze/math/shims/Pow2.h>
52 #include <blaze/math/shims/Sqrt.h>
62 #include <blaze/util/Assert.h>
64 #include <blaze/util/mpl/If.h>
65 #include <blaze/util/Types.h>
70 
71 
72 namespace blaze {
73 
74 //=================================================================================================
75 //
76 // GLOBAL OPERATORS
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
83 template< typename VT, bool TF, typename ST >
84 auto operator*=( SparseVector<VT,TF>& vec, ST scalar )
85  -> EnableIf_t< IsNumeric_v<ST>, VT& >;
86 
87 template< typename VT, bool TF, typename ST >
88 auto operator*=( SparseVector<VT,TF>&& vec, ST scalar )
89  -> EnableIf_t< IsNumeric_v<ST>, VT& >;
90 
91 template< typename VT, bool TF, typename ST >
92 auto operator/=( SparseVector<VT,TF>& vec, ST scalar )
93  -> EnableIf_t< IsNumeric_v<ST>, VT& >;
94 
95 template< typename VT, bool TF, typename ST >
96 auto operator/=( SparseVector<VT,TF>&& vec, ST scalar )
97  -> EnableIf_t< IsNumeric_v<ST>, VT& >;
99 //*************************************************************************************************
100 
101 
102 //*************************************************************************************************
115 template< typename VT // Type of the left-hand side sparse vector
116  , bool TF // Transpose flag
117  , typename ST > // Data type of the right-hand side scalar
118 inline auto operator*=( SparseVector<VT,TF>& vec, ST scalar )
120 {
121  if( IsRestricted_v<VT> ) {
122  if( !tryMult( ~vec, 0UL, (~vec).size(), scalar ) ) {
123  BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted vector" );
124  }
125  }
126 
127  if( !IsResizable_v< ElementType_t<VT> > && isZero( scalar ) )
128  {
129  reset( ~vec );
130  }
131  else
132  {
133  BLAZE_DECLTYPE_AUTO( left, derestrict( ~vec ) );
134 
135  const auto last( left.end() );
136  for( auto element=left.begin(); element!=last; ++element ) {
137  element->value() *= scalar;
138  }
139  }
140 
141  BLAZE_INTERNAL_ASSERT( isIntact( ~vec ), "Invariant violation detected" );
142 
143  return ~vec;
144 }
145 //*************************************************************************************************
146 
147 
148 //*************************************************************************************************
161 template< typename VT // Type of the left-hand side sparse vector
162  , bool TF // Transpose flag
163  , typename ST > // Data type of the right-hand side scalar
164 inline auto operator*=( SparseVector<VT,TF>&& vec, ST scalar )
166 {
167  return operator*=( ~vec, scalar );
168 }
169 //*************************************************************************************************
170 
171 
172 //*************************************************************************************************
187 template< typename VT // Type of the left-hand side sparse vector
188  , bool TF // Transpose flag
189  , typename ST > // Data type of the right-hand side scalar
190 inline auto operator/=( SparseVector<VT,TF>& vec, ST scalar )
192 {
193  BLAZE_USER_ASSERT( !isZero( scalar ), "Division by zero detected" );
194 
195  if( IsRestricted_v<VT> ) {
196  if( !tryDiv( ~vec, 0UL, (~vec).size(), scalar ) ) {
197  BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted vector" );
198  }
199  }
200 
202  IsFloatingPoint_v< UnderlyingBuiltin_t<ST> >
203  , If_t< IsComplex_v< UnderlyingNumeric_t<VT> > && IsBuiltin_v<ST>
206  , ST >;
207 
208  BLAZE_DECLTYPE_AUTO( left, derestrict( ~vec ) );
209 
210  if( IsInvertible_v<ScalarType> ) {
211  const ScalarType tmp( ScalarType(1)/static_cast<ScalarType>( scalar ) );
212  for( auto element=left.begin(); element!=left.end(); ++element ) {
213  element->value() *= tmp;
214  }
215  }
216  else {
217  for( auto element=left.begin(); element!=left.end(); ++element ) {
218  element->value() /= scalar;
219  }
220  }
221 
222  BLAZE_INTERNAL_ASSERT( isIntact( ~vec ), "Invariant violation detected" );
223 
224  return ~vec;
225 }
226 //*************************************************************************************************
227 
228 
229 //*************************************************************************************************
244 template< typename VT // Type of the left-hand side sparse vector
245  , bool TF // Transpose flag
246  , typename ST > // Data type of the right-hand side scalar
247 inline auto operator/=( SparseVector<VT,TF>&& vec, ST scalar )
249 {
250  return operator/=( ~vec, scalar );
251 }
252 //*************************************************************************************************
253 
254 
255 
256 
257 //=================================================================================================
258 //
259 // GLOBAL FUNCTIONS
260 //
261 //=================================================================================================
262 
263 //*************************************************************************************************
266 template< typename VT, bool TF >
267 bool isnan( const SparseVector<VT,TF>& sv );
268 
269 template< bool RF, typename VT, bool TF >
270 bool isUniform( const SparseVector<VT,TF>& sv );
271 
272 template< bool RF, typename VT, bool TF >
273 bool isZero( const SparseVector<VT,TF>& sv );
274 
275 template< typename VT, bool TF >
276 const ElementType_t<VT> sqrLength( const SparseVector<VT,TF>& sv );
277 
278 template< typename VT, bool TF >
279 auto length( const SparseVector<VT,TF>& sv ) -> decltype( sqrt( sqrLength( ~sv ) ) );
281 //*************************************************************************************************
282 
283 
284 //*************************************************************************************************
304 template< typename VT // Type of the sparse vector
305  , bool TF > // Transpose flag
306 inline bool isnan( const SparseVector<VT,TF>& sv )
307 {
308  using CT = CompositeType_t<VT>;
309 
310  CT a( ~sv ); // Evaluation of the sparse vector operand
311 
312  const auto end( a.end() );
313  for( auto element=a.begin(); element!=end; ++element ) {
314  if( isnan( element->value() ) ) return true;
315  }
316  return false;
317 }
318 //*************************************************************************************************
319 
320 
321 //*************************************************************************************************
354 template< bool RF // Relaxation flag
355  , typename VT // Type of the sparse vector
356  , bool TF > // Transpose flag
358 {
359  using CT = CompositeType_t<VT>;
360 
361  if( IsUniform_v<VT> || (~sv).size() < 2UL )
362  return true;
363 
364  CT a( ~sv ); // Evaluation of the sparse vector operand
365 
366  if( a.nonZeros() != a.size() )
367  {
368  const auto end( a.end() );
369  for( auto element=a.begin(); element!=end; ++element ) {
370  if( !isDefault<RF>( element->value() ) )
371  return false;
372  }
373  }
374  else
375  {
376  const auto& cmp( a[0] );
377  auto element( a.begin() );
378  const auto end( a.end() );
379 
380  ++element;
381 
382  for( ; element!=end; ++element ) {
383  if( !equal<RF>( element->value(), cmp ) )
384  return false;
385  }
386  }
387 
388  return true;
389 }
390 //*************************************************************************************************
391 
392 
393 //*************************************************************************************************
426 template< bool RF // Relaxation flag
427  , typename VT // Type of the sparse vector
428  , bool TF > // Transpose flag
429 bool isZero( const SparseVector<VT,TF>& sv )
430 {
431  if( IsZero_v<VT> || (~sv).nonZeros() == 0UL )
432  return true;
433 
434  CompositeType_t<VT> a( ~sv ); // Evaluation of the sparse vector operand
435 
436  const auto end( a.end() );
437  for( auto element=a.begin(); element!=end; ++element ) {
438  if( !isZero<RF>( element->value() ) )
439  return false;
440  }
441 
442  return true;
443 }
444 //*************************************************************************************************
445 
446 
447 //*************************************************************************************************
460 template< typename VT // Type of the sparse vector
461  , bool TF > // Transpose flag
463 {
465 
467 
468  ElementType sum( 0 );
469  for( auto element=(~sv).begin(); element!=(~sv).end(); ++element )
470  sum += pow2( element->value() );
471  return sum;
472 }
473 //*************************************************************************************************
474 
475 
476 //*************************************************************************************************
513 template< typename VT // Type of the sparse vector
514  , bool TF > // Transpose flag
515 inline auto length( const SparseVector<VT,TF>& sv ) -> decltype( sqrt( sqrLength( ~sv ) ) )
516 {
517  return sqrt( sqrLength( ~sv ) );
518 }
519 //*************************************************************************************************
520 
521 
522 //*************************************************************************************************
536 template< typename VT // Type of the sparse vector
537  , bool TF // Transpose flag
538  , typename... Args > // Type of the erase arguments
539 auto erase( SparseVector<VT,TF>& sv, Args&&... args )
540  -> decltype( (~sv).erase( std::forward<Args>( args )... ) )
541 {
542  return (~sv).erase( std::forward<Args>( args )... );
543 }
545 //*************************************************************************************************
546 
547 } // namespace blaze
548 
549 #endif
Header file for the isnan shim.
Header file for the UnderlyingNumeric type trait.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Constraint on the data type.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:354
Header file for basic type definitions.
Header file for the SparseVector base class.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
Header file for the isZero shim.
typename DivTrait< T1, T2 >::Type DivTrait_t
Auxiliary alias declaration for the DivTrait class template.The DivTrait_t alias declaration provides...
Definition: DivTrait.h:239
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
Header file for the decltype(auto) workaround.
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
auto length(const DenseVector< VT, TF > &dv) -> decltype(sqrt(sqrLength(~dv)))
Calculation of the length (magnitude) of the dense vector .
Definition: DenseVector.h:606
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:673
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
Header file for the sqrt shim.
Header file for the IsUniform type trait.
constexpr bool IsResizable_v
Auxiliary variable template for the IsResizable type trait.The IsResizable_v variable template provid...
Definition: IsResizable.h:134
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
const ElementType_t< VT > sqrLength(const DenseVector< VT, TF > &dv)
Calculation of the square length (magnitude) of the dense vector .
Definition: DenseVector.h:553
Header file for the IsFloatingPoint type trait.
Header file for the UnderlyingBuiltin type trait.
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3080
decltype(auto) sum(const DenseMatrix< MT, SO > &dm)
Reduces the given dense matrix by means of addition.
Definition: DMatReduceExpr.h:2146
Header file for the pow2 shim.
Header file for the equal shim.
bool isnan(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is not a number.
Definition: DiagonalProxy.h:713
Header file for the exception macros of the math module.
bool isUniform(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a uniform matrix.
Definition: DenseMatrix.h:849
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:438
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
Header file for the division trait.
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:61
Header file for the IsZero type trait.
decltype(auto) pow2(const Proxy< PT, RT > &proxy)
Computing the square value of the represented element.
Definition: Proxy.h:1384
Header file for the isDefault shim.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
Header file for the RemoveReference type trait.
Header file for the IsInvertible type trait.
decltype(auto) sqrt(const DenseMatrix< MT, SO > &dm)
Computes the square root of each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1453
Header file for the IsBuiltin type trait.
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:290
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:138
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
Header file for the IsComplex type trait.
Header file for the IsResizable type trait.
Header file for the IsRestricted type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101