public Vector Solve(Slae<ProfileMatrix> SLAE, Vector Initial, int maxiter, double eps) { int iterNum, vec_index; double residual, diff, ML, MU; Vector result = new Vector(Initial); residual = SLAE.RightPart.Differ(SLAE.Matrix.Multiply(result)).Norm() / SLAE.RightPart.Norm(); for (iterNum = 0; iterNum < maxiter && residual >= eps; iterNum++) { for (vec_index = 0; vec_index < result.size; vec_index++) { ML = SLAE.Matrix.MultiplyL(vec_index, result); MU = SLAE.Matrix.MultiplyU(vec_index, result); diff = SLAE.RightPart.values[vec_index] - ML - MU; result.values[vec_index] += diff / SLAE.Matrix.get_di(vec_index); } residual = SLAE.RightPart.Differ(SLAE.Matrix.Multiply(result)).Norm() / SLAE.RightPart.Norm(); if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum, residual, maxiter, false)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum - 1, residual, maxiter, true)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } return result; }
//разность векторов public Vector Differ(Vector B) { double[] values_res = new double[size]; for (int i = 0; i < size; i++) { values_res[i] = 0; } var res = new Vector(size, values_res); for (int i = 0; i < size; i++) { res.values[i] = this.values[i]; res.values[i] -= B.values[i]; } return res; }
public Vector Solve(Slae<ProfileMatrix> SLAE, Vector Initial, int maxiter, double eps) { int iterNum; double pr, pr1, alpha, betta, residual; Vector Az; Vector r = new Vector(SLAE.RightPart.Differ(SLAE.Matrix.Multiply(Initial))); Vector result = new Vector(Initial); residual = r.Norm() / SLAE.RightPart.Norm(); Vector z = new Vector(r); Vector s = new Vector(r); Vector p = new Vector(r); pr1 = p.Scalar(r); for (iterNum = 0; iterNum < maxiter && residual >= eps; iterNum++) { Az = SLAE.Matrix.Multiply(z); alpha = pr1 / Az.Scalar(s); result = result.Sum(z.Mult(alpha)); r = r.Differ(Az.Mult(alpha)); p = p.Differ(SLAE.Matrix.TMultiply(s).Mult(alpha)); pr = p.Scalar(r); betta = pr / pr1; pr1 = pr; z = r.Sum(z.Mult(betta)); s = p.Sum(s.Mult(betta)); residual = r.Norm() / SLAE.RightPart.Norm(); if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum, residual, maxiter, false)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum - 1, residual, maxiter, true)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } return result; }
public Vector Solve(Slae<ProfileMatrix> SLAE, Vector Initial, int maxiter, double eps) { int iterNum; double iner_r,iner_mr, alpha, betta, residual; Vector Az, Mr; Vector r = new Vector(SLAE.RightPart.Differ(SLAE.Matrix.Multiply(Initial))); Vector result = new Vector(Initial); residual = r.Norm() / SLAE.RightPart.Norm(); if (Data.preconditioner == 0)//нет предобуславливания { Vector z = new Vector(r); for (iterNum = 0; iterNum < maxiter && residual >= eps; iterNum++) { iner_r = r.Scalar(r); Az = SLAE.Matrix.Multiply(z); alpha = r.Scalar(r) / Az.Scalar(z); result = result.Sum(z.Mult(alpha)); r = r.Differ(Az.Mult(alpha)); betta = r.Scalar(r) / iner_r; z = r.Sum(z.Mult(betta)); residual = r.Norm() / SLAE.RightPart.Norm(); if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum, residual, maxiter, false)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum - 1, residual, maxiter, true)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } else if (Data.preconditioner == 1 || Data.preconditioner == 2 || Data.preconditioner == 3 || Data.preconditioner == 4)//диагональное предобуславливание или Неполное разложение Холесского { Vector z = new Vector(SLAE.PMatrix.ReverseProgress(SLAE.PMatrix.DirectProgress(r))); for (iterNum = 0; iterNum < maxiter && residual >= eps; iterNum++) { Mr = SLAE.PMatrix.ReverseProgress(SLAE.PMatrix.DirectProgress(r));//M^-1*r(k-1) Az = SLAE.Matrix.Multiply(z);//A*z(k-1) alpha = Mr.Scalar(r) / Az.Scalar(z); result = result.Sum(z.Mult(alpha)); iner_mr = Mr.Scalar(r);//(M^-1*r(k-1),r(k-1)) r = r.Differ(Az.Mult(alpha)); Mr = SLAE.PMatrix.ReverseProgress(SLAE.PMatrix.DirectProgress(r)); betta = Mr.Scalar(r) / iner_mr; z = Mr.Sum(z.Mult(betta)); residual = r.Norm() / SLAE.RightPart.Norm(); if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum, residual, maxiter, false)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum - 1, residual, maxiter, true)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } return result; }
//умножение вектора на число public Vector Mult(double A) { double[] values_res = new double[size]; var res = new Vector(size, values_res); for (int i = 0; i < size; i++) { res.values[i] = this.values[i] * A; } return res; }
//Конструктор копий public Vector(Vector Original) { this.size = Original.size; this.values = new double[this.size]; Array.Copy(Original.values, this.values, this.size); }
//скалярное произведение векторов public double Scalar(Vector A) { double res = 0; for (int i = 0; i < size; i++) { res+= this.values[i] * A.values[i]; } return res; }
public Vector Solve(Slae<DisperseMatrix> SLAE, Vector Initial, int maxiter, double eps) { int iterNum; double iner_p, alpha, betta, residual; Vector Ar; Vector result = new Vector(Initial); if (Data.preconditioner == 0)//нет предобуславливания { Vector r = new Vector(SLAE.RightPart.Differ(SLAE.Matrix.Multiply(Initial))); Vector z = new Vector(r); Vector p = new Vector(SLAE.Matrix.Multiply(z)); residual = Math.Sqrt(r.Scalar(r)) / SLAE.RightPart.Norm(); for (iterNum = 0; iterNum < maxiter && residual >= eps; iterNum++) { iner_p = p.Scalar(p); alpha = p.Scalar(r) / iner_p; result = result.Sum(z.Mult(alpha)); r = r.Differ(p.Mult(alpha)); Ar = SLAE.Matrix.Multiply(r); betta = -p.Scalar(Ar) / iner_p; z = r.Sum(z.Mult(betta)); p = Ar.Sum(p.Mult(betta)); residual = Math.Sqrt(r.Scalar(r)) / SLAE.RightPart.Norm(); if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum, residual, maxiter, false)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum - 1, residual, maxiter, true)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } else if (Data.preconditioner == 1 || Data.preconditioner == 2 || Data.preconditioner == 3 || Data.preconditioner == 4)//LU или LU(sq)-предобуславливание { Vector fAx = new Vector(SLAE.RightPart.Differ(SLAE.Matrix.Multiply(result))); Vector r = new Vector(SLAE.PMatrix.DirectProgress(fAx)); Vector z = new Vector(SLAE.PMatrix.ReverseProgress(r)); Vector p = new Vector(SLAE.PMatrix.DirectProgress(SLAE.Matrix.Multiply(z))); if ((r == null) || (z == null) || (p == null)) return null; residual = Math.Sqrt(r.Scalar(r)) / SLAE.RightPart.Norm(); for (iterNum = 0; iterNum < maxiter && residual >= eps; iterNum++) { iner_p = p.Scalar(p); alpha = p.Scalar(r) / iner_p; result = result.Sum(z.Mult(alpha)); r = r.Differ(p.Mult(alpha)); Ar = SLAE.PMatrix.DirectProgress(SLAE.Matrix.Multiply(SLAE.PMatrix.ReverseProgress(r)));//L^-1*A*U^-1*r(k) betta = -p.Scalar(Ar) / iner_p; z = SLAE.PMatrix.ReverseProgress(r).Sum(z.Mult(betta)); p = Ar.Sum(p.Mult(betta)); residual = Math.Sqrt(r.Scalar(r)) / SLAE.RightPart.Norm(); if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum, residual, maxiter, false)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } if (!autotest) { if (!InputOutput.OutputIterationToForm(iterNum - 1, residual, maxiter, true)) MessageBox.Show("Ошибка при выводе данных на форму.", "Опаньки...", MessageBoxButtons.OK); } } return result; }
public static bool OutputVector(string filename, Vector vector) { try { StreamWriter str = new StreamWriter(filename); for (int i = 0; i < vector.SIZE; i++) { str.WriteLine(vector.VALUES[i]); } str.Close(); return true; } catch (Exception error) { if (debug) MessageBox.Show(error.Message, "Ошибка!", MessageBoxButtons.OK); return false; } }
private void solve_button_Click(object sender, EventArgs e) { //Запуск решения bool success; if (checkinput()) { success = true; richTextBox1.Clear(); Data.richtextbox = richTextBox1; Data.ZedGraph.GraphPane.CurveList.Clear(); InputOutput.points.Clear(); Vector Initial; ISolver solver; double eps; eps = 1.0; for (int i = 0; i < eps_numericUpDown.Value; i++) { eps /= 10.0; } switch (Data.matrixformat) { case 0: //Плотная { Slae<DenseMatrix> SLAE = new Slae<DenseMatrix>(); SLAE.Matrix = new DenseMatrix(Data.matrixPath); SLAE.RightPart = new Vector(Data.rightpartPath); if (initial_checkBox.Checked) Initial = new Vector(SLAE.Matrix.getMatrix().N); else Initial = new Vector(Data.initialPath); if ((SLAE.Matrix.getMatrix().N == 0) || (SLAE.RightPart.SIZE == 0) || (Initial.SIZE == 0)) { MessageBox.Show("Размерность матрицы/вектора правой части/вектора приближения равна нулю.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } if ((SLAE.Matrix.getMatrix().N != SLAE.RightPart.SIZE) || (SLAE.Matrix.getMatrix().N != Initial.SIZE)) { MessageBox.Show("Размерности матрицы/вектора правой части/вектора приближения не совпадают.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } switch (Data.preconditioner) { case 0: //Нет предобуславливателя { switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: //БСГ стаб { solver = new BSGstab(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 3: //Гаусс-Зейдель { solver = new GaussZeidel(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } } break; } case 1: //Диагональный { IPreconditioner<DenseMatrix> preconditioner = new DensePreconditioner(); if (!preconditioner.createDiag(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 2: //LLT { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного предобуславливателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } IPreconditioner<DenseMatrix> preconditioner = new DensePreconditioner(); if (!preconditioner.createLLT(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 3: //LU { IPreconditioner<DenseMatrix> preconditioner = new DensePreconditioner(); if (!preconditioner.createLU(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 4: //LUsq { IPreconditioner<DenseMatrix> preconditioner = new DensePreconditioner(); if (!preconditioner.createLUsq(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } } break; } case 1: //Профильная { Slae<ProfileMatrix> SLAE = new Slae<ProfileMatrix>(); SLAE.Matrix = new ProfileMatrix(Data.matrixPath); SLAE.RightPart = new Vector(Data.rightpartPath); if (initial_checkBox.Checked) Initial = new Vector(SLAE.Matrix.getMatrix().N); else Initial = new Vector(Data.initialPath); if ((SLAE.Matrix.getMatrix().N == 0) || (SLAE.RightPart.SIZE == 0) || (Initial.SIZE == 0)) { MessageBox.Show("Размерность матрицы/вектора правой части/вектора приближения равна нулю.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } if ((SLAE.Matrix.getMatrix().N != SLAE.RightPart.SIZE) || (SLAE.Matrix.getMatrix().N != Initial.SIZE)) { MessageBox.Show("Размерности матрицы/вектора правой части/вектора приближения не совпадают.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } switch (Data.preconditioner) { case 0: //Нет предобуславливателя { switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: //БСГ стаб { solver = new BSGstab(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 3: //Гаусс-Зейдель { solver = new GaussZeidel(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } } break; } case 1: //Диагональный { IPreconditioner<ProfileMatrix> preconditioner = new ProfilePreconditioner(); if (!preconditioner.createDiag(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 2: //LLT { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного предобуславливателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } IPreconditioner<ProfileMatrix> preconditioner = new ProfilePreconditioner(); if (!preconditioner.createLLT(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { //if (MessageBox.Show("Ваша матрица должна быть положительно определённой.\nЭто так?\nЕсли не уверены, исользуйте решатель МСГ.", "Обратите внимание!", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) break; solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 3: //LU { IPreconditioner<ProfileMatrix> preconditioner = new ProfilePreconditioner(); if (!preconditioner.createLU(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 4: //LUsq { IPreconditioner<ProfileMatrix> preconditioner = new ProfilePreconditioner(); if (!preconditioner.createLUsq(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } } break; } case 2: //Диагональная { Slae<DiagonalMatrix> SLAE = new Slae<DiagonalMatrix>(); SLAE.Matrix = new DiagonalMatrix(Data.matrixPath); SLAE.RightPart = new Vector(Data.rightpartPath); if (initial_checkBox.Checked) Initial = new Vector(SLAE.Matrix.getMatrix().N); else Initial = new Vector(Data.initialPath); if ((SLAE.Matrix.getMatrix().N == 0) || (SLAE.RightPart.SIZE == 0) || (Initial.SIZE == 0)) { MessageBox.Show("Размерность матрицы/вектора правой части/вектора приближения равна нулю.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } if ((SLAE.Matrix.getMatrix().N != SLAE.RightPart.SIZE) || (SLAE.Matrix.getMatrix().N != Initial.SIZE)) { MessageBox.Show("Размерности матрицы/вектора правой части/вектора приближения не совпадают.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } switch (Data.preconditioner) { case 0: //Нет предобуславливателя { switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: //БСГ стаб { solver = new BSGstab(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 3: //Гаусс-Зейдель { solver = new GaussZeidel(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } } break; } case 1: //Диагональный { IPreconditioner<DiagonalMatrix> preconditioner = new DiagonalPreconditioner(); if (!preconditioner.createDiag(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 2: //LLT { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного предобуславливателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } IPreconditioner<DiagonalMatrix> preconditioner = new DiagonalPreconditioner(); if (!preconditioner.createLLT(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 3: //LU { IPreconditioner<DiagonalMatrix> preconditioner = new DiagonalPreconditioner(); if (!preconditioner.createLU(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 4: //LUsq { IPreconditioner<DiagonalMatrix> preconditioner = new DiagonalPreconditioner(); if (!preconditioner.createLUsq(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } } break; } case 3: //Разреженая { Slae<DisperseMatrix> SLAE = new Slae<DisperseMatrix>(); SLAE.Matrix = new DisperseMatrix(Data.matrixPath); SLAE.RightPart = new Vector(Data.rightpartPath); if (initial_checkBox.Checked) Initial = new Vector(SLAE.Matrix.getMatrix().N); else Initial = new Vector(Data.initialPath); if ((SLAE.Matrix.getMatrix().N == 0) || (SLAE.RightPart.SIZE == 0) || (Initial.SIZE == 0)) { MessageBox.Show("Размерность матрицы/вектора правой части/вектора приближения равна нулю.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } if ((SLAE.Matrix.getMatrix().N != SLAE.RightPart.SIZE) || (SLAE.Matrix.getMatrix().N != Initial.SIZE)) { MessageBox.Show("Размерности матрицы/вектора правой части/вектора приближения не совпадают.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } switch (Data.preconditioner) { case 0: //Нет предобуславливателя { switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: //БСГ стаб { solver = new BSGstab(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 3: //Гаусс-Зейдель { solver = new GaussZeidel(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } } break; } case 1: //Диагональный { IPreconditioner<DisperseMatrix> preconditioner = new DispersePreconditioner(); if (!preconditioner.createDiag(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 2: //LLT { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного предобуславливателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } IPreconditioner<DisperseMatrix> preconditioner = new DispersePreconditioner(); if (!preconditioner.createLLT(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 3: //LU { IPreconditioner<DisperseMatrix> preconditioner = new DispersePreconditioner(); if (!preconditioner.createLU(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } case 4: //LUsq { IPreconditioner<DisperseMatrix> preconditioner = new DispersePreconditioner(); if (!preconditioner.createLUsq(SLAE)) { success = false; break; } switch (Data.solver) { case 0: //МСГ { if (!SLAE.Matrix.CheckSymmetry()) { MessageBox.Show("Для выбранного решателя ваша матрица должна быть симметричной.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); success = false; break; } solver = new MSG(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 1: //ЛОС { solver = new LOS(); Data.result = solver.Solve(SLAE, Initial, (int)maxiter_numericUpDown.Value, eps); break; } case 2: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } case 3: { MessageBox.Show("Для выбранного решателя предобуславливание недоступно.", "Такие дела.", MessageBoxButtons.OK, MessageBoxIcon.Information); success = false; break; } } break; } } break; } } } else success = false; if (success) MessageBox.Show("Сохраните ответ в файл на вкладке \"Вывод\".", "Решение завершено!", MessageBoxButtons.OK, MessageBoxIcon.Information); else MessageBox.Show("В процессе решения возникла ошибка.", "Решение не завершено!", MessageBoxButtons.OK, MessageBoxIcon.Error); }
private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.F2) { int i, n, iter; Vector Initial; ISolver solver; IPreconditioner<DisperseMatrix> preconditioner = new DispersePreconditioner(); double eps; if (System.IO.File.Exists("./auto/info.txt")) { string[] lines = System.IO.File.ReadAllLines("./auto/info.txt"); n = Int32.Parse(lines[0]); for (i = 1; i <= n; i++) { eps = 1e-16; Data.matrixformat = 3; Data.matrixPath = "./auto/m" + i + ".txt"; Data.rightpartPath = "./auto/r" + i + ".txt"; System.IO.Directory.CreateDirectory("./auto/ans"); preconditioner.set_autotest(true); if ((System.IO.File.Exists(Data.matrixPath)) && (System.IO.File.Exists(Data.rightpartPath))) { Slae<DisperseMatrix> SLAE = new Slae<DisperseMatrix>(); SLAE.Matrix = new DisperseMatrix(Data.matrixPath); SLAE.RightPart = new Vector(Data.rightpartPath); Initial = new Vector(SLAE.Matrix.getMatrix().N); if ((SLAE.Matrix.getMatrix().N == 0) || (SLAE.RightPart.SIZE == 0) || (Initial.SIZE == 0)) { MessageBox.Show("Размерность матрицы/вектора правой части/вектора приближения равна нулю.\nОшибка ввода матрицы.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); continue; } if ((SLAE.Matrix.getMatrix().N != SLAE.RightPart.SIZE) || (SLAE.Matrix.getMatrix().N != Initial.SIZE)) { MessageBox.Show("Размерности матрицы/вектора правой части/вектора приближения не совпадают.", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Error); continue; } if (SLAE.Matrix.getMatrix().N <= 1000) iter = 20000; else iter = 2000; if (SLAE.Matrix.CheckSymmetry()) { Data.preconditioner = 0; solver = new MSG(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); InputOutput.OutputVector("./auto/ans/x" + i + " MSG.txt", Data.result); Data.preconditioner = 1; if (preconditioner.createDiag(SLAE)) { solver = new MSG(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " MSG_DIAG.txt", Data.result); } Data.preconditioner = 2; if (preconditioner.createLLT(SLAE)) { solver = new MSG(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " MSG_LLT.txt", Data.result); } Data.preconditioner = 3; if (preconditioner.createLU(SLAE)) { solver = new MSG(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " MSG_LU.txt", Data.result); } Data.preconditioner = 4; if (preconditioner.createLUsq(SLAE)) { solver = new MSG(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " MSG_LUsq.txt", Data.result); } } Data.preconditioner = 0; solver = new LOS(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " LOS.txt", Data.result); Data.preconditioner = 1; if (preconditioner.createDiag(SLAE)) { solver = new LOS(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " LOS_DIAG.txt", Data.result); } if (SLAE.Matrix.CheckSymmetry()) { Data.preconditioner = 2; if (preconditioner.createLLT(SLAE)) { solver = new LOS(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " LOS_LLT.txt", Data.result); } } Data.preconditioner = 3; if (preconditioner.createLU(SLAE)) { solver = new LOS(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " LOS_LU.txt", Data.result); } Data.preconditioner = 4; if (preconditioner.createLUsq(SLAE)) { solver = new LOS(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " LOS_LUsq.txt", Data.result); } Data.preconditioner = 0; solver = new BSGstab(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " BSGStab.txt", Data.result); if (SLAE.Matrix.getMatrix().N < 50) { solver = new GaussZeidel(); solver.set_autotest(true); Data.result = solver.Solve(SLAE, Initial, iter, eps); solver.set_autotest(false); if (Data.result != null) InputOutput.OutputVector("./auto/ans/x" + i + " GaussZeidel.txt", Data.result); } preconditioner.set_autotest(false); if (i % (n / 10) == 0) MessageBox.Show("Матрица " + i + " протестирована.", "OK.", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("Матрица " + i + " потеряна.", "OK.", MessageBoxButtons.OK, MessageBoxIcon.Information); } } MessageBox.Show("Автотестирование завершено.", "OK.", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("Потерялся файл /auto/info.txt\n", "Ошибка.", MessageBoxButtons.OK, MessageBoxIcon.Information); } } }