39 #ifndef GMM_DENSE_HOUSEHOLDER_H 
   40 #define GMM_DENSE_HOUSEHOLDER_H 
   51   template <
typename Matrix, 
typename VecX, 
typename VecY>
 
   52   inline void rank_one_update(Matrix &A, 
const VecX& x,
 
   53                               const VecY& y, row_major) {
 
   54     typedef typename linalg_traits<Matrix>::value_type T;
 
   56     GMM_ASSERT2(N <= vect_size(x) && mat_ncols(A) <= vect_size(y),
 
   57                 "dimensions mismatch");
 
   58     typename linalg_traits<VecX>::const_iterator itx = vect_const_begin(x);
 
   59     for (
size_type i = 0; i < N; ++i, ++itx) {
 
   60       typedef typename linalg_traits<Matrix>::sub_row_type row_type;
 
   61       row_type row = mat_row(A, i);
 
   62       typename linalg_traits<typename org_type<row_type>::t>::iterator
 
   63         it = vect_begin(row), ite = vect_end(row);
 
   64       typename linalg_traits<VecY>::const_iterator ity = vect_const_begin(y);
 
   66       for (; it != ite; ++it, ++ity) *it += conj_product(*ity, tx);
 
   70   template <
typename Matrix, 
typename VecX, 
typename VecY>
 
   71   inline void rank_one_update(Matrix &A, 
const VecX& x,
 
   72                               const VecY& y, col_major) {
 
   73     typedef typename linalg_traits<Matrix>::value_type T;
 
   75     GMM_ASSERT2(mat_nrows(A) <= vect_size(x) && M <= vect_size(y),
 
   76                 "dimensions mismatch");
 
   77     typename linalg_traits<VecY>::const_iterator ity = vect_const_begin(y);
 
   78     for (
size_type i = 0; i < M; ++i, ++ity) {
 
   79       typedef typename linalg_traits<Matrix>::sub_col_type col_type;
 
   80       col_type col = mat_col(A, i);
 
   81       typename linalg_traits<typename org_type<col_type>::t>::iterator
 
   82         it = vect_begin(col), ite = vect_end(col);
 
   83       typename linalg_traits<VecX>::const_iterator itx = vect_const_begin(x);
 
   85       for (; it != ite; ++it, ++itx) *it += conj_product(ty, *itx);
 
   90   template <
typename Matrix, 
typename VecX, 
typename VecY>
 
   91   inline void rank_one_update(
const Matrix &AA, 
const VecX& x,
 
   93     Matrix& A = 
const_cast<Matrix&
>(AA);
 
   94     rank_one_update(A, x, y, 
typename principal_orientation_type<
typename 
   95                     linalg_traits<Matrix>::sub_orientation>::potype());
 
  103   template <
typename Matrix, 
typename VecX, 
typename VecY>
 
  104   inline void rank_two_update(Matrix &A, 
const VecX& x,
 
  105                               const VecY& y, row_major) {
 
  106     typedef typename linalg_traits<Matrix>::value_type value_type;
 
  108     GMM_ASSERT2(N <= vect_size(x) && mat_ncols(A) <= vect_size(y),
 
  109                 "dimensions mismatch");
 
  110     typename linalg_traits<VecX>::const_iterator itx1 = vect_const_begin(x);
 
  111     typename linalg_traits<VecY>::const_iterator ity2 = vect_const_begin(y);
 
  112     for (
size_type i = 0; i < N; ++i, ++itx1, ++ity2) {
 
  113       typedef typename linalg_traits<Matrix>::sub_row_type row_type;
 
  114       row_type row = mat_row(A, i);
 
  115       typename linalg_traits<typename org_type<row_type>::t>::iterator
 
  116         it = vect_begin(row), ite = vect_end(row);
 
  117       typename linalg_traits<VecX>::const_iterator itx2 = vect_const_begin(x);
 
  118       typename linalg_traits<VecY>::const_iterator ity1 = vect_const_begin(y);
 
  119       value_type tx = *itx1, ty = *ity2;
 
  120       for (; it != ite; ++it, ++ity1, ++itx2)
 
  121         *it += conj_product(*ity1, tx) + conj_product(*itx2, ty);
 
  125   template <
typename Matrix, 
typename VecX, 
typename VecY>
 
  126   inline void rank_two_update(Matrix &A, 
const VecX& x,
 
  127                               const VecY& y, col_major) {
 
  128     typedef typename linalg_traits<Matrix>::value_type value_type;
 
  130     GMM_ASSERT2(mat_nrows(A) <= vect_size(x) && M <= vect_size(y),
 
  131                 "dimensions mismatch");
 
  132     typename linalg_traits<VecX>::const_iterator itx2 = vect_const_begin(x);
 
  133     typename linalg_traits<VecY>::const_iterator ity1 = vect_const_begin(y);
 
  134     for (
size_type i = 0; i < M; ++i, ++ity1, ++itx2) {
 
  135       typedef typename linalg_traits<Matrix>::sub_col_type col_type;
 
  136       col_type col = mat_col(A, i);
 
  137       typename linalg_traits<typename org_type<col_type>::t>::iterator
 
  138         it = vect_begin(col), ite = vect_end(col);
 
  139       typename linalg_traits<VecX>::const_iterator itx1 = vect_const_begin(x);
 
  140       typename linalg_traits<VecY>::const_iterator ity2 = vect_const_begin(y);
 
  141       value_type ty = *ity1, tx = *itx2;
 
  142       for (; it != ite; ++it, ++itx1, ++ity2)
 
  143         *it += conj_product(ty, *itx1) + conj_product(tx, *ity2);
 
  148   template <
typename Matrix, 
typename VecX, 
typename VecY>
 
  149   inline void rank_two_update(
const Matrix &AA, 
const VecX& x,
 
  151     Matrix& A = 
const_cast<Matrix&
>(AA);
 
  152     rank_two_update(A, x, y, 
typename principal_orientation_type<
typename 
  153                     linalg_traits<Matrix>::sub_orientation>::potype());
 
  161   template <
typename VECT> 
void house_vector(
const VECT &VV) {
 
  162     VECT &V = 
const_cast<VECT &
>(VV);
 
  163     typedef typename linalg_traits<VECT>::value_type T;
 
  164     typedef typename number_traits<T>::magnitude_type R;
 
  166     R mu = 
vect_norm2(V), abs_v0 = gmm::abs(V[0]);
 
  168       gmm::scale(V, (abs_v0 == R(0)) ? T(R(1) / mu)
 
  169                                      : (safe_divide(T(abs_v0), V[0]) / (abs_v0 + mu)));
 
  170     if (gmm::real(V[vect_size(V)-1]) * R(0) != R(0))
 
  175   template <
typename VECT> 
void house_vector_last(
const VECT &VV) {
 
  176     VECT &V = 
const_cast<VECT &
>(VV);
 
  177     typedef typename linalg_traits<VECT>::value_type T;
 
  178     typedef typename number_traits<T>::magnitude_type R;
 
  181     R mu = 
vect_norm2(V), abs_v0 = gmm::abs(V[m-1]);
 
  183       gmm::scale(V, (abs_v0 == R(0)) ? T(R(1) / mu)
 
  184                                      : ((abs_v0 / V[m-1]) / (abs_v0 + mu)));
 
  185     if (gmm::real(V[0]) * R(0) != R(0))
 
  195   template <
typename MAT, 
typename VECT1, 
typename VECT2> 
inline 
  196   void row_house_update(
const MAT &AA, 
const VECT1 &V, 
const VECT2 &WW) {
 
  197     VECT2 &W = 
const_cast<VECT2 &
>(WW); MAT &A = 
const_cast<MAT &
>(AA);
 
  198     typedef typename linalg_traits<MAT>::value_type value_type;
 
  199     typedef typename number_traits<value_type>::magnitude_type magnitude_type;
 
  203     rank_one_update(A, V, W);
 
  207   template <
typename MAT, 
typename VECT1, 
typename VECT2> 
inline 
  208   void col_house_update(
const MAT &AA, 
const VECT1 &V, 
const VECT2 &WW) {
 
  209     VECT2 &W = 
const_cast<VECT2 &
>(WW); MAT &A = 
const_cast<MAT &
>(AA);
 
  210     typedef typename linalg_traits<MAT>::value_type value_type;
 
  211     typedef typename number_traits<value_type>::magnitude_type magnitude_type;
 
  215     rank_one_update(A, W, V);
 
  224   template <
typename MAT1, 
typename MAT2>
 
  225   void Hessenberg_reduction(
const MAT1& AA, 
const MAT2 &QQ, 
bool compute_Q){
 
  226     MAT1& A = 
const_cast<MAT1&
>(AA); MAT2& Q = 
const_cast<MAT2&
>(QQ);
 
  227     typedef typename linalg_traits<MAT1>::value_type value_type;
 
  228     if (compute_Q) 
gmm::copy(identity_matrix(), Q);
 
  229     size_type n = mat_nrows(A); 
if (n < 2) 
return;
 
  230     std::vector<value_type> v(n), w(n);
 
  231     sub_interval SUBK(0,n);
 
  233       sub_interval SUBI(k, n-k), SUBJ(k-1,n-k+1);
 
  235       for (
size_type j = k; j < n; ++j) v[j-k] = A(j, k-1);
 
  237       row_house_update(sub_matrix(A, SUBI, SUBJ), v, sub_vector(w, SUBJ));
 
  238       col_house_update(sub_matrix(A, SUBK, SUBI), v, w);
 
  240       if (compute_Q) col_house_update(sub_matrix(Q, SUBK, SUBI), v, w);
 
  248   template <
typename MAT1, 
typename MAT2>
 
  249   void Householder_tridiagonalization(
const MAT1 &AA, 
const MAT2 &QQ,
 
  251     MAT1 &A = 
const_cast<MAT1 &
>(AA); MAT2 &Q = 
const_cast<MAT2 &
>(QQ);
 
  252     typedef typename linalg_traits<MAT1>::value_type T;
 
  253     typedef typename number_traits<T>::magnitude_type R;
 
  255     size_type n = mat_nrows(A); 
if (n < 2) 
return;
 
  256     std::vector<T> v(n), p(n), w(n), ww(n);
 
  257     sub_interval SUBK(0,n);
 
  260       sub_interval SUBI(k, n-k);
 
  261       v.resize(n-k); p.resize(n-k); w.resize(n-k);
 
  263         { v[l-k] = w[l-k] = A(l, k-1); A(l, k-1) = A(k-1, l) = T(0); }
 
  266       A(k-1, k) = gmm::conj(A(k, k-1) = w[0] - T(2)*v[0]*
vect_hp(w, v)/norm);
 
  268       gmm::mult(sub_matrix(A, SUBI), gmm::scaled(v, T(-2) / norm), p);
 
  270       rank_two_update(sub_matrix(A, SUBI), v, w);
 
  273         col_house_update(sub_matrix(Q, SUBK, SUBI), v, ww);
 
  281   template <
typename T> 
void Givens_rotation(T a, T b, T &c, T &s) {
 
  282     typedef typename number_traits<T>::magnitude_type R;
 
  283     R aa = gmm::abs(a), bb = gmm::abs(b);
 
  284     if (bb == R(0)) { c = T(1); s = T(0);   
return; }
 
  285     if (aa == R(0)) { c = T(0); s = b / bb; 
return; }
 
  287       { T t = -safe_divide(a,b); s = T(R(1) / (sqrt(R(1)+gmm::abs_sqr(t)))); c = s * t; }
 
  289       { T t = -safe_divide(b,a); c = T(R(1) / (sqrt(R(1)+gmm::abs_sqr(t)))); s = c * t; }
 
  293   template <
typename T> 
inline 
  294   void Apply_Givens_rotation_left(T &x, T &y, T c, T s)
 
  295   { T t1=x, t2=y; x = gmm::conj(c)*t1 - gmm::conj(s)*t2; y = c*t2 + s*t1; }
 
  298   template <
typename T> 
inline 
  299   void Apply_Givens_rotation_right(T &x, T &y, T c, T s)
 
  300   { T t1=x, t2=y; x = c*t1 - s*t2; y = gmm::conj(c)*t2 + gmm::conj(s)*t1; }
 
  302   template <
typename MAT, 
typename T>
 
  304     MAT &A = 
const_cast<MAT &
>(AA); 
 
  305     for (
size_type j = 0; j < mat_ncols(A); ++j)
 
  306       Apply_Givens_rotation_left(A(i,j), A(k,j), c, s);
 
  309   template <
typename MAT, 
typename T>
 
  311     MAT &A = 
const_cast<MAT &
>(AA); 
 
  312     for (
size_type j = 0; j < mat_nrows(A); ++j)
 
  313       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