00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SELDON_FILE_ITERATIVE_COCG_CXX
00021
00022 namespace Seldon
00023 {
00024
00026
00044 template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00045 int CoCg(Matrix1& A, Vector1& x, const Vector1& b,
00046 Preconditioner& M, Iteration<Titer> & iter)
00047 {
00048 const int N = A.GetM();
00049 if (N <= 0)
00050 return 0;
00051
00052 typedef typename Vector1::value_type Complexe;
00053 Complexe rho, rho_1(0), alpha, beta, delta, zero;
00054 zero = b(0)*Titer(0);
00055 rho = zero+Titer(1);
00056
00057 Vector1 p(b), q(b), r(b), z(b);
00058 p.Fill(zero); q.Fill(zero); r.Fill(zero); z.Fill(zero);
00059
00060
00061
00062 int success_init = iter.Init(b);
00063 if (success_init != 0)
00064 return iter.ErrorCode();
00065
00066 Copy(b,r);
00067 if (!iter.IsInitGuess_Null())
00068 MltAdd(Complexe(-1), A, x, Complexe(1), r);
00069 else
00070 x.Fill(zero);
00071
00072 iter.SetNumberIteration(0);
00073
00074 while (! iter.Finished(r))
00075 {
00076
00077 M.Solve(A, r, z);
00078
00079
00080 rho = DotProd(r, z);
00081
00082 if (rho == zero)
00083 {
00084 iter.Fail(1, "Cocg breakdown #1");
00085 break;
00086 }
00087
00088 if (iter.First())
00089 Copy(z, p);
00090 else
00091 {
00092 beta = rho / rho_1;
00093 Mlt(beta, p);
00094 Add(Complexe(1), z, p);
00095 }
00096
00097 Mlt(A, p, q);
00098
00099 delta = DotProd(p, q);
00100 if (delta == zero)
00101 {
00102 iter.Fail(2, "Cocg breakdown #2");
00103 break;
00104 }
00105 alpha = rho / delta;
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 ITERATIVE_COCG_CXX
00122 #endif