00001 // This is core/vnl/algo/vnl_cholesky.h 00002 #ifndef vnl_cholesky_h_ 00003 #define vnl_cholesky_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief Decomposition of symmetric matrix 00010 // \author Andrew W. Fitzgibbon, Oxford RRG 00011 // \date 08 Dec 96 00012 // 00013 // \verbatim 00014 // Modifications 00015 // Peter Vanroose, Leuven, Apr 1998: added L() (return decomposition matrix) 00016 // dac (Manchester) 26/03/2001: tidied up documentation 00017 // Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line 00018 // \endverbatim 00019 00020 #include <vnl/vnl_vector.h> 00021 #include <vnl/vnl_matrix.h> 00022 00023 //: Decomposition of symmetric matrix. 00024 // A class to hold the Cholesky decomposition of a symmetric matrix and 00025 // use that to solve linear systems, compute determinants and inverses. 00026 // The cholesky decomposition decomposes symmetric A = L*L.transpose() 00027 // where L is lower triangular 00028 // 00029 // To check that the decomposition can be used safely for solving a linear 00030 // equation it is wise to construct with mode==estimate_condition and 00031 // check that rcond()>sqrt(machine precision). If this is not the case 00032 // it might be a good idea to use vnl_svd instead. 00033 class vnl_cholesky 00034 { 00035 public: 00036 //: Modes of computation. See constructor for details. 00037 enum Operation { 00038 quiet, 00039 verbose, 00040 estimate_condition 00041 }; 00042 00043 //: Make cholesky decomposition of M optionally computing the reciprocal condition number. 00044 vnl_cholesky(vnl_matrix<double> const& M, Operation mode = verbose); 00045 ~vnl_cholesky() {} 00046 00047 //: Solve LS problem M x = b 00048 vnl_vector<double> solve(vnl_vector<double> const& b) const; 00049 00050 //: Solve LS problem M x = b 00051 void solve(vnl_vector<double> const& b, vnl_vector<double>* x) const; 00052 00053 //: Compute determinant 00054 double determinant() const; 00055 00056 // Compute inverse. Not efficient. 00057 // It's broken, I don't have time to fix it. 00058 // Mail awf@robots if you need it and I'll tell you as much as I can 00059 // to fix it. 00060 vnl_matrix<double> inverse() const; 00061 00062 //: Return lower-triangular factor. 00063 vnl_matrix<double> lower_triangle() const; 00064 00065 //: Return upper-triangular factor. 00066 vnl_matrix<double> upper_triangle() const; 00067 00068 //: Return the decomposition matrix 00069 vnl_matrix<double> const& L_badly_named_method() const { return A_; } 00070 00071 //: A Success/failure flag 00072 int rank_deficiency() const { return num_dims_rank_def_; } 00073 00074 //: Return reciprocal condition number (smallest/largest singular values). 00075 // As long as rcond()>sqrt(precision) the decomposition can be used for 00076 // solving equations safely. 00077 // Not calculated unless Operation mode at construction was estimate_condition. 00078 double rcond() const { return rcond_; } 00079 00080 //: Return computed nullvector. 00081 // Not calculated unless Operation mode at construction was estimate_condition. 00082 vnl_vector<double> & nullvector() { return nullvector_; } 00083 vnl_vector<double> const& nullvector() const { return nullvector_; } 00084 00085 protected: 00086 // Data Members-------------------------------------------------------------- 00087 vnl_matrix<double> A_; 00088 double rcond_; 00089 long num_dims_rank_def_; 00090 vnl_vector<double> nullvector_; 00091 00092 private: 00093 //: Copy constructor - privatised to avoid it being used 00094 vnl_cholesky(vnl_cholesky const & that); 00095 //: Assignment operator - privatised to avoid it being used 00096 vnl_cholesky& operator=(vnl_cholesky const & that); 00097 }; 00098 00099 #endif // vnl_cholesky_h_