00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SELDON_FILE_ITERATIVE_CGNE_CXX
00021
00022 namespace Seldon
00023 {
00024
00026
00040 template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00041 int Cgne(Matrix1& A, Vector1& x, const Vector1& b,
00042 Preconditioner& M, Iteration<Titer> & iter)
00043 {
00044 const int N = A.GetM();
00045 if (N <= 0)
00046 return 0;
00047
00048 typedef typename Vector1::value_type Complexe;
00049 Complexe rho(1), rho_1(0), alpha, beta, delta;
00050 Vector1 p(b), q(b), r(b), z(b);
00051 Titer dp;
00052
00053
00054
00055
00056
00057
00058
00059 Mlt(SeldonTrans, A, b, q);
00060
00061 int success_init = iter.Init(q);
00062 if (success_init != 0)
00063 return iter.ErrorCode();
00064
00065 if (!iter.IsInitGuess_Null())
00066 {
00067
00068 Mlt(A, x, p);
00069 Mlt(SeldonTrans, A, p, r); Mlt(Complexe(-1), r);
00070 Add(Complexe(1), q, r);
00071 }
00072 else
00073 {
00074 Copy(q, r);
00075 x.Zero();
00076 }
00077
00078 dp = Norm2(q);
00079 iter.SetNumberIteration(0);
00080
00081 while (! iter.Finished(dp))
00082 {
00083
00084 M.TransSolve(A, r, q);
00085 M.Solve(A, q, z);
00086
00087 rho = DotProd(r,z);
00088 if (rho == Complexe(0))
00089 {
00090 iter.Fail(1, "Cgne breakdown #1");
00091 break;
00092 }
00093
00094 if (iter.First())
00095 Copy(z, p);
00096 else
00097 {
00098 beta = rho / rho_1;
00099 Mlt(beta, p);
00100 Add(Complexe(1), z, p);
00101 }
00102
00103
00104 Mlt(A, p, q);
00105 Mlt(SeldonTrans, A, q, z);
00106
00107 delta = DotProd(p, z);
00108 if (delta == Complexe(0))
00109 {
00110 iter.Fail(2, "Cgne breakdown #2");
00111 break;
00112 }
00113 alpha = rho / delta;
00114
00115 Add(alpha, p, x);
00116 Add(-alpha, z, r);
00117
00118 rho_1 = rho;
00119 dp = Norm2(r);
00120
00121
00122 ++iter;
00123 ++iter;
00124 }
00125
00126 return iter.ErrorCode();
00127 }
00128
00129
00130 }
00131
00132 #define SELDON_FILE_ITERATIVE_CGNE_CXX
00133 #endif