public override IVector Solve(IMatrix A, IVector b, IVector x0) { IVector result = new Vector(b.Size); IVector r = new Vector(b.Size); IVector p = new Vector(b.Size); IVector z = new Vector(b.Size); double alpha, betta; double p_scal; r.Equalize(b); result.Equalize(x0); r.Add(MatrixAssistant.multMatrixVector(A, result), -1); z.Equalize(r); p.Equalize(MatrixAssistant.multMatrixVector(A, z)); p_scal = VectorAssistant.multVector(p, p); residual = VectorAssistant.multVector(r, r); residual = Math.Sqrt(VectorAssistant.multVector(r, r)) / b.Norm; for (iteration = 1; iteration <= maxIteration && residual > minResidual; iteration++) { alpha = VectorAssistant.multVector(p, r) / p_scal; result.Add(z, alpha); r.Add(p, -alpha); betta = -VectorAssistant.multVector(p, MatrixAssistant.multMatrixVector(A, r)) / p_scal; z = VectorAssistant.multScalar(betta, z); z.Add(r, 1); p = VectorAssistant.multScalar(betta, p); p.Add(MatrixAssistant.multMatrixVector(A, r), 1); /* residual -= alpha * alpha * p_scal; if (residual < 0) //она всё равно отрицательная { residual += alpha * alpha * p_scal; return result; } if (alpha * alpha * p_scal < residual * 10E-5) return result; */ p_scal = VectorAssistant.multVector(p, p); residual = Math.Sqrt(VectorAssistant.multVector(r, r)) / b.Norm; Debugger.DebugSolver(iteration, residual, result); } return result; }
public override IVector Solve(IMatrix A, IVector b, IVector x0) { IVector x_prev= new Vector(b.Size); IVector result = new Vector(b.Size); IVector difference = new Vector(b.Size);//f-Ax double residual1, residual2; double residual_prev;//для проверки изменения невязки residual =1; residual1 = b.Norm; x_prev.Equalize(x0); for (int i = 0; i < b.Size; i++) if (Math.Abs(A.Diagonal[i]) < EPS_NULL) throw new Exception("Divide by NULL in GaussZeidel_solver: diagonal"); residual_prev = 2 * residual; for (iteration = 0; iteration < maxIteration && residual > minResidual && residual_prev > residual; iteration++) { difference.Equalize(b); difference.Add(MatrixAssistant.multMatrixUpperVector(A,x_prev),-1); for (int i = 0; i < b.Size; i++) { double sum = 0; IVector Lx = MatrixAssistant.multMatrixLowerVector(A, result, i); for (int ii = 0; ii < Lx.Size; ii++) sum += Lx[ii]; difference[i] -= sum; result[i] = relaxation*difference[i]/A.Diagonal[i]; } difference.Equalize(b); difference.Add(MatrixAssistant.multMatrixVector(A, result), -1); residual2 = difference.Norm; residual_prev = residual; residual = residual2 / residual1; Debugger.DebugSolver(iteration, residual, result); x_prev.Equalize(result); } return result; }
public override IVector Solve(IMatrix A, IVector b, IVector x0) { IVector x = new Vector(b.Size); IVector r = new Vector(b.Size); IVector z = new Vector(b.Size); // Check errors double Azz, rr; double norm; norm = b.Norm; if (norm < EPS_NULL) { x.Nullify(); return x; } x.Equalize(x0); r.Equalize(b); r.Add(MatrixAssistant.multMatrixVector(A,x),-1); z.Equalize(r); alpha = 1000; for (iteration = 0; iteration < maxIteration && residual > minResidual; iteration++ ) { rr = VectorAssistant.multVector(r, r); var Az = MatrixAssistant.multMatrixVector(A, z); Azz = VectorAssistant.multVector(Az, z); if (Math.Abs(Azz) < EPS_NULL) return x; alpha = rr / Azz; x.Add(z,alpha); r.Add(Az, -alpha); betta = VectorAssistant.multVector(r, r) / rr; z=VectorAssistant.multScalar(z,betta); z.Add(r, 1); residual = r.Norm / norm; } return x; }
public override IVector Solve(IMatrix A, IVector b, IVector x0) { IVector result = new Vector(b.Size); IVector difference = new Vector(b.Size);//f-Ax double residual1, residual2; double residual_prev;//для проверки изменения невязки residual = 1; residual1 = b.Norm; result.Equalize(x0); difference.Equalize(b); difference.Add(MatrixAssistant.multMatrixVector(A, result), -1); for (int i = 0; i < b.Size; i++) if (Math.Abs(A.Diagonal[i]) < EPS_NULL) throw new Exception("Divide by NULL in Jacobi_solver: diagonal"); residual_prev = 2 * residual; for (iteration = 0; iteration < maxIteration && residual > minResidual && residual_prev > residual; iteration++) { for (int i = 0; i < b.Size; i++) { difference[i] = difference[i] / A.Diagonal[i]; } result.Add(difference, relaxation); difference.Equalize(b); difference.Add(MatrixAssistant.multMatrixVector(A, result), -1); residual2 = difference.Norm; if (Math.Abs(residual1) < EPS_NULL) throw new Exception("Divide by NULL in Jacobi_solver: residual1"); residual_prev = residual; residual = residual2 / residual1; //Debugger.DebugSolver(iteration, residual, result); } return result; }
public override IVector Solve(IMatrix A, IVector b, IVector x0) { IVector x_prev= new Vector(b.Size); IVector result = new Vector(b.Size); IVector difference = new Vector(b.Size);//f-Ax double residual1, residual2; double residual_prev;//для проверки изменения невязки residual =1; residual1 = b.Norm; x_prev.Equalize(x0); for (int i = 0; i < b.Size; i++) if (Math.Abs(A.Diagonal[i]) < EPS_NULL) throw new Exception("Divide by NULL in GaussZeidel_solver: diagonal"); residual_prev = 2 * residual; for (iteration = 0; iteration < maxIteration && residual > minResidual && residual_prev > residual; iteration++) { difference.Equalize(b); //result.Nullify(); for (int i = 0; i < b.Size; i++) { for (int j = 0; j < i; j++) difference[i] -= A[i,j]*result[j]; for (int j = i; j < b.Size; j++) { difference[i] -= A[i,j]*x_prev[j]; } difference[i] *= (relaxation/A.Diagonal[i]); result[i] = x_prev[i] + difference[i]; } difference.Equalize(b); difference.Add(MatrixAssistant.multMatrixVector(A, result), -1); residual2 = difference.Norm; residual_prev = residual; residual = residual2 / residual1; //Debugger.DebugSolver(iteration, residual, result); x_prev.Equalize(result); } return result; }