• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

/home/hauberg/Dokumenter/Capture/humim-tracker-0.1/src/OpenTissue/OpenTissue/core/math/big/big_cholesky.h

Go to the documentation of this file.
00001 #ifndef OPENTISSUE_CORE_MATH_BIG_BIG_CHOLESKY_H
00002 #define OPENTISSUE_CORE_MATH_BIG_BIG_CHOLESKY_H
00003 //
00004 // OpenTissue Template Library
00005 // - A generic toolbox for physics-based modeling and simulation.
00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen.
00007 //
00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php
00009 //
00010 #include <OpenTissue/configuration.h>
00011 
00012 //#include <OpenTissue/core/math/big/big_types.h> // Not needed for here! 
00013 
00014 //
00015 // 2007-9-28: The implementation in this file is based on a
00016 // modification of code originally developed by Gunter Winkler and Konstantin Kutzkow.
00017 // 
00019 /*
00020 -   begin                : 2005-08-24
00021 -   copyright            : (C) 2005 by Gunter Winkler, Konstantin Kutzkow
00022 -   email                : guwi17@gmx.de
00023 
00024 This library is free software; you can redistribute it and/or
00025 modify it under the terms of the GNU Lesser General Public
00026 License as published by the Free Software Foundation; either
00027 version 2.1 of the License, or (at your option) any later version.
00028 
00029 This library is distributed in the hope that it will be useful,
00030 but WITHOUT ANY WARRANTY; without even the implied warranty of
00031 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00032 Lesser General Public License for more details.
00033 
00034 You should have received a copy of the GNU Lesser General Public
00035 License along with this library; if not, write to the Free Software
00036 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00037 
00038 */
00039 
00040 #include <boost/numeric/ublas/vector.hpp>
00041 #include <boost/numeric/ublas/vector_proxy.hpp>
00042 
00043 #include <boost/numeric/ublas/matrix.hpp>
00044 #include <boost/numeric/ublas/matrix_proxy.hpp>
00045 
00046 #include <boost/numeric/ublas/vector_expression.hpp>
00047 #include <boost/numeric/ublas/matrix_expression.hpp>
00048 
00049 #include <boost/numeric/ublas/triangular.hpp>
00050 
00051 namespace ublas = boost::numeric::ublas;
00052 #include <cassert>
00053 #include <stdexcept>
00054 
00055 namespace OpenTissue
00056 {
00057   namespace math
00058   {
00059     namespace big
00060     {
00061 
00069       template < typename matrix_type, typename triangular_matrix_type >
00070       inline size_t cholesky_decompose(matrix_type const & A, triangular_matrix_type& L)
00071       {
00072         using std::sqrt;
00073         using namespace ublas;
00074 
00075         typedef typename matrix_type::value_type T;
00076 
00077         if( A.size1() != A.size2() )
00078           throw std::invalid_argument("A could not be a symmetric matrix.");
00079         if( A.size1() != L.size1() )
00080           throw std::invalid_argument("Incompatible dimensions of A and L");
00081         if( A.size2() != L.size2() )
00082           throw std::invalid_argument("Incompatible dimensions of A and L");
00083 
00084         size_t const n = A.size1();
00085 
00086         for (size_t k = 0 ; k < n; ++k) 
00087         {        
00088           double qL_kk = A(k,k) - inner_prod( project( row(L, k), range(0, k) ), project( row(L, k), range(0, k) ) );
00089           if (qL_kk <= 0) 
00090           {
00091             return 1 + k;
00092           }
00093           else 
00094           {
00095             double L_kk = sqrt( qL_kk );
00096             L(k,k) = L_kk;
00097 
00098             matrix_column<triangular_matrix_type> cLk(L, k);
00099 
00100             project( cLk, range(k+1, n) )
00101               = ( project( column(A, k), range(k+1, n) )
00102               - prod( project(L, range(k+1, n), range(0, k)), 
00103               project(row(L, k), range(0, k) ) ) ) / L_kk;
00104           }
00105         }
00106         return 0;      
00107       }
00108 
00115       template < typename matrix_type >
00116       inline size_t cholesky_decompose(matrix_type & A)
00117       {
00118         using namespace ublas;
00119         using std::sqrt;
00120 
00121         typedef typename matrix_type::value_type T;
00122 
00123         matrix_type const & A_c(A);
00124         size_t const n = A.size1();
00125 
00126         for (size_t k=0 ; k < n; ++k) 
00127         {
00128           double qL_kk = A_c(k,k) - inner_prod( project( row(A_c, k), range(0, k) ), project( row(A_c, k), range(0, k) ) );
00129           if (qL_kk <= 0) 
00130           {
00131             return 1 + k;
00132           }
00133           else 
00134           {
00135             double L_kk = sqrt( qL_kk );
00136 
00137             matrix_column<matrix_type> cLk(A, k);
00138 
00139             project( cLk, range(k+1, n) )
00140               = ( project( column(A_c, k), range(k+1, n) )
00141               - prod( project(A_c, range(k+1, n), range(0, k)), 
00142               project(row(A_c, k), range(0, k) ) ) ) / L_kk;
00143             A(k,k) = L_kk;
00144           }
00145         }
00146         return 0;      
00147       }
00148 
00155       template < typename matrix_type >
00156       inline size_t incomplete_cholesky_decompose(matrix_type & A)
00157       {
00158         using namespace ublas;
00159         using std::sqrt;
00160 
00161         typedef typename matrix_type::value_type T;
00162 
00163         // read access to a const matrix is faster
00164         matrix_type const & A_c(A);
00165         size_t const n = A.size1();
00166 
00167         for (size_t k=0 ; k < n; ++k)
00168         {
00169           double qL_kk = A_c(k,k) - inner_prod( project( row( A_c, k ), range(0, k) ), project( row( A_c, k ), range(0, k) ) );
00170 
00171           if (qL_kk <= 0) 
00172           {
00173             return 1 + k;
00174           }
00175           else 
00176           {
00177             double L_kk = sqrt( qL_kk );
00178 
00179             for (size_t i = k+1; i < A.size1(); ++i) 
00180             {
00181               T* Aik = A.find_element(i, k);
00182 
00183               if (Aik != 0) 
00184               {
00185                 *Aik = ( *Aik - inner_prod( project( row( A_c, k ), range(0, k) ), project( row( A_c, i ), range(0, k) ) ) ) / L_kk;
00186               }
00187             }
00188 
00189             A(k,k) = L_kk;
00190           }
00191         }
00192 
00193         return 0;
00194       }
00195 
00202       template < typename triangular_matrix_type, typename vector_type >
00203       inline void cholesky_solve(triangular_matrix_type const & L, vector_type & x, ublas::lower)
00204       {
00205         using namespace ublas;
00206         inplace_solve(L, x, lower_tag() );
00207         inplace_solve(trans(L), x, upper_tag());
00208       }
00209 
00217       template < typename T >
00218       inline void cholesky_solve(
00219         ublas::compressed_matrix<T> const & A
00220         , ublas::vector<T> & x
00221         , ublas::vector<T> const & b
00222         )
00223       {
00224         ublas::compressed_matrix<double> L(A);
00225         OpenTissue::math::big::incomplete_cholesky_decompose(L);
00226         x = b;
00227         OpenTissue::math::big::cholesky_solve(L, x, ublas::lower());
00228       }
00229 
00237       template < typename T >
00238       inline void cholesky_solve(
00239         ublas::matrix<T> const & A
00240         , ublas::vector<T> & x
00241         , ublas::vector<T> const & b
00242         )
00243       {
00244         ublas::matrix<double> L(A);
00245         OpenTissue::math::big::cholesky_decompose(L);
00246         x = b;
00247         OpenTissue::math::big::cholesky_solve(L, x, ublas::lower());
00248       }
00249 
00250     } // namespace big
00251   } // namespace math
00252 } // namespace OpenTissue
00253 
00254 // OPENTISSUE_CORE_MATH_BIG_BIG_CHOLESKY_H
00255 #endif

Generated on Thu Dec 1 2011 12:52:04 for HUMIM Tracker by  doxygen 1.7.1