00001 // This is core/vnl/algo/vnl_qr.h 00002 #ifndef vnl_qr_h_ 00003 #define vnl_qr_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief Calculate inverse of a matrix using QR 00010 // \author Andrew W. Fitzgibbon, Oxford RRG 00011 // \date 08 Dec 1996 00012 // 00013 // \verbatim 00014 // Modifications 00015 // 081296 AWF Temporarily abandoned as I realized my problem was symmetric... 00016 // 080697 AWF Recovered, implemented solve(). 00017 // 200897 AWF Added determinant(). 00018 // 071097 AWF Added Q(), R(). 00019 // Christian Stoecklin, ETH Zurich, added QtB(v) 00020 // 31-mar-2000 fsm: templated 00021 // 28/03/2001 - dac (Manchester) - tidied up documentation 00022 // 13 Jan.2003 - Peter Vanroose - added missing implementation for inverse(), 00023 // tinverse(), solve(matrix), extract_q_and_r(). 00024 // \endverbatim 00025 00026 #include <vnl/vnl_vector.h> 00027 #include <vnl/vnl_matrix.h> 00028 #include <vcl_iosfwd.h> 00029 00030 //: Extract the Q*R decomposition of matrix M. 00031 // The decomposition is stored in a compact and time-efficient 00032 // packed form, which is most easily used via the "solve" and 00033 // "determinant" methods. 00034 00035 export template <class T> 00036 class vnl_qr 00037 { 00038 public: 00039 vnl_qr(vnl_matrix<T> const & M); 00040 ~vnl_qr(); 00041 00042 //: return the inverse matrix of M 00043 vnl_matrix<T> inverse () const; 00044 //: return the transpose of the inverse matrix of M 00045 vnl_matrix<T> tinverse () const; 00046 //: return the original matrix M 00047 vnl_matrix<T> recompose () const; 00048 00049 //: Solve equation M x = rhs for x using the computed decomposition. 00050 vnl_matrix<T> solve (const vnl_matrix<T>& rhs) const; 00051 //: Solve equation M x = rhs for x using the computed decomposition. 00052 vnl_vector<T> solve (const vnl_vector<T>& rhs) const; 00053 00054 //: Return the determinant of M. This is computed from M = Q R as follows: 00055 // |M| = |Q| |R|. 00056 // |R| is the product of the diagonal elements. 00057 // |Q| is (-1)^n as it is a product of Householder reflections. 00058 // So det = -prod(-r_ii). 00059 T determinant() const; 00060 //: Unpack and return unitary part Q. 00061 vnl_matrix<T> const& Q() const; 00062 //: Unpack and return R. 00063 vnl_matrix<T> const& R() const; 00064 //: Return residual vector d of M x = b -> d = Q'b 00065 vnl_vector<T> QtB(const vnl_vector<T>& b) const; 00066 00067 void extract_q_and_r(vnl_matrix<T>* q, vnl_matrix<T>* r) const { *q = Q(); *r = R(); } 00068 00069 private: 00070 vnl_matrix<T> qrdc_out_; 00071 vnl_vector<T> qraux_; 00072 vnl_vector<long> jpvt_; 00073 mutable vnl_matrix<T>* Q_; 00074 mutable vnl_matrix<T>* R_; 00075 00076 // Disallow assignment. 00077 vnl_qr(const vnl_qr<T> &) { } 00078 vnl_qr<T>& operator=(const vnl_qr<T> &) { return *this; } 00079 }; 00080 00081 //: Compute determinant of matrix "M" using QR. 00082 template <class T> 00083 inline T vnl_qr_determinant(vnl_matrix<T> const& m) 00084 { 00085 return vnl_qr<T>(m).determinant(); 00086 } 00087 00088 export template <class T> 00089 vcl_ostream& operator<<(vcl_ostream&, vnl_qr<T> const & qr); 00090 00091 #endif // vnl_qr_h_