Blaze 3.9
UniUpperMatrix.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_UNIUPPERMATRIX_H_
36#define _BLAZE_MATH_UNIUPPERMATRIX_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <cmath>
44#include <vector>
45#include <blaze/math/Aliases.h>
57#include <blaze/util/Indices.h>
60#include <blaze/util/Random.h>
61#include <blaze/util/Types.h>
62
63
64namespace blaze {
65
66//=================================================================================================
67//
68// RAND SPECIALIZATION
69//
70//=================================================================================================
71
72//*************************************************************************************************
79template< typename MT // Type of the adapted matrix
80 , bool SO // Storage order of the adapted matrix
81 , bool DF > // Density flag
82class Rand< UniUpperMatrix<MT,SO,DF> >
83{
84 public:
85 //*************************************************************************************************
90 inline const UniUpperMatrix<MT,SO,DF> generate() const
91 {
93
94 UniUpperMatrix<MT,SO,DF> matrix;
95 randomize( matrix );
96 return matrix;
97 }
98 //*************************************************************************************************
99
100 //*************************************************************************************************
106 inline const UniUpperMatrix<MT,SO,DF> generate( size_t n ) const
107 {
109
110 UniUpperMatrix<MT,SO,DF> matrix( n );
111 randomize( matrix );
112 return matrix;
113 }
114 //*************************************************************************************************
115
116 //*************************************************************************************************
124 inline const UniUpperMatrix<MT,SO,DF> generate( size_t n, size_t nonzeros ) const
125 {
128
129 if( nonzeros > UniUpperMatrix<MT,SO,DF>::maxNonZeros( n ) ) {
130 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
131 }
132
133 UniUpperMatrix<MT,SO,DF> matrix( n );
134 randomize( matrix, nonzeros );
135
136 return matrix;
137 }
138 //*************************************************************************************************
139
140 //*************************************************************************************************
147 template< typename Arg > // Min/max argument type
148 inline const UniUpperMatrix<MT,SO,DF>
149 generate( const Arg& min, const Arg& max ) const
150 {
152
153 UniUpperMatrix<MT,SO,DF> matrix;
154 randomize( matrix, min, max );
155 return matrix;
156 }
157 //*************************************************************************************************
158
159 //*************************************************************************************************
167 template< typename Arg > // Min/max argument type
168 inline const UniUpperMatrix<MT,SO,DF>
169 generate( size_t n, const Arg& min, const Arg& max ) const
170 {
172
173 UniUpperMatrix<MT,SO,DF> matrix( n );
174 randomize( matrix, min, max );
175 return matrix;
176 }
177 //*************************************************************************************************
178
179 //*************************************************************************************************
189 template< typename Arg > // Min/max argument type
190 inline const UniUpperMatrix<MT,SO,DF>
191 generate( size_t n, size_t nonzeros, const Arg& min, const Arg& max ) const
192 {
195
196 if( nonzeros > UniUpperMatrix<MT,SO,DF>::maxNonZeros( n ) ) {
197 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
198 }
199
200 UniUpperMatrix<MT,SO,DF> matrix( n );
201 randomize( matrix, nonzeros, min, max );
202
203 return matrix;
204 }
205 //*************************************************************************************************
206
207 //*************************************************************************************************
213 inline void randomize( UniUpperMatrix<MT,SO,DF>& matrix ) const
214 {
215 randomize( matrix, typename IsDenseMatrix<MT>::Type() );
216 }
217 //*************************************************************************************************
218
219 //*************************************************************************************************
227 inline void randomize( UniUpperMatrix<MT,false,DF>& matrix, size_t nonzeros ) const
228 {
230
231 using ET = ElementType_t<MT>;
232
233 const size_t n( matrix.rows() );
234
235 if( nonzeros > UniUpperMatrix<MT,SO,DF>::maxNonZeros( n ) ) {
236 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
237 }
238
239 if( n == 0UL || n == 1UL ) return;
240
241 matrix.reset();
242 matrix.reserve( nonzeros );
243
244 std::vector<size_t> dist( n-1UL );
245
246 for( size_t nz=0UL; nz<nonzeros; ) {
247 const size_t index = rand<size_t>( 0UL, n-2UL );
248 if( dist[index] == n - index - 1UL ) continue;
249 ++dist[index];
250 ++nz;
251 }
252
253 for( size_t i=0UL; i<n-1UL; ++i ) {
254 const Indices<size_t> indices( i+1UL, n-1UL, dist[i] );
255 for( size_t j : indices ) {
256 matrix.append( i, j, rand<ET>() );
257 }
258 matrix.finalize( i );
259 }
260
261 matrix.finalize( n-1UL );
262 }
263 //*************************************************************************************************
264
265 //*************************************************************************************************
273 inline void randomize( UniUpperMatrix<MT,true,DF>& matrix, size_t nonzeros ) const
274 {
276
277 using ET = ElementType_t<MT>;
278
279 const size_t n( matrix.rows() );
280
281 if( nonzeros > UniUpperMatrix<MT,SO,DF>::maxNonZeros( n ) ) {
282 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
283 }
284
285 if( n == 0UL || n == 1UL ) return;
286
287 matrix.reset();
288 matrix.reserve( nonzeros );
289 matrix.finalize( 0UL );
290
291 std::vector<size_t> dist( n );
292
293 for( size_t nz=0UL; nz<nonzeros; ) {
294 const size_t index = rand<size_t>( 1UL, n-1UL );
295 if( dist[index] == index ) continue;
296 ++dist[index];
297 ++nz;
298 }
299
300 for( size_t j=1UL; j<n; ++j ) {
301 const Indices<size_t> indices( 0UL, j-1UL, dist[j] );
302 for( size_t i : indices ) {
303 matrix.append( i, j, rand<ET>() );
304 }
305 matrix.finalize( j );
306 }
307 }
308 //*************************************************************************************************
309
310 //*************************************************************************************************
318 template< typename Arg > // Min/max argument type
319 inline void randomize( UniUpperMatrix<MT,SO,DF>& matrix, const Arg& min, const Arg& max ) const
320 {
321 randomize( matrix, min, max, typename IsDenseMatrix<MT>::Type() );
322 }
323 //*************************************************************************************************
324
325 //*************************************************************************************************
335 template< typename Arg > // Min/max argument type
336 inline void randomize( UniUpperMatrix<MT,false,DF>& matrix,
337 size_t nonzeros, const Arg& min, const Arg& max ) const
338 {
340
341 using ET = ElementType_t<MT>;
342
343 const size_t n( matrix.rows() );
344
345 if( nonzeros > UniUpperMatrix<MT,SO,DF>::maxNonZeros( n ) ) {
346 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
347 }
348
349 if( n == 0UL || n == 1UL ) return;
350
351 matrix.reset();
352 matrix.reserve( nonzeros );
353
354 std::vector<size_t> dist( n-1UL );
355
356 for( size_t nz=0UL; nz<nonzeros; ) {
357 const size_t index = rand<size_t>( 0UL, n-2UL );
358 if( dist[index] == n - index - 1UL ) continue;
359 ++dist[index];
360 ++nz;
361 }
362
363 for( size_t i=0UL; i<n-1UL; ++i ) {
364 const Indices<size_t> indices( i+1UL, n-1UL, dist[i] );
365 for( size_t j : indices ) {
366 matrix.append( i, j, rand<ET>( min, max ) );
367 }
368 matrix.finalize( i );
369 }
370
371 matrix.finalize( n-1UL );
372 }
373 //*************************************************************************************************
374
375 //*************************************************************************************************
385 template< typename Arg > // Min/max argument type
386 inline void randomize( UniUpperMatrix<MT,true,DF>& matrix,
387 size_t nonzeros, const Arg& min, const Arg& max ) const
388 {
390
391 using ET = ElementType_t<MT>;
392
393 const size_t n( matrix.rows() );
394
395 if( nonzeros > UniUpperMatrix<MT,SO,DF>::maxNonZeros( n ) ) {
396 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" );
397 }
398
399 if( n == 0UL || n == 1UL ) return;
400
401 matrix.reset();
402 matrix.reserve( nonzeros );
403 matrix.finalize( 0UL );
404
405 std::vector<size_t> dist( n );
406
407 for( size_t nz=0UL; nz<nonzeros; ) {
408 const size_t index = rand<size_t>( 1UL, n-1UL );
409 if( dist[index] == index ) continue;
410 ++dist[index];
411 ++nz;
412 }
413
414 for( size_t j=1UL; j<n; ++j ) {
415 const Indices<size_t> indices( 0UL, j-1UL, dist[j] );
416 for( size_t i : indices ) {
417 matrix.append( i, j, rand<ET>( min, max ) );
418 }
419 matrix.finalize( j );
420 }
421 }
422 //*************************************************************************************************
423
424 private:
425 //*************************************************************************************************
431 inline void randomize( UniUpperMatrix<MT,SO,DF>& matrix, TrueType ) const
432 {
434
435 using ET = ElementType_t<MT>;
436
437 const size_t n( matrix.rows() );
438
439 for( size_t i=0UL; i<n; ++i ) {
440 for( size_t j=i+1UL; j<n; ++j ) {
441 matrix(i,j) = rand<ET>();
442 }
443 }
444 }
445 //*************************************************************************************************
446
447 //*************************************************************************************************
453 inline void randomize( UniUpperMatrix<MT,SO,DF>& matrix, FalseType ) const
454 {
456
457 const size_t n( matrix.rows() );
458
459 if( n == 0UL || n == 1UL ) return;
460
461 const size_t nonzeros( rand<size_t>( 1UL, std::ceil( 0.2*n*n ) ) );
462
463 randomize( matrix, nonzeros );
464 }
465 //*************************************************************************************************
466
467 //*************************************************************************************************
475 template< typename Arg > // Min/max argument type
476 inline void randomize( UniUpperMatrix<MT,SO,DF>& matrix,
477 const Arg& min, const Arg& max, TrueType ) const
478 {
480
481 using ET = ElementType_t<MT>;
482
483 const size_t n( matrix.rows() );
484
485 for( size_t i=0UL; i<n; ++i ) {
486 for( size_t j=i+1UL; j<n; ++j ) {
487 matrix(i,j) = rand<ET>( min, max );
488 }
489 }
490 }
491 //*************************************************************************************************
492
493 //*************************************************************************************************
501 template< typename Arg > // Min/max argument type
502 inline void randomize( UniUpperMatrix<MT,SO,DF>& matrix,
503 const Arg& min, const Arg& max, FalseType ) const
504 {
506
507 const size_t n( matrix.rows() );
508
509 if( n == 0UL || n == 1UL ) return;
510
511 const size_t nonzeros( rand<size_t>( 1UL, std::ceil( 0.2*n*n ) ) );
512
513 randomize( matrix, nonzeros, min, max );
514 }
515 //*************************************************************************************************
516};
518//*************************************************************************************************
519
520
521
522
523//=================================================================================================
524//
525// MAKE FUNCTIONS
526//
527//=================================================================================================
528
529//*************************************************************************************************
536template< typename MT // Type of the adapted matrix
537 , bool SO // Storage order of the adapted matrix
538 , bool DF > // Density flag
539void makeSymmetric( UniUpperMatrix<MT,SO,DF>& matrix )
540{
541 reset( matrix );
542
543 BLAZE_INTERNAL_ASSERT( isSymmetric( matrix ), "Non-symmetric matrix detected" );
544}
546//*************************************************************************************************
547
548
549//*************************************************************************************************
558template< typename MT // Type of the adapted matrix
559 , bool SO // Storage order of the adapted matrix
560 , bool DF // Density flag
561 , typename Arg > // Min/max argument type
562void makeSymmetric( UniUpperMatrix<MT,SO,DF>& matrix, const Arg& min, const Arg& max )
563{
564 MAYBE_UNUSED( min, max );
565
566 makeSymmetric( matrix );
567}
569//*************************************************************************************************
570
571
572//*************************************************************************************************
579template< typename MT // Type of the adapted matrix
580 , bool SO // Storage order of the adapted matrix
581 , bool DF > // Density flag
582void makeHermitian( UniUpperMatrix<MT,SO,DF>& matrix )
583{
584 reset( matrix );
585
586 BLAZE_INTERNAL_ASSERT( isHermitian( matrix ), "Non-Hermitian matrix detected" );
587}
589//*************************************************************************************************
590
591
592//*************************************************************************************************
601template< typename MT // Type of the adapted matrix
602 , bool SO // Storage order of the adapted matrix
603 , bool DF // Density flag
604 , typename Arg > // Min/max argument type
605void makeHermitian( UniUpperMatrix<MT,SO,DF>& matrix, const Arg& min, const Arg& max )
606{
607 MAYBE_UNUSED( min, max );
608
609 makeHermitian( matrix );
610}
612//*************************************************************************************************
613
614
615//*************************************************************************************************
622template< typename MT // Type of the adapted matrix
623 , bool SO // Storage order of the adapted matrix
624 , bool DF > // Density flag
625void makePositiveDefinite( UniUpperMatrix<MT,SO,DF>& matrix )
626{
627 makeHermitian( matrix );
628}
630//*************************************************************************************************
631
632} // namespace blaze
633
634#endif
Header file for auxiliary alias declarations.
Header file for all basic DenseMatrix functionality.
Header file for the Indices class.
Header file for the IntegralConstant class template.
Header file for the IsDenseMatrix type trait.
Header file for the MAYBE_UNUSED function template.
Constraint on the data type.
Header file for all basic SparseMatrix functionality.
Header file for the complete UniLowerMatrix implementation.
Header file for the implementation of a strictly upper triangular matrix adaptor.
Header file for the implementation of a upper unitriangular matrix adaptor.
Header file for the implementation of an upper matrix adaptor.
Constraint on the data type.
Constraint on the data type.
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) ceil(const DenseMatrix< MT, SO > &dm)
Applies the ceil() function to each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1380
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:1534
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
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
void randomize(T &&value)
Randomization of a given variable.
Definition: Random.h:626
#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
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#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.
Implementation of a random number generator.
Header file for basic type definitions.