38 #ifndef GMM_DENSE_HOUSEHOLDER_H
39 #define GMM_DENSE_HOUSEHOLDER_H
50 template <
typename Matrix,
typename VecX,
typename VecY>
51 inline void rank_one_update(Matrix &A,
const VecX& x,
52 const VecY& y, row_major) {
53 typedef typename linalg_traits<Matrix>::value_type T;
55 GMM_ASSERT2(N <= vect_size(x) && mat_ncols(A) <= vect_size(y),
56 "dimensions mismatch");
57 typename linalg_traits<VecX>::const_iterator itx = vect_const_begin(x);
58 for (
size_type i = 0; i < N; ++i, ++itx) {
59 typedef typename linalg_traits<Matrix>::sub_row_type row_type;
60 row_type row = mat_row(A, i);
61 typename linalg_traits<typename org_type<row_type>::t>::iterator
62 it = vect_begin(row), ite = vect_end(row);
63 typename linalg_traits<VecY>::const_iterator ity = vect_const_begin(y);
65 for (; it != ite; ++it, ++ity) *it += conj_product(*ity, tx);
69 template <
typename Matrix,
typename VecX,
typename VecY>
70 inline void rank_one_update(Matrix &A,
const VecX& x,
71 const VecY& y, col_major) {
72 typedef typename linalg_traits<Matrix>::value_type T;
74 GMM_ASSERT2(mat_nrows(A) <= vect_size(x) && M <= vect_size(y),
75 "dimensions mismatch");
76 typename linalg_traits<VecY>::const_iterator ity = vect_const_begin(y);
77 for (
size_type i = 0; i < M; ++i, ++ity) {
78 typedef typename linalg_traits<Matrix>::sub_col_type col_type;
79 col_type col = mat_col(A, i);
80 typename linalg_traits<typename org_type<col_type>::t>::iterator
81 it = vect_begin(col), ite = vect_end(col);
82 typename linalg_traits<VecX>::const_iterator itx = vect_const_begin(x);
84 for (; it != ite; ++it, ++itx) *it += conj_product(ty, *itx);
89 template <
typename Matrix,
typename VecX,
typename VecY>
90 inline void rank_one_update(
const Matrix &AA,
const VecX& x,
92 Matrix& A =
const_cast<Matrix&
>(AA);
93 rank_one_update(A, x, y,
typename principal_orientation_type<
typename
94 linalg_traits<Matrix>::sub_orientation>::potype());
102 template <
typename Matrix,
typename VecX,
typename VecY>
103 inline void rank_two_update(Matrix &A,
const VecX& x,
104 const VecY& y, row_major) {
105 typedef typename linalg_traits<Matrix>::value_type value_type;
107 GMM_ASSERT2(N <= vect_size(x) && mat_ncols(A) <= vect_size(y),
108 "dimensions mismatch");
109 typename linalg_traits<VecX>::const_iterator itx1 = vect_const_begin(x);
110 typename linalg_traits<VecY>::const_iterator ity2 = vect_const_begin(y);
111 for (
size_type i = 0; i < N; ++i, ++itx1, ++ity2) {
112 typedef typename linalg_traits<Matrix>::sub_row_type row_type;
113 row_type row = mat_row(A, i);
114 typename linalg_traits<typename org_type<row_type>::t>::iterator
115 it = vect_begin(row), ite = vect_end(row);
116 typename linalg_traits<VecX>::const_iterator itx2 = vect_const_begin(x);
117 typename linalg_traits<VecY>::const_iterator ity1 = vect_const_begin(y);
118 value_type tx = *itx1, ty = *ity2;
119 for (; it != ite; ++it, ++ity1, ++itx2)
120 *it += conj_product(*ity1, tx) + conj_product(*itx2, ty);
124 template <
typename Matrix,
typename VecX,
typename VecY>
125 inline void rank_two_update(Matrix &A,
const VecX& x,
126 const VecY& y, col_major) {
127 typedef typename linalg_traits<Matrix>::value_type value_type;
129 GMM_ASSERT2(mat_nrows(A) <= vect_size(x) && M <= vect_size(y),
130 "dimensions mismatch");
131 typename linalg_traits<VecX>::const_iterator itx2 = vect_const_begin(x);
132 typename linalg_traits<VecY>::const_iterator ity1 = vect_const_begin(y);
133 for (
size_type i = 0; i < M; ++i, ++ity1, ++itx2) {
134 typedef typename linalg_traits<Matrix>::sub_col_type col_type;
135 col_type col = mat_col(A, i);
136 typename linalg_traits<typename org_type<col_type>::t>::iterator
137 it = vect_begin(col), ite = vect_end(col);
138 typename linalg_traits<VecX>::const_iterator itx1 = vect_const_begin(x);
139 typename linalg_traits<VecY>::const_iterator ity2 = vect_const_begin(y);
140 value_type ty = *ity1, tx = *itx2;
141 for (; it != ite; ++it, ++itx1, ++ity2)
142 *it += conj_product(ty, *itx1) + conj_product(tx, *ity2);
147 template <
typename Matrix,
typename VecX,
typename VecY>
148 inline void rank_two_update(
const Matrix &AA,
const VecX& x,
150 Matrix& A =
const_cast<Matrix&
>(AA);
151 rank_two_update(A, x, y,
typename principal_orientation_type<
typename
152 linalg_traits<Matrix>::sub_orientation>::potype());
160 template <
typename VECT>
void house_vector(
const VECT &VV) {
161 VECT &V =
const_cast<VECT &
>(VV);
162 typedef typename linalg_traits<VECT>::value_type T;
163 typedef typename number_traits<T>::magnitude_type R;
165 R mu =
vect_norm2(V), abs_v0 = gmm::abs(V[0]);
167 gmm::scale(V, (abs_v0 == R(0)) ? T(R(1) / mu)
168 : (safe_divide(T(abs_v0), V[0]) / (abs_v0 + mu)));
169 if (gmm::real(V[vect_size(V)-1]) * R(0) != R(0))
174 template <
typename VECT>
void house_vector_last(
const VECT &VV) {
175 VECT &V =
const_cast<VECT &
>(VV);
176 typedef typename linalg_traits<VECT>::value_type T;
177 typedef typename number_traits<T>::magnitude_type R;
180 R mu =
vect_norm2(V), abs_v0 = gmm::abs(V[m-1]);
182 gmm::scale(V, (abs_v0 == R(0)) ? T(R(1) / mu)
183 : ((abs_v0 / V[m-1]) / (abs_v0 + mu)));
184 if (gmm::real(V[0]) * R(0) != R(0))
194 template <
typename MAT,
typename VECT1,
typename VECT2>
inline
195 void row_house_update(
const MAT &AA,
const VECT1 &V,
const VECT2 &WW) {
196 VECT2 &W =
const_cast<VECT2 &
>(WW); MAT &A =
const_cast<MAT &
>(AA);
197 typedef typename linalg_traits<MAT>::value_type value_type;
198 typedef typename number_traits<value_type>::magnitude_type magnitude_type;
202 rank_one_update(A, V, W);
206 template <
typename MAT,
typename VECT1,
typename VECT2>
inline
207 void col_house_update(
const MAT &AA,
const VECT1 &V,
const VECT2 &WW) {
208 VECT2 &W =
const_cast<VECT2 &
>(WW); MAT &A =
const_cast<MAT &
>(AA);
209 typedef typename linalg_traits<MAT>::value_type value_type;
210 typedef typename number_traits<value_type>::magnitude_type magnitude_type;
214 rank_one_update(A, W, V);
223 template <
typename MAT1,
typename MAT2>
224 void Hessenberg_reduction(
const MAT1& AA,
const MAT2 &QQ,
bool compute_Q){
225 MAT1& A =
const_cast<MAT1&
>(AA); MAT2& Q =
const_cast<MAT2&
>(QQ);
226 typedef typename linalg_traits<MAT1>::value_type value_type;
227 if (compute_Q)
gmm::copy(identity_matrix(), Q);
228 size_type n = mat_nrows(A);
if (n < 2)
return;
229 std::vector<value_type> v(n), w(n);
230 sub_interval SUBK(0,n);
232 sub_interval SUBI(k, n-k), SUBJ(k-1,n-k+1);
234 for (
size_type j = k; j < n; ++j) v[j-k] = A(j, k-1);
236 row_house_update(sub_matrix(A, SUBI, SUBJ), v, sub_vector(w, SUBJ));
237 col_house_update(sub_matrix(A, SUBK, SUBI), v, w);
239 if (compute_Q) col_house_update(sub_matrix(Q, SUBK, SUBI), v, w);
247 template <
typename MAT1,
typename MAT2>
248 void Householder_tridiagonalization(
const MAT1 &AA,
const MAT2 &QQ,
250 MAT1 &A =
const_cast<MAT1 &
>(AA); MAT2 &Q =
const_cast<MAT2 &
>(QQ);
251 typedef typename linalg_traits<MAT1>::value_type T;
252 typedef typename number_traits<T>::magnitude_type R;
254 size_type n = mat_nrows(A);
if (n < 2)
return;
255 std::vector<T> v(n), p(n), w(n), ww(n);
256 sub_interval SUBK(0,n);
259 sub_interval SUBI(k, n-k);
260 v.resize(n-k); p.resize(n-k); w.resize(n-k);
262 { v[l-k] = w[l-k] = A(l, k-1); A(l, k-1) = A(k-1, l) = T(0); }
265 A(k-1, k) = gmm::conj(A(k, k-1) = w[0] - T(2)*v[0]*
vect_hp(w, v)/norm);
267 gmm::mult(sub_matrix(A, SUBI), gmm::scaled(v, T(-2) / norm), p);
269 rank_two_update(sub_matrix(A, SUBI), v, w);
272 col_house_update(sub_matrix(Q, SUBK, SUBI), v, ww);
280 template <
typename T>
void Givens_rotation(T a, T b, T &c, T &s) {
281 typedef typename number_traits<T>::magnitude_type R;
282 R aa = gmm::abs(a), bb = gmm::abs(b);
283 if (bb == R(0)) { c = T(1); s = T(0);
return; }
284 if (aa == R(0)) { c = T(0); s = b / bb;
return; }
286 { T t = -safe_divide(a,b); s = T(R(1) / (sqrt(R(1)+gmm::abs_sqr(t)))); c = s * t; }
288 { T t = -safe_divide(b,a); c = T(R(1) / (sqrt(R(1)+gmm::abs_sqr(t)))); s = c * t; }
292 template <
typename T>
inline
293 void Apply_Givens_rotation_left(T &x, T &y, T c, T s)
294 { T t1=x, t2=y; x = gmm::conj(c)*t1 - gmm::conj(s)*t2; y = c*t2 + s*t1; }
297 template <
typename T>
inline
298 void Apply_Givens_rotation_right(T &x, T &y, T c, T s)
299 { T t1=x, t2=y; x = c*t1 - s*t2; y = gmm::conj(c)*t2 + gmm::conj(s)*t1; }
301 template <
typename MAT,
typename T>
303 MAT &A =
const_cast<MAT &
>(AA);
304 for (
size_type j = 0; j < mat_ncols(A); ++j)
305 Apply_Givens_rotation_left(A(i,j), A(k,j), c, s);
308 template <
typename MAT,
typename T>
310 MAT &A =
const_cast<MAT &
>(AA);
311 for (
size_type j = 0; j < mat_nrows(A); ++j)
312 Apply_Givens_rotation_right(A(j,i), A(j,k), c, s);
void copy(const L1 &l1, L2 &l2)
*/
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
strongest_value_type< V1, V2 >::value_type vect_hp(const V1 &v1, const V2 &v2)
*/
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2_sqr(const V &v)
squared Euclidean norm of a vector.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
void add(const L1 &l1, L2 &l2)
*/
conjugated_return< L >::return_type conjugated(const L &v)
return a conjugated view of the input matrix or vector.
Include the base gmm files.
size_t size_type
used as the common size type in the library