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_TFQMR_CXX
00022
00023 namespace Seldon
00024 {
00025
00027
00044 template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00045 int TfQmr(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 Vector1 tmp(b), r0(b), v(b), h(b), w(b),
00053 y1(b), g(b), y0(b), rtilde(b), d(b);
00054
00055 typedef typename Vector1::value_type Complexe;
00056 Complexe sigma, alpha, beta, eta, rho, rho0;
00057 Titer c, kappa, tau, theta;
00058
00059 tmp.Zero();
00060
00061
00062 Copy(b, tmp);
00063 if (!iter.IsInitGuess_Null())
00064 MltAdd(Complexe(-1), A, x, Complexe(1), tmp);
00065 else
00066 x.Zero();
00067
00068 M.Solve(A, tmp, r0);
00069
00070
00071 int success_init = iter.Init(r0);
00072 if (success_init != 0)
00073 return iter.ErrorCode();
00074
00075
00076 Copy(r0, w);
00077 Copy(r0, y1);
00078
00079
00080 Copy(y1, v);
00081 Mlt(A, v, tmp);
00082 M.Solve(A, tmp, v);
00083 ++iter;
00084
00085 Copy(v, g);
00086
00087
00088 d.Zero();
00089
00090
00091 tau = Norm2(r0);
00092
00093
00094 theta = 0.0;
00095 eta = 0.0;
00096
00097
00098 Copy(r0, rtilde);
00099
00100
00101 rho = DotProd(rtilde, r0);
00102 rho0 = rho;
00103
00104 iter.SetNumberIteration(0);
00105
00106 for (;;)
00107 {
00108
00109
00110
00111
00112 sigma = DotProd(rtilde, v);
00113
00114 if (sigma == Complexe(0))
00115 {
00116 iter.Fail(1, "Tfqmr breakdown: sigma=0");
00117 break;
00118 }
00119 alpha = rho / sigma;
00120
00121
00122 Copy(y1, y0);
00123 Add(-alpha, v, y0);
00124
00125
00126 Copy(y0, h);
00127 Mlt(A, h, tmp);
00128 M.Solve(A, tmp, h);
00129
00130
00131
00132
00133
00134 Add(-alpha, g, w);
00135
00136 if (alpha == Complexe(0))
00137 {
00138 iter.Fail(2, "Tfqmr breakdown: alpha=0");
00139 break;
00140 }
00141
00142 Mlt(theta * theta * eta / alpha,d);
00143 Add(Complexe(1), y1, d);
00144
00145
00146 if (tau == Titer(0))
00147 {
00148 iter.Fail(3, "Tfqmr breakdown: tau=0");
00149 break;
00150 }
00151 theta = Norm2(w) / tau;
00152
00153
00154 c = Titer(1) / sqrt(Titer(1) + theta * theta);
00155
00156
00157 tau = tau * c * theta;
00158
00159
00160 eta = c * c * alpha;
00161
00162
00163 Add(eta, d, x);
00164
00165 kappa = tau * sqrt( 2.* (iter.GetNumberIteration()+1) );
00166
00167
00168 if ( iter.Finished(kappa) )
00169 {
00170 break;
00171 }
00172 ++iter;
00173
00174 Copy(h, g);
00175
00176
00177
00178
00179 Add(-alpha,g,w);
00180
00181 Mlt(theta * theta * eta / alpha,d);
00182 Add(Complexe(1), y0, d);
00183
00184 if (tau == Titer(0))
00185 {
00186 iter.Fail(4, "Tfqmr breakdown: tau=0");
00187 break;
00188 }
00189 theta = Norm2(w) / tau;
00190
00191
00192 c = Titer(1) / sqrt(Titer(1) + theta * theta);
00193
00194
00195 tau = tau * c * theta;
00196
00197
00198 eta = c * c * alpha;
00199
00200
00201 Add(eta, d, x);
00202
00203
00204 kappa = tau * sqrt(2.* (iter.GetNumberIteration()+1) + 1.);
00205
00206
00207 if ( iter.Finished(kappa) )
00208 {
00209 break;
00210 }
00211
00212
00213
00214
00215 rho0 = rho;
00216 rho = DotProd(rtilde, w);
00217 if (rho0 == Complexe(0))
00218 {
00219 iter.Fail(5, "tfqmr breakdown: beta=0");
00220 break;
00221 }
00222 beta = rho/rho0;
00223
00224
00225 Copy(w, y1);
00226 Add(beta, y0, y1);
00227
00228
00229 Copy(y1, g);
00230 Mlt(A, g, tmp);
00231 M.Solve(A, tmp, g);
00232
00233
00234
00235 Mlt(beta*beta, v);
00236 Add(beta, h, v);
00237 Add(Complexe(1), g, v);
00238
00239 ++iter;
00240 }
00241
00242 return iter.ErrorCode();
00243 }
00244
00245 }
00246
00247 #define SELDON_FILE_ITERATIVE_TFQMR_CXX
00248 #endif