00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _GIVENS_ROTATION_H
00020 #define _GIVENS_ROTATION_H
00021
00022 #include <boost/numeric/ublas/vector.hpp>
00023 #include <boost/numeric/ublas/matrix.hpp>
00024 #include <boost/numeric/ublas/matrix_proxy.hpp>
00025
00026 using namespace boost::numeric::ublas;
00027
00028 namespace lsp{
00029
00052 template< class T > class givens_rotation{
00053 public:
00054 typedef T value_type;
00055
00056 private:
00057 value_type m_c, m_s;
00058
00059 public:
00079 givens_rotation( value_type& x, value_type& y ) {
00080 value_type w,q;
00081
00082 if( std::abs( x ) <= std::abs( y ) ) {
00083 if( y == 0 ) {
00084 m_c = value_type( 1 );
00085 m_s = value_type( 0 );
00086 } else {
00087 w = x / y;
00088 q = std::sqrt( value_type( 1 ) + w*w );
00089 m_s = value_type( 1 ) / q;
00090 if( y < 0 )
00091 m_s = -m_s;
00092 m_c = w * m_s;
00093 x = std::abs( y * q );
00094 y = value_type( 0 );
00095 }
00096 } else {
00097 w = y / x;
00098 q = std::sqrt( value_type( 1 ) + w*w );
00099 m_c = value_type( 1 ) / q;
00100 if( x < 0 )
00101 m_c = -m_c;
00102 m_s = w * m_c;
00103 x = std::abs( x * q );
00104 y = value_type( 0 );
00105 }
00106 }
00107
00135 template<class U> void apply ( U& x, U& y ) const {
00136 U w ( x * m_c + y * m_s );
00137 y = x * ( -m_s ) + y * m_c;
00138 x = w;
00139 }
00140 template<class M> void apply ( matrix_row< M > x, matrix_row< M > y ) const {
00141 typename vector_temporary_traits< matrix_row< M > >::type w ( x * m_c + y * m_s );
00142 y = x * ( -m_s ) + y * m_c;
00143 x = w;
00144 }
00145 template<class M> void apply ( matrix_column< M > x, matrix_column< M > y ) const {
00146 typename vector_temporary_traits< matrix_column< M > >::type w ( x * m_c + y * m_s );
00147 y = x * ( -m_s ) + y * m_c;
00148 x = w;
00149 }
00150
00154 inline const value_type c() const { return m_c; }
00155
00159 inline const value_type s() const { return m_s; }
00160 };
00161
00162 };
00163
00164 #endif // _GIVENS_ROTATION_H