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_BICGCR_CXX
00022
00023 namespace Seldon
00024 {
00025
00027
00044 template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00045 int BiCgcr(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, mu, alpha, beta, tau;
00054 Vector1 v(b), w(b), s(b), z(b), p(b), a(b);
00055 v.Zero(); w.Zero(); s.Zero(); z.Zero(); p.Zero(); a.Zero();
00056
00057
00058 int success_init = iter.Init(b);
00059 if (success_init != 0)
00060 return iter.ErrorCode();
00061
00062
00063 Copy(b, v);
00064 if (!iter.IsInitGuess_Null())
00065 MltAdd(Complexe(-1), A, x, Complexe(1), v);
00066 else
00067 x.Zero();
00068
00069 iter.SetNumberIteration(0);
00070
00071 M.Solve(A, v, s); Copy(s, p);
00072
00073 Mlt(A, p, a); M.Solve(A, a, w);
00074
00075 ++iter;
00076
00077 while (! iter.Finished(v))
00078 {
00079 rho = DotProd(w, v);
00080 mu = DotProd(w, a);
00081
00082
00083 if (mu == Complexe(0))
00084 {
00085 iter.Fail(1, "Bicgcr breakdown #1");
00086 break;
00087 }
00088 alpha = rho/mu;
00089 Add(alpha, p, x);
00090
00091
00092
00093 Add(-alpha, a, v);
00094 Add(-alpha, w, s);
00095
00096 Mlt(A, s, z);
00097 tau = DotProd(w, z);
00098
00099 if (tau == Complexe(0))
00100 {
00101 iter.Fail(2, "Bicgcr breakdown #2");
00102 break;
00103 }
00104
00105 beta = tau/mu;
00106
00107 Mlt(Complexe(-beta), p);
00108 Add(Complexe(1), s, p);
00109 Mlt(Complexe(-beta), a);
00110 Add(Complexe(1), z, a);
00111
00112 M.Solve(A, a, w);
00113
00114 ++iter;
00115 }
00116
00117 return iter.ErrorCode();
00118 }
00119
00120 }
00121
00122 #define SELDON_FILE_ITERATIVE_BICGCR_CXX
00123 #endif