Blaze 3.9
heevx.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_LAPACK_HEEVX_H_
36#define _BLAZE_MATH_LAPACK_HEEVX_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <memory>
44#include <blaze/math/Aliases.h>
55#include <blaze/util/Assert.h>
59#include <blaze/util/Types.h>
61
62
63namespace blaze {
64
65//=================================================================================================
66//
67// LAPACK HERMITIAN MATRIX EIGENVALUE FUNCTIONS (HEEVX)
68//
69//=================================================================================================
70
71//*************************************************************************************************
74template< typename MT, bool SO, typename VT, bool TF >
75size_t heevx( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w, char uplo );
76
77template< typename MT, bool SO, typename VT, bool TF, typename ST >
78size_t heevx( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w, char uplo, ST low, ST upp );
79
80template< typename MT1, bool SO1, typename VT, bool TF, typename MT2, bool SO2 >
81size_t heevx( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w,
82 DenseMatrix<MT2,SO2>& Z, char uplo );
83
84template< typename MT1, bool SO1, typename VT, bool TF, typename MT2, bool SO2, typename ST >
85size_t heevx( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w,
86 DenseMatrix<MT2,SO2>& Z, char uplo, ST low, ST upp );
88//*************************************************************************************************
89
90
91//*************************************************************************************************
114template< typename MT // Type of the matrix A
115 , bool SO // Storage order of the matrix A
116 , typename VT // Type of the vector w
117 , bool TF // Transpose flag of the vector w
118 , typename ST > // Type of the scalar boundary values
119inline size_t heevx_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w,
120 char uplo, char range, ST vl, ST vu,
121 blas_int_t il, blas_int_t iu )
122{
123 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Invalid non-square matrix detected" );
124 BLAZE_INTERNAL_ASSERT( range != 'A' || (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
125 BLAZE_INTERNAL_ASSERT( range != 'V' || (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
126 BLAZE_INTERNAL_ASSERT( range != 'I' || (*w).size() == size_t( iu-il+1 ), "Invalid vector dimension detected" );
127
128 using CT = ElementType_t<MT>;
129 using BT = UnderlyingElement_t<CT>;
130
133
134 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
135 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
136 blas_int_t m ( 0 );
137 blas_int_t info( 0 );
138
139 blas_int_t lwork( 12*n + 2 );
140 const std::unique_ptr<CT[]> work ( new CT[lwork] );
141 const std::unique_ptr<BT[]> rwork( new BT[7*n] );
142 const std::unique_ptr<blas_int_t[]> iwork( new blas_int_t[5*n] );
143 const std::unique_ptr<blas_int_t[]> ifail( new blas_int_t[n] );
144
145 heevx( 'N', range, uplo, n, (*A).data(), lda, vl, vu, il, iu, BT(0), &m, (*w).data(),
146 nullptr, 1, work.get(), lwork, rwork.get(), iwork.get(), ifail.get(), &info );
147
148 const size_t num( numeric_cast<size_t>( m ) );
149
150 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
151 BLAZE_INTERNAL_ASSERT( num <= (*w).size(), "Invalid number of eigenvalues detected" );
152
153 if( info > 0 ) {
154 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
155 }
156
157 return num;
158}
160//*************************************************************************************************
161
162
163//*************************************************************************************************
219template< typename MT // Type of the matrix A
220 , bool SO // Storage order of the matrix A
221 , typename VT // Type of the vector w
222 , bool TF > // Transpose flag of the vector w
223inline size_t heevx( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w, char uplo )
224{
231
237
238 using CT = ElementType_t<MT>;
239 using BT = UnderlyingElement_t<CT>;
240
241 const size_t N( (*A).rows() );
242
243 if( !isSquare( *A ) ) {
244 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
245 }
246
247 if( uplo != 'L' && uplo != 'U' ) {
248 BLAZE_THROW_INVALID_ARGUMENT( "Invalid uplo argument provided" );
249 }
250
251 resize( *w, N, false );
252
253 if( N == 0UL ) {
254 return 0;
255 }
256
257 return heevx_backend( *A, *w, uplo, 'A', BT(), BT(), 0, 0 );
258}
259//*************************************************************************************************
260
261
262//*************************************************************************************************
348template< typename MT // Type of the matrix A
349 , bool SO // Storage order of the matrix A
350 , typename VT // Type of the vector w
351 , bool TF // Transpose flag of the vector w
352 , typename ST > // Type of the scalar boundary values
353inline size_t heevx( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w, char uplo, ST low, ST upp )
354{
361
367
368 if( !isSquare( *A ) ) {
369 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
370 }
371
372 if( IsFloatingPoint_v<ST> && low >= upp ) {
373 BLAZE_THROW_INVALID_ARGUMENT( "Invalid value range provided" );
374 }
375
376 if( !IsFloatingPoint_v<ST> && low > upp ) {
377 BLAZE_THROW_INVALID_ARGUMENT( "Invalid index range provided" );
378 }
379
380 const size_t N( (*A).rows() );
381 const size_t num( IsFloatingPoint_v<ST> ? N : size_t( upp - low ) + 1UL );
382
383 if( !IsFloatingPoint_v<ST> && num > N ) {
384 BLAZE_THROW_INVALID_ARGUMENT( "Invalid index range provided" );
385 }
386
387 if( uplo != 'L' && uplo != 'U' ) {
388 BLAZE_THROW_INVALID_ARGUMENT( "Invalid uplo argument provided" );
389 }
390
391 resize( *w, num, false );
392
393 if( N == 0UL ) {
394 return 0;
395 }
396
397 const char range( IsFloatingPoint_v<ST> ? 'V' : 'I' );
398 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
399 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
400 const blas_int_t il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( low ) );
401 const blas_int_t iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( upp ) );
402
403 return heevx_backend( *A, *w, uplo, range, vl, vu, il, iu );
404}
405//*************************************************************************************************
406
407
408//*************************************************************************************************
432template< typename MT1 // Type of the matrix A
433 , bool SO1 // Storage order of the matrix A
434 , typename VT // Type of the vector w
435 , bool TF // Transpose flag of the vector w
436 , typename MT2 // Type of the matrix Z
437 , bool SO2 // Storage order of the matrix Z
438 , typename ST > // Type of the scalar boundary values
439inline size_t heevx_backend( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w,
440 DenseMatrix<MT2,SO2>& Z, char uplo, char range,
441 ST vl, ST vu, blas_int_t il, blas_int_t iu )
442{
443 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Invalid non-square matrix detected" );
444 BLAZE_INTERNAL_ASSERT( range != 'A' || (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
445 BLAZE_INTERNAL_ASSERT( range != 'V' || (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
446 BLAZE_INTERNAL_ASSERT( range != 'I' || (*w).size() == size_t( iu-il+1 ), "Invalid vector dimension detected" );
447 BLAZE_INTERNAL_ASSERT( SO2 || (*Z).rows() == (*w).size(), "Invalid matrix dimension detected" );
448 BLAZE_INTERNAL_ASSERT( SO2 || (*Z).columns() == (*A).rows(), "Invalid matrix dimension detected" );
449 BLAZE_INTERNAL_ASSERT( !SO2 || (*Z).rows() == (*A).rows(), "Invalid matrix dimension detected" );
450 BLAZE_INTERNAL_ASSERT( !SO2 || (*Z).columns() == (*w).size(), "Invalid matrix dimension detected" );
451
452 using CT = ElementType_t<MT1>;
453 using BT = UnderlyingElement_t<CT>;
454
457
458 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
459 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
460 blas_int_t m ( 0 );
461 blas_int_t ldz ( numeric_cast<blas_int_t>( (*Z).spacing() ) );
462 blas_int_t info( 0 );
463
464 blas_int_t lwork( 12*n + 2 );
465 const std::unique_ptr<CT[]> work ( new CT[lwork] );
466 const std::unique_ptr<BT[]> rwork( new BT[7*n] );
467 const std::unique_ptr<blas_int_t[]> iwork( new blas_int_t[5*n] );
468 const std::unique_ptr<blas_int_t[]> ifail( new blas_int_t[n] );
469
470 heevx( 'N', range, uplo, n, (*A).data(), lda, vl, vu, il, iu, BT(0), &m, (*w).data(),
471 (*Z).data(), ldz, work.get(), lwork, rwork.get(), iwork.get(), ifail.get(), &info );
472
473 const size_t num( numeric_cast<size_t>( m ) );
474
475 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
476 BLAZE_INTERNAL_ASSERT( num <= (*w).size(), "Invalid number of eigenvalues detected" );
477
478 if( info > 0 ) {
479 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
480 }
481
482 return num;
483}
485//*************************************************************************************************
486
487
488//*************************************************************************************************
551template< typename MT1 // Type of the matrix A
552 , bool SO1 // Storage order of the matrix A
553 , typename VT // Type of the vector w
554 , bool TF // Transpose flag of the vector w
555 , typename MT2 // Type of the matrix Z
556 , bool SO2 > // Storage order of the matrix Z
558 DenseMatrix<MT2,SO2>& Z, char uplo )
559{
566
572
579
580 using CT = ElementType_t<MT1>;
581 using BT = UnderlyingElement_t<CT>;
582
583 const size_t N( (*A).rows() );
584
585 if( !isSquare( *A ) ) {
586 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
587 }
588
589 if( uplo != 'L' && uplo != 'U' ) {
590 BLAZE_THROW_INVALID_ARGUMENT( "Invalid uplo argument provided" );
591 }
592
593 resize( *w, N, false );
594 resize( *Z, N, N, false );
595
596 if( N == 0UL ) {
597 return 0;
598 }
599
600 return heevx_backend( *A, *w, *Z, uplo, 'A', BT(), BT(), 0, 0 );
601}
602//*************************************************************************************************
603
604
605//*************************************************************************************************
701template< typename MT1 // Type of the matrix A
702 , bool SO1 // Storage order of the matrix A
703 , typename VT // Type of the vector w
704 , bool TF // Transpose flag of the vector w
705 , typename MT2 // Type of the matrix Z
706 , bool SO2 // Storage order of the matrix Z
707 , typename ST > // Type of the scalar boundary values
709 DenseMatrix<MT2,SO2>& Z, char uplo, ST low, ST upp )
710{
717
723
730
731 if( !isSquare( *A ) ) {
732 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
733 }
734
735 if( IsFloatingPoint_v<ST> && low >= upp ) {
736 BLAZE_THROW_INVALID_ARGUMENT( "Invalid value range provided" );
737 }
738
739 if( !IsFloatingPoint_v<ST> && low > upp ) {
740 BLAZE_THROW_INVALID_ARGUMENT( "Invalid index range provided" );
741 }
742
743 const size_t N( (*A).rows() );
744 const size_t num( IsFloatingPoint_v<ST> ? N : size_t( upp - low ) + 1UL );
745
746 if( !IsFloatingPoint_v<ST> && num > N ) {
747 BLAZE_THROW_INVALID_ARGUMENT( "Invalid index range provided" );
748 }
749
750 if( uplo != 'L' && uplo != 'U' ) {
751 BLAZE_THROW_INVALID_ARGUMENT( "Invalid uplo argument provided" );
752 }
753
754 resize( *w, num, false );
755 resize( *Z, ( IsRowMajorMatrix_v<MT2> ? num : N ),
756 ( IsRowMajorMatrix_v<MT2> ? N : num ), false );
757
758 if( N == 0UL ) {
759 return 0;
760 }
761
762 const char range( IsFloatingPoint_v<ST> ? 'V' : 'I' );
763 const ST vl ( IsFloatingPoint_v<ST> ? low : ST() );
764 const ST vu ( IsFloatingPoint_v<ST> ? upp : ST() );
765 const blas_int_t il ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( low ) );
766 const blas_int_t iu ( IsFloatingPoint_v<ST> ? 0 : numeric_cast<blas_int_t>( upp ) );
767
768 return heevx_backend( *A, *w, *Z, uplo, range, vl, vu, il, iu );
769}
770//*************************************************************************************************
771
772} // namespace blaze
773
774#endif
Constraint on the data type.
Header file for auxiliary alias declarations.
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
Header file for run time assertion macros.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the IsFloatingPoint type trait.
Header file for the IsRowMajorMatrix type trait.
Constraint on the data type.
Cast operators for numeric types.
Header file for the CLAPACK heevx wrapper functions.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Base class for N-dimensional dense vectors.
Definition: DenseVector.h:77
Constraint on the data type.
Constraint on the data type.
Header file for the DenseMatrix base class.
Header file for the DenseVector base class.
#define BLAZE_CONSTRAINT_MUST_BE_BUILTIN_TYPE(T)
Constraint on the data type.
Definition: Builtin.h:60
#define BLAZE_CONSTRAINT_MUST_BE_COMPLEX_TYPE(T)
Constraint on the data type.
Definition: Complex.h:62
size_t heevx(DenseMatrix< MT1, SO1 > &A, DenseVector< VT, TF > &w, DenseMatrix< MT2, SO2 > &Z, char uplo, ST low, ST upp)
LAPACK kernel for computing the eigenvalues of the given dense Hermitian matrix.
Definition: heevx.h:708
#define BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE(T)
Constraint on the data type.
Definition: BLASCompatible.h:61
#define BLAZE_CONSTRAINT_MUST_BE_CONTIGUOUS_TYPE(T)
Constraint on the data type.
Definition: Contiguous.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ADAPTOR_TYPE(T)
Constraint on the data type.
Definition: Adaptor.h:81
#define BLAZE_CONSTRAINT_MUST_HAVE_MUTABLE_DATA_ACCESS(T)
Constraint on the data type.
Definition: MutableDataAccess.h:61
typename UnderlyingElement< T >::Type UnderlyingElement_t
Auxiliary alias declaration for the UnderlyingElement type trait.
Definition: UnderlyingElement.h:119
int32_t blas_int_t
Signed integer type used in the BLAS/LAPACK wrapper functions.
Definition: Types.h:64
#define BLAZE_THROW_LAPACK_ERROR(MESSAGE)
Macro for the emission of an exception on detection of a LAPACK error.
Definition: Exception.h:146
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
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_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 basic type definitions.