Blaze  3.6
SymmetricMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SYMMETRICMATRIX_H_
36 #define _BLAZE_MATH_SYMMETRICMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <cmath>
44 #include <vector>
45 #include <blaze/math/Aliases.h>
51 #include <blaze/math/DenseMatrix.h>
52 #include <blaze/math/Exception.h>
53 #include <blaze/math/shims/Real.h>
57 #include <blaze/util/Assert.h>
59 #include <blaze/util/Random.h>
60 #include <blaze/util/Types.h>
61 
62 
63 namespace blaze {
64 
65 //=================================================================================================
66 //
67 // RAND SPECIALIZATION
68 //
69 //=================================================================================================
70 
71 //*************************************************************************************************
78 template< typename MT // Type of the adapted matrix
79  , bool SO // Storage order of the adapted matrix
80  , bool DF // Density flag
81  , bool NF > // Numeric flag
82 class Rand< SymmetricMatrix<MT,SO,DF,NF> >
83 {
84  public:
85  //**Generate functions**************************************************************************
88  inline const SymmetricMatrix<MT,SO,DF,NF> generate() const;
89  inline const SymmetricMatrix<MT,SO,DF,NF> generate( size_t n ) const;
90  inline const SymmetricMatrix<MT,SO,DF,NF> generate( size_t n, size_t nonzeros ) const;
91 
92  template< typename Arg >
93  inline const SymmetricMatrix<MT,SO,DF,NF> generate( const Arg& min, const Arg& max ) const;
94 
95  template< typename Arg >
96  inline const SymmetricMatrix<MT,SO,DF,NF> generate( size_t n, const Arg& min, const Arg& max ) const;
97 
98  template< typename Arg >
99  inline const SymmetricMatrix<MT,SO,DF,NF> generate( size_t n, size_t nonzeros,
100  const Arg& min, const Arg& max ) const;
102  //**********************************************************************************************
103 
104  //**Randomize functions*************************************************************************
107  inline void randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix ) const;
108  inline void randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, size_t nonzeros ) const;
109 
110  template< typename Arg >
111  inline void randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, const Arg& min, const Arg& max ) const;
112 
113  template< typename Arg >
114  inline void randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, size_t nonzeros,
115  const Arg& min, const Arg& max ) const;
117  //**********************************************************************************************
118 
119  private:
120  //**Randomize functions*************************************************************************
123  inline void randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, TrueType ) const;
124  inline void randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, FalseType ) const;
125 
126  template< typename Arg >
127  inline void randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, const Arg& min, const Arg& max, TrueType ) const;
128 
129  template< typename Arg >
130  inline void randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, const Arg& min, const Arg& max, FalseType ) const;
132  //**********************************************************************************************
133 };
135 //*************************************************************************************************
136 
137 
138 //*************************************************************************************************
144 template< typename MT // Type of the adapted matrix
145  , bool SO // Storage order of the adapted matrix
146  , bool DF // Density flag
147  , bool NF > // Numeric flag
148 inline const SymmetricMatrix<MT,SO,DF,NF> Rand< SymmetricMatrix<MT,SO,DF,NF> >::generate() const
149 {
151 
152  SymmetricMatrix<MT,SO,DF,NF> matrix;
153  randomize( matrix );
154  return matrix;
155 }
157 //*************************************************************************************************
158 
159 
160 //*************************************************************************************************
167 template< typename MT // Type of the adapted matrix
168  , bool SO // Storage order of the adapted matrix
169  , bool DF // Density flag
170  , bool NF > // Numeric flag
171 inline const SymmetricMatrix<MT,SO,DF,NF>
172  Rand< SymmetricMatrix<MT,SO,DF,NF> >::generate( size_t n ) const
173 {
175 
176  SymmetricMatrix<MT,SO,DF,NF> matrix( n );
177  randomize( matrix );
178  return matrix;
179 }
181 //*************************************************************************************************
182 
183 
184 //*************************************************************************************************
193 template< typename MT // Type of the adapted matrix
194  , bool SO // Storage order of the adapted matrix
195  , bool DF // Density flag
196  , bool NF > // Numeric flag
197 inline const SymmetricMatrix<MT,SO,DF,NF>
198  Rand< SymmetricMatrix<MT,SO,DF,NF> >::generate( size_t n, size_t nonzeros ) const
199 {
202 
203  if( nonzeros > n*n ) {
204  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
205  }
206 
207  SymmetricMatrix<MT,SO,DF,NF> matrix( n );
208  randomize( matrix, nonzeros );
209 
210  return matrix;
211 }
213 //*************************************************************************************************
214 
215 
216 //*************************************************************************************************
224 template< typename MT // Type of the adapted matrix
225  , bool SO // Storage order of the adapted matrix
226  , bool DF // Density flag
227  , bool NF > // Numeric flag
228 template< typename Arg > // Min/max argument type
229 inline const SymmetricMatrix<MT,SO,DF,NF>
230  Rand< SymmetricMatrix<MT,SO,DF,NF> >::generate( const Arg& min, const Arg& max ) const
231 {
233 
234  SymmetricMatrix<MT,SO,DF,NF> matrix;
235  randomize( matrix, min, max );
236  return matrix;
237 }
239 //*************************************************************************************************
240 
241 
242 //*************************************************************************************************
251 template< typename MT // Type of the adapted matrix
252  , bool SO // Storage order of the adapted matrix
253  , bool DF // Density flag
254  , bool NF > // Numeric flag
255 template< typename Arg > // Min/max argument type
256 inline const SymmetricMatrix<MT,SO,DF,NF>
257  Rand< SymmetricMatrix<MT,SO,DF,NF> >::generate( size_t n, const Arg& min, const Arg& max ) const
258 {
260 
261  SymmetricMatrix<MT,SO,DF,NF> matrix( n );
262  randomize( matrix, min, max );
263  return matrix;
264 }
266 //*************************************************************************************************
267 
268 
269 //*************************************************************************************************
280 template< typename MT // Type of the adapted matrix
281  , bool SO // Storage order of the adapted matrix
282  , bool DF // Density flag
283  , bool NF > // Numeric flag
284 template< typename Arg > // Min/max argument type
285 inline const SymmetricMatrix<MT,SO,DF,NF>
286  Rand< SymmetricMatrix<MT,SO,DF,NF> >::generate( size_t n, size_t nonzeros,
287  const Arg& min, const Arg& max ) const
288 {
291 
292  if( nonzeros > n*n ) {
293  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
294  }
295 
296  SymmetricMatrix<MT,SO,DF,NF> matrix( n );
297  randomize( matrix, nonzeros, min, max );
298 
299  return matrix;
300 }
302 //*************************************************************************************************
303 
304 
305 //*************************************************************************************************
312 template< typename MT // Type of the adapted matrix
313  , bool SO // Storage order of the adapted matrix
314  , bool DF // Density flag
315  , bool NF > // Numeric flag
316 inline void Rand< SymmetricMatrix<MT,SO,DF,NF> >::randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix ) const
317 {
318  randomize( matrix, typename IsDenseMatrix<MT>::Type() );
319 }
321 //*************************************************************************************************
322 
323 
324 //*************************************************************************************************
331 template< typename MT // Type of the adapted matrix
332  , bool SO // Storage order of the adapted matrix
333  , bool DF // Density flag
334  , bool NF > // Numeric flag
335 inline void Rand< SymmetricMatrix<MT,SO,DF,NF> >::randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, TrueType ) const
336 {
338 
339  using ET = ElementType_t<MT>;
340 
341  const size_t n( matrix.rows() );
342 
343  for( size_t i=0UL; i<n; ++i ) {
344  for( size_t j=0UL; j<=i; ++j ) {
345  matrix(i,j) = rand<ET>();
346  }
347  }
348 }
350 //*************************************************************************************************
351 
352 
353 //*************************************************************************************************
360 template< typename MT // Type of the adapted matrix
361  , bool SO // Storage order of the adapted matrix
362  , bool DF // Density flag
363  , bool NF > // Numeric flag
364 inline void Rand< SymmetricMatrix<MT,SO,DF,NF> >::randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, FalseType ) const
365 {
367 
368  const size_t n( matrix.rows() );
369 
370  if( n == 0UL ) return;
371 
372  const size_t nonzeros( rand<size_t>( 1UL, std::ceil( 0.5*n*n ) ) );
373 
374  randomize( matrix, nonzeros );
375 }
377 //*************************************************************************************************
378 
379 
380 //*************************************************************************************************
389 template< typename MT // Type of the adapted matrix
390  , bool SO // Storage order of the adapted matrix
391  , bool DF // Density flag
392  , bool NF > // Numeric flag
393 inline void Rand< SymmetricMatrix<MT,SO,DF,NF> >::randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix, size_t nonzeros ) const
394 {
396 
397  using ET = ElementType_t<MT>;
398 
399  const size_t n( matrix.rows() );
400 
401  if( nonzeros > n*n ) {
402  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
403  }
404 
405  if( n == 0UL ) return;
406 
407  matrix.reset();
408  matrix.reserve( nonzeros+1UL );
409 
410  while( matrix.nonZeros() < nonzeros ) {
411  matrix( rand<size_t>( 0UL, n-1UL ), rand<size_t>( 0UL, n-1UL ) ) = rand<ET>();
412  }
413 }
415 //*************************************************************************************************
416 
417 
418 //*************************************************************************************************
427 template< typename MT // Type of the adapted matrix
428  , bool SO // Storage order of the adapted matrix
429  , bool DF // Density flag
430  , bool NF > // Numeric flag
431 template< typename Arg > // Min/max argument type
432 inline void Rand< SymmetricMatrix<MT,SO,DF,NF> >::randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix,
433  const Arg& min, const Arg& max ) const
434 {
435  randomize( matrix, min, max, typename IsDenseMatrix<MT>::Type() );
436 }
438 //*************************************************************************************************
439 
440 
441 //*************************************************************************************************
450 template< typename MT // Type of the adapted matrix
451  , bool SO // Storage order of the adapted matrix
452  , bool DF // Density flag
453  , bool NF > // Numeric flag
454 template< typename Arg > // Min/max argument type
455 inline void Rand< SymmetricMatrix<MT,SO,DF,NF> >::randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix,
456  const Arg& min, const Arg& max, TrueType ) const
457 {
459 
460  using ET = ElementType_t<MT>;
461 
462  const size_t n( matrix.rows() );
463 
464  for( size_t i=0UL; i<n; ++i ) {
465  for( size_t j=0UL; j<=i; ++j ) {
466  matrix(i,j) = rand<ET>( min, max );
467  }
468  }
469 }
471 //*************************************************************************************************
472 
473 
474 //*************************************************************************************************
483 template< typename MT // Type of the adapted matrix
484  , bool SO // Storage order of the adapted matrix
485  , bool DF // Density flag
486  , bool NF > // Numeric flag
487 template< typename Arg > // Min/max argument type
488 inline void Rand< SymmetricMatrix<MT,SO,DF,NF> >::randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix,
489  const Arg& min, const Arg& max, FalseType ) const
490 {
492 
493  const size_t n( matrix.rows() );
494 
495  if( n == 0UL ) return;
496 
497  const size_t nonzeros( rand<size_t>( 1UL, std::ceil( 0.5*n*n ) ) );
498 
499  randomize( matrix, nonzeros, min, max );
500 }
502 //*************************************************************************************************
503 
504 
505 //*************************************************************************************************
516 template< typename MT // Type of the adapted matrix
517  , bool SO // Storage order of the adapted matrix
518  , bool DF // Density flag
519  , bool NF > // Numeric flag
520 template< typename Arg > // Min/max argument type
521 inline void Rand< SymmetricMatrix<MT,SO,DF,NF> >::randomize( SymmetricMatrix<MT,SO,DF,NF>& matrix,
522  size_t nonzeros, const Arg& min, const Arg& max ) const
523 {
525 
526  using ET = ElementType_t<MT>;
527 
528  const size_t n( matrix.rows() );
529 
530  if( nonzeros > n*n ) {
531  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
532  }
533 
534  if( n == 0UL ) return;
535 
536  std::vector<size_t> dist( n );
537  std::vector<bool> structure( n*n );
538  size_t nz( 0UL );
539 
540  while( nz < nonzeros )
541  {
542  const size_t row = rand<size_t>( 0UL, n-1UL );
543  const size_t col = rand<size_t>( 0UL, n-1UL );
544 
545  if( structure[row*n+col] ) continue;
546 
547  ++dist[row];
548  structure[row*n+col] = true;
549  ++nz;
550 
551  if( row != col ) {
552  ++dist[col];
553  structure[col*n+row] = true;
554  ++nz;
555  }
556  }
557 
558  matrix.reset();
559  matrix.reserve( nz );
560 
561  for( size_t i=0UL; i<n; ++i ) {
562  matrix.reserve( i, dist[i] );
563  }
564 
565  for( size_t i=0UL; i<n; ++i ) {
566  for( size_t j=i; j<n; ++j ) {
567  if( structure[i*n+j] ) {
568  matrix.append( i, j, rand<ET>( min, max ) );
569  }
570  }
571  }
572 }
574 //*************************************************************************************************
575 
576 
577 
578 
579 //=================================================================================================
580 //
581 // MAKE FUNCTIONS
582 //
583 //=================================================================================================
584 
585 //*************************************************************************************************
592 template< typename MT // Type of the adapted matrix
593  , bool SO // Storage order of the adapted matrix
594  , bool NF > // Numeric flag
595 void makeSymmetric( SymmetricMatrix<MT,SO,true,NF>& matrix )
596 {
597  using blaze::randomize;
598 
599  randomize( matrix );
600 }
602 //*************************************************************************************************
603 
604 
605 //*************************************************************************************************
614 template< typename MT // Type of the adapted matrix
615  , bool SO // Storage order of the adapted matrix
616  , bool NF // Numeric flag
617  , typename Arg > // Min/max argument type
618 void makeSymmetric( SymmetricMatrix<MT,SO,true,NF>& matrix, const Arg& min, const Arg& max )
619 {
620  using blaze::randomize;
621 
622  randomize( matrix, min, max );
623 }
625 //*************************************************************************************************
626 
627 
628 //*************************************************************************************************
635 template< typename MT // Type of the adapted matrix
636  , bool SO // Storage order of the adapted matrix
637  , bool NF > // Numeric flag
638 void makeHermitian( SymmetricMatrix<MT,SO,true,NF>& matrix )
639 {
640  using BT = UnderlyingBuiltin_t< ElementType_t<MT> >;
641 
642  const size_t n( matrix.rows() );
643 
644  for( size_t i=0UL; i<n; ++i ) {
645  for( size_t j=0UL; j<=i; ++j ) {
646  matrix(i,j) = rand<BT>();
647  }
648  }
649 
650  BLAZE_INTERNAL_ASSERT( isHermitian( matrix ), "Non-Hermitian matrix detected" );
651 }
653 //*************************************************************************************************
654 
655 
656 //*************************************************************************************************
665 template< typename MT // Type of the adapted matrix
666  , bool SO // Storage order of the adapted matrix
667  , bool NF // Numeric flag
668  , typename Arg > // Min/max argument type
669 void makeHermitian( SymmetricMatrix<MT,SO,true,NF>& matrix, const Arg& min, const Arg& max )
670 {
671  using BT = UnderlyingBuiltin_t< ElementType_t<MT> >;
672 
673  const size_t n( matrix.rows() );
674 
675  for( size_t i=0UL; i<n; ++i ) {
676  for( size_t j=0UL; j<=i; ++j ) {
677  matrix(i,j) = rand<BT>( real( min ), real( max ) );
678  }
679  }
680 
681  BLAZE_INTERNAL_ASSERT( isHermitian( matrix ), "Non-Hermitian matrix detected" );
682 }
684 //*************************************************************************************************
685 
686 
687 //*************************************************************************************************
694 template< typename MT // Type of the adapted matrix
695  , bool SO // Storage order of the adapted matrix
696  , bool NF > // Numeric flag
697 void makePositiveDefinite( SymmetricMatrix<MT,SO,true,NF>& matrix )
698 {
699  using BT = UnderlyingBuiltin_t< ElementType_t<MT> >;
700 
701  const size_t n( matrix.rows() );
702 
703  makeHermitian( matrix );
704  matrix *= matrix;
705 
706  for( size_t i=0UL; i<n; ++i ) {
707  matrix(i,i) += BT(n);
708  }
709 
710  BLAZE_INTERNAL_ASSERT( isHermitian( matrix ), "Non-Hermitian matrix detected" );
711 }
713 //*************************************************************************************************
714 
715 } // namespace blaze
716 
717 #endif
BoolConstant< false > FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: IntegralConstant.h:121
#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.
Header file for basic type definitions.
decltype(auto) real(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the real part of each single element of dm.
Definition: DMatMapExpr.h:1389
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type,...
Definition: DenseMatrix.h:61
Constraint on the data type.
decltype(auto) ceil(const DenseMatrix< MT, SO > &dm)
Applies the ceil() function to each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1240
void randomize(T &&value)
Randomization of a given variable.
Definition: Random.h:929
Implementation of a random number generator.
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: IntegralConstant.h:132
Constraint on the data type.
Constraint on the data type.
void randomize(T &value) const
Randomization of the given variable with a new value in the range .
Definition: Random.h:292
Header file for the implementation of a symmetric matrix adaptor.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for all basic SparseMatrix functionality.
Header file for the UnderlyingBuiltin type trait.
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1162
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
Header file for the IsDenseMatrix type trait.
Header file for run time assertion macros.
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
#define BLAZE_CONSTRAINT_MUST_NOT_BE_RESIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is resizable, i.e. has a 'resize' member fu...
Definition: Resizable.h:81
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:1406
T generate() const
Generation of a random value in the range .
Definition: Random.h:252
Header file for all basic DenseMatrix functionality.
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not resizable, i.e. does not have a 'res...
Definition: Resizable.h:61
Header file for the implementation of a diagonal matrix adaptor.
Header file for the IntegralConstant class template.
Header file for the real shim.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type,...
Definition: SparseMatrix.h:61