Blaze 3.9
HermitianMatrix.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_HERMITIANMATRIX_H_
36#define _BLAZE_MATH_HERMITIANMATRIX_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <cmath>
44#include <vector>
45#include <blaze/math/Aliases.h>
57#include <blaze/util/Assert.h>
59#include <blaze/util/Random.h>
60#include <blaze/util/Types.h>
61
62
63namespace blaze {
64
65//=================================================================================================
66//
67// RAND SPECIALIZATION
68//
69//=================================================================================================
70
71//*************************************************************************************************
78template< typename MT // Type of the adapted matrix
79 , bool SO // Storage order of the adapted matrix
80 , bool DF > // Density flag
81class Rand< HermitianMatrix<MT,SO,DF> >
82{
83 public:
84 //**********************************************************************************************
89 inline const HermitianMatrix<MT,SO,DF> generate() const
90 {
92
93 HermitianMatrix<MT,SO,DF> matrix;
94 randomize( matrix );
95 return matrix;
96 }
97 //**********************************************************************************************
98
99 //**********************************************************************************************
105 inline const HermitianMatrix<MT,SO,DF> generate( size_t n ) const
106 {
108
109 HermitianMatrix<MT,SO,DF> matrix( n );
110 randomize( matrix );
111 return matrix;
112 }
113 //**********************************************************************************************
114
115 //**********************************************************************************************
123 inline const HermitianMatrix<MT,SO,DF> generate( size_t n, size_t nonzeros ) const
124 {
127
128 if( nonzeros > n*n ) {
129 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
130 }
131
132 HermitianMatrix<MT,SO,DF> matrix( n );
133 randomize( matrix, nonzeros );
134
135 return matrix;
136 }
137 //**********************************************************************************************
138
139 //**********************************************************************************************
146 template< typename Arg > // Min/max argument type
147 inline const HermitianMatrix<MT,SO,DF> generate( const Arg& min, const Arg& max ) const
148 {
150
151 HermitianMatrix<MT,SO,DF> matrix;
152 randomize( matrix, min, max );
153 return matrix;
154 }
155 //**********************************************************************************************
156
157 //**********************************************************************************************
165 template< typename Arg > // Min/max argument type
166 inline const HermitianMatrix<MT,SO,DF> generate( size_t n, const Arg& min, const Arg& max ) const
167 {
169
170 HermitianMatrix<MT,SO,DF> matrix( n );
171 randomize( matrix, min, max );
172 return matrix;
173 }
174 //**********************************************************************************************
175
176 //**********************************************************************************************
186 template< typename Arg > // Min/max argument type
187 inline const HermitianMatrix<MT,SO,DF> generate( size_t n, size_t nonzeros,
188 const Arg& min, const Arg& max ) const
189 {
192
193 if( nonzeros > n*n ) {
194 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
195 }
196
197 HermitianMatrix<MT,SO,DF> matrix( n );
198 randomize( matrix, nonzeros, min, max );
199
200 return matrix;
201 }
202 //**********************************************************************************************
203
204 //**********************************************************************************************
210 inline void randomize( HermitianMatrix<MT,SO,DF>& matrix ) const
211 {
212 randomize( matrix, typename IsDenseMatrix<MT>::Type() );
213 }
214 //**********************************************************************************************
215
216 //**********************************************************************************************
224 inline void randomize( HermitianMatrix<MT,SO,DF>& matrix, size_t nonzeros ) const
225 {
227
228 using ET = ElementType_t<MT>;
229 using BT = UnderlyingBuiltin_t<ET>;
230
231 const size_t n( matrix.rows() );
232
233 if( nonzeros > n*n ) {
234 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
235 }
236
237 if( n == 0UL ) return;
238
239 matrix.reset();
240 matrix.reserve( nonzeros );
241
242 while( matrix.nonZeros() < nonzeros )
243 {
244 const size_t row ( rand<size_t>( 0UL, n-1UL ) );
245 const size_t column( rand<size_t>( 0UL, n-1UL ) );
246
247 if( row == column )
248 matrix(row,column) = rand<BT>();
249 else
250 matrix(row,column) = rand<ET>();
251 }
252 }
253 //**********************************************************************************************
254
255 //**********************************************************************************************
263 template< typename Arg > // Min/max argument type
264 inline void randomize( HermitianMatrix<MT,SO,DF>& matrix, const Arg& min, const Arg& max ) const
265 {
266 randomize( matrix, min, max, typename IsDenseMatrix<MT>::Type() );
267 }
268 //**********************************************************************************************
269
270 //**********************************************************************************************
280 template< typename Arg > // Min/max argument type
281 inline void randomize( HermitianMatrix<MT,SO,DF>& matrix,
282 size_t nonzeros, const Arg& min, const Arg& max ) const
283 {
285
286 using ET = ElementType_t<MT>;
287 using BT = UnderlyingBuiltin_t<ET>;
288
289 const size_t n( matrix.rows() );
290
291 if( nonzeros > n*n ) {
292 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
293 }
294
295 if( n == 0UL ) return;
296
297 std::vector<size_t> dist( n );
298 std::vector<bool> structure( n*n );
299 size_t nz( 0UL );
300
301 while( nz < nonzeros )
302 {
303 const size_t row = rand<size_t>( 0UL, n-1UL );
304 const size_t col = rand<size_t>( 0UL, n-1UL );
305
306 if( structure[row*n+col] ) continue;
307
308 ++dist[row];
309 structure[row*n+col] = true;
310 ++nz;
311
312 if( row != col ) {
313 ++dist[col];
314 structure[col*n+row] = true;
315 ++nz;
316 }
317 }
318
319 matrix.reset();
320 matrix.reserve( nz );
321
322 for( size_t i=0UL; i<n; ++i ) {
323 matrix.reserve( i, dist[i] );
324 }
325
326 for( size_t i=0UL; i<n; ++i ) {
327 for( size_t j=i; j<n; ++j ) {
328 if( structure[i*n+j] ) {
329 if( i == j )
330 matrix.append( i, j, rand<BT>( real( min ), real( max ) ) );
331 else
332 matrix.append( i, j, rand<ET>( min, max ) );
333 }
334 }
335 }
336 }
337 //**********************************************************************************************
338
339 private:
340 //**********************************************************************************************
346 inline void randomize( HermitianMatrix<MT,SO,DF>& matrix, TrueType ) const
347 {
349
350 using ET = ElementType_t<MT>;
351 using BT = UnderlyingBuiltin_t<ET>;
352
353 const size_t n( matrix.rows() );
354
355 for( size_t i=0UL; i<n; ++i ) {
356 for( size_t j=0UL; j<i; ++j ) {
357 matrix(i,j) = rand<ET>();
358 }
359 matrix(i,i) = rand<BT>();
360 }
361 }
362 //**********************************************************************************************
363
364 //**********************************************************************************************
370 inline void randomize( HermitianMatrix<MT,SO,DF>& matrix, FalseType ) const
371 {
373
374 const size_t n( matrix.rows() );
375
376 if( n == 0UL ) return;
377
378 const size_t nonzeros( rand<size_t>( 1UL, std::ceil( 0.5*n*n ) ) );
379
380 randomize( matrix, nonzeros );
381 }
382 //**********************************************************************************************
383
384 //**********************************************************************************************
392 template< typename Arg > // Min/max argument type
393 inline void randomize( HermitianMatrix<MT,SO,DF>& matrix,
394 const Arg& min, const Arg& max, TrueType ) const
395 {
397
398 using ET = ElementType_t<MT>;
399 using BT = UnderlyingBuiltin_t<ET>;
400
401 const size_t n( matrix.rows() );
402
403 for( size_t i=0UL; i<n; ++i ) {
404 for( size_t j=0UL; j<i; ++j ) {
405 matrix(i,j) = rand<ET>( min, max );
406 }
407 matrix(i,i) = rand<BT>( real( min ), real( max ) );
408 }
409 }
410 //**********************************************************************************************
411
412 //**********************************************************************************************
420 template< typename Arg > // Min/max argument type
421 inline void randomize( HermitianMatrix<MT,SO,DF>& matrix,
422 const Arg& min, const Arg& max, FalseType ) const
423 {
425
426 const size_t n( matrix.rows() );
427
428 if( n == 0UL ) return;
429
430 const size_t nonzeros( rand<size_t>( 1UL, std::ceil( 0.5*n*n ) ) );
431
432 randomize( matrix, nonzeros, min, max );
433 }
434 //**********************************************************************************************
435};
437//*************************************************************************************************
438
439
440
441
442//=================================================================================================
443//
444// MAKE FUNCTIONS
445//
446//=================================================================================================
447
448//*************************************************************************************************
455template< typename MT // Type of the adapted matrix
456 , bool SO // Storage order of the adapted matrix
457 , bool DF > // Density flag
458void makeSymmetric( HermitianMatrix<MT,SO,DF>& matrix )
459{
460 using BT = UnderlyingBuiltin_t< 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<BT>();
467 }
468 }
469
470 BLAZE_INTERNAL_ASSERT( isSymmetric( matrix ), "Non-symmetric matrix detected" );
471}
473//*************************************************************************************************
474
475
476//*************************************************************************************************
485template< typename MT // Type of the adapted matrix
486 , bool SO // Storage order of the adapted matrix
487 , bool DF // Density flag
488 , typename Arg > // Min/max argument type
489void makeSymmetric( HermitianMatrix<MT,SO,DF>& matrix, const Arg& min, const Arg& max )
490{
491 using BT = UnderlyingBuiltin_t< ElementType_t<MT> >;
492
493 const size_t n( matrix.rows() );
494
495 for( size_t i=0UL; i<n; ++i ) {
496 for( size_t j=0UL; j<=i; ++j ) {
497 matrix(i,j) = rand<BT>( real( min ), real( max ) );
498 }
499 }
500
501 BLAZE_INTERNAL_ASSERT( isSymmetric( matrix ), "Non-symmetric matrix detected" );
502}
504//*************************************************************************************************
505
506
507//*************************************************************************************************
514template< typename MT // Type of the adapted matrix
515 , bool SO // Storage order of the adapted matrix
516 , bool DF > // Density flag
517void makeHermitian( HermitianMatrix<MT,SO,DF>& matrix )
518{
519 using blaze::randomize;
520
521 randomize( matrix );
522}
524//*************************************************************************************************
525
526
527//*************************************************************************************************
536template< typename MT // Type of the adapted matrix
537 , bool SO // Storage order of the adapted matrix
538 , bool DF // Density flag
539 , typename Arg > // Min/max argument type
540void makeHermitian( HermitianMatrix<MT,SO,DF>& matrix, const Arg& min, const Arg& max )
541{
542 using blaze::randomize;
543
544 randomize( matrix, min, max );
545}
547//*************************************************************************************************
548
549
550//*************************************************************************************************
557template< typename MT // Type of the adapted matrix
558 , bool SO // Storage order of the adapted matrix
559 , bool DF > // Density flag
560void makePositiveDefinite( HermitianMatrix<MT,SO,DF>& matrix )
561{
562 using blaze::randomize;
563
564 using BT = UnderlyingBuiltin_t< ElementType_t<MT> >;
565
566 const size_t n( matrix.rows() );
567
568 randomize( matrix );
569 matrix *= matrix;
570
571 for( size_t i=0UL; i<n; ++i ) {
572 matrix(i,i) += BT(n);
573 }
574}
576//*************************************************************************************************
577
578} // namespace blaze
579
580#endif
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Header file for all basic DenseMatrix functionality.
Header file for the IntegralConstant class template.
Header file for the IsDenseMatrix type trait.
Constraint on the data type.
Header file for all basic SparseMatrix functionality.
Header file for the UnderlyingBuiltin type trait.
Header file for the implementation of a diagonal matrix adaptor.
Header file for the implementation of a Hermitian matrix adaptor.
Constraint on the data type.
Constraint on the data type.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
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:1339
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
decltype(auto) real(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the real part of each single element of dm.
Definition: DMatMapExpr.h:1529
decltype(auto) ceil(const DenseMatrix< MT, SO > &dm)
Applies the ceil() function to each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1380
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:1456
decltype(auto) generate(size_t m, size_t n, OP op)
Generates a new dense matrix filled via the given custom binary operation.
Definition: DMatGenExpr.h:675
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_RESIZABLE_TYPE(T)
Constraint on the data type.
Definition: Resizable.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: SparseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE_TYPE(T)
Constraint on the data type.
Definition: Resizable.h:61
void randomize(T &&value)
Randomization of a given variable.
Definition: Random.h:626
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
BoolConstant< true > TrueType
Type traits base class.
Definition: IntegralConstant.h:132
BoolConstant< false > FalseType
Type/value traits base class.
Definition: IntegralConstant.h:121
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
Header file for the exception macros of the math module.
Header file for the real shim.
Implementation of a random number generator.
Header file for basic type definitions.