public Vector Start_Solver(CSlR_Matrix A, Vector F, Preconditioner.Type_Preconditioner PREC) { switch (PREC) { case Preconditioner.Type_Preconditioner.Diagonal_Preconditioner: { Preconditioner = new Diagonal_Preconditioner(A); break; } case Preconditioner.Type_Preconditioner.LU_Decomposition: { Preconditioner = new LU_Preconditioner(A); break; } } int n = A.N; Vector RES = new Vector(n); for (int i = 0; i < n; i++) { RES.Elem[i] = 0.0; } Vector r = new Vector(n); Vector rs = new Vector(n); Vector p = new Vector(n); Vector ps = new Vector(n); Vector vec = new Vector(n); Vector vec2 = new Vector(n); double alpha, beta, sc1, sc2; bool Flag = true; A.Mult_MV(RES, vec); for (int i = 0; i < n; i++) { r.Elem[i] = F.Elem[i] - vec.Elem[i]; } Preconditioner.Start_Preconditioner(r, ps); for (int i = 0; i < n; i++) { r.Elem[i] = ps.Elem[i]; rs.Elem[i] = ps.Elem[i]; p.Elem[i] = ps.Elem[i]; } while (Flag && Iter < Max_Iter) { sc1 = r * rs; A.Mult_MV(p, vec); Preconditioner.Start_Preconditioner(vec, vec2); sc2 = vec2 * ps; alpha = sc1 / sc2; for (int i = 0; i < n; i++) { RES.Elem[i] += alpha * p.Elem[i]; r.Elem[i] -= alpha * vec2.Elem[i]; } Preconditioner.Start_Tr_Preconditioner(ps, vec); A.Mult_MtV(vec, vec2); for (int i = 0; i < n; i++) { rs.Elem[i] -= alpha * vec2.Elem[i]; } sc2 = r * rs; beta = sc2 / sc1; double Norma_r = r.Norma(); if (Norma_r < Eps) { Flag = false; } if (Math.Abs(beta) < Double.Epsilon) { throw new Exception("BiConjurate_Gradient_Method: diverges given ~r(0)"); } for (int i = 0; i < n; i++) { p.Elem[i] = r.Elem[i] + beta * p.Elem[i]; ps.Elem[i] = rs.Elem[i] + beta * ps.Elem[i]; } Iter++; Console.WriteLine("{0,-20} {1,-20}", Iter, Norma_r); } return(RES); }
public Vector Start_Solver(CSlR_Matrix A, Vector F, int PREC) { int n = A.N; // решение Vector RES = new Vector(n); for (int i = 0; i < n; i++) { RES.Elem[i] = 0.0; } //реализация предобусловливателя switch (PREC) { case 1: { Pr = new Diag_Predconditioner(A); break; } case 2: { Pr = new ILU_Decomposition(A); break; } // default: { Pr = new E_Predconditioner(); break; } } var r = new Vector(n); var p = new Vector(n); var r_ = new Vector(n); var p_ = new Vector(n); var vec = new Vector(n); var vec_ = new Vector(n); var vec_help = new Vector(n); // параметры double alpha, betta, sc1, sc2; // флаг для остановки int Flag = 0; // ||r|| double nev_r = 0; // начало Bi_Conjugate_Gradient_Method A.Mult_MV(RES, vec_help); for (int i = 0; i < n; i++) { vec_help.Elem[i] = F.Elem[i] - vec_help.Elem[i]; } Pr.Start_Predconditioner(vec_help, r); // в r предобусловленная система-невязка p.Copy(r); r_.Copy(r); p_.Copy(r_); while (Flag != 1 && Iter < Max_Iter) { sc1 = r * r_; A.Mult_MV(p, vec_help); Pr.Start_Predconditioner(vec_help, vec); sc2 = vec * p_; alpha = sc1 / sc2; for (int i = 0; i < n; i++) { RES.Elem[i] += alpha * p.Elem[i]; r.Elem[i] -= alpha * vec.Elem[i]; } Pr.Start_Tr_Predconditioner(p_, vec_help); A.Mult_MtV(vec_help, vec_); for (int i = 0; i < n; i++) { r_.Elem[i] -= alpha * vec_.Elem[i]; } sc2 = r * r_; betta = sc2 / sc1; nev_r = r.Norm(); if (nev_r < Eps) { Flag = 1; } if (Flag == 0) { for (int i = 0; i < n; i++) { p.Elem[i] = r.Elem[i] + betta * p.Elem[i]; p_.Elem[i] = r_.Elem[i] + betta * p_.Elem[i]; } } //Console.WriteLine("{0,-20} {1,-20}", Iter, nev_r.ToString("E")); Console.WriteLine(nev_r.ToString("E")); Iter++; } return(RES); }