core/vnl/algo/vnl_qr.h
Go to the documentation of this file.
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_