Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_BIG_BIG_LU_H
00002 #define OPENTISSUE_CORE_MATH_BIG_BIG_LU_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #ifdef USE_ATLAS
00013 # include <boost/numeric/bindings/atlas/cblas2.hpp>
00014 # include <boost/numeric/bindings/atlas/cblas3.hpp>
00015 # include <boost/numeric/bindings/atlas/clapack.hpp>
00016 # include <boost/numeric/bindings/traits/ublas_matrix.hpp>
00017 # include <boost/numeric/bindings/traits/ublas_vector.hpp>
00018
00019 namespace atlas = boost::numeric::bindings::atlas;
00020 #endif
00021
00022 #include <OpenTissue/core/math/big/big_types.h>
00023
00024 #include <boost/numeric/ublas/triangular.hpp>
00025 #include <boost/numeric/ublas/lu.hpp>
00026
00027 #include <stdexcept>
00028
00029
00030 namespace OpenTissue
00031 {
00032 namespace math
00033 {
00034 namespace big
00035 {
00036
00037 #ifdef USE_ATLAS
00038
00048 template<typename matrix_type, typename vector_type>
00049 inline bool lu_atlas( matrix_type const & A, vector_type & x, vector_type const & b)
00050 {
00051 typedef typename matrix_type::value_type value_type;
00052 typedef typename matrix_type::size_type size_type;
00053
00054 if(A.size1() <= 0 || A.size2() <= 0)
00055 throw std::invalid_argument("A was empty");
00056
00057 if(b.size() != A.size1())
00058 throw std::invalid_argument("The size of b must be the same as the number of rows in A");
00059
00060 if(x.size() != A.size2())
00061 throw std::invalid_argument("The size of x must be the same as the number of columns in A");
00062
00063 size_type m = A.size1();
00064 size_type n = A.size2();
00065
00066 ublas::matrix<value_type, ublas::column_major> Acpy( m, n );
00067 Acpy.assign(A);
00068 ublas::matrix<value_type, ublas::column_major> B( n, 1 );
00069 ublas::column( B, 0 ) = b;
00070 atlas::gesv( Acpy, B );
00071 x = ublas::column( B, 0 );
00072
00073 return true;
00074 }
00075
00076 template<typename matrix_type, typename vector_type>
00077 inline bool lu( matrix_type const & A, vector_type & x, vector_type const & b)
00078 {
00079 return lu_atlas(A, x, b);
00080 }
00081
00096 template<typename T>
00097 inline bool lu_atlas_invert( ublas::matrix<T> const & A, ublas::matrix<T> & invA)
00098 {
00099 typedef typename ublas::matrix<T>::size_type size_type;
00100
00101 if(A.size1() <= 0 || A.size2() <= 0)
00102 throw std::invalid_argument("A was empty");
00103
00104 size_type m = A.size1();
00105 size_type n = A.size2();
00106
00107 invA.resize(m,n,false);
00108 invA.assign( A );
00109
00110 std::vector<int> ipiv (n);
00111 int rc = atlas::lu_factor (invA, ipiv);
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 if(rc!=0)
00124 return false;
00125
00126 atlas::lu_invert (invA, ipiv);
00127 return true;
00128 }
00129
00130 template<typename T>
00131 inline bool lu_invert( ublas::matrix<T> const & A, ublas::matrix<T> & invA)
00132 {
00133 return lu_atlas_invert(A, invA);
00134 }
00135
00136 #else
00137
00147 template<class matrix_type, class vector_type>
00148 inline bool lu(matrix_type const & A, vector_type & x, vector_type const & b)
00149 {
00150 typedef typename matrix_type::size_type size_type;
00151 typedef typename matrix_type::value_type real_type;
00152 typedef typename boost::numeric::ublas::permutation_matrix<size_t> pmatrix_type;
00153 typedef typename boost::numeric::ublas::identity_matrix<real_type> identity_matrix_type;
00154
00155 if(A.size1() <= 0 || A.size2() <= 0)
00156 throw std::invalid_argument("A was empty");
00157
00158 if(b.size() != A.size1())
00159 throw std::invalid_argument("The size of b must be the same as the number of rows in A");
00160
00161 if(x.size() != A.size2())
00162 throw std::invalid_argument("The size of x must be the same as the number of columns in A");
00163
00164 matrix_type tmp(A);
00165 pmatrix_type pm(tmp.size1());
00166 int res = lu_factorize(tmp,pm);
00167 if( res != 0 )
00168 return false;
00169 x.assign(b);
00170 lu_substitute(tmp, pm, x);
00171 return true;
00172 }
00173
00185 template<class matrix_type>
00186 inline bool lu_invert(matrix_type const & A, matrix_type& invA)
00187 {
00188 typedef typename matrix_type::size_type size_type;
00189 typedef typename matrix_type::value_type real_type;
00190 typedef typename boost::numeric::ublas::permutation_matrix<size_t> pmatrix_type;
00191 typedef typename boost::numeric::ublas::identity_matrix<real_type> identity_matrix_type;
00192
00193 if(A.size1() <= 0 || A.size2() <= 0)
00194 throw std::invalid_argument("A was empty");
00195
00196 size_type m = A.size1();
00197 size_type n = A.size2();
00198 invA.resize(m,n,false);
00199
00200 matrix_type tmp(A);
00201
00202 pmatrix_type pm(tmp.size1());
00203 int res = lu_factorize(tmp,pm);
00204 if( res != 0 )
00205 return false;
00206 invA.assign(identity_matrix_type(tmp.size1()));
00207 lu_substitute(tmp, pm, invA);
00208 return true;
00209 }
00210
00211 #endif
00212
00213
00214
00215
00216 }
00217 }
00218 }
00219
00220
00221 #endif