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_CG_CXX
00022
00023 namespace Seldon
00024 {
00025
00027
00045 template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00046 int Cg(Matrix1& A, Vector1& x, const Vector1& b,
00047 Preconditioner& M, Iteration<Titer> & iter)
00048 {
00049 const int N = A.GetM();
00050 if (N <= 0)
00051 return 0;
00052
00053 typedef typename Vector1::value_type Complexe;
00054 Complexe rho(1), rho_1(1), alpha, beta,delta;
00055 Vector1 p(b), q(b), r(b), z(b);
00056
00057
00058 int success_init = iter.Init(b);
00059 if (success_init != 0)
00060 return iter.ErrorCode();
00061
00062
00063 Copy(b, r);
00064 if (!iter.IsInitGuess_Null())
00065 MltAdd(Complexe(-1), A, x, Complexe(1), r);
00066 else
00067 x.Zero();
00068
00069 iter.SetNumberIteration(0);
00070
00071 while (! iter.Finished(r))
00072 {
00073
00074
00075 M.Solve(A, r, z);
00076
00077
00078 rho = DotProdConj(r, z);
00079
00080 if (rho == Complexe(0) )
00081 {
00082 iter.Fail(1, "Cg breakdown #1");
00083 break;
00084 }
00085
00086 if (iter.First())
00087 Copy(z, p);
00088 else
00089 {
00090
00091 beta = rho / rho_1;
00092 Mlt(beta, p);
00093 Add(Complexe(1), z, p);
00094 }
00095
00096
00097 Mlt(A, p, q);
00098 delta = DotProdConj(p, q);
00099 if (delta == Complexe(0))
00100 {
00101 iter.Fail(2, "Cg breakdown #2");
00102 break;
00103 }
00104 alpha = rho / delta;
00105
00106
00107 Add(alpha, p, x);
00108 Add(-alpha, q, r);
00109
00110 rho_1 = rho;
00111
00112 ++iter;
00113 }
00114
00115 return iter.ErrorCode();
00116 }
00117
00118
00119 }
00120
00121 #define SELDON_FILE_ITERATIVE_CG_CXX
00122 #endif
00123