47   template <
typename T> compare_vp {
 
   48     bool operator()(
const std::pair<T, size_type> &a,
 
   49                     const std::pair<T, size_type> &b)
 const 
   50     { 
return (gmm::abs(a.first) > gmm::abs(b.first)); }
 
   53   struct idgmres_state {
 
   54     size_type m, tb_deb, tb_def, p, k, nb_want, nb_unwant;
 
   55     size_type nb_nolong, tb_deftot, tb_defwant, conv, nb_un, fin;
 
   59       : m(mm), tb_deb(1), tb_def(0), p(pp), k(kk), nb_want(0),
 
   60         nb_unwant(0), nb_nolong(0), tb_deftot(0), tb_defwant(0),
 
   61         conv(0), nb_un(0), fin(0), ok(false); {}
 
   65     : m(mm), tb_deb(1), tb_def(0), p(pp), k(kk), nb_want(0),
 
   66       nb_unwant(0), nb_nolong(0), tb_deftot(0), tb_defwant(0),
 
   67       conv(0), nb_un(0), fin(0), ok(false); {}
 
   70   template <
typename CONT, 
typename IND>
 
   71   apply_permutation(CONT &cont, 
const IND &ind) {
 
   73     std::vector<bool> sorted(m, 
false);
 
   76       if (!sorted[l] && ind[l] != l) {
 
   78         typeid(cont[0]) aux = cont[l];
 
   83         for(k2 = ind[k]; k2 != l; k2 = ind[k]) {
 
  111   template < 
typename Mat, 
typename Vec, 
typename VecB, 
typename Precond,
 
  113   void idgmres(
const Mat &A, Vec &x, 
const VecB &b, 
const Precond &M,
 
  115              iteration &outer, Basis& KS) {
 
  117     typedef typename linalg_traits<Mat>::value_type T;
 
  118     typedef typename number_traits<T>::magnitude_type R;
 
  121     idgmres_state st(m, p, k);
 
  123     std::vector<T> w(vect_size(x)), r(vect_size(x)), u(vect_size(x));
 
  124     std::vector<T> c_rot(m+1), s_rot(m+1), s(m+1);
 
  125     std::vector<T> y(m+1), ztest(m+1), gam(m+1);
 
  126     std::vector<T> gamma(m+1);
 
  127     gmm::dense_matrix<T> H(m+1, m), Hess(m+1, m),
 
  128                          Hobl(m+1, m), W(vect_size(x), m+1);
 
  131     outer.set_rhsnorm(gmm::vect_norm2(b));
 
  132     if (outer.get_rhsnorm() == 0.0) { 
clear(x); 
return; }
 
  134     mult(A, scaled(x, -1.0), b, w);
 
  138     iteration inner = outer;
 
  139     inner.reduce_noisy();
 
  140     inner.set_maxiter(m);
 
  141     inner.set_name(
"GMRes inner iter");
 
  143     while (! outer.finished(beta)) {
 
  145       gmm::copy(gmm::scaled(r, 1.0/beta), KS[0]);
 
  150       inner.set_maxiter(m - st.tb_deb + 1);
 
  151       size_type i = st.tb_deb - 1; inner.init();
 
  156         orthogonalize_with_refinment(KS, mat_col(H, i), i);
 
  158         gmm::scale(KS[i+1], R(1) / a);
 
  160         gmm::copy(mat_col(H, i), mat_col(Hess, i));
 
  161         gmm::copy(mat_col(H, i), mat_col(Hobl, i));
 
  164           Apply_Givens_rotation_left(H(l,i), H(l+1,i), c_rot[l], s_rot[l]);
 
  166         Givens_rotation(H(i,i), H(i+1,i), c_rot[i], s_rot[i]);
 
  167         Apply_Givens_rotation_left(H(i,i), H(i+1,i), c_rot[i], s_rot[i]);
 
  169         Apply_Givens_rotation_left(s[i], s[i+1], c_rot[i], s_rot[i]);
 
  171         ++inner, ++outer, ++i;
 
  172       } 
while (! inner.finished(gmm::abs(s[i])));
 
  174       if (inner.converged()) {
 
  176         upper_tri_solve(H, y, i, 
false);
 
  177         combine(KS, y, x, i);
 
  178         mult(A, gmm::scaled(x, T(-1)), b, w);
 
  186         Apply_Givens_rotation_left(gam[l-1], gam[l], gmm::conj(c_rot[l-1]),
 
  189       mult(KS.mat(), gam, r);
 
  192       mult(Hess, scaled(y, T(-1)), gamma, ztest);
 
  198         T nss = H(m,m-1) / ztest[m];
 
  199         nss /= gmm::abs(nss); 
 
  203         sub_interval SUBI(0, m);
 
  204         add(scaled(sub_vector(ztest, SUBI), -Hobl(m, m-1) / ztest[m]),
 
  205             sub_vector(mat_col(Hobl, m-1), SUBI));
 
  206         Hobl(m, m-1) *= nss * beta / ztest[m];
 
  213         std::vector<std::complex<R> > eval(m);
 
  214         dense_matrix<T> YB(m-st.tb_def, m-st.tb_def);
 
  215         std::vector<char> pure(m-st.tb_def, 0);
 
  218         select_eval(Hobl, eval, YB, pure, st);
 
  223           T 
alpha = Lock(W, Hobl,
 
  224                          sub_matrix(YB,  sub_interval(0, m-st.tb_def)),
 
  225                          sub_interval(st.tb_def, m-st.tb_def),
 
  226                          (st.tb_defwant < p));
 
  233           for (
size_type j = st.tb_def; j < st.tb_deftot; ++j) {
 
  234             if ( pure[j-st.tb_def] == 0)
 
  235               gmm::clear(sub_vector(mat_col(Hobl,j), sub_interval(j+1,m-j)));
 
  236             else if (pure[j-st.tb_def] == 1) {
 
  237               gmm::clear(sub_matrix(Hobl, sub_interval(j+2,m-j-1),
 
  238                                           sub_interval(j, 2)));
 
  241             else GMM_ASSERT3(
false, 
"internal error");
 
  246             size_type mm = std::min(k+st.nb_unwant+st.nb_nolong, m-1);
 
  248             if (eval_sort[m-mm-1].second != R(0)
 
  249                 && eval_sort[m-mm-1].second == -eval_sort[m-mm].second)
 
  252             std::vector<complex<R> > shifts(m-mm);
 
  254               shifts[i] = eval_sort[i].second;
 
  256             apply_shift_to_Arnoldi_factorization(W, Hobl, shifts, mm,
 
  262             st.fin = st.tb_deftot;
 
  269           if (st.nb_nolong + st.nb_unwant > 0) {
 
  271             std::vector<std::complex<R> > eval(m);
 
  272             dense_matrix<T> YB(st.fin, st.tb_deftot);
 
  273             std::vector<char> pure(st.tb_deftot, 0);
 
  275             st.nb_un = st.nb_nolong + st.nb_unwant;
 
  277             select_eval_for_purging(Hobl, eval, YB, pure, st);
 
  279             T 
alpha = Lock(W, Hobl, YB, sub_interval(0, st.fin), ok);
 
  283             for (
size_type j = 0; j < st.tb_deftot; ++j) {
 
  285                 gmm::clear(sub_vector(mat_col(Hobl,j), sub_interval(j+1,m-j)));
 
  286               else if (pure[j] == 1) {
 
  287                 gmm::clear(sub_matrix(Hobl, sub_interval(j+2,m-j-1),
 
  288                                             sub_interval(j, 2)));
 
  291               else GMM_ASSERT3(
false, 
"internal error");
 
  294             gmm::dense_matrix<T> z(st.nb_un, st.fin - st.nb_un);
 
  295             sub_interval SUBI(0, st.nb_un), SUBJ(st.nb_un, st.fin - st.nb_un);
 
  296             sylvester(sub_matrix(Hobl, SUBI),
 
  297                       sub_matrix(Hobl, SUBJ),
 
  298                       sub_matrix(gmm::scaled(Hobl, -T(1)), SUBI, SUBJ), z);
 
  306   template < 
typename Mat, 
typename Vec, 
typename VecB, 
typename Precond >
 
  307     void idgmres(
const Mat &A, Vec &x, 
const VecB &b,
 
  308                  const Precond &M, 
size_type m, iteration& outer) {
 
  309     typedef typename linalg_traits<Mat>::value_type T;
 
  310     modified_gram_schmidt<T> orth(m, vect_size(x));
 
  311     gmres(A, x, b, M, m, outer, orth);
 
  323   template <
typename T, 
typename MATYB>
 
  324   void Lock(gmm::dense_matrix<T> &W, gmm::dense_matrix<T> &H,
 
  325             const MATYB &YB, 
const sub_interval SUB,
 
  326             bool restore, T &ns) {
 
  328     size_type n = mat_nrows(W), m = mat_ncols(W) - 1;
 
  329     size_type ncols = mat_ncols(YB), nrows = mat_nrows(YB);
 
  330     size_type begin = min(SUB); end = max(SUB) - 1;
 
  331     sub_interval SUBR(0, nrows), SUBC(0, ncols);
 
  334     GMM_ASSERT2(((end-begin) == ncols) && (m == mat_nrows(H))
 
  335                 && (m+1 == mat_ncols(H)), 
"dimensions mismatch");
 
  339     dense_matrix<T> QR(n_rows, n_rows);
 
  340     gmmm::copy(YB, sub_matrix(QR, SUBR, SUBC));
 
  341     gmm::clear(submatrix(QR, SUBR, sub_interval(ncols, nrows-ncols)));
 
  344     apply_house_left(QR, sub_matrix(H, SUB));
 
  345     apply_house_right(QR, sub_matrix(H, SUBR, SUB));
 
  346     apply_house_right(QR, sub_matrix(W, sub_interval(0, n), SUB));
 
  353       gmm::dense_matrix tab_p(end - st.tb_deftot, end - st.tb_deftot);
 
  356       for (
size_type j = end-1; j >= st.tb_deftot+2; --j) {
 
  359         std::vector<T> v(jm - st.tb_deftot);
 
  360         sub_interval SUBtot(st.tb_deftot, jm - st.tb_deftot);
 
  361         sub_interval SUBtot2(st.tb_deftot, end - st.tb_deftot);
 
  362         gmm::copy(sub_vector(mat_row(H, j), SUBtot), v);
 
  363         house_vector_last(v);
 
  365         col_house_update(sub_matrix(H, SUBI, SUBtot), v, w);
 
  366         w.resize(end - st.tb_deftot);
 
  367         row_house_update(sub_matrix(H, SUBtot, SUBtot2), v, w);
 
  369                               sub_interval(st.tb_deftot, j-1-st.tb_deftot)));
 
  370         w.resize(end - st.tb_deftot);
 
  371         col_house_update(sub_matrix(tab_p, sub_interval(0, end-st.tb_deftot),
 
  372                                     sub_interval(0, jm-st.tb_deftot)), v, w);
 
  374         col_house_update(sub_matrix(W, sub_interval(0, n), SUBtot), v, w);
 
  379       std::vector<T> d(fin-st.tb_deftot); d[0] = T(1);
 
  384       for (
size_type j = 0; j+1 < end-st.tb_deftot; ++j) {
 
  385         T e = H(st.tb_deftot+j, st.tb_deftot+j-1);
 
  386         d[j+1] = (e == T(0)) ? T(1) :  d[j] * gmm::abs(e) / e;
 
  387         scale(sub_vector(mat_row(H, st.tb_deftot+j+1),
 
  388                          sub_interval(st.tb_deftot, m-st.tb_deftot)), d[j+1]);
 
  389         scale(mat_col(H, st.tb_deftot+j+1), T(1) / d[j+1]);
 
  390         scale(mat_col(W, st.tb_deftot+j+1), T(1) / d[j+1]);
 
  393       alpha = tab_p(end-st.tb_deftot-1, end-st.tb_deftot-1) / d[end-st.tb_deftot-1];
 
  394       alpha /= gmm::abs(alpha);
 
  395       scale(mat_col(W, m), alpha);
 
  409   template<
typename T, 
typename C>
 
  410   apply_shift_to_Arnoldi_factorization(dense_matrix<T> V, dense_matrix<T> H,
 
  414     size_type k1 = 0, num = 0, kend = k+p, kp1 = k + 1;
 
  418     dense_matrix<T> q(1, kend);
 
  420     std::vector<T> hv(3), w(std::max(kend, mat_nrows(V)));
 
  426       if (abs(Lambda[jj].real()) == 0.0) {
 
  429         for (
size_type k1 = 0, k2 = 0; k2 != kend-1; k1 = k2+1) {
 
  431           while (h(k2+1, k2) != T(0) && k2 < kend-1)
 
  434           Givens_rotation(H(k1, k1) - Lambda[jj], H(k1+1, k1), c, s);
 
  436           for (i = k1; i <= k2; ++i) {
 
  438               Givens_rotation(H(i, i-1), H(i+1, i-1), c, s);
 
  444             row_rot(sub_matrix(H, sub_interval(i,2), sub_interval(i, kend-i)),
 
  449             col_rot(sub_matrix(H, sub_interval(0, ip2), sub_interval(i, 2))
 
  453             col_rot(V, c, s, i, i+1);
 
  456             Apply_Givens_rotation_left(q(0,i), q(0,i+1), c, s);
 
  476           for (
size_type k1 = 0, k3 = 0; k3 != kend-2; k1 = k3+1) {
 
  478             while (h(k3+1, k3) != T(0) && k3 < kend-2)
 
  483             x = H(k1,k1) * H(k1,k1) + H(k1,k2) * H(k2,k1)
 
  484               - 2.0*Lambda[jj].real() * H(k1,k1) + gmm::abs_sqr(Lambda[jj]);
 
  485             y = H(k2,k1) * (H(k1,k1) + H(k2,k2) - 2.0*Lambda[jj].real());
 
  486             z = H(k2+1,k2) * H(k2,k1);
 
  497               hv[0] = x; hv[1] = y; hv[2] = z;
 
  504               row_house_update(sub_matrix(H, sub_interval(i, 2),
 
  505                                              sub_interval(i, kend-i)),
 
  512               col_house_update(sub_matrix(H, sub_interval(0, ip3),
 
  518               w.resize(mat_nrows(V));
 
  519               col_house_update(sub_matrix(V, sub_interval(0, mat_nrows(V)),
 
  525               col_house_update(sub_matrix(q, sub_interval(0,1),
 
  537             Givens_rotation(H(i, i-1), H(i+1, i-1), c, s);
 
  543           row_rot(sub_matrix(H, sub_interval(i,2), sub_interval(i, kend-i)),
 
  548           col_rot(sub_matrix(H, sub_interval(0, ip2), sub_interval(i, 2))
 
  552           col_rot(V, c, s, i, i+1);
 
  555           Apply_Givens_rotation_left(q(0,i), q(0,i+1), c, s);
 
  563     scale(mat_col(V, kend), q(0, k));
 
  565     if (k < mat_nrows(H)) {
 
  567         gmm::copy(mat_col(V, kend), mat_col(V, k));
 
  571         gmm::add(scaled(mat_col(V, kend), H(kend, kend-1)),
 
  572                  scaled(mat_col(V, k), H(k, k-1)), mat_col(V, k));
 
  576     scale(mat_col(V, kend), T(1) / H(k, k-1));
 
  581   template<
typename MAT, 
typename EVAL, 
typename PURE>
 
  582   void select_eval(
const MAT &Hobl, EVAL &eval, MAT &YB, PURE &pure,
 
  585     typedef typename linalg_traits<MAT>::value_type T;
 
  586     typedef typename number_traits<T>::magnitude_type R;
 
  591     col_matrix< std::vector<T> > evect(m-st.tb_def, m-st.tb_def);
 
  593     std::vector<R> ritznew(m, T(-1));
 
  597     sub_interval SUB1(st.tb_def, m-st.tb_def);
 
  598     implicit_qr_algorithm(sub_matrix(Hobl, SUB1),
 
  599                           sub_vector(eval, SUB1), evect);
 
  600     sub_interval SUB2(0, st.tb_def);
 
  601     implicit_qr_algorithm(sub_matrix(Hobl, SUB2),
 
  602                           sub_vector(eval, SUB2), );
 
  604     for (
size_type l = st.tb_def; l < m; ++l)
 
  605       ritznew[l] = gmm::abs(evect(m-st.tb_def-1, l-st.tb_def) * Hobl(m, m-1));
 
  607     std::vector< std::pair<T, size_type> > eval_sort(m);
 
  609       eval_sort[l] = std::pair<T, size_type>(eval[l], l);
 
  610     std::sort(eval_sort.begin(), eval_sort.end(), compare_vp());
 
  612     std::vector<size_type> index(m);
 
  613     for (
size_type l = 0; l < m; ++l) index[l] = eval_sort[l].second;
 
  615     std::vector<bool> kept(m, 
false);
 
  616     std::fill(kept.begin(), kept.begin()+st.tb_def, 
true);
 
  618     apply_permutation(eval, index);
 
  619     apply_permutation(evect, index);
 
  620     apply_permutation(ritznew, index);
 
  621     apply_permutation(kept, index);
 
  640     st.nb_want = 0, st.nb_unwant = 0, st.nb_nolong = 0;
 
  643     for (j = 0, ind = 0; j < m-p; ++j) {
 
  644       if (ritznew[j] == R(-1)) {
 
  645         if (std::imag(eval[j]) != R(0)) {
 
  646           st.nb_nolong += 2; ++j; 
 
  650         if (ritznew[j] < tol_vp * gmm::abs(eval[j])) {
 
  652           for (
size_type l = 0, l < m-st.tb_def; ++l)
 
  653             YB(l, ind) = std::real(evect(l, j));
 
  655           ++j; ++st.nb_unwant; ind++;
 
  657           if (std::imag(eval[j]) != R(0)) {
 
  658             for (
size_type l = 0, l < m-st.tb_def; ++l)
 
  659               YB(l, ind) = std::imag(evect(l, j));
 
  674       if (ritznew[j] != R(-1)) {
 
  676         for (
size_type l = 0, l < m-st.tb_def; ++l)
 
  677           YB(l, ind) = std::real(evect(l, j));
 
  683         if (ritznew[j] < tol_vp * gmm::abs(eval[j])) {
 
  684           for (
size_type l = 0, l < m-st.tb_def; ++l)
 
  685             YB(l, ind) = std::imag(evect(l, j));
 
  697     std::vector<T> shift(m - st.tb_def - st.nb_want - st.nb_unwant);
 
  700         shift[i++] = eval[j];
 
  707     size_type st.tb_deftot = st.tb_def + st.conv;
 
  708     size_type st.tb_defwant = st.tb_def + st.nb_want - st.nb_nolong;
 
  710     sub_interval SUBYB(0, st.conv);
 
  712     if ( st.tb_defwant >= p ) { 
 
  715       st.nb_want = p + st.nb_nolong - st.tb_def;
 
  718       if ( pure[st.conv - st.nb_want + 1] == 2 ) {
 
  719         ++st.nb_want; st.tb_defwant = ++p;
 
  722       SUBYB = sub_interval(st.conv - st.nb_want, st.nb_want);
 
  725       st.conv = st.nb_want;
 
  726       st.tb_deftot = st.tb_def + st.conv;
 
  733   template<
typename MAT, 
typename EVAL, 
typename PURE>
 
  734   void select_eval_for_purging(
const MAT &Hobl, EVAL &eval, MAT &YB,
 
  735                                PURE &pure, idgmres_state &st) {
 
  737     typedef typename linalg_traits<MAT>::value_type T;
 
  738     typedef typename number_traits<T>::magnitude_type R;
 
  743     col_matrix< std::vector<T> > evect(st.tb_deftot, st.tb_deftot);
 
  745     sub_interval SUB1(0, st.tb_deftot);
 
  746     implicit_qr_algorithm(sub_matrix(Hobl, SUB1),
 
  747                           sub_vector(eval, SUB1), evect);
 
  748     std::fill(eval.begin() + st.tb_deftot, eval.end(), std::complex<R>(0));
 
  750     std::vector< std::pair<T, size_type> > eval_sort(m);
 
  752       eval_sort[l] = std::pair<T, size_type>(eval[l], l);
 
  753     std::sort(eval_sort.begin(), eval_sort.end(), compare_vp());
 
  755     std::vector<bool> sorted(m);
 
  756     std::fill(sorted.begin(), sorted.end(), 
false);
 
  758     std::vector<size_type> ind(m);
 
  759     for (
size_type l = 0; l < m; ++l) ind[l] = eval_sort[l].second;
 
  761     std::vector<bool> kept(m, 
false);
 
  762     std::fill(kept.begin(), kept.begin()+st.tb_def, 
true);
 
  764     apply_permutation(eval, ind);
 
  765     apply_permutation(evect, ind);
 
  768     for (j = 0; j < st.tb_deftot; ++j) {
 
  770       for (
size_type l = 0, l < st.tb_deftot; ++l)
 
  771         YB(l, j) = std::real(evect(l, j));
 
  773       if (std::imag(eval[j]) != R(0)) {
 
  774         for (
size_type l = 0, l < m-st.tb_def; ++l)
 
  775           YB(l, j+1) = std::imag(evect(l, j));
 
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.
 
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)
*/
 
void qr_factor(const MAT1 &A_)
QR factorization using Householder method (complex and real version).
 
Sylvester equation solver.
 
Include the base gmm files.
 
void gmres(const Mat &A, Vec &x, const VecB &b, const Precond &M, int restart, iteration &outer, Basis &KS)
Generalized Minimum Residual.
 
size_t size_type
used as the common size type in the library
 
size_type alpha(short_type n, short_type d)
Return the value of  which is the number of monomials of a polynomial of  variables and degree .