00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SELDON_FILE_ITERATIVE_GMRES_CXX
00021
00022 namespace Seldon
00023 {
00024
00026
00044 template <class Titer, class MatrixSparse, class Vector1, class Preconditioner>
00045 int Gmres(MatrixSparse& A, Vector1& x, const Vector1& b,
00046 Preconditioner& M, Iteration<Titer> & outer)
00047 {
00048 const int N = A.GetM();
00049 if (N <= 0)
00050 return 0;
00051
00052 typedef typename Vector1::value_type Complexe;
00053 Complexe zero(0);
00054
00055 int m = outer.GetRestart();
00056
00057
00058 std::vector<Vector1> V(m+1, b);
00059
00060
00061
00062
00063 Matrix<Complexe, General, ColUpTriang> H(m+1,m+1); H.Fill(zero);
00064
00065
00066
00067
00068
00069 Vector1 w(b), r(b), u(b);
00070 Vector<Complexe> s(m+1);
00071 s.Fill(zero); w.Fill(zero); r.Fill(zero); u.Fill(zero);
00072
00073 for (int i = 0; i < m+1; i++)
00074 V[i].Fill(zero);
00075
00076 Vector<Complexe> rotations_sin(m+1);
00077 rotations_sin.Fill(zero);
00078 Vector<Titer> rotations_cos(m+1);
00079 rotations_cos.Fill(Titer(0));
00080
00081
00082 Copy(b, w);
00083 if (!outer.IsInitGuess_Null())
00084 MltAdd(Complexe(-1), A, x, Complexe(1), w);
00085 else
00086 x.Fill(zero);
00087
00088
00089 M.Solve(A, w, r);
00090 Titer beta = Norm2(r);
00091
00092
00093 int success_init = outer.Init(r);
00094 if (success_init != 0)
00095 return outer.ErrorCode();
00096
00097
00098 Complexe hi_ip1;
00099
00100 outer.SetNumberIteration(0);
00101
00102 while (! outer.Finished(beta))
00103 {
00104
00105 Copy(r, V[0]);
00106 Mlt(Complexe(Complexe(1)/beta), V[0]);
00107 s.Fill(zero);
00108 s(0) = beta;
00109
00110 int i = 0, k;
00111
00112
00113
00114 Iteration<Titer> inner(outer);
00115 inner.SetNumberIteration(outer.GetNumberIteration());
00116 inner.SetMaxNumberIteration(outer.GetNumberIteration()+m);
00117
00118 do
00119 {
00120
00121 Mlt(A, V[i], u);
00122
00123
00124 M.Solve(A, u, w);
00125
00126
00127 for (k = 0; k <= i; k++)
00128 {
00129
00130 H.Val(k, i) = DotProdConj(V[k], w);
00131 Add(-H(k,i), V[k], w);
00132 }
00133
00134
00135 hi_ip1 = Norm2(w);
00136 Copy(w, V[i+1]);
00137
00138
00139 if (hi_ip1 != zero)
00140 Mlt(Complexe(1)/hi_ip1, V[i+1]);
00141
00142
00143
00144 for (k = 0; k < i; k++)
00145 ApplyRot(H.Val(k,i), H.Val(k+1,i),
00146 rotations_cos(k), rotations_sin(k));
00147
00148
00149
00150 if (hi_ip1 != zero)
00151 {
00152 GenRot(H.Val(i,i), hi_ip1,
00153 rotations_cos(i), rotations_sin(i));
00154
00155
00156
00157 ApplyRot(s(i), s(i+1), rotations_cos(i), rotations_sin(i));
00158 }
00159
00160 ++inner, ++outer, ++i;
00161
00162 } while (! inner.Finished(abs(s(i))));
00163
00164
00165 H.Resize(i, i); s.Resize(i);
00166 Solve(H, s); s.Resize(m+1);
00167
00168
00169 for (k = 0; k < i; k++)
00170 Add(s(k), V[k], x);
00171
00172
00173 Copy(b, w);
00174 MltAdd(Complexe(-1), A, x, Complexe(1), w);
00175 M.Solve(A, w, r);
00176
00177
00178 beta = Norm2(r);
00179 }
00180
00181 return outer.ErrorCode();
00182
00183 }
00184
00185 }
00186
00187 #define SELDON_FILE_ITERATIVE_GMRES_CXX
00188 #endif