00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef TOON_INCLUDE_CHOLESKY_H
00032 #define TOON_INCLUDE_CHOLESKY_H
00033
00034 #include <TooN/TooN.h>
00035
00036 namespace TooN {
00037
00038
00067 template <int Size, tyepname Precision>
00068 class Lapack_Cholesky {
00069 public:
00070
00071 Lapack_Cholesky(){}
00072
00073 template<class P2, class B2>
00074 Lapack_Cholesky(const Matrix<Size, Size, P2, B2>& m) {
00075 : my_cholesky(m) {
00076 SizeMismatch<Size,Size>::test(m.num_rows(), m.num_cols());
00077 do_compute();
00078 }
00079
00081 Lapack_Cholesky(int size) : my_cholesky(size,size) {}
00082
00083 template<class P2, class B2> void compute(const Matrix<Size, Size, P2, B2>& m){
00084 SizeMismatch<Size,Size>::test(m.num_rows(), m.num_cols());
00085 SizeMismatch<Size,Size>::test(m.num_rows(), my_cholesky.num_rows());
00086 my_cholesky=m;
00087 do_compute();
00088 }
00089
00090
00091
00092 void do_compute(){
00093 int N = my_cholesky.num_rows();
00094 int info;
00095 dpotrf_("L", &N, L.get_data_ptr(), &N, &info);
00096 assert(info >= 0);
00097 if (info > 0) {
00098 my_rank = info-1;
00099 }
00100 }
00101
00102 int rank() const { return my_rank; }
00103
00104 template <int Size2, typename P2, typename B2>
00105 Vector<Size, Precision> backsub (const Vector<Size2, P2, B2>& v) {
00106 SizeMismatch<Size,Size2>::test(my_cholesky.num_cols(), v.size());
00107
00108 Vector<Size> result(v);
00109 int N=L.num_rows();
00110 int NRHS=1;
00111 int info;
00112 dpotrs_("L", &N, &NRHS, my_cholesky.my_data, &N, result.my_data, &N, &info);
00113 assert(info==0);
00114 return result;
00115 }
00116
00117 template <int Size2, int Cols2, typename P2, typename B2>
00118 Matrix<Size, Cols2, Precision, ColMajor> backsub (const Matrix<Size2, Cols2, P2, B2>& m) {
00119 SizeMismatch<Size,Size2>::test(my_cholesky.num_cols(), m.num_rows());
00120
00121 Matrix<Size, Cols2, Precision, ColMajor> result(m);
00122 int N=my_cholesky.num_rows();
00123 int NRHS=m.num_cols();
00124 int info;
00125 dpotrs_("L", &N, &NRHS, my_cholesky.my_data, &N, result.my_data, &N, &info);
00126 assert(info==0);
00127 return result;
00128 }
00129
00130
00131
00132
00133
00134 template <int Size2, typename P2, typename B2>
00135 Precision mahalanobis(const Vector<Size2, P2, B2>& v) const {
00136 return v * backsub(v);
00137 }
00138
00139 const Matrix<>& get_L() const {
00140 return my_cholesky;
00141 }
00142
00143 Precision determinant() const {
00144 Precision det = L[0][0];
00145 for (int i=1; i<my_cholesky.num_rows(); i++)
00146 det *= L[i][i];
00147 return det*det;
00148 }
00149
00150 Matrix<> get_inverse() const {
00151 Matrix<Size> M(my_cholesky);
00152 int N = my_cholesky.num_rows();
00153 int info;
00154 dpotri_("L", &N, M.my_data, &N, &info);
00155 assert(info == 0);
00156 TooN::Symmetrize(M);
00157 return M;
00158 }
00159
00160 private:
00161 Matrix<Size,Size,Precision> my_cholesky;
00162 int rank;
00163 };
00164
00165
00166 }
00167
00168 #endif