Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_BIG_BIG_BACKSOLVE_H
00002 #define OPENTISSUE_CORE_MATH_BIG_BIG_BACKSOLVE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_precision.h>
00013 #include <OpenTissue/core/math/math_is_number.h>
00014
00015 #include <boost/cast.hpp>
00016
00017 #include <cassert>
00018 #include <cmath>
00019
00020 namespace OpenTissue
00021 {
00022 namespace math
00023 {
00024 namespace big
00025 {
00034 template<typename size_type, typename matrix_type, typename vector_type>
00035 inline void backsolve (
00036 size_type m
00037 , matrix_type const & A
00038 , vector_type & x
00039 , vector_type const & b
00040 )
00041 {
00042 using std::fabs;
00043
00044 typedef typename vector_type::value_type value_type;
00045
00046 assert(m>0 || !"backsolve: m too small");
00047 assert(b.size() >= m || !"backsolve: b too small");
00048 assert(A.size1() >= m || !"backsolve: A too small");
00049 assert(A.size2() >= m || !"backsolve: A too small");
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 x.resize(b.size(), false);
00076 x = b;
00077
00078 int k = ::boost::numeric_cast<int>(m);
00079
00080 for ( int i = k - 1; i >= 0; --i)
00081 {
00082 assert( fabs(A( i, i ))> math::working_precision<value_type>() || !"back_solve(): A is near singular");
00083 x [ i ] /= A( i, i );
00084 assert( is_number( x[i] ) || !"back_solve(): x_i is not a number");
00085 for ( int j = i - 1; j >= 0; --j)
00086 x [ j ] -= A ( j, i ) * x [ i ];
00087 }
00088 }
00089
00090 }
00091 }
00092 }
00093
00094
00095 #endif