cholesky.hpp
Go to the documentation of this file.
00001 
00002 /*
00003  -   begin                : 2005-08-24
00004  -   copyright            : (C) 2005 by Gunter Winkler, Konstantin Kutzkow
00005  -   email                : guwi17@gmx.de
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2.1 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #ifndef _H_CHOLESKY_HPP_
00024 #define _H_CHOLESKY_HPP_
00025 
00026 
00027 #include <cassert>
00028 
00029 #include <boost/numeric/ublas/vector.hpp>
00030 #include <boost/numeric/ublas/vector_proxy.hpp>
00031 
00032 #include <boost/numeric/ublas/matrix.hpp>
00033 #include <boost/numeric/ublas/matrix_proxy.hpp>
00034 
00035 #include <boost/numeric/ublas/vector_expression.hpp>
00036 #include <boost/numeric/ublas/matrix_expression.hpp>
00037 
00038 #include <boost/numeric/ublas/triangular.hpp>
00039 
00040 namespace ublas = boost::numeric::ublas;
00041 
00042 
00051 template < class MATRIX, class TRIA >
00052 size_t cholesky_decompose(const MATRIX& A, TRIA& L)
00053 {
00054   using namespace ublas;
00055 
00056   typedef typename MATRIX::value_type T;
00057   
00058   assert( A.size1() == A.size2() );
00059   assert( A.size1() == L.size1() );
00060   assert( A.size2() == L.size2() );
00061 
00062   const size_t n = A.size1();
00063   
00064   for (size_t k=0 ; k < n; k++) {
00065         
00066     double qL_kk = A(k,k) - inner_prod( project( row(L, k), range(0, k) ),
00067                                         project( row(L, k), range(0, k) ) );
00068     
00069     if (qL_kk <= 0) {
00070       return 1 + k;
00071     } else {
00072       double L_kk = sqrt( qL_kk );
00073       L(k,k) = L_kk;
00074       
00075       matrix_column<TRIA> cLk(L, k);
00076       project( cLk, range(k+1, n) )
00077         = ( project( column(A, k), range(k+1, n) )
00078             - prod( project(L, range(k+1, n), range(0, k)), 
00079                     project(row(L, k), range(0, k) ) ) ) / L_kk;
00080     }
00081   }
00082   return 0;      
00083 }
00084 
00085 
00093 template < class MATRIX >
00094 size_t cholesky_decompose(MATRIX& A)
00095 {
00096   using namespace ublas;
00097 
00098   typedef typename MATRIX::value_type T;
00099   
00100   const MATRIX& A_c(A);
00101 
00102   const size_t n = A.size1();
00103   
00104   for (size_t k=0 ; k < n; k++) {
00105         
00106     double qL_kk = A_c(k,k) - inner_prod( project( row(A_c, k), range(0, k) ),
00107                                           project( row(A_c, k), range(0, k) ) );
00108     
00109     if (qL_kk <= 0) {
00110       return 1 + k;
00111     } else {
00112       double L_kk = sqrt( qL_kk );
00113       
00114       matrix_column<MATRIX> cLk(A, k);
00115       project( cLk, range(k+1, n) )
00116         = ( project( column(A_c, k), range(k+1, n) )
00117             - prod( project(A_c, range(k+1, n), range(0, k)), 
00118                     project(row(A_c, k), range(0, k) ) ) ) / L_kk;
00119       A(k,k) = L_kk;
00120     }
00121   }
00122   return 0;      
00123 }
00124 
00125 #if 0
00126   using namespace ublas;
00127 
00128     // Operations:
00129     //  n * (n - 1) / 2 + n = n * (n + 1) / 2 multiplications,
00130     //  n * (n - 1) / 2 additions
00131 
00132     // Dense (proxy) case
00133     template<class E1, class E2>
00134     void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
00135                         lower_tag, column_major_tag) {
00136       std::cout << " is_lc ";
00137         typedef typename E2::size_type size_type;
00138         typedef typename E2::difference_type difference_type;
00139         typedef typename E2::value_type value_type;
00140 
00141         BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
00142         BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
00143         size_type size = e2 ().size ();
00144         for (size_type n = 0; n < size; ++ n) {
00145 #ifndef BOOST_UBLAS_SINGULAR_CHECK
00146             BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
00147 #else
00148             if (e1 () (n, n) == value_type/*zero*/())
00149                 singular ().raise ();
00150 #endif
00151             value_type t = e2 () (n) / e1 () (n, n);
00152             e2 () (n) = t;
00153             if (t != value_type/*zero*/()) {
00154               project( e2 (), range(n+1, size) )
00155                 .minus_assign( t * project( column( e1 (), n), range(n+1, size) ) );
00156             }
00157         }
00158     }
00159 #endif
00160 
00161 
00162 
00163 
00164 
00172 template < class MATRIX >
00173 size_t incomplete_cholesky_decompose(MATRIX& A)
00174 {
00175   using namespace ublas;
00176 
00177   typedef typename MATRIX::value_type T;
00178   
00179   // read access to a const matrix is faster
00180   const MATRIX& A_c(A);
00181 
00182   const size_t n = A.size1();
00183   
00184   for (size_t k=0 ; k < n; k++) {
00185     
00186     double qL_kk = A_c(k,k) - inner_prod( project( row( A_c, k ), range(0, k) ),
00187                                           project( row( A_c, k ), range(0, k) ) );
00188     
00189     if (qL_kk <= 0) {
00190       return 1 + k;
00191     } else {
00192       double L_kk = sqrt( qL_kk );
00193 
00194       // aktualisieren
00195       for (size_t i = k+1; i < A.size1(); ++i) {
00196         T* Aik = A.find_element(i, k);
00197 
00198         if (Aik != 0) {
00199           *Aik = ( *Aik - inner_prod( project( row( A_c, k ), range(0, k) ),
00200                                       project( row( A_c, i ), range(0, k) ) ) ) / L_kk;
00201         }
00202       }
00203         
00204       A(k,k) = L_kk;
00205     }
00206   }
00207         
00208   return 0;
00209 }
00210 
00211 
00212 
00213 
00219 template < class TRIA, class VEC >
00220 void
00221 cholesky_solve(const TRIA& L, VEC& x, ublas::lower)
00222 {
00223   using namespace ublas;
00224 //   ::inplace_solve(L, x, lower_tag(), typename TRIA::orientation_category () );
00225   inplace_solve(L, x, lower_tag() );
00226   inplace_solve(trans(L), x, upper_tag());
00227 }
00228 
00229 
00230 #endif


gaussian_process
Author(s): Maintained by Juergen Sturm
autogenerated on Mon Oct 6 2014 00:09:34