/// <summary> /// Решение /// </summary> /// <param name="slae">СЛАУ</param> /// <param name="eps">Точность</param> public void SolveWithoutInvertible(SLAE slae, double eps) { a_matrix = slae.A; x_vector = slae.X; b_vector = slae.B; this.eps = eps; this.size = b_vector.N; int[] index = InitIndex(); JordanWithoutInvertible(index); }
private Vector x_vector; // вектор неизвестных x #endregion Fields #region Methods /// <summary> /// Решение /// </summary> /// <param name="slae">СЛАУ</param> /// <param name="eps">Точность</param> public Matrix SolveWithInvertible(SLAE slae, double eps) { a_matrix = slae.A; x_vector = slae.X; b_vector = slae.B; this.eps = eps; this.size = b_vector.N; int[] index = InitIndex(); JordanWithInvertible(index); slae.X = x_vector; return a_inverse; }
public SLAE(Matrix a, Vector b, Vector x) { double[,] a_temp = new double[a.N, a.N]; for (int i = 0; i < a.N; i++) for (int j = 0; j < a.N; j++) a_temp[i, j] = a.Coeff[i, j]; A = new Matrix(a_temp, a.N); double[] b_temp = new double[b.N]; for (int i = 0; i < b.N; i++) b_temp[i] = b.Coeff[i]; B = new Vector(b_temp, b.N); double[] x_temp = new double[x.N]; for (int i = 0; i < x.N; i++) x_temp[i] = x.Coeff[i]; X = new Vector(x_temp, x.N); }
/// <summary> /// Решение /// </summary> /// <param name="slae">СЛАУ</param> /// <param name="eps">Точность</param> /// <param name="isMax">Использовать ли поиск по всей матрице?</param> /// <returns>Определитель матрицы</returns> public double Solve(SLAE slae, double eps, bool isMax) { double result = 0; a_matrix = slae.A; x_vector = slae.X; b_vector = slae.B; this.eps = eps; this.size = b_vector.N; int[] index = InitIndex(); int isOk = GaussSolve(index, isMax); if (isOk != -1) { det = FindDeterminant(); result = det; } return result; }
/// <summary> /// Прямой ход /// </summary> /// <param name="index">Массив индексов</param> private int JordanWithInvertible(int[] index) { double[,] inverse_matrix = new double[size, size]; for (int i = 0; i < size; i++) inverse_matrix[i, i] = 1; for (int i = 0; i < size; ++i) { double r = 0; try { r = FindStart(i, index); if (r == 0) throw new Exception("Система уравнений не имеет решений"); } catch (Exception ex) { Console.WriteLine(ex.Message); return -1; } // Делим главную строку на разрешающий элемент for (int j = 0; j < size; ++j) { a_matrix.Coeff[i, j] /= r; inverse_matrix[i, j] /= r; } // Отнимаем строку из всех строк выше главной for (int k = 0; k < i; ++k) { double p = a_matrix.Coeff[k, index[i]]; for (int j = 0; j < size; ++j) { a_matrix.Coeff[k, index[j]] -= a_matrix.Coeff[i, index[j]] * p; inverse_matrix[k, index[j]] -= inverse_matrix[i, index[j]] * p; } } // Отнимаем строку из всех строк ниже главной for (int k = i + 1; k < size; ++k) { double p = a_matrix.Coeff[k, index[i]]; for (int j = 0; j < size; ++j) { a_matrix.Coeff[k, index[j]] -= a_matrix.Coeff[i, index[j]] * p; inverse_matrix[k, index[j]] -= inverse_matrix[i, index[j]] * p; } a_matrix.Coeff[k, index[i]] = 0.0; } } a_inverse = new Matrix(inverse_matrix, a_matrix.N); // Матричный метод double[] result = new double[size]; for (int i = 0; i < size; i++) { double temp = 0; for (int j = 0; j < size; j++) { temp += a_inverse.Coeff[i, j] * b_vector.Coeff[j]; } result[i] = temp; } x_vector = new Vector(result, size); return 0; }
static void Main(string[] args) { const int K = 5; Matrix A = Matrix.LoadSpecial("D:\\C.txt", "D:\\D.txt", K); Vector b = Vector.Load("D:\\vector.txt", A.N); Vector x = new Vector(new double[A.N], A.N); SLAE slae1 = new SLAE(A, b, x); SLAE slae2 = new SLAE(A, b, x); SLAE slae3 = new SLAE(A, b, x); SLAE slae4 = new SLAE(A, b, x); double eps = 0.0001; Gauss gauss = new Gauss(); Jordan jordan = new Jordan(); DateTime time1before = DateTime.Now; for (int i = 0; i < 100000; i++) { new Gauss().Solve(new SLAE(A, b, x), eps, false); } DateTime time1after = DateTime.Now; DateTime time2before = DateTime.Now; for (int i = 0; i < 100000; i++) { new Gauss().Solve(new SLAE(A, b, x), eps, true); } DateTime time2after = DateTime.Now; DateTime time3before = DateTime.Now; for (int i = 0; i < 100000; i++) { new Jordan().SolveWithoutInvertible(new SLAE(A, b, x), eps); } DateTime time3after = DateTime.Now; DateTime time4before = DateTime.Now; for (int i = 0; i < 100000; i++) { new Jordan().SolveWithInvertible(new SLAE(A, b, x), eps); } DateTime time4after = DateTime.Now; Console.WriteLine("1) Решение СЛАУ методом Гаусса с выбором первого элемента"); double det = gauss.Solve(slae1, eps, false); Console.WriteLine("Матрица А:"); slae1.A.Print(eps); Console.WriteLine("Вектор X:"); slae1.X.Print(eps); Console.WriteLine("Определитель = {0}\n", det); Console.WriteLine("2) Решение СЛАУ методом Гаусса с выбором элемента по матрице"); gauss.Solve(slae2, eps, true); Console.WriteLine("Матрица А:"); slae2.A.Print(eps); Console.WriteLine("Вектор X:"); slae2.X.Print(eps); Console.WriteLine("3) Решение СЛАУ методом Гаусса-Жордана без нахождения обратной матрицы"); jordan.SolveWithoutInvertible(slae3, eps); Console.WriteLine("Матрица А:"); slae3.A.Print(eps); Console.WriteLine("Вектор X:"); slae3.X.Print(eps); if (det != 0) { Console.WriteLine("4) Решение СЛАУ методом Гаусса-Жордана с нахождением обратной матрицы"); Matrix inverse = jordan.SolveWithInvertible(slae4, eps); Console.WriteLine("Матрица А:"); slae4.A.Print(eps); Console.WriteLine("Вектор X:"); slae4.X.Print(eps); Console.WriteLine("Обратная матрица:"); inverse.Print(eps); } Console.WriteLine("Время выполнения методов (повторено 100000 раз):"); Console.WriteLine("Time 1 : {0}", time1after - time1before); Console.WriteLine("Time 2 : {0}", time2after - time2before); Console.WriteLine("Time 3 : {0}", time3after - time3before); Console.WriteLine("Time 4 : {0}", time4after - time4before); Console.ReadKey(); }