Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011 #include "vnl_generalized_eigensystem.h"
00012
00013 #include <vcl_iostream.h>
00014 #ifdef VCL_SGI_CC_730
00015 # include <vcl_cmath.h>
00016 #endif
00017
00018 #include <vnl/vnl_fortran_copy.h>
00019 #include <vnl/vnl_matlab_print.h>
00020 #include <vnl/algo/vnl_symmetric_eigensystem.h>
00021 #include <vnl/algo/vnl_svd.h>
00022 #include <vnl/algo/vnl_netlib.h>
00023
00024 vnl_generalized_eigensystem::vnl_generalized_eigensystem(const vnl_matrix<double>& A,
00025 const vnl_matrix<double>& B)
00026 :
00027 n(A.rows()), V(n,n), D(n)
00028 {
00029
00030 vnl_fortran_copy<double> a(A);
00031 vnl_fortran_copy<double> b(B);
00032
00033
00034 vnl_vector<double> work1(n);
00035 vnl_vector<double> work2(n);
00036 vnl_vector<double> V1(n*n);
00037
00038 long want_eigenvectors = 1;
00039 long ierr = -1;
00040
00041
00042 v3p_netlib_rsg_ (&n, &n, a, b, D.data_block(),
00043 &want_eigenvectors,
00044 V1.begin(),
00045 work1.begin(),
00046 work2.begin(), &ierr);
00047
00048
00049 if (ierr == 7*n+1) {
00050 const double THRESH = 1e-8;
00051 vnl_symmetric_eigensystem<double> eig(B);
00052 if (eig.D(0,0) < -THRESH) {
00053 vcl_cerr << "**** vnl_generalized_eigensystem: ERROR\n"
00054 << "Matrix B is not nonneg-definite\n";
00055 vnl_matlab_print(vcl_cerr, B, "B");
00056 vcl_cerr << "**** eigenvalues(B) = " << eig.D << vcl_endl;
00057 return;
00058 }
00059
00060 return;
00061 #if 0 // so don't compile it then...
00062 int rank_deficiency = 0;
00063 while (eig.D(rank_deficiency,rank_deficiency) < THRESH)
00064 ++rank_deficiency;
00065 int rank = B.columns() - rank_deficiency;
00066
00067 vcl_cerr << "vnl_generalized_eigensystem: B rank def by " << rank_deficiency << vcl_endl;
00068
00069 vnl_matrix<double> M = eig.V.get_n_columns(rank_deficiency, rank);
00070 vnl_matrix<double> N = eig.V.get_n_columns(0, rank_deficiency);
00071
00072 vnl_svd<double> svd(vnl_transpose(M)*A*N);
00073
00074 vnl_generalized_eigensystem reduced(vnl_transpose(M) * A * M,
00075 vnl_transpose(M) * B * M);
00076
00077 vcl_cerr << "AN: " << reduced.D << vcl_endl;
00078
00079 vnl_matrix<double> V05 = M * vnl_transpose(reduced.V);
00080 vnl_svd<double> sv6(V05.transpose());
00081 V.update(V05, 0, 0);
00082 V.update(sv6.nullspace(), 0, rank - 1);
00083 for (int i = 0; i < rank; ++i)
00084 D(i,i) = reduced.D(i,i);
00085 for (unsigned i = rank; i < B.columns(); ++i)
00086 D(i,i) = 0;
00087 vcl_cerr << "AN: " << D << vcl_endl;
00088
00089 return;
00090 #endif
00091 }
00092
00093
00094 {
00095 double *vptr = &V1[0];
00096 for (int c = 0; c < n; ++c)
00097 for (int r = 0; r < n; ++r)
00098 V(r,c) = *vptr++;
00099 }
00100
00101
00102 if (ierr) {
00103 if (ierr == 10*n)
00104 vcl_cerr << "vnl_generalized_eigensystem: N is greater than NM. Bug in interface to rsg.f\n";
00105 else {
00106 vcl_cerr << "vnl_generalized_eigensystem: The "
00107 << ierr << "-th eigenvalue has not been determined after 30 iterations.\n"
00108 << "The eigenvalues should be correct for indices 1.." << ierr-1
00109 << ", but no eigenvectors are computed.\n"
00110 << "A = " << A
00111 << "\nsingular values(A) = " << vnl_svd<double>(A).W() << '\n'
00112 << "B = " << B
00113 << "\nsingular values(B) = " << vnl_svd<double>(B).W() << '\n';
00114 }
00115 }
00116 }