core/vnl/algo/vnl_generalized_schur.h
Go to the documentation of this file.
00001 // This is core/vnl/algo/vnl_generalized_schur.h
00002 #ifndef vnl_generalized_schur_h_
00003 #define vnl_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 fsm, Oxford RRG
00011 // \date   2 Oct 2001
00012 
00013 #include <vnl/vnl_matrix.h>
00014 #include <vnl/vnl_vector.h>
00015 
00016 //:
00017 // For a \e real scalar type T, this function uses orthogonal
00018 // matrices L, R to reduce the (square) matrices A, B to generalized
00019 // (real) Schur form. This means that B is upper triangular and A is
00020 // block upper triangular with blocks of size at most 2x2 such that
00021 // the 2x2 blocks B corresponding to 2x2 blocks of A are diagonal.
00022 // E.g.:
00023 // \verbatim
00024 //                [ * * * * * ]
00025 //                [   * * * * ]
00026 // A <- L^* A R = [   * * * * ]
00027 //                [       * * ]
00028 //                [       * * ]
00029 //
00030 //                [ * * * * * ]
00031 //                [   *   * * ]
00032 // B <- L^* B R = [     * * * ]
00033 //                [       *   ]
00034 //                [         * ]
00035 // \endverbatim
00036 //
00037 // In addition, the function computes the generalized eigenvalues
00038 // (alphar(k) + i alphai(k) : beta(k) for k = 0, 1, 2,...
00039 template <class T>
00040 bool vnl_generalized_schur(vnl_matrix<T> *A,
00041                            vnl_matrix<T> *B,
00042                            vnl_vector<T> *alphar,
00043                            vnl_vector<T> *alphai,
00044                            vnl_vector<T> *beta,
00045                            vnl_matrix<T> *L,
00046                            vnl_matrix<T> *R);
00047 
00048 VCL_DEFINE_SPECIALIZATION
00049 bool vnl_generalized_schur(vnl_matrix<double> *A,
00050                            vnl_matrix<double> *B,
00051                            vnl_vector<double> *alphar,
00052                            vnl_vector<double> *alphai,
00053                            vnl_vector<double> *beta,
00054                            vnl_matrix<double> *L,
00055                            vnl_matrix<double> *R);
00056 
00057 #include <vcl_algorithm.h>
00058 
00059 template <class T>
00060 T vnl_generalized_schur_convert_cast(double a) { return static_cast<T>(a); }
00061 
00062 template <class T>
00063 inline bool vnl_generalized_schur(vnl_matrix<T> *A,
00064                                   vnl_matrix<T> *B,
00065                                   vnl_vector<T> *alphar,
00066                                   vnl_vector<T> *alphai,
00067                                   vnl_vector<T> *beta,
00068                                   vnl_matrix<T> *L,
00069                                   vnl_matrix<T> *R)
00070 {
00071   vnl_matrix<double> A_(A->rows(), A->cols());
00072   vnl_matrix<double> B_(B->rows(), B->cols());
00073   vcl_copy(A->begin(), A->end(), A_.begin());
00074   vcl_copy(B->begin(), B->end(), B_.begin());
00075 
00076   vnl_vector<double> alphar_;
00077   vnl_vector<double> alphai_;
00078   vnl_vector<double> beta_;
00079   vnl_matrix<double> L_;
00080   vnl_matrix<double> R_;
00081 
00082   if (! vnl_generalized_schur/*<double>*/(&A_, &B_, &alphar_, &alphai_, &beta_, &L_, &R_))
00083     return false;
00084 
00085   vcl_transform(A_.begin(), A_.end(), A->begin(), vnl_generalized_schur_convert_cast<T>);
00086   vcl_transform(B_.begin(), B_.end(), B->begin(), vnl_generalized_schur_convert_cast<T>);
00087 
00088   alphar->set_size(alphar_.size());
00089   vcl_transform(alphar_.begin(), alphar_.end(), alphar->begin(), vnl_generalized_schur_convert_cast<T>);
00090 
00091   alphai->set_size(alphai_.size());
00092   vcl_transform(alphai_.begin(), alphai_.end(), alphai->begin(), vnl_generalized_schur_convert_cast<T>);
00093 
00094   beta  ->set_size(beta_  .size());
00095   vcl_transform(beta_  .begin(), beta_  .end(), beta  ->begin(), vnl_generalized_schur_convert_cast<T>);
00096 
00097   L->set_size(L_.rows(), L_.cols());
00098   vcl_transform(L_.begin(), L_.end(), L->begin(), vnl_generalized_schur_convert_cast<T>);
00099 
00100   R->set_size(R_.rows(), R_.cols());
00101   vcl_transform(R_.begin(), R_.end(), R->begin(), vnl_generalized_schur_convert_cast<T>);
00102 
00103   return true;
00104 }
00105 
00106 #endif // vnl_generalized_schur_h_