public void MakeStep(out int iter, out double residual) { if (!init) { throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно"); } if (currentIter % 20 == 0) { r_prev = A.LSolve(b.Add(A.Multiply(xk), -1), true); r0 = r_prev.Clone(); z = A.USolve(r_prev.Clone(), true); dotproduct_rr = r_prev.DotProduct(r_prev); dotproduct_rprevr0 = dotproduct_rr; } currentIter++; iter = currentIter; LAUz = A.LSolve(A.Multiply(A.USolve(z, true)), true); var alfa = dotproduct_rprevr0 / (LAUz.DotProduct(r0)); var p = r_prev.Add(LAUz, -alfa); LAUp = A.LSolve(A.Multiply(A.USolve(p, true)), true); var gamma = (LAUp.DotProduct(p)) / (LAUp.DotProduct(LAUp)); xk = xk.Add(z, alfa).Add(p, gamma); r = p.Add(LAUp, -gamma); dotproduct_rkr0 = r.DotProduct(r0); var betta = alfa * dotproduct_rkr0 / (gamma * dotproduct_rprevr0); z = r.Add(z, betta).Add(LAUz, -betta * gamma); dotproduct_rprevr0 = dotproduct_rkr0; r_prev = r; dotproduct_rr = r.DotProduct(r); if (Double.IsNaN(alfa) || Double.IsNaN(betta) || Double.IsNaN(gamma)) { residual = -1; return; } x = A.USolve(xk, true); residual = Math.Sqrt(dotproduct_rr) / norm_b; }
public void MakeStep(out int iter, out double residual) { if (!init) { throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно"); } currentIter++; //x_k=(L+D)^(-1)*(b-Ux) var x_k = A.LSolve(b.Add(Ux, -1), true); double w = 1.0; double tempResidual = Double.MaxValue; while (w >= 0.1) { ////???????????????? for (int i = 0; i < x.Size; i++) { x_temp[i] = w * x_k[i] + (1 - w) * x[i]; } ////???????????????? Ux = Ux = A.UMult(x_temp, false, 0); //tempResidual = ||b - (Ux+Lx+Dx)|| / ||b|| tempResidual = Ux.Add(A.LMult(x_temp, false, 0)).Add(A.Diagonal.HadamardProduct(x_temp)).Add(b, -1).Norm / norm_b; w -= 0.1; if (tempResidual < lastResidual) { break; } } lastResidual = tempResidual; ////???????????????? for (int i = 0; i < x.Size; i++) { x[i] = x_temp[i]; } ////??????????????? residual = lastResidual; iter = currentIter; }
public IVector InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false) { if (malloc) { x = new Vector(x0.Size); } else { x = x0; } xk = x0; this.b = b; this.A = A; norm_b = b.Norm; currentIter = 0; r_prev = A.LSolve(b.Add(A.Multiply(xk), -1), true); r0 = r_prev.Clone(); z = A.USolve(r_prev.Clone(), true); dotproduct_rr = r_prev.DotProduct(r_prev); dotproduct_rprevr0 = dotproduct_rr; init = true; return(x); }
public IVector LSolve(IVector x, bool UseDiagonal) { return(linear.LSolve(x, UseDiagonal)); }