00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SELDON_FILE_ITERATIVE_GCR_CXX
00022
00023 namespace Seldon
00024 {
00025
00027
00045 template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00046 int Gcr(Matrix1& A, Vector1& x, const Vector1& b,
00047 Preconditioner& M, Iteration<Titer> & outer)
00048 {
00049 const int N = A.GetM();
00050 if (N <= 0)
00051 return 0;
00052
00053 typedef typename Vector1::value_type Complexe;
00054 int m = outer.GetRestart();
00055
00056 int success_init = outer.Init(b);
00057 if (success_init != 0)
00058 return outer.ErrorCode();
00059
00060 std::vector<Vector1> p(m+1, b), w(m+1, b);
00061
00062 Vector<Complexe> beta(m+1);
00063
00064 Vector1 r(b), q(b), u(b);
00065
00066 for (int i = 0; i < (m+1); i++)
00067 {
00068 p[i].Zero();
00069 w[i].Zero();
00070 }
00071
00072
00073 Copy(b,u);
00074 if (!outer.IsInitGuess_Null())
00075 MltAdd(Complexe(-1), A, x, Complexe(1), u);
00076 else
00077 x.Zero();
00078
00079 M.Solve(A, u, r);
00080
00081 Complexe alpha,delta;
00082
00083 Titer normr = Norm2(r);
00084 outer.SetNumberIteration(0);
00085
00086 while (! outer.Finished(r))
00087 {
00088
00089 Iteration<Titer> inner(outer);
00090 inner.SetNumberIteration(outer.GetNumberIteration());
00091 inner.SetMaxNumberIteration(outer.GetNumberIteration()+m);
00092 Copy(r, p[0]);
00093 Mlt(Titer(1)/normr, p[0]);
00094
00095 int j = 0;
00096
00097 while (! inner.Finished(r) )
00098 {
00099
00100 Mlt(A, p[j], u);
00101
00102
00103 M.Solve(A, u, w[j]);
00104
00105 beta(j) = DotProdConj(w[j], w[j]);
00106 if (beta(j) == Complexe(0))
00107 {
00108 outer.Fail(1, "Gcr breakdown #1");
00109 break;
00110 }
00111
00112
00113
00114 alpha = DotProdConj(w[j], r) / beta(j);
00115 Add(alpha, p[j], x);
00116 Add(-alpha, w[j], r);
00117
00118 ++inner;
00119 ++outer;
00120
00121 Mlt(A, r, u);
00122 M.Solve(A, u, q);
00123
00124 Copy(r, p[j+1]);
00125
00126
00127 for (int i = 0; i <= j; i++)
00128 {
00129 delta = -DotProdConj(w[i], q)/beta(i);
00130 Add(delta, p[i], p[j+1]);
00131 }
00132
00133 ++inner;
00134 ++outer;
00135 ++j;
00136 }
00137 normr = Norm2(r);
00138 }
00139
00140 return outer.ErrorCode();
00141 }
00142
00143 }
00144
00145 #define SELDON_FILE_ITERATIVE_GCR_CXX
00146 #endif