@@ -863,45 +863,49 @@ class EigenvalueDecomposition {
863
863
d = alloc_1d<double > (n);
864
864
e = alloc_1d<double > (n);
865
865
ort = alloc_1d<double > (n);
866
- // Reduce to Hessenberg form.
867
- orthes ();
868
- // Reduce Hessenberg to real Schur form.
869
- hqr2 ();
870
- // Copy eigenvalues to OpenCV Matrix.
871
- _eigenvalues.create (1 , n, CV_64FC1);
872
- for (int i = 0 ; i < n; i++) {
873
- _eigenvalues.at <double > (0 , i) = d[i];
866
+ try {
867
+ // Reduce to Hessenberg form.
868
+ orthes ();
869
+ // Reduce Hessenberg to real Schur form.
870
+ hqr2 ();
871
+ // Copy eigenvalues to OpenCV Matrix.
872
+ _eigenvalues.create (1 , n, CV_64FC1);
873
+ for (int i = 0 ; i < n; i++) {
874
+ _eigenvalues.at <double > (0 , i) = d[i];
875
+ }
876
+ // Copy eigenvectors to OpenCV Matrix.
877
+ _eigenvectors.create (n, n, CV_64FC1);
878
+ for (int i = 0 ; i < n; i++)
879
+ for (int j = 0 ; j < n; j++)
880
+ _eigenvectors.at <double > (i, j) = V[i][j];
881
+ // Deallocate the memory by releasing all internal working data.
882
+ release ();
883
+ }
884
+ catch (...)
885
+ {
886
+ release ();
887
+ throw ;
874
888
}
875
- // Copy eigenvectors to OpenCV Matrix.
876
- _eigenvectors.create (n, n, CV_64FC1);
877
- for (int i = 0 ; i < n; i++)
878
- for (int j = 0 ; j < n; j++)
879
- _eigenvectors.at <double > (i, j) = V[i][j];
880
- // Deallocate the memory by releasing all internal working data.
881
- release ();
882
889
}
883
890
884
891
public:
885
- EigenvalueDecomposition ()
886
- : n(0 ), cdivr(0 ), cdivi(0 ), d(0 ), e(0 ), ort(0 ), V(0 ), H(0 ) {}
887
-
888
892
// Initializes & computes the Eigenvalue Decomposition for a general matrix
889
893
// given in src. This function is a port of the EigenvalueSolver in JAMA,
890
894
// which has been released to public domain by The MathWorks and the
891
895
// National Institute of Standards and Technology (NIST).
892
- EigenvalueDecomposition (InputArray src) {
893
- compute (src);
896
+ EigenvalueDecomposition (InputArray src, bool fallbackSymmetric = true ) {
897
+ compute (src, fallbackSymmetric );
894
898
}
895
899
896
900
// This function computes the Eigenvalue Decomposition for a general matrix
897
901
// given in src. This function is a port of the EigenvalueSolver in JAMA,
898
902
// which has been released to public domain by The MathWorks and the
899
903
// National Institute of Standards and Technology (NIST).
900
- void compute (InputArray src)
904
+ void compute (InputArray src, bool fallbackSymmetric )
901
905
{
902
906
CV_INSTRUMENT_REGION ()
903
907
904
- if (isSymmetric (src)) {
908
+ if (fallbackSymmetric && isSymmetric (src)) {
905
909
// Fall back to OpenCV for a symmetric matrix!
906
910
cv::eigen (src, _eigenvalues, _eigenvectors);
907
911
} else {
@@ -930,11 +934,60 @@ class EigenvalueDecomposition {
930
934
~EigenvalueDecomposition () {}
931
935
932
936
// Returns the eigenvalues of the Eigenvalue Decomposition.
933
- Mat eigenvalues () { return _eigenvalues; }
937
+ Mat eigenvalues () const { return _eigenvalues; }
934
938
// Returns the eigenvectors of the Eigenvalue Decomposition.
935
- Mat eigenvectors () { return _eigenvectors; }
939
+ Mat eigenvectors () const { return _eigenvectors; }
936
940
};
937
941
942
+ void eigenNonSymmetric (InputArray _src, OutputArray _evals, OutputArray _evects)
943
+ {
944
+ CV_INSTRUMENT_REGION ()
945
+
946
+ Mat src = _src.getMat ();
947
+ int type = src.type ();
948
+ size_t n = (size_t )src.rows ;
949
+
950
+ CV_Assert (src.rows == src.cols );
951
+ CV_Assert (type == CV_32F || type == CV_64F);
952
+
953
+ Mat src64f;
954
+ if (type == CV_32F)
955
+ src.convertTo (src64f, CV_32FC1);
956
+ else
957
+ src64f = src;
958
+
959
+ EigenvalueDecomposition eigensystem (src64f, false );
960
+
961
+ // EigenvalueDecomposition returns transposed and non-sorted eigenvalues
962
+ std::vector<double > eigenvalues64f;
963
+ eigensystem.eigenvalues ().copyTo (eigenvalues64f);
964
+ CV_Assert (eigenvalues64f.size () == n);
965
+
966
+ std::vector<int > sort_indexes (n);
967
+ cv::sortIdx (eigenvalues64f, sort_indexes, SORT_EVERY_ROW | SORT_DESCENDING);
968
+
969
+ std::vector<double > sorted_eigenvalues64f (n);
970
+ for (size_t i = 0 ; i < n; i++) sorted_eigenvalues64f[i] = eigenvalues64f[sort_indexes[i]];
971
+
972
+ Mat (sorted_eigenvalues64f).convertTo (_evals, type);
973
+
974
+ if ( _evects.needed () )
975
+ {
976
+ Mat eigenvectors64f = eigensystem.eigenvectors ().t (); // transpose
977
+ CV_Assert ((size_t )eigenvectors64f.rows == n);
978
+ CV_Assert ((size_t )eigenvectors64f.cols == n);
979
+ Mat_<double > sorted_eigenvectors64f ((int )n, (int )n, CV_64FC1);
980
+ for (size_t i = 0 ; i < n; i++)
981
+ {
982
+ double * pDst = sorted_eigenvectors64f.ptr <double >((int )i);
983
+ double * pSrc = eigenvectors64f.ptr <double >(sort_indexes[(int )i]);
984
+ CV_Assert (pSrc != NULL );
985
+ memcpy (pDst, pSrc, n * sizeof (double ));
986
+ }
987
+ sorted_eigenvectors64f.convertTo (_evects, type);
988
+ }
989
+ }
990
+
938
991
939
992
// ------------------------------------------------------------------------------
940
993
// Linear Discriminant Analysis implementation
0 commit comments