core/vnl/algo/vnl_complex_generalized_schur.h
Go to the documentation of this file.
00001 // This is core/vnl/algo/vnl_complex_generalized_schur.h
00002 #ifndef vnl_complex_generalized_schur_h_
00003 #define vnl_complex_generalized_schur_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief  Solves the generalized eigenproblem det(t A - s B) = 0.
00010 // \author Peter Vanroose, ABIS Leuven
00011 // \date   9 Jan 2011
00012 // Adapted from vnl_generalized_schur.h/.cxx
00013 
00014 #include <vnl/vnl_matrix.h>
00015 #include <vnl/vnl_vector.h>
00016 
00017 #include <vcl_complex.h>
00018 
00019 //:
00020 // For a scalar type T, this function uses orthogonal matrices L, R
00021 // over complex<T> to reduce the (square) matrices A, B to generalized
00022 // (complex) Schur form. This means that A and B become upper triangular,
00023 // A <-- L^* A R, and B <-- L^* B R.
00024 // Of course, A and B should be of the same size.
00025 //
00026 // In addition, the function computes the (complex) generalized eigenvalues
00027 // alpha(k) : beta(k) for k = 0, 1, 2,...
00028 //
00029 // To pass in scalar type T matrices A and B, you'll have to first convert them
00030 // to complex matrices since they will be overwritten by they (complex) upper
00031 // triangular decomposition.
00032 template <class T>
00033 bool vnl_generalized_schur(vnl_matrix<vcl_complex<T> > *A,
00034                            vnl_matrix<vcl_complex<T> > *B,
00035                            vnl_vector<vcl_complex<T> > *alpha,
00036                            vnl_vector<vcl_complex<T> > *beta,
00037                            vnl_matrix<vcl_complex<T> > *L,
00038                            vnl_matrix<vcl_complex<T> > *R);
00039 
00040 VCL_DEFINE_SPECIALIZATION
00041 bool vnl_generalized_schur(vnl_matrix<vcl_complex<double> > *A,
00042                            vnl_matrix<vcl_complex<double> > *B,
00043                            vnl_vector<vcl_complex<double> > *alpha,
00044                            vnl_vector<vcl_complex<double> > *beta,
00045                            vnl_matrix<vcl_complex<double> > *L,
00046                            vnl_matrix<vcl_complex<double> > *R);
00047 
00048 #include <vcl_algorithm.h>
00049 
00050 template <class T>
00051 vcl_complex<T> vnl_complex_generalized_schur_convert_cast(vcl_complex<double> a) { return static_cast<vcl_complex<T> >(a); }
00052 
00053 template <class T>
00054 inline bool vnl_generalized_schur(vnl_matrix<vcl_complex<T> > *A,
00055                                   vnl_matrix<vcl_complex<T> > *B,
00056                                   vnl_vector<vcl_complex<T> > *alpha,
00057                                   vnl_vector<vcl_complex<T> > *beta,
00058                                   vnl_matrix<vcl_complex<T> > *L,
00059                                   vnl_matrix<vcl_complex<T> > *R)
00060 {
00061   vnl_matrix<vcl_complex<double> > A_(A->rows(), A->cols());
00062   vnl_matrix<vcl_complex<double> > B_(B->rows(), B->cols());
00063   vcl_copy(A->begin(), A->end(), A_.begin());
00064   vcl_copy(B->begin(), B->end(), B_.begin());
00065 
00066   vnl_vector<vcl_complex<double> > alpha_;
00067   vnl_vector<vcl_complex<double> > beta_;
00068   vnl_matrix<vcl_complex<double> > L_;
00069   vnl_matrix<vcl_complex<double> > R_;
00070 
00071   if (! vnl_generalized_schur/*<vcl_complex<double> >*/(&A_, &B_, &alpha_, &beta_, &L_, &R_))
00072     return false;
00073 
00074   vcl_transform(A_.begin(), A_.end(), A->begin(), vnl_complex_generalized_schur_convert_cast<T>);
00075   vcl_transform(B_.begin(), B_.end(), B->begin(), vnl_complex_generalized_schur_convert_cast<T>);
00076 
00077   alpha->set_size(alpha_.size());
00078   vcl_transform(alpha_.begin(), alpha_.end(), alpha->begin(), vnl_complex_generalized_schur_convert_cast<T>);
00079   
00080   beta->set_size(beta_.size());
00081   vcl_transform(beta_.begin(), beta_.end(), beta->begin(), vnl_complex_generalized_schur_convert_cast<T>);
00082   
00083   L->set_size(L_.rows(), L_.cols());
00084   vcl_transform(L_.begin(), L_.end(), L->begin(), vnl_complex_generalized_schur_convert_cast<T>);
00085 
00086   R->set_size(R_.rows(), R_.cols());
00087   vcl_transform(R_.begin(), R_.end(), R->begin(), vnl_complex_generalized_schur_convert_cast<T>);
00088 
00089   return true;
00090 }
00091 
00092 #endif // vnl_complex_generalized_schur_h_