Blaze 3.9
geev.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_LAPACK_GEEV_H_
36#define _BLAZE_MATH_LAPACK_GEEV_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <memory>
44#include <blaze/math/Aliases.h>
56#include <blaze/util/Assert.h>
57#include <blaze/util/Complex.h>
60#include <blaze/util/EnableIf.h>
63
64
65namespace blaze {
66
67//=================================================================================================
68//
69// LAPACK GENERAL MATRIX EIGENVALUE FUNCTIONS (GEEV)
70//
71//=================================================================================================
72
73//*************************************************************************************************
76template< typename MT, bool SO, typename VT, bool TF >
77void geev( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w );
78
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 );
81
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 );
84
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 );
89//*************************************************************************************************
90
91
92//*************************************************************************************************
109template< typename MT // Type of the matrix A
110 , bool SO // Storage order of the matrix A
111 , typename VT // Type of the vector w
112 , bool TF > // Transpose flag of the vector w
113inline auto geev_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
114 -> DisableIf_t< IsComplex_v< ElementType_t<MT> > >
115{
116 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Invalid non-square matrix detected" );
117 BLAZE_INTERNAL_ASSERT( (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
118
119 using CT = ElementType_t<VT>;
120 using BT = ElementType_t<MT>;
121
124
125 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
126 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
127 blas_int_t info( 0 );
128
129 blas_int_t lwork( 3*n + 2 );
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] );
133
134 geev( 'N', 'N', n, (*A).data(), lda, wr.get(), wi.get(),
135 nullptr, 1, nullptr, 1, work.get(), lwork, &info );
136
137 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
138
139 if( info > 0 ) {
140 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
141 }
142
143 for( size_t i=0UL; i<(*A).rows(); ++i ) {
144 (*w)[i] = CT( wr[i], wi[i] );
145 }
146}
148//*************************************************************************************************
149
150
151//*************************************************************************************************
168template< typename MT // Type of the matrix A
169 , bool SO // Storage order of the matrix A
170 , typename VT // Type of the vector w
171 , bool TF > // Transpose flag of the vector w
172inline auto geev_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
173 -> EnableIf_t< IsComplex_v< ElementType_t<MT> > >
174{
175 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Invalid non-square matrix detected" );
176 BLAZE_INTERNAL_ASSERT( (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
177
178 using CT = ElementType_t<MT>;
179 using BT = UnderlyingElement_t<CT>;
180
183
184 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
185 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
186 blas_int_t info( 0 );
187
188 blas_int_t lwork( 2*n + 2 );
189 const std::unique_ptr<CT[]> work ( new CT[lwork] );
190 const std::unique_ptr<BT[]> rwork( new BT[2*n] );
191
192 geev( 'N', 'N', n, (*A).data(), lda, (*w).data(),
193 nullptr, 1, nullptr, 1, work.get(), lwork, rwork.get(), &info );
194
195 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
196
197 if( info > 0 ) {
198 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
199 }
200}
202//*************************************************************************************************
203
204
205//*************************************************************************************************
260template< typename MT // Type of the matrix A
261 , bool SO // Storage order of the matrix A
262 , typename VT // Type of the vector w
263 , bool TF > // Transpose flag of the vector w
265{
271
277
278 const size_t N( (*A).rows() );
279
280 if( !isSquare( *A ) ) {
281 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
282 }
283
284 resize( *w, N, false );
285
286 if( N == 0UL ) {
287 return;
288 }
289
290 geev_backend( *A, *w );
291}
292//*************************************************************************************************
293
294
295//*************************************************************************************************
313template< typename MT1 // Type of the matrix A
314 , bool SO1 // Storage order of the matrix A
315 , typename MT2 // Type of the matrix VL
316 , bool SO2 // Storage order of the matrix VL
317 , typename VT // Type of the vector w
318 , bool TF > // Transpose flag of the vector w
319inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL, DenseVector<VT,TF>& w )
320 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
321{
322 BLAZE_INTERNAL_ASSERT( isSquare( *A ) , "Invalid non-square matrix detected" );
323 BLAZE_INTERNAL_ASSERT( isSquare( *VL ), "Invalid non-square matrix detected" );
324 BLAZE_INTERNAL_ASSERT( (*VL).rows() == (*A).rows(), "Invalid matrix dimension detected" );
325 BLAZE_INTERNAL_ASSERT( (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
326
327 using CT = ElementType_t<VT>;
328 using BT = ElementType_t<MT1>;
329
332
333 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
334 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
335 blas_int_t info( 0 );
336
337 blas_int_t lwork( 4*n + 2 );
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] );
342
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 );
347
348 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
349
350 if( info > 0 ) {
351 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
352 }
353
354 const size_t N( (*A).rows() );
355
356 for( size_t j=0UL; j<N; ++j ) {
357 (*w)[j] = CT( wr[j], wi[j] );
358 }
359
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 )
363 {
364 const size_t j1( SO1 ? j : j+1UL );
365 const size_t j2( SO1 ? j+1UL : j );
366
367 const BT vl1( vl[i+j*N] );
368 const BT vl2( vl[i+(j+1UL)*N] );
369
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 ) );
372 }
373
374 ++j;
375 }
376 else {
377 for( size_t i=0UL; i<N; ++i ) {
378 ( SO2 ? (*VL)(i,j) : (*VL)(j,i) ) = CT( vl[i+j*N] );
379 }
380 }
381 }
382}
384//*************************************************************************************************
385
386
387//*************************************************************************************************
405template< typename MT1 // Type of the matrix A
406 , bool SO1 // Storage order of the matrix A
407 , typename MT2 // Type of the matrix VL
408 , bool SO2 // Storage order of the matrix VL
409 , typename VT // Type of the vector w
410 , bool TF > // Transpose flag of the vector w
411inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL, DenseVector<VT,TF>& w )
412 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
413{
414 BLAZE_INTERNAL_ASSERT( isSquare( *A ) , "Invalid non-square matrix detected" );
415 BLAZE_INTERNAL_ASSERT( isSquare( *VL ), "Invalid non-square matrix detected" );
416 BLAZE_INTERNAL_ASSERT( (*VL).rows() == (*A).rows(), "Invalid matrix dimension detected" );
417 BLAZE_INTERNAL_ASSERT( (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
418
419 using CT = ElementType_t<MT1>;
420 using BT = UnderlyingElement_t<CT>;
421
424
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() ) );
428 blas_int_t info( 0 );
429
430 blas_int_t lwork( 2*n + 2 );
431 const std::unique_ptr<CT[]> work ( new CT[lwork] );
432 const std::unique_ptr<BT[]> rwork( new BT[2*n] );
433
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 );
438
439 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
440
441 if( info > 0 ) {
442 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
443 }
444}
446//*************************************************************************************************
447
448
449//*************************************************************************************************
518template< typename MT1 // Type of the matrix A
519 , bool SO1 // Storage order of the matrix A
520 , typename MT2 // Type of the matrix VL
521 , bool SO2 // Storage order of the matrix VL
522 , typename VT // Type of the vector w
523 , bool TF > // Transpose flag of the vector w
525{
531
538
544
545 const size_t N( (*A).rows() );
546
547 if( !isSquare( *A ) ) {
548 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
549 }
550
551 resize( *w, N, false );
552 resize( *VL, N, N, false );
553
554 if( N == 0UL ) {
555 return;
556 }
557
558 geev_backend( *A, *VL, *w );
559}
560//*************************************************************************************************
561
562
563//*************************************************************************************************
581template< typename MT1 // Type of the matrix A
582 , bool SO1 // Storage order of the matrix A
583 , typename VT // Type of the vector w
584 , bool TF // Transpose flag of the vector w
585 , typename MT2 // Type of the matrix VR
586 , bool SO2 > // Storage order of the matrix VR
587inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& VR )
588 -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
589{
590 BLAZE_INTERNAL_ASSERT( isSquare( *A ) , "Invalid non-square matrix detected" );
591 BLAZE_INTERNAL_ASSERT( isSquare( *VR ), "Invalid non-square matrix detected" );
592 BLAZE_INTERNAL_ASSERT( (*VR).rows() == (*A).rows(), "Invalid matrix dimension detected" );
593 BLAZE_INTERNAL_ASSERT( (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
594
595 using CT = ElementType_t<VT>;
596 using BT = ElementType_t<MT1>;
597
600
601 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
602 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
603 blas_int_t info( 0 );
604
605 blas_int_t lwork( 4*n + 2 );
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] );
610
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 );
615
616 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
617
618 if( info > 0 ) {
619 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
620 }
621
622 const size_t N( (*A).rows() );
623
624 for( size_t j=0UL; j<N; ++j ) {
625 (*w)[j] = CT( wr[j], wi[j] );
626 }
627
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 )
631 {
632 const size_t j1( SO1 ? j : j+1UL );
633 const size_t j2( SO1 ? j+1UL : j );
634
635 const BT vr1( vr[i+j*N] );
636 const BT vr2( vr[i+(j+1UL)*N] );
637
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 ) );
640 }
641
642 ++j;
643 }
644 else {
645 for( size_t i=0UL; i<N; ++i ) {
646 ( SO2 ? (*VR)(i,j) : (*VR)(j,i) ) = CT( vr[i+j*N] );
647 }
648 }
649 }
650}
652//*************************************************************************************************
653
654
655//*************************************************************************************************
673template< typename MT1 // Type of the matrix A
674 , bool SO1 // Storage order of the matrix A
675 , typename VT // Type of the vector w
676 , bool TF // Transpose flag of the vector w
677 , typename MT2 // Type of the matrix VR
678 , bool SO2 > // Storage order of the matrix VR
679inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& VR )
680 -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
681{
682 BLAZE_INTERNAL_ASSERT( isSquare( *A ) , "Invalid non-square matrix detected" );
683 BLAZE_INTERNAL_ASSERT( isSquare( *VR ), "Invalid non-square matrix detected" );
684 BLAZE_INTERNAL_ASSERT( (*VR).rows() == (*A).rows(), "Invalid matrix dimension detected" );
685 BLAZE_INTERNAL_ASSERT( (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
686
687 using CT = ElementType_t<MT1>;
688 using BT = UnderlyingElement_t<CT>;
689
692
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() ) );
696 blas_int_t info( 0 );
697
698 blas_int_t lwork( 2*n + 2 );
699 const std::unique_ptr<CT[]> work ( new CT[lwork] );
700 const std::unique_ptr<BT[]> rwork( new BT[2*n] );
701
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 );
706
707 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
708
709 if( info > 0 ) {
710 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
711 }
712}
714//*************************************************************************************************
715
716
717//*************************************************************************************************
786template< typename MT1 // Type of the matrix A
787 , bool SO1 // Storage order of the matrix A
788 , typename VT // Type of the vector w
789 , bool TF // Transpose flag of the vector w
790 , typename MT2 // Type of the matrix VR
791 , bool SO2 > // Storage order of the matrix VR
793{
798
803
809
810 const size_t N( (*A).rows() );
811
812 if( !isSquare( *A ) ) {
813 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
814 }
815
816 resize( *w, N, false );
817 resize( *VR, N, N, false );
818
819 if( N == 0UL ) {
820 return;
821 }
822
823 geev_backend( *A, *w, *VR );
824}
825//*************************************************************************************************
826
827
828//*************************************************************************************************
847template< typename MT1 // Type of the matrix A
848 , bool SO1 // Storage order of the matrix A
849 , typename MT2 // Type of the matrix VL
850 , bool SO2 // Storage order of the matrix VL
851 , typename VT // Type of the vector w
852 , bool TF // Transpose flag of the vector w
853 , typename MT3 // Type of the matrix VR
854 , bool SO3 > // Storage order of the matrix VR
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> > >
858{
859 BLAZE_INTERNAL_ASSERT( isSquare( *A ) , "Invalid non-square matrix detected" );
860 BLAZE_INTERNAL_ASSERT( isSquare( *VL ), "Invalid non-square matrix detected" );
861 BLAZE_INTERNAL_ASSERT( isSquare( *VR ), "Invalid non-square matrix detected" );
862 BLAZE_INTERNAL_ASSERT( (*VL).rows() == (*A).rows(), "Invalid matrix dimension detected" );
863 BLAZE_INTERNAL_ASSERT( (*VR).rows() == (*A).rows(), "Invalid matrix dimension detected" );
864 BLAZE_INTERNAL_ASSERT( (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
865
866 using CT = ElementType_t<VT>;
867 using BT = ElementType_t<MT1>;
868
871
872 blas_int_t n ( numeric_cast<blas_int_t>( (*A).rows() ) );
873 blas_int_t lda ( numeric_cast<blas_int_t>( (*A).spacing() ) );
874 blas_int_t info( 0 );
875
876 blas_int_t lwork( 4*n + 2 );
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] );
882
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 );
886
887 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
888
889 if( info > 0 ) {
890 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
891 }
892
893 const size_t N( (*A).rows() );
894
895 for( size_t j=0UL; j<N; ++j ) {
896 (*w)[j] = CT( wr[j], wi[j] );
897 }
898
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 )
902 {
903 const size_t j1( SO1 ? j : j+1UL );
904 const size_t j2( SO1 ? j+1UL : j );
905
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] );
910
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 ) );
915 }
916
917 ++j;
918 }
919 else {
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] );
923 }
924 }
925 }
926}
928//*************************************************************************************************
929
930
931//*************************************************************************************************
950template< typename MT1 // Type of the matrix A
951 , bool SO1 // Storage order of the matrix A
952 , typename MT2 // Type of the matrix VL
953 , bool SO2 // Storage order of the matrix VL
954 , typename VT // Type of the vector w
955 , bool TF // Transpose flag of the vector w
956 , typename MT3 // Type of the matrix VR
957 , bool SO3 > // Storage order of the matrix VR
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> > >
961{
962 BLAZE_INTERNAL_ASSERT( isSquare( *A ) , "Invalid non-square matrix detected" );
963 BLAZE_INTERNAL_ASSERT( isSquare( *VL ), "Invalid non-square matrix detected" );
964 BLAZE_INTERNAL_ASSERT( isSquare( *VR ), "Invalid non-square matrix detected" );
965 BLAZE_INTERNAL_ASSERT( (*VL).rows() == (*A).rows(), "Invalid matrix dimension detected" );
966 BLAZE_INTERNAL_ASSERT( (*VR).rows() == (*A).rows(), "Invalid matrix dimension detected" );
967 BLAZE_INTERNAL_ASSERT( (*w).size() == (*A).rows(), "Invalid vector dimension detected" );
968
969 using CT = ElementType_t<MT1>;
970 using BT = UnderlyingElement_t<CT>;
971
974
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() ) );
979 blas_int_t info( 0 );
980
981 blas_int_t lwork( 2*n + 2 );
982 const std::unique_ptr<CT[]> work ( new CT[lwork] );
983 const std::unique_ptr<BT[]> rwork( new BT[2*n] );
984
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 );
989
990 BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
991
992 if( info > 0 ) {
993 BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
994 }
995}
997//*************************************************************************************************
998
999
1000//*************************************************************************************************
1078template< typename MT1 // Type of the matrix A
1079 , bool SO1 // Storage order of the matrix A
1080 , typename MT2 // Type of the matrix VL
1081 , bool SO2 // Storage order of the matrix VL
1082 , typename VT // Type of the vector w
1083 , bool TF // Transpose flag of the vector w
1084 , typename MT3 // Type of the matrix VR
1085 , bool SO3 > // Storage order of the matrix VR
1088{
1093
1099
1104
1110
1111 const size_t N( (*A).rows() );
1112
1113 if( !isSquare( *A ) ) {
1114 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
1115 }
1116
1117 resize( *w, N, false );
1118 resize( *VL, N, N, false );
1119 resize( *VR, N, N, false );
1120
1121 if( N == 0UL ) {
1122 return;
1123 }
1124
1125 geev_backend( *A, *VL, *w, *VR );
1126}
1127//*************************************************************************************************
1128
1129} // namespace blaze
1130
1131#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.
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.