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 namespace cholesky {
00029
00030
00031 #ifdef WITH_BOOST
00032
00040 template< typename T >
00041 class CholeskyBase
00042 {
00043 public:
00045 typedef ublas::symmetric_matrix< T, ublas::lower > CovarMat;
00046
00048
00049 typedef ublas::matrix< T > FactorMat;
00050
00054 CholeskyBase( size_t s1 = 1, size_t s2 = 1 ) :
00055 _L(ublas::zero_matrix<T>(s1,s2))
00056 {}
00057
00061 CholeskyBase(const CovarMat& V) :
00062 _L(ublas::zero_matrix<T>(V.size1(),V.size2()))
00063 {
00064 (*this)( V );
00065 }
00066
00068 virtual void factorize( const CovarMat& V ) = 0;
00069
00071 virtual const FactorMat& operator()( const CovarMat& V )
00072 {
00073 this->factorize( V );
00074 return decomposition();
00075 }
00076
00078 const FactorMat & decomposition() const
00079 {
00080 return _L;
00081 }
00082
00083 protected:
00084
00089 unsigned assert_properties( const CovarMat& V )
00090 {
00091 unsigned int Vl = V.size1();
00092
00093
00094 _L = ublas::zero_matrix<T>(Vl,Vl);
00095
00096 #ifndef NDEBUG
00097 assert(Vl > 0);
00098
00099 unsigned int Vc = V.size2();
00100 assert(Vc > 0);
00101 assert( Vl == Vc );
00102
00103
00104
00105 for( unsigned int i=0; i < Vl; ++i ) {
00106 assert( V(i,i) > 0 );
00107 }
00108
00109
00110
00111
00112
00113
00114 #endif
00115
00116 return Vl;
00117 }
00118
00120 FactorMat _L;
00121 };
00122
00123
00132 template< typename T >
00133 class CholeskyLLT : public CholeskyBase<T>
00134 {
00135 public:
00136 virtual void factorize( const typename CholeskyBase<T>::CovarMat& V )
00137 {
00138 unsigned int N = assert_properties( V );
00139
00140 unsigned int i=0, j=0, k;
00141 this->_L(0, 0) = sqrt( V(0, 0) );
00142
00143
00144 for ( j = 1; j < N; ++j ) {
00145 this->_L(j, 0) = V(0, j) / this->_L(0, 0);
00146 }
00147
00148
00149 for ( i = 1; i < N; ++i ) {
00150
00151 double sum = 0.0;
00152 for ( k = 0; k < i; ++k) {
00153 sum += this->_L(i, k) * this->_L(i, k);
00154 }
00155
00156 this->_L(i,i) = L_i_i( V, i, sum );
00157
00158 for ( j = i + 1; j < N; ++j ) {
00159
00160 sum = 0.0;
00161 for ( k = 0; k < i; ++k ) {
00162 sum += this->_L(j, k) * this->_L(i, k);
00163 }
00164
00165 this->_L(j, i) = (V(j, i) - sum) / this->_L(i, i);
00166
00167 }
00168 }
00169 }
00170
00171
00173 inline virtual T L_i_i( const typename CholeskyBase<T>::CovarMat& V, const unsigned int& i, const double& sum ) const
00174 {
00175
00176 assert( V(i,i) - sum >= 0 );
00177 return sqrt( V(i,i) - sum );
00178 }
00179 };
00180
00181
00190 template< typename T >
00191 class CholeskyLLTabs : public CholeskyLLT<T>
00192 {
00193 public:
00194 inline virtual T L_i_i( const typename CholeskyBase<T>::CovarMat& V, const unsigned int& i, const double& sum ) const
00195 {
00196
00197 return sqrt( fabs( V(i,i) - sum) );
00198 }
00199 };
00200
00201
00209 template< typename T >
00210 class CholeskyLLTzero : public CholeskyLLT<T>
00211 {
00212 public:
00213 inline virtual T L_i_i( const typename CholeskyBase<T>::CovarMat& V, const unsigned int& i, const double& sum ) const
00214 {
00215 T Lii;
00216 if( V(i,i) - sum >= 0 ) {
00217 Lii = sqrt( V(i,i) - sum);
00218 } else {
00219
00220 Lii = 0;
00221 }
00222 return Lii;
00223 }
00224 };
00225
00226
00233 template< typename T >
00234 class CholeskyLDLT : public CholeskyBase<T>
00235 {
00236 public:
00237 virtual void factorize( const typename CholeskyBase<T>::CovarMat& V )
00238 {
00239
00240 int N = assert_properties( V );
00241
00242 assert( V(0,0) != 0 );
00243
00244 typename CholeskyBase<T>::FactorMat L = ublas::zero_matrix<T>(N,N);
00245 typename CholeskyBase<T>::FactorMat D = ublas::zero_matrix<T>(N,N);
00246 D(0,0) = V(0,0);
00247
00248 for( int j=0; j<N; ++j ) {
00249 L(j, j) = 1;
00250
00251 D(j,j) = V(j,j);
00252 for( int k=0; k<=j-1; ++k) {
00253 D(j,j) -= L(j,k) * L(j,k) * D(k,k);
00254 }
00255
00256 for( int i=j+1; i<N; ++i ) {
00257
00258 L(i,j) = V(i,j);
00259 for( int k=0; k<=j-1; ++k) {
00260 L(i,j) -= L(i,k)*L(j,k) * D(k,k);
00261 }
00262 L(i,j) /= D(j,j);
00263
00264 }
00265 }
00266
00267 this->_L = root( L, D );
00268 }
00269
00270
00271 inline typename CholeskyBase<T>::FactorMat root( typename CholeskyBase<T>::FactorMat& L, typename CholeskyBase<T>::FactorMat& D )
00272 {
00273
00274
00275
00276
00277
00278 typename CholeskyBase<T>::FactorMat sqrt_D = D;
00279 for( int i=0; i < D.size1(); ++i) {
00280 sqrt_D(i,i) = sqrt(D(i,i));
00281 }
00282
00283
00284 return ublas::prod( L, sqrt_D );
00285 }
00286 };
00287
00288 #else
00289 #ifdef WITH_EIGEN
00290
00291 #endif // WITH_EIGEN
00292 #endif // WITH_BOOST
00293
00294
00295 }