Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_BIG_BIG_JACOBI_H
00002 #define OPENTISSUE_CORE_MATH_BIG_BIG_JACOBI_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/big/big_types.h>
00013 #include <OpenTissue/core/math/big/big_prod_row.h>
00014 #include <boost/cast.hpp>
00015 #include <stdexcept>
00016
00017 namespace OpenTissue
00018 {
00019 namespace math
00020 {
00021 namespace big
00022 {
00023
00033 template<typename T>
00034 inline void jacobi(
00035 ublas::compressed_matrix<T> const & A
00036 , ublas::vector<T> & x
00037 , ublas::vector<T> const & b
00038 )
00039 {
00040 typedef ublas::compressed_matrix<T> matrix_type;
00041 typedef ublas::vector<T> vector_type;
00042 typedef typename vector_type::size_type size_type;
00043
00044 if(A.size1() <= 0 || A.size2() <= 0)
00045 throw std::invalid_argument("jacobi(): A was empty");
00046 if(b.size() != A.size1())
00047 throw std::invalid_argument("jacobi(): The size of b must be the same as the number of rows in A");
00048 if(x.size() != A.size2())
00049 throw std::invalid_argument("jacobi(): The size of x must be the same as the number of columns in A");
00050
00051 size_type n = x.size();
00052 vector_type x_old = x;
00053 for ( size_type i = 0; i < n; ++i )
00054 {
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 x(i) = ( b(i) - prod_row(A,x_old,i)) / A(i,i) + x_old(i);
00071 }
00072 }
00073
00085 template<typename T>
00086 inline void jacobi(
00087 ublas::compressed_matrix<T> const & A
00088 , ublas::vector<T> & x
00089 , ublas::vector<T> const & b
00090 , size_t const & max_iterations
00091 , T const &
00092 , size_t & iterations
00093 )
00094 {
00095 if(max_iterations < 1)
00096 throw std::invalid_argument("jacobi(): max_iterations must be a positive number");
00097
00098 iterations = 0;
00099 while ( iterations < max_iterations )
00100 {
00101 jacobi(A,x,b);
00102 ++iterations;
00103 }
00104 }
00105
00119 template<typename T>
00120 inline void jacobi(
00121 ublas::compressed_matrix<T> const & A
00122 , ublas::vector<T> & x
00123 , ublas::vector<T> const & b
00124 , size_t & iterations
00125 )
00126 {
00127 size_t max_iterations( 15 );
00128 T epsilon = boost::numeric_cast<T>( 10e-4 );
00129 jacobi(A,x,b,max_iterations, epsilon, iterations);
00130 }
00131
00141 class JacobiFunctor
00142 {
00143 public:
00144
00145 template<typename T>
00146 void operator()(
00147 ublas::compressed_matrix<T> const & A
00148 , ublas::vector<T> & x
00149 , ublas::vector<T> const & b
00150 )
00151 {
00152 jacobi(A,x,b);
00153 }
00154
00155 template<typename T>
00156 void operator()(
00157 ublas::compressed_matrix<T> const & A
00158 , ublas::vector<T> & x
00159 , ublas::vector<T> const & b
00160 , size_t const & max_iterations
00161 , T const & epsilon
00162 , size_t & iterations
00163 )
00164 {
00165 jacobi(A,x,b,max_iterations,epsilon,iterations);
00166 }
00167
00168 template<typename T>
00169 void operator()(
00170 ublas::compressed_matrix<T> const & A
00171 , ublas::vector<T> & x
00172 , ublas::vector<T> const & b
00173 , size_t & iterations
00174 )
00175 {
00176 jacobi(A,x,b,iterations);
00177 }
00178
00179 };
00180
00181 }
00182 }
00183 }
00184
00185
00186 #endif