35#ifndef _BLAZE_MATH_LAPACK_GEEV_H_
36#define _BLAZE_MATH_LAPACK_GEEV_H_
76template<
typename MT,
bool SO,
typename VT,
bool TF >
77void geev( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w );
79template<
typename MT1,
bool SO1,
typename MT2,
bool SO2,
typename VT,
bool TF >
80void geev( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL, DenseVector<VT,TF>& w );
82template<
typename MT1,
bool SO1,
typename VT,
bool TF,
typename MT2,
bool SO2 >
83void geev( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& VR );
85template<
typename MT1,
bool SO1,
typename MT2,
bool SO2,
typename VT,
bool TF,
typename MT3,
bool SO3 >
86void geev( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL,
87 DenseVector<VT,TF>& w, DenseMatrix<MT3,SO3>& VR );
113inline auto geev_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
114 -> DisableIf_t< IsComplex_v< ElementType_t<MT> > >
119 using CT = ElementType_t<VT>;
120 using BT = ElementType_t<MT>;
125 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
126 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
130 const std::unique_ptr<BT[]> wr (
new BT[n] );
131 const std::unique_ptr<BT[]> wi (
new BT[n] );
132 const std::unique_ptr<BT[]> work(
new BT[lwork] );
134 geev(
'N',
'N', n, (*A).data(), lda, wr.get(), wi.get(),
135 nullptr, 1,
nullptr, 1, work.get(), lwork, &info );
143 for(
size_t i=0UL; i<(*A).rows(); ++i ) {
144 (*w)[i] = CT( wr[i], wi[i] );
172inline auto geev_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
173 -> EnableIf_t< IsComplex_v< ElementType_t<MT> > >
178 using CT = ElementType_t<MT>;
179 using BT = UnderlyingElement_t<CT>;
184 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
185 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
189 const std::unique_ptr<CT[]> work (
new CT[lwork] );
190 const std::unique_ptr<BT[]> rwork(
new BT[2*n] );
192 geev(
'N',
'N', n, (*A).data(), lda, (*w).data(),
193 nullptr, 1,
nullptr, 1, work.get(), lwork, rwork.get(), &info );
278 const size_t N( (*A).rows() );
290 geev_backend( *A, *w );
313template<
typename MT1
319inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL, DenseVector<VT,TF>& w )
320 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
327 using CT = ElementType_t<VT>;
328 using BT = ElementType_t<MT1>;
333 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
334 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
338 const std::unique_ptr<BT[]> vl (
new BT[n*n] );
339 const std::unique_ptr<BT[]> wr (
new BT[n] );
340 const std::unique_ptr<BT[]> wi (
new BT[n] );
341 const std::unique_ptr<BT[]> work(
new BT[lwork] );
343 geev( ( SO1 ?
'V' :
'N' ), ( SO1 ?
'N' :
'V' ), n, (*A).data(), lda, wr.get(), wi.get(),
344 ( SO1 ? vl.get() :
nullptr ), ( SO1 ? n : 1 ),
345 ( SO1 ?
nullptr : vl.get() ), ( SO1 ? 1 : n ),
346 work.get(), lwork, &info );
354 const size_t N( (*A).rows() );
356 for(
size_t j=0UL; j<N; ++j ) {
357 (*w)[j] = CT( wr[j], wi[j] );
360 for(
size_t j=0UL; j<N; ++j ) {
361 if( j+1UL < N &&
equal( (*w)[j],
conj( (*w)[j+1UL] ) ) ) {
362 for(
size_t i=0UL; i<N; ++i )
364 const size_t j1( SO1 ? j : j+1UL );
365 const size_t j2( SO1 ? j+1UL : j );
367 const BT vl1( vl[i+j*N] );
368 const BT vl2( vl[i+(j+1UL)*N] );
370 ( SO2 ? (*VL)(i,j1) : (*VL)(j1,i) ) = CT( vl1, ( SO2 ? vl2 : -vl2 ) );
371 ( SO2 ? (*VL)(i,j2) : (*VL)(j2,i) ) = CT( vl1, ( SO2 ? -vl2 : vl2 ) );
377 for(
size_t i=0UL; i<N; ++i ) {
378 ( SO2 ? (*VL)(i,j) : (*VL)(j,i) ) = CT( vl[i+j*N] );
405template<
typename MT1
411inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL, DenseVector<VT,TF>& w )
412 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
419 using CT = ElementType_t<MT1>;
420 using BT = UnderlyingElement_t<CT>;
425 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
426 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
427 blas_int_t ldvl( numeric_cast<blas_int_t>( (*VL).spacing() ) );
431 const std::unique_ptr<CT[]> work (
new CT[lwork] );
432 const std::unique_ptr<BT[]> rwork(
new BT[2*n] );
434 geev( ( SO1 ?
'V' :
'N' ), ( SO1 ?
'N' :
'V' ), n, (*A).data(), lda, (*w).data(),
435 ( SO1 ? (*VL).data() :
nullptr ), ( SO1 ? ldvl : 1 ),
436 ( SO1 ?
nullptr : (*VL).data() ), ( SO1 ? 1 : ldvl ),
437 work.get(), lwork, rwork.get(), &info );
518template<
typename MT1
545 const size_t N( (*A).rows() );
552 resize( *VL, N, N,
false );
558 geev_backend( *A, *VL, *w );
581template<
typename MT1
587inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& VR )
588 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
595 using CT = ElementType_t<VT>;
596 using BT = ElementType_t<MT1>;
601 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
602 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
606 const std::unique_ptr<BT[]> vr (
new BT[n*n] );
607 const std::unique_ptr<BT[]> wr (
new BT[n] );
608 const std::unique_ptr<BT[]> wi (
new BT[n] );
609 const std::unique_ptr<BT[]> work(
new BT[lwork] );
611 geev( ( SO1 ?
'N' :
'V' ), ( SO1 ?
'V' :
'N' ), n, (*A).data(), lda, wr.get(), wi.get(),
612 ( SO1 ?
nullptr : vr.get() ), ( SO1 ? 1 : n ),
613 ( SO1 ? vr.get() :
nullptr ), ( SO1 ? n : 1 ),
614 work.get(), lwork, &info );
622 const size_t N( (*A).rows() );
624 for(
size_t j=0UL; j<N; ++j ) {
625 (*w)[j] = CT( wr[j], wi[j] );
628 for(
size_t j=0UL; j<N; ++j ) {
629 if( j+1UL < N &&
equal( (*w)[j],
conj( (*w)[j+1UL] ) ) ) {
630 for(
size_t i=0UL; i<N; ++i )
632 const size_t j1( SO1 ? j : j+1UL );
633 const size_t j2( SO1 ? j+1UL : j );
635 const BT vr1( vr[i+j*N] );
636 const BT vr2( vr[i+(j+1UL)*N] );
638 ( SO2 ? (*VR)(i,j1) : (*VR)(j1,i) ) = CT( vr1, ( SO2 ? vr2 : -vr2 ) );
639 ( SO2 ? (*VR)(i,j2) : (*VR)(j2,i) ) = CT( vr1, ( SO2 ? -vr2 : vr2 ) );
645 for(
size_t i=0UL; i<N; ++i ) {
646 ( SO2 ? (*VR)(i,j) : (*VR)(j,i) ) = CT( vr[i+j*N] );
673template<
typename MT1
679inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& VR )
680 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
687 using CT = ElementType_t<MT1>;
688 using BT = UnderlyingElement_t<CT>;
693 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
694 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
695 blas_int_t ldvr( numeric_cast<blas_int_t>( (*VR).spacing() ) );
699 const std::unique_ptr<CT[]> work (
new CT[lwork] );
700 const std::unique_ptr<BT[]> rwork(
new BT[2*n] );
702 geev( ( SO1 ?
'N' :
'V' ), ( SO1 ?
'V' :
'N' ), n, (*A).data(), lda, (*w).data(),
703 ( SO1 ?
nullptr : (*VR).data() ), ( SO1 ? 1 : ldvr ),
704 ( SO1 ? (*VR).data() :
nullptr ), ( SO1 ? ldvr : 1 ),
705 work.get(), lwork, rwork.get(), &info );
786template<
typename MT1
810 const size_t N( (*A).rows() );
817 resize( *VR, N, N,
false );
823 geev_backend( *A, *w, *VR );
847template<
typename MT1
855inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL,
856 DenseVector<VT,TF>& w, DenseMatrix<MT3,SO3>& VR )
857 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
866 using CT = ElementType_t<VT>;
867 using BT = ElementType_t<MT1>;
872 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
873 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
877 const std::unique_ptr<BT[]> vl (
new BT[n*n] );
878 const std::unique_ptr<BT[]> vr (
new BT[n*n] );
879 const std::unique_ptr<BT[]> wr (
new BT[n] );
880 const std::unique_ptr<BT[]> wi (
new BT[n] );
881 const std::unique_ptr<BT[]> work(
new BT[lwork] );
883 geev(
'V',
'V', n, (*A).data(), lda, wr.get(), wi.get(),
884 ( SO1 ? vl.get() : vr.get() ), n, ( SO1 ? vr.get() : vl.get() ), n,
885 work.get(), lwork, &info );
893 const size_t N( (*A).rows() );
895 for(
size_t j=0UL; j<N; ++j ) {
896 (*w)[j] = CT( wr[j], wi[j] );
899 for(
size_t j=0UL; j<N; ++j ) {
900 if( j+1UL < N &&
equal( (*w)[j],
conj( (*w)[j+1UL] ) ) ) {
901 for(
size_t i=0UL; i<N; ++i )
903 const size_t j1( SO1 ? j : j+1UL );
904 const size_t j2( SO1 ? j+1UL : j );
906 const BT vl1( vl[i+j*N] );
907 const BT vl2( vl[i+(j+1UL)*N] );
908 const BT vr1( vr[i+j*N] );
909 const BT vr2( vr[i+(j+1UL)*N] );
911 ( SO2 ? (*VL)(i,j1) : (*VL)(j1,i) ) = CT( vl1, ( SO2 ? vl2 : -vl2 ) );
912 ( SO2 ? (*VL)(i,j2) : (*VL)(j2,i) ) = CT( vl1, ( SO2 ? -vl2 : vl2 ) );
913 ( SO3 ? (*VR)(i,j1) : (*VR)(j1,i) ) = CT( vr1, ( SO3 ? vr2 : -vr2 ) );
914 ( SO3 ? (*VR)(i,j2) : (*VR)(j2,i) ) = CT( vr1, ( SO3 ? -vr2 : vr2 ) );
920 for(
size_t i=0UL; i<N; ++i ) {
921 ( SO2 ? (*VL)(i,j) : (*VL)(j,i) ) = CT( vl[i+j*N] );
922 ( SO3 ? (*VR)(i,j) : (*VR)(j,i) ) = CT( vr[i+j*N] );
950template<
typename MT1
958inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL,
959 DenseVector<VT,TF>& w, DenseMatrix<MT3,SO3>& VR )
960 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
969 using CT = ElementType_t<MT1>;
970 using BT = UnderlyingElement_t<CT>;
975 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
976 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
977 blas_int_t ldvl( numeric_cast<blas_int_t>( (*VL).spacing() ) );
978 blas_int_t ldvr( numeric_cast<blas_int_t>( (*VR).spacing() ) );
982 const std::unique_ptr<CT[]> work (
new CT[lwork] );
983 const std::unique_ptr<BT[]> rwork(
new BT[2*n] );
985 geev(
'V',
'V', n, (*A).data(), lda, (*w).data(),
986 ( SO1 ? (*VL).data() : (*VR).data() ), ( SO1 ? ldvl : ldvr ),
987 ( SO1 ? (*VR).data() : (*VL).data() ), ( SO1 ? ldvr : ldvl ),
988 work.get(), lwork, rwork.get(), &info );
1078template<
typename MT1
1111 const size_t N( (*A).rows() );
1118 resize( *VL, N, N,
false );
1119 resize( *VR, N, N,
false );
1125 geev_backend( *A, *VL, *w, *VR );
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.
Header file for the complex data type.
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsComplex type trait.
Constraint on the data type.
Cast operators for numeric types.
Header file for the UnderlyingElement type trait.
Header file for the CLAPACK geev 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
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1464
void geev(DenseMatrix< MT1, SO1 > &A, DenseMatrix< MT2, SO2 > &VL, DenseVector< VT, TF > &w, DenseMatrix< MT3, SO3 > &VR)
LAPACK kernel for computing the eigenvalues of the given dense general matrix.
Definition: geev.h:1086
#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
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
bool equal(const SharedValue< T1 > &lhs, const SharedValue< T2 > &rhs)
Equality check for a two shared values.
Definition: SharedValue.h:343
#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 equal shim.