Blaze  3.6
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>
50 #include <blaze/math/Exception.h>
54 #include <blaze/math/shims/Equal.h>
56 #include <blaze/util/Assert.h>
57 #include <blaze/util/Complex.h>
60 #include <blaze/util/DisableIf.h>
61 #include <blaze/util/EnableIf.h>
62 #include <blaze/util/NumericCast.h>
64 
65 
66 namespace blaze {
67 
68 //=================================================================================================
69 //
70 // LAPACK GENERAL MATRIX EIGENVALUE FUNCTIONS (GEEV)
71 //
72 //=================================================================================================
73 
74 //*************************************************************************************************
77 template< typename MT, bool SO, typename VT, bool TF >
78 void geev( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w );
79 
80 template< typename MT1, bool SO1, typename MT2, bool SO2, typename VT, bool TF >
81 void geev( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL, DenseVector<VT,TF>& w );
82 
83 template< typename MT1, bool SO1, typename VT, bool TF, typename MT2, bool SO2 >
84 void geev( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& VR );
85 
86 template< typename MT1, bool SO1, typename MT2, bool SO2, typename VT, bool TF, typename MT3, bool SO3 >
87 void geev( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL,
88  DenseVector<VT,TF>& w, DenseMatrix<MT3,SO3>& VR );
90 //*************************************************************************************************
91 
92 
93 //*************************************************************************************************
110 template< typename MT // Type of the matrix A
111  , bool SO // Storage order of the matrix A
112  , typename VT // Type of the vector w
113  , bool TF > // Transpose flag of the vector w
114 inline auto geev_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
115  -> DisableIf_t< IsComplex_v< ElementType_t<MT> > >
116 {
117  BLAZE_INTERNAL_ASSERT( isSquare( ~A ), "Invalid non-square matrix detected" );
118  BLAZE_INTERNAL_ASSERT( (~w).size() == (~A).rows(), "Invalid vector dimension detected" );
119 
120  using CT = ElementType_t<VT>;
121  using BT = ElementType_t<MT>;
122 
125 
126  int n ( numeric_cast<int>( (~A).rows() ) );
127  int lda ( numeric_cast<int>( (~A).spacing() ) );
128  int info( 0 );
129 
130  int lwork( 3*n + 2 );
131  const std::unique_ptr<BT[]> wr ( new BT[n] );
132  const std::unique_ptr<BT[]> wi ( new BT[n] );
133  const std::unique_ptr<BT[]> work( new BT[lwork] );
134 
135  geev( 'N', 'N', n, (~A).data(), lda, wr.get(), wi.get(),
136  nullptr, 1, nullptr, 1, work.get(), lwork, &info );
137 
138  BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
139 
140  if( info > 0 ) {
141  BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
142  }
143 
144  for( size_t i=0UL; i<(~A).rows(); ++i ) {
145  (~w)[i] = CT( wr[i], wi[i] );
146  }
147 }
149 //*************************************************************************************************
150 
151 
152 //*************************************************************************************************
169 template< typename MT // Type of the matrix A
170  , bool SO // Storage order of the matrix A
171  , typename VT // Type of the vector w
172  , bool TF > // Transpose flag of the vector w
173 inline auto geev_backend( DenseMatrix<MT,SO>& A, DenseVector<VT,TF>& w )
174  -> EnableIf_t< IsComplex_v< ElementType_t<MT> > >
175 {
176  BLAZE_INTERNAL_ASSERT( isSquare( ~A ), "Invalid non-square matrix detected" );
177  BLAZE_INTERNAL_ASSERT( (~w).size() == (~A).rows(), "Invalid vector dimension detected" );
178 
179  using CT = ElementType_t<MT>;
180  using BT = UnderlyingElement_t<CT>;
181 
184 
185  int n ( numeric_cast<int>( (~A).rows() ) );
186  int lda ( numeric_cast<int>( (~A).spacing() ) );
187  int info( 0 );
188 
189  int lwork( 2*n + 2 );
190  const std::unique_ptr<CT[]> work ( new CT[lwork] );
191  const std::unique_ptr<BT[]> rwork( new BT[2*n] );
192 
193  geev( 'N', 'N', n, (~A).data(), lda, (~w).data(),
194  nullptr, 1, nullptr, 1, work.get(), lwork, rwork.get(), &info );
195 
196  BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
197 
198  if( info > 0 ) {
199  BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
200  }
201 }
203 //*************************************************************************************************
204 
205 
206 //*************************************************************************************************
261 template< typename MT // Type of the matrix A
262  , bool SO // Storage order of the matrix A
263  , typename VT // Type of the vector w
264  , bool TF > // Transpose flag of the vector w
266 {
272 
278 
279  const size_t N( (~A).rows() );
280 
281  if( !isSquare( ~A ) ) {
282  BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
283  }
284 
285  resize( ~w, N, false );
286 
287  if( N == 0UL ) {
288  return;
289  }
290 
291  geev_backend( ~A, ~w );
292 }
293 //*************************************************************************************************
294 
295 
296 //*************************************************************************************************
314 template< typename MT1 // Type of the matrix A
315  , bool SO1 // Storage order of the matrix A
316  , typename MT2 // Type of the matrix VL
317  , bool SO2 // Storage order of the matrix VL
318  , typename VT // Type of the vector w
319  , bool TF > // Transpose flag of the vector w
320 inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL, DenseVector<VT,TF>& w )
321  -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
322 {
323  BLAZE_INTERNAL_ASSERT( isSquare( ~A ) , "Invalid non-square matrix detected" );
324  BLAZE_INTERNAL_ASSERT( isSquare( ~VL ), "Invalid non-square matrix detected" );
325  BLAZE_INTERNAL_ASSERT( (~VL).rows() == (~A).rows(), "Invalid matrix dimension detected" );
326  BLAZE_INTERNAL_ASSERT( (~w).size() == (~A).rows(), "Invalid vector dimension detected" );
327 
328  using CT = ElementType_t<VT>;
329  using BT = ElementType_t<MT1>;
330 
333 
334  int n ( numeric_cast<int>( (~A).rows() ) );
335  int lda ( numeric_cast<int>( (~A).spacing() ) );
336  int info( 0 );
337 
338  int lwork( 4*n + 2 );
339  const std::unique_ptr<BT[]> vl ( new BT[n*n] );
340  const std::unique_ptr<BT[]> wr ( new BT[n] );
341  const std::unique_ptr<BT[]> wi ( new BT[n] );
342  const std::unique_ptr<BT[]> work( new BT[lwork] );
343 
344  geev( ( SO1 ? 'V' : 'N' ), ( SO1 ? 'N' : 'V' ), n, (~A).data(), lda, wr.get(), wi.get(),
345  ( SO1 ? vl.get() : nullptr ), ( SO1 ? n : 1 ),
346  ( SO1 ? nullptr : vl.get() ), ( SO1 ? 1 : n ),
347  work.get(), lwork, &info );
348 
349  BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
350 
351  if( info > 0 ) {
352  BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
353  }
354 
355  const size_t N( (~A).rows() );
356 
357  for( size_t j=0UL; j<N; ++j ) {
358  (~w)[j] = CT( wr[j], wi[j] );
359  }
360 
361  for( size_t j=0UL; j<N; ++j ) {
362  if( j+1UL < N && equal( (~w)[j], conj( (~w)[j+1UL] ) ) ) {
363  for( size_t i=0UL; i<N; ++i )
364  {
365  const size_t j1( SO1 ? j : j+1UL );
366  const size_t j2( SO1 ? j+1UL : j );
367 
368  const BT vl1( vl[i+j*N] );
369  const BT vl2( vl[i+(j+1UL)*N] );
370 
371  ( SO2 ? (~VL)(i,j1) : (~VL)(j1,i) ) = CT( vl1, ( SO2 ? vl2 : -vl2 ) );
372  ( SO2 ? (~VL)(i,j2) : (~VL)(j2,i) ) = CT( vl1, ( SO2 ? -vl2 : vl2 ) );
373  }
374 
375  ++j;
376  }
377  else {
378  for( size_t i=0UL; i<N; ++i ) {
379  ( SO2 ? (~VL)(i,j) : (~VL)(j,i) ) = CT( vl[i+j*N] );
380  }
381  }
382  }
383 }
385 //*************************************************************************************************
386 
387 
388 //*************************************************************************************************
406 template< typename MT1 // Type of the matrix A
407  , bool SO1 // Storage order of the matrix A
408  , typename MT2 // Type of the matrix VL
409  , bool SO2 // Storage order of the matrix VL
410  , typename VT // Type of the vector w
411  , bool TF > // Transpose flag of the vector w
412 inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL, DenseVector<VT,TF>& w )
413  -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
414 {
415  BLAZE_INTERNAL_ASSERT( isSquare( ~A ) , "Invalid non-square matrix detected" );
416  BLAZE_INTERNAL_ASSERT( isSquare( ~VL ), "Invalid non-square matrix detected" );
417  BLAZE_INTERNAL_ASSERT( (~VL).rows() == (~A).rows(), "Invalid matrix dimension detected" );
418  BLAZE_INTERNAL_ASSERT( (~w).size() == (~A).rows(), "Invalid vector dimension detected" );
419 
420  using CT = ElementType_t<MT1>;
421  using BT = UnderlyingElement_t<CT>;
422 
425 
426  int n ( numeric_cast<int>( (~A).rows() ) );
427  int lda ( numeric_cast<int>( (~A).spacing() ) );
428  int ldvl( numeric_cast<int>( (~VL).spacing() ) );
429  int info( 0 );
430 
431  int lwork( 2*n + 2 );
432  const std::unique_ptr<CT[]> work ( new CT[lwork] );
433  const std::unique_ptr<BT[]> rwork( new BT[2*n] );
434 
435  geev( ( SO1 ? 'V' : 'N' ), ( SO1 ? 'N' : 'V' ), n, (~A).data(), lda, (~w).data(),
436  ( SO1 ? (~VL).data() : nullptr ), ( SO1 ? ldvl : 1 ),
437  ( SO1 ? nullptr : (~VL).data() ), ( SO1 ? 1 : ldvl ),
438  work.get(), lwork, rwork.get(), &info );
439 
440  BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
441 
442  if( info > 0 ) {
443  BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
444  }
445 }
447 //*************************************************************************************************
448 
449 
450 //*************************************************************************************************
519 template< typename MT1 // Type of the matrix A
520  , bool SO1 // Storage order of the matrix A
521  , typename MT2 // Type of the matrix VL
522  , bool SO2 // Storage order of the matrix VL
523  , typename VT // Type of the vector w
524  , bool TF > // Transpose flag of the vector w
526 {
532 
539 
545 
546  const size_t N( (~A).rows() );
547 
548  if( !isSquare( ~A ) ) {
549  BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
550  }
551 
552  resize( ~w, N, false );
553  resize( ~VL, N, N, false );
554 
555  if( N == 0UL ) {
556  return;
557  }
558 
559  geev_backend( ~A, ~VL, ~w );
560 }
561 //*************************************************************************************************
562 
563 
564 //*************************************************************************************************
582 template< typename MT1 // Type of the matrix A
583  , bool SO1 // Storage order of the matrix A
584  , typename VT // Type of the vector w
585  , bool TF // Transpose flag of the vector w
586  , typename MT2 // Type of the matrix VR
587  , bool SO2 > // Storage order of the matrix VR
588 inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& VR )
589  -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
590 {
591  BLAZE_INTERNAL_ASSERT( isSquare( ~A ) , "Invalid non-square matrix detected" );
592  BLAZE_INTERNAL_ASSERT( isSquare( ~VR ), "Invalid non-square matrix detected" );
593  BLAZE_INTERNAL_ASSERT( (~VR).rows() == (~A).rows(), "Invalid matrix dimension detected" );
594  BLAZE_INTERNAL_ASSERT( (~w).size() == (~A).rows(), "Invalid vector dimension detected" );
595 
596  using CT = ElementType_t<VT>;
597  using BT = ElementType_t<MT1>;
598 
601 
602  int n ( numeric_cast<int>( (~A).rows() ) );
603  int lda ( numeric_cast<int>( (~A).spacing() ) );
604  int info( 0 );
605 
606  int lwork( 4*n + 2 );
607  const std::unique_ptr<BT[]> vr ( new BT[n*n] );
608  const std::unique_ptr<BT[]> wr ( new BT[n] );
609  const std::unique_ptr<BT[]> wi ( new BT[n] );
610  const std::unique_ptr<BT[]> work( new BT[lwork] );
611 
612  geev( ( SO1 ? 'N' : 'V' ), ( SO1 ? 'V' : 'N' ), n, (~A).data(), lda, wr.get(), wi.get(),
613  ( SO1 ? nullptr : vr.get() ), ( SO1 ? 1 : n ),
614  ( SO1 ? vr.get() : nullptr ), ( SO1 ? n : 1 ),
615  work.get(), lwork, &info );
616 
617  BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
618 
619  if( info > 0 ) {
620  BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
621  }
622 
623  const size_t N( (~A).rows() );
624 
625  for( size_t j=0UL; j<N; ++j ) {
626  (~w)[j] = CT( wr[j], wi[j] );
627  }
628 
629  for( size_t j=0UL; j<N; ++j ) {
630  if( j+1UL < N && equal( (~w)[j], conj( (~w)[j+1UL] ) ) ) {
631  for( size_t i=0UL; i<N; ++i )
632  {
633  const size_t j1( SO1 ? j : j+1UL );
634  const size_t j2( SO1 ? j+1UL : j );
635 
636  const BT vr1( vr[i+j*N] );
637  const BT vr2( vr[i+(j+1UL)*N] );
638 
639  ( SO2 ? (~VR)(i,j1) : (~VR)(j1,i) ) = CT( vr1, ( SO2 ? vr2 : -vr2 ) );
640  ( SO2 ? (~VR)(i,j2) : (~VR)(j2,i) ) = CT( vr1, ( SO2 ? -vr2 : vr2 ) );
641  }
642 
643  ++j;
644  }
645  else {
646  for( size_t i=0UL; i<N; ++i ) {
647  ( SO2 ? (~VR)(i,j) : (~VR)(j,i) ) = CT( vr[i+j*N] );
648  }
649  }
650  }
651 }
653 //*************************************************************************************************
654 
655 
656 //*************************************************************************************************
674 template< typename MT1 // Type of the matrix A
675  , bool SO1 // Storage order of the matrix A
676  , typename VT // Type of the vector w
677  , bool TF // Transpose flag of the vector w
678  , typename MT2 // Type of the matrix VR
679  , bool SO2 > // Storage order of the matrix VR
680 inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseVector<VT,TF>& w, DenseMatrix<MT2,SO2>& VR )
681  -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
682 {
683  BLAZE_INTERNAL_ASSERT( isSquare( ~A ) , "Invalid non-square matrix detected" );
684  BLAZE_INTERNAL_ASSERT( isSquare( ~VR ), "Invalid non-square matrix detected" );
685  BLAZE_INTERNAL_ASSERT( (~VR).rows() == (~A).rows(), "Invalid matrix dimension detected" );
686  BLAZE_INTERNAL_ASSERT( (~w).size() == (~A).rows(), "Invalid vector dimension detected" );
687 
688  using CT = ElementType_t<MT1>;
689  using BT = UnderlyingElement_t<CT>;
690 
693 
694  int n ( numeric_cast<int>( (~A).rows() ) );
695  int lda ( numeric_cast<int>( (~A).spacing() ) );
696  int ldvr( numeric_cast<int>( (~VR).spacing() ) );
697  int info( 0 );
698 
699  int lwork( 2*n + 2 );
700  const std::unique_ptr<CT[]> work ( new CT[lwork] );
701  const std::unique_ptr<BT[]> rwork( new BT[2*n] );
702 
703  geev( ( SO1 ? 'N' : 'V' ), ( SO1 ? 'V' : 'N' ), n, (~A).data(), lda, (~w).data(),
704  ( SO1 ? nullptr : (~VR).data() ), ( SO1 ? 1 : ldvr ),
705  ( SO1 ? (~VR).data() : nullptr ), ( SO1 ? ldvr : 1 ),
706  work.get(), lwork, rwork.get(), &info );
707 
708  BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
709 
710  if( info > 0 ) {
711  BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
712  }
713 }
715 //*************************************************************************************************
716 
717 
718 //*************************************************************************************************
787 template< typename MT1 // Type of the matrix A
788  , bool SO1 // Storage order of the matrix A
789  , typename VT // Type of the vector w
790  , bool TF // Transpose flag of the vector w
791  , typename MT2 // Type of the matrix VR
792  , bool SO2 > // Storage order of the matrix VR
794 {
799 
804 
810 
811  const size_t N( (~A).rows() );
812 
813  if( !isSquare( ~A ) ) {
814  BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
815  }
816 
817  resize( ~w, N, false );
818  resize( ~VR, N, N, false );
819 
820  if( N == 0UL ) {
821  return;
822  }
823 
824  geev_backend( ~A, ~w, ~VR );
825 }
826 //*************************************************************************************************
827 
828 
829 //*************************************************************************************************
848 template< typename MT1 // Type of the matrix A
849  , bool SO1 // Storage order of the matrix A
850  , typename MT2 // Type of the matrix VL
851  , bool SO2 // Storage order of the matrix VL
852  , typename VT // Type of the vector w
853  , bool TF // Transpose flag of the vector w
854  , typename MT3 // Type of the matrix VR
855  , bool SO3 > // Storage order of the matrix VR
856 inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL,
857  DenseVector<VT,TF>& w, DenseMatrix<MT3,SO3>& VR )
858  -> DisableIf_t< IsComplex_v< ElementType_t<MT1> > >
859 {
860  BLAZE_INTERNAL_ASSERT( isSquare( ~A ) , "Invalid non-square matrix detected" );
861  BLAZE_INTERNAL_ASSERT( isSquare( ~VL ), "Invalid non-square matrix detected" );
862  BLAZE_INTERNAL_ASSERT( isSquare( ~VR ), "Invalid non-square matrix detected" );
863  BLAZE_INTERNAL_ASSERT( (~VL).rows() == (~A).rows(), "Invalid matrix dimension detected" );
864  BLAZE_INTERNAL_ASSERT( (~VR).rows() == (~A).rows(), "Invalid matrix dimension detected" );
865  BLAZE_INTERNAL_ASSERT( (~w).size() == (~A).rows(), "Invalid vector dimension detected" );
866 
867  using CT = ElementType_t<VT>;
868  using BT = ElementType_t<MT1>;
869 
872 
873  int n ( numeric_cast<int>( (~A).rows() ) );
874  int lda ( numeric_cast<int>( (~A).spacing() ) );
875  int info( 0 );
876 
877  int lwork( 4*n + 2 );
878  const std::unique_ptr<BT[]> vl ( new BT[n*n] );
879  const std::unique_ptr<BT[]> vr ( new BT[n*n] );
880  const std::unique_ptr<BT[]> wr ( new BT[n] );
881  const std::unique_ptr<BT[]> wi ( new BT[n] );
882  const std::unique_ptr<BT[]> work( new BT[lwork] );
883 
884  geev( 'V', 'V', n, (~A).data(), lda, wr.get(), wi.get(),
885  ( SO1 ? vl.get() : vr.get() ), n, ( SO1 ? vr.get() : vl.get() ), n,
886  work.get(), lwork, &info );
887 
888  BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
889 
890  if( info > 0 ) {
891  BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
892  }
893 
894  const size_t N( (~A).rows() );
895 
896  for( size_t j=0UL; j<N; ++j ) {
897  (~w)[j] = CT( wr[j], wi[j] );
898  }
899 
900  for( size_t j=0UL; j<N; ++j ) {
901  if( j+1UL < N && equal( (~w)[j], conj( (~w)[j+1UL] ) ) ) {
902  for( size_t i=0UL; i<N; ++i )
903  {
904  const size_t j1( SO1 ? j : j+1UL );
905  const size_t j2( SO1 ? j+1UL : j );
906 
907  const BT vl1( vl[i+j*N] );
908  const BT vl2( vl[i+(j+1UL)*N] );
909  const BT vr1( vr[i+j*N] );
910  const BT vr2( vr[i+(j+1UL)*N] );
911 
912  ( SO2 ? (~VL)(i,j1) : (~VL)(j1,i) ) = CT( vl1, ( SO2 ? vl2 : -vl2 ) );
913  ( SO2 ? (~VL)(i,j2) : (~VL)(j2,i) ) = CT( vl1, ( SO2 ? -vl2 : vl2 ) );
914  ( SO3 ? (~VR)(i,j1) : (~VR)(j1,i) ) = CT( vr1, ( SO3 ? vr2 : -vr2 ) );
915  ( SO3 ? (~VR)(i,j2) : (~VR)(j2,i) ) = CT( vr1, ( SO3 ? -vr2 : vr2 ) );
916  }
917 
918  ++j;
919  }
920  else {
921  for( size_t i=0UL; i<N; ++i ) {
922  ( SO2 ? (~VL)(i,j) : (~VL)(j,i) ) = CT( vl[i+j*N] );
923  ( SO3 ? (~VR)(i,j) : (~VR)(j,i) ) = CT( vr[i+j*N] );
924  }
925  }
926  }
927 }
929 //*************************************************************************************************
930 
931 
932 //*************************************************************************************************
951 template< typename MT1 // Type of the matrix A
952  , bool SO1 // Storage order of the matrix A
953  , typename MT2 // Type of the matrix VL
954  , bool SO2 // Storage order of the matrix VL
955  , typename VT // Type of the vector w
956  , bool TF // Transpose flag of the vector w
957  , typename MT3 // Type of the matrix VR
958  , bool SO3 > // Storage order of the matrix VR
959 inline auto geev_backend( DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& VL,
960  DenseVector<VT,TF>& w, DenseMatrix<MT3,SO3>& VR )
961  -> EnableIf_t< IsComplex_v< ElementType_t<MT1> > >
962 {
963  BLAZE_INTERNAL_ASSERT( isSquare( ~A ) , "Invalid non-square matrix detected" );
964  BLAZE_INTERNAL_ASSERT( isSquare( ~VL ), "Invalid non-square matrix detected" );
965  BLAZE_INTERNAL_ASSERT( isSquare( ~VR ), "Invalid non-square matrix detected" );
966  BLAZE_INTERNAL_ASSERT( (~VL).rows() == (~A).rows(), "Invalid matrix dimension detected" );
967  BLAZE_INTERNAL_ASSERT( (~VR).rows() == (~A).rows(), "Invalid matrix dimension detected" );
968  BLAZE_INTERNAL_ASSERT( (~w).size() == (~A).rows(), "Invalid vector dimension detected" );
969 
970  using CT = ElementType_t<MT1>;
971  using BT = UnderlyingElement_t<CT>;
972 
975 
976  int n ( numeric_cast<int>( (~A).rows() ) );
977  int lda ( numeric_cast<int>( (~A).spacing() ) );
978  int ldvl( numeric_cast<int>( (~VL).spacing() ) );
979  int ldvr( numeric_cast<int>( (~VR).spacing() ) );
980  int info( 0 );
981 
982  int lwork( 2*n + 2 );
983  const std::unique_ptr<CT[]> work ( new CT[lwork] );
984  const std::unique_ptr<BT[]> rwork( new BT[2*n] );
985 
986  geev( 'V', 'V', n, (~A).data(), lda, (~w).data(),
987  ( SO1 ? (~VL).data() : (~VR).data() ), ( SO1 ? ldvl : ldvr ),
988  ( SO1 ? (~VR).data() : (~VL).data() ), ( SO1 ? ldvr : ldvl ),
989  work.get(), lwork, rwork.get(), &info );
990 
991  BLAZE_INTERNAL_ASSERT( info >= 0, "Invalid argument for eigenvalue computation" );
992 
993  if( info > 0 ) {
994  BLAZE_THROW_LAPACK_ERROR( "Eigenvalue computation failed" );
995  }
996 }
998 //*************************************************************************************************
999 
1000 
1001 //*************************************************************************************************
1079 template< typename MT1 // Type of the matrix A
1080  , bool SO1 // Storage order of the matrix A
1081  , typename MT2 // Type of the matrix VL
1082  , bool SO2 // Storage order of the matrix VL
1083  , typename VT // Type of the vector w
1084  , bool TF // Transpose flag of the vector w
1085  , typename MT3 // Type of the matrix VR
1086  , bool SO3 > // Storage order of the matrix VR
1089 {
1094 
1100 
1105 
1111 
1112  const size_t N( (~A).rows() );
1113 
1114  if( !isSquare( ~A ) ) {
1115  BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
1116  }
1117 
1118  resize( ~w, N, false );
1119  resize( ~VL, N, N, false );
1120  resize( ~VR, N, N, false );
1121 
1122  if( N == 0UL ) {
1123  return;
1124  }
1125 
1126  geev_backend( ~A, ~VL, ~w, ~VR );
1127 }
1128 //*************************************************************************************************
1129 
1130 } // namespace blaze
1131 
1132 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
#define BLAZE_CONSTRAINT_MUST_HAVE_MUTABLE_DATA_ACCESS(T)
Constraint on the data type.In case the given data type T does not provide low-level data access to m...
Definition: MutableDataAccess.h:61
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:170
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i....
Definition: Computation.h:81
Constraint on the data type.
Header file for the DenseVector base class.
Header file for the UnderlyingElement type trait.
Constraint on the data type.
Constraint on the data type.
Cast operators for numeric types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ADAPTOR_TYPE(T)
Constraint on the data type.In case the given data type T is an adaptor type (as for instance LowerMa...
Definition: Adaptor.h:81
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:253
Constraint on the data type.
Header file for the DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_CONSTRAINT_MUST_BE_CONTIGUOUS_TYPE(T)
Constraint on the data type.In case the given data type T is not an array-like data type with contigu...
Definition: Contiguous.h:61
void geev(char jobvl, char jobvr, int n, float *A, int lda, float *wr, float *wi, float *VL, int ldvl, float *VR, int ldvr, float *work, int lwork, int *info)
LAPACK kernel for computing the eigenvalues of the given dense general single precision column-major ...
Definition: geev.h:172
Header file for the DenseMatrix base class.
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
Header file for the equal shim.
Header file for the exception macros of the math module.
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:738
Constraint on the data type.
Header file for the EnableIf class template.
Header file for run time assertion macros.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
#define BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a BLAS compatible data type (i....
Definition: BLASCompatible.h:61
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
#define BLAZE_CONSTRAINT_MUST_BE_BUILTIN_TYPE(T)
Constraint on the data type.In case the given data type T is not a built-in data type,...
Definition: Builtin.h:60
#define BLAZE_CONSTRAINT_MUST_BE_COMPLEX_TYPE(T)
Constraint on the data type.This compile time constraint checks that the given data type T is a compl...
Definition: Complex.h:62
#define BLAZE_THROW_LAPACK_ERROR(MESSAGE)
Macro for the emission of an exception on detection of a LAPACK error.This macro encapsulates the def...
Definition: Exception.h:146
Header file for the IsComplex type trait.
Header file for the complex data type.
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1324
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:951
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
bool equal(const SharedValue< T1 > &lhs, const SharedValue< T2 > &rhs)
Equality check for a two shared values.
Definition: SharedValue.h:342
Constraint on the data type.
Header file for the CLAPACK geev wrapper functions.