00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef MTL_MATRIX_GIVENS_INCLUDE
00015 #define MTL_MATRIX_GIVENS_INCLUDE
00016
00017 #include <cmath>
00018 #include <boost/numeric/mtl/utility/exception.hpp>
00019 #include <boost/numeric/mtl/utility/irange.hpp>
00020 #include <boost/numeric/mtl/concept/collection.hpp>
00021 #include <boost/numeric/mtl/operation/householder.hpp>
00022 #include <boost/numeric/mtl/operation/rank_one_update.hpp>
00023 #include <boost/numeric/mtl/operation/trans.hpp>
00024
00025
00026 namespace mtl { namespace matrix {
00027
00029 template <typename Matrix>
00030 class givens
00031 {
00032 typedef typename Collection<Matrix>::value_type value_type;
00033 typedef typename Collection<Matrix>::size_type size_type;
00034
00035 public:
00037 givens(Matrix& H, value_type a, value_type b) : H(H)
00038 {
00039 using std::abs;
00040 value_type zero= math::zero(a), one= math::one(b), t;
00041
00042 if ( b == zero )
00043 std::make_pair(one, zero);
00044
00045 if ( abs(b) > abs(a) ) {
00046 t= -a/b;
00047 d= one/sqrt(one + t*t);
00048 c= d*t;
00049 } else {
00050 t= -b/a;
00051 c= one/sqrt(one + t*t);
00052 d= c*t;
00053 }
00054 }
00055
00057 Matrix& trafo(const Matrix& G, size_type k)
00058 {
00059 irange r(k,k+2);
00060
00061
00062
00063 Matrix col_block(H[r][iall]), col_perm(trans(G) * col_block);
00064 H[r][iall]= col_perm;
00065
00066 Matrix row_perm(H[iall][r] * G);
00067 H[iall][r]= row_perm;
00068
00069 return H;
00070 }
00071
00073 Matrix& trafo(size_type k)
00074 {
00075 Matrix G(2, 2);
00076 G= c, d,
00077 -d, c;
00078 return trafo(G, k);
00079 }
00080
00081 private:
00082 Matrix& H;
00083 value_type c, d;
00084 };
00085
00086 }}
00087
00088 #endif // MTL_MATRIX_GIVENS_INCLUDE