Blaze 3.9
Eigen.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_DENSE_EIGEN_H_
36#define _BLAZE_MATH_DENSE_EIGEN_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <blaze/math/Aliases.h>
60#include <blaze/util/EnableIf.h>
62#include <blaze/util/mpl/If.h>
65
66
67namespace blaze {
68
69//=================================================================================================
70//
71// EIGENVALUE FUNCTIONS
72//
73//=================================================================================================
74
75//*************************************************************************************************
78template< typename MT, bool SO, typename VT, bool TF >
79inline void eigen( const DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w );
80
81template< typename MT1, bool SO1, typename VT, bool TF, typename MT2, bool SO2 >
82inline void eigen( const DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& V );
84//*************************************************************************************************
85
86
87//*************************************************************************************************
106template< typename MT // Type of the matrix A
107 , bool SO // Storage order of the matrix A
108 , typename VT // Type of the vector w
109 , bool TF > // Transpose flag of the vector w
110inline auto eigen_backend( const DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
111 -> EnableIf_t< IsSymmetric_v<MT> && !IsDiagonal_v<MT> && IsFloatingPoint_v< ElementType_t<MT> > >
112{
113 using ATmp = RemoveAdaptor_t< ResultType_t<MT> >;
114
119
120 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
121
122 ATmp Atmp( *A );
123
124 syevd( Atmp, *w, 'N', 'L' );
125}
127//*************************************************************************************************
128
129
130//*************************************************************************************************
149template< typename MT // Type of the matrix A
150 , bool SO // Storage order of the matrix A
151 , typename VT // Type of the vector w
152 , bool TF > // Transpose flag of the vector w
153inline auto eigen_backend( const DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
154 -> EnableIf_t< IsHermitian_v<MT> && IsComplex_v< ElementType_t<MT> > >
155{
156 using ATmp = RemoveAdaptor_t< ResultType_t<MT> >;
157
162
163 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
164
165 ATmp Atmp( *A );
166
167 heevd( Atmp, *w, 'N', 'L' );
168}
170//*************************************************************************************************
171
172
173//*************************************************************************************************
192template< typename MT // Type of the matrix A
193 , bool SO // Storage order of the matrix A
194 , typename VT // Type of the vector w
195 , bool TF > // Transpose flag of the vector w
196inline auto eigen_backend( const DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
197 -> EnableIf_t< IsTriangular_v<MT> >
198{
199 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
200
201 const size_t N( (*A).rows() );
202
203 CompositeType_t<MT> Atmp( *A );
204
205 resize( *w, N, false );
206
207 for( size_t i=0UL; i<N; ++i ) {
208 (*w)[i] = Atmp(i,i);
209 }
210}
212//*************************************************************************************************
213
214
215//*************************************************************************************************
234template< typename MT // Type of the matrix A
235 , bool SO // Storage order of the matrix A
236 , typename VT // Type of the vector w
237 , bool TF > // Transpose flag of the vector w
238inline auto eigen_backend( const DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
239 -> DisableIf_t< ( IsSymmetric_v<MT> && !IsDiagonal_v<MT> && IsFloatingPoint_v< ElementType_t<MT> > ) ||
240 ( IsHermitian_v<MT> && IsComplex_v< ElementType_t<MT> > ) ||
241 ( IsTriangular_v<MT> ) >
242{
243 using ATmp = RemoveAdaptor_t< ResultType_t<MT> >;
244
249
250 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
251
252 ATmp Atmp( *A );
253
254 geev( Atmp, *w );
255}
257//*************************************************************************************************
258
259
260//*************************************************************************************************
347template< typename MT // Type of the matrix A
348 , bool SO // Storage order of the matrix A
349 , typename VT // Type of the vector w
350 , bool TF > // Transpose flag of the vector w
351inline void eigen( const DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
352{
354
356
360
361 if( !isSquare( *A ) ) {
362 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
363 }
364
365 using WTmp = If_t< IsContiguous_v<VT>, VT&, ResultType_t<VT> >;
366 WTmp wtmp( *w );
367
368 eigen_backend( *A, wtmp );
369
370 if( IsContiguous_v<VT> ) {
371 (*w) = wtmp;
372 }
373}
374//*************************************************************************************************
375
376
377//*************************************************************************************************
398template< typename MT1 // Type of the matrix A
399 , bool SO1 // Storage order of the matrix A
400 , typename VT // Type of the vector w
401 , bool TF // Transpose flag of the vector w
402 , typename MT2 // Type of the matrix V
403 , bool SO2 > // Storage order of the matrix V
404inline auto eigen_backend( const DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& V )
405 -> EnableIf_t< IsSymmetric_v<MT1> && !IsDiagonal_v<MT1> && IsFloatingPoint_v< ElementType_t<MT1> > >
406{
407 using ATmp = RemoveAdaptor_t< ResultType_t<MT1> >;
408
413
414 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
415
416 ATmp Atmp( *A );
417
418 syevd( Atmp, *w, 'V', 'L' );
419
420 if( SO1 == SO2 )
421 (*V) = Atmp;
422 else
423 (*V) = trans( Atmp );
424}
426//*************************************************************************************************
427
428
429//*************************************************************************************************
450template< typename MT1 // Type of the matrix A
451 , bool SO1 // Storage order of the matrix A
452 , typename VT // Type of the vector w
453 , bool TF // Transpose flag of the vector w
454 , typename MT2 // Type of the matrix V
455 , bool SO2 > // Storage order of the matrix V
456inline auto eigen_backend( const DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& V )
457 -> EnableIf_t< IsHermitian_v<MT1> && IsComplex_v< ElementType_t<MT1> > >
458{
459 using ATmp = RemoveAdaptor_t< ResultType_t<MT1> >;
460
465
466 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
467
468 ATmp Atmp( *A );
469
470 heevd( Atmp, *w, 'V', 'L' );
471
472 if( SO1 == SO2 )
473 (*V) = Atmp;
474 else
475 (*V) = trans( Atmp );
476}
478//*************************************************************************************************
479
480
481//*************************************************************************************************
502template< typename MT1 // Type of the matrix A
503 , bool SO1 // Storage order of the matrix A
504 , typename VT // Type of the vector w
505 , bool TF // Transpose flag of the vector w
506 , typename MT2 // Type of the matrix V
507 , bool SO2 > // Storage order of the matrix V
508inline auto eigen_backend( const DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& V )
509 -> EnableIf_t< IsDiagonal_v<MT1> >
510{
511 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
512
513 const size_t N( (*A).rows() );
514
515 CompositeType_t<MT1> Atmp( *A );
516
517 resize( *w, N, false );
518 resize( *V, N, N, false );
519 reset( *V );
520
521 for( size_t i=0UL; i<N; ++i ) {
522 (*w)[i] = Atmp(i,i);
523 (*V)(i,i) = ElementType_t<MT2>(1);
524 }
525}
527//*************************************************************************************************
528
529
530//*************************************************************************************************
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 V
556 , bool SO2 > // Storage order of the matrix V
557inline auto eigen_backend( const DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& V )
558 -> DisableIf_t< ( IsSymmetric_v<MT1> && !IsDiagonal_v<MT1> && IsFloatingPoint_v< ElementType_t<MT1> > ) ||
559 ( IsHermitian_v<MT1> && IsComplex_v< ElementType_t<MT1> > ) ||
560 ( IsDiagonal_v<MT1> ) >
561{
562 using ATmp = RemoveAdaptor_t< ResultType_t<MT1> >;
563
568
569 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
570
571 ATmp Atmp( *A );
572
573 if( IsRowMajorMatrix_v<MT1> )
574 geev( Atmp, *V, *w );
575 else
576 geev( Atmp, *w, *V );
577}
579//*************************************************************************************************
580
581
582//*************************************************************************************************
683template< typename MT1 // Type of the matrix A
684 , bool SO1 // Storage order of the matrix A
685 , typename VT // Type of the vector w
686 , bool TF // Transpose flag of the vector w
687 , typename MT2 // Type of the matrix V
688 , bool SO2 > // Storage order of the matrix V
690{
692
694
698
703
704 using WTmp = If_t< IsContiguous_v<VT>, VT&, ResultType_t<VT> >;
705 using VTmp = If_t< IsContiguous_v<MT2>, MT2&, ResultType_t<MT2> >;
706
707 if( !isSquare( *A ) ) {
708 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
709 }
710
711 WTmp wtmp( *w );
712 VTmp Vtmp( *V );
713
714 eigen_backend( *A, wtmp, Vtmp );
715
716 if( !IsContiguous_v<VT> ) {
717 (*w) = wtmp;
718 }
719
720 if( !IsContiguous_v<MT2> ) {
721 (*V) = Vtmp;
722 }
723}
724//*************************************************************************************************
725
726} // namespace blaze
727
728#endif
Constraint on the data type.
Header file for auxiliary alias declarations.
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the function trace functionality.
Header file for the If class template.
Header file for the IsComplex type trait.
Header file for the IsContiguous type trait.
Header file for the IsDiagonal type trait.
Header file for the IsFloatingPoint type trait.
Header file for the IsHermitian type trait.
Header file for the IsRowMajorMatrix type trait.
Header file for the IsSymmetric type trait.
Header file for the IsTriangular type trait.
Constraint on the data type.
Header file for the RemoveAdaptor type trait.
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.
Header file for the DenseMatrix base class.
Header file for the DenseVector base class.
Header file for the LAPACK general matrix eigenvalue functions (geev)
void eigen(const DenseMatrix< MT1, SO1 > &A, DenseVector< VT, TF > &w, DenseMatrix< MT2, SO2 > &V)
Eigenvalue computation of the given dense matrix.
Definition: Eigen.h:689
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
void heevd(char jobz, char uplo, blas_int_t n, complex< float > *A, blas_int_t lda, float *w, complex< float > *work, blas_int_t lwork, float *rwork, blas_int_t lrwork, blas_int_t *iwork, blas_int_t liwork, blas_int_t *info)
LAPACK kernel for computing the eigenvalues of the given dense Hermitian single precision column-majo...
Definition: heevd.h:143
void geev(char jobvl, char jobvr, blas_int_t n, float *A, blas_int_t lda, float *wr, float *wi, float *VL, blas_int_t ldvl, float *VR, blas_int_t ldvr, float *work, blas_int_t lwork, blas_int_t *info)
LAPACK kernel for computing the eigenvalues of the given dense general single precision column-major ...
Definition: geev.h:179
void syevd(char jobz, char uplo, blas_int_t n, float *A, blas_int_t lda, float *w, float *work, blas_int_t lwork, blas_int_t *iwork, blas_int_t liwork, blas_int_t *info)
LAPACK kernel for computing the eigenvalues of the given dense symmetric single precision column-majo...
Definition: syevd.h:141
#define BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE(T)
Constraint on the data type.
Definition: BLASCompatible.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
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
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
constexpr bool IsComplex_v
Auxiliary variable template for the IsComplex type trait.
Definition: IsComplex.h:139
typename If< Condition >::template Type< T1, T2 > If_t
Auxiliary alias template for the If class template.
Definition: If.h:108
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
#define BLAZE_FUNCTION_TRACE
Function trace macro.
Definition: FunctionTrace.h:94
Header file for the LAPACK Hermitian matrix eigenvalue functions (heevd)
Header file for the LAPACK symmetric matrix eigenvalue functions (syevd)