core/vnl/algo/vnl_real_eigensystem.cxx
Go to the documentation of this file.
00001 // This is core/vnl/algo/vnl_real_eigensystem.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 //
00008 // \author Andrew W. Fitzgibbon, Oxford RRG
00009 // \date   23 Jan 97
00010 
00011 //-----------------------------------------------------------------------------
00012 
00013 #include "vnl_real_eigensystem.h"
00014 #include <vcl_cassert.h>
00015 #include <vcl_iostream.h>
00016 #include <vnl/vnl_fortran_copy.h>
00017 #include <vnl/algo/vnl_netlib.h> // rg_()
00018 
00019 //: Extract eigensystem of non-symmetric matrix M, using the EISPACK routine rg.
00020 //  Should probably switch to using LAPACK's dgeev to avoid transposing.
00021 vnl_real_eigensystem::vnl_real_eigensystem(vnl_matrix<double> const & M):
00022   Vreal(M.rows(), M.columns()),
00023   V(M.rows(), M.columns()),
00024   D(M.rows())
00025 {
00026   long n = M.rows();
00027   assert(n == (int)(M.columns()));
00028 
00029   vnl_fortran_copy<double> mf(M);
00030 
00031   vnl_vector<double> wr(n);
00032   vnl_vector<double> wi(n);
00033   vnl_vector<long> iv1(n);
00034   vnl_vector<double> fv1(n);
00035   vnl_matrix<double> devout(n, n);
00036 
00037   long ierr = 0;
00038   long matz = 1;
00039   v3p_netlib_rg_(&n, &n, mf,
00040                  wr.data_block(), wi.data_block(),
00041                  &matz, devout.data_block(),
00042                  iv1.data_block(), fv1.data_block(),
00043                  &ierr);
00044 
00045   if (ierr != 0) {
00046     vcl_cerr << " *** vnl_real_eigensystem: Failed on " << ierr << "th eigenvalue\n"
00047              << M << vcl_endl;
00048   }
00049 
00050   // Copy out eigenvalues and eigenvectors
00051   for (int c = 0; c < n; ++c) {
00052     D(c,c) = vcl_complex<double>(wr[c], wi[c]);
00053     if (wi[c] != 0) {
00054       // Complex - copy conjugates and inc c.
00055       D(c+1, c+1) = vcl_complex<double>(wr[c], -wi[c]);
00056       for (int r = 0; r < n; ++r) {
00057         V(r, c) = vcl_complex<double>(devout(c,r), devout(c+1,r));
00058         V(r, c+1) = vcl_complex<double>(devout(c,r), -devout(c+1,r));
00059       }
00060 
00061       ++c;
00062     }
00063     else
00064       for (int r = 0; r < n; ++r) {
00065         V(r, c) = vcl_complex<double>(devout(c,r), 0);
00066         Vreal(r,c) = devout(c,r);
00067       }
00068   }
00069 }