Численный метод Якоби. С Matlab на C#
Формулировка задачи:
помогите пожалуйста с методом Якобы, чтобы на экран выводил только ответы , программа написано в матлабе
Листинг программы
- clear all
- clc
- n=input('количество строк (n): ');
- A=input('вводить матрицу A: ');
- b=input('ввдоить матрицу b, вектор столбец: ');
- m=input('максимальное число итераций (m): ');
- E=input('допустимая погрешность (стандартного значения): ');
- X0=zeros(1,n);
- X=X0;
- K=0;
- Norma=1;
- while Norma>E
- K=K+1;
- fprintf ('%d',K);
- for i=1:n
- suma=0;
- for j=1:n
- if j~=i
- suma=suma+A(i,j)*X(j);
- end
- end
- X(i)=(b(i)-suma)/A(i,j);
- fprintf('%10.6f',X(i));
- end
- Norma=norm(X0-X);
- fprintf('%10.6f\n',Norma);
- X0=X;
- if K>=m
- break
- end
- end
а вот и матрица {3 -2 1 5
2 1 -1 4
1 -5 3 0}
Решение задачи: «Численный метод Якоби. С Matlab на C#»
textual
Листинг программы
- using System;
- using System.Threading;
- //-------------------------------------------
- // Simple Iterations Classes.
- // Seidel and Jacobi.
- // Grinchenko University. Informatics, 2-nd course.
- // Kudinov Ruslan
- // (c) 2014
- //-------------------------------------------
- namespace app
- {
- class Application
- {
- // Entry point
- // Точка входа.
- static void Main(string[] args)
- {
- // m m m | a
- // m m m | a
- // m m m | a
- // Matrix coefficients
- // Матрица коеффциентов СЛАУ
- double[,] matrix = new double[3, 3] {
- { 4, 0.24, -0.08},
- { 0.09, 3, -0.15},
- { 0.04, -0.08, 4}
- };
- // matrix of free coefficients
- // матрица свободных членов
- double[] additional = new double[3] {
- 8,
- 9,
- 20
- };
- // Enter values by user
- // Ввод значений вручную.
- // matrix = setVal(matrix);
- // additional = setVal(additional);
- // Create and init.
- // Объявляем и инициализимруем классы.
- Seidel i = new Seidel(matrix, additional, 0.0001);
- Jacobi j = new Jacobi(matrix, additional, 0.0001);
- // set method args of ThreadStart delegate
- // Передаем методы потоку через делегат ThreadStart
- Thread Z = new Thread(new ThreadStart(i.calculateMatrix));
- Thread Y = new Thread(new ThreadStart(j.calculateMatrix));
- // Start threads
- // Запускаем потоки.
- Z.Start();
- Y.Start();
- // wait for endings
- // Ожидаем завершения.
- Z.Join();
- Y.Join();
- // Show results of calculations
- // Выводим на экран.
- Console.WriteLine("\n Seidel method:");
- showMatrix(i.ResultMatrix);
- Console.WriteLine("\n Jakobi method:");
- showMatrix(j.ResultMatrix);
- Console.ReadKey();
- }
- //------------------------------------------
- // setVal - method of array values enter overloads
- // setVal - Перегрузки методов ввода значений для
- // матрицы коеффициентов и свободных членов.
- //------------------------------------------
- static double[,] setVal(double[,] x)
- {
- Console.WriteLine("\n Matrix cofficients:");
- for (int i = 0; i < x.GetLength(0); i++)
- {
- for (int j = 0; j < x.GetLength(1); j++)
- {
- Console.Write("Enter value of {0}{1}: ", i, j);
- x[i, j] = Convert.ToDouble(Console.ReadLine());
- }
- }
- return x;
- }
- static double[] setVal(double[] x)
- {
- Console.WriteLine("\n Addtional matrix values:");
- for (int i = 0; i < x.Length; i++)
- {
- Console.Write("Enter value of {0}: ", i);
- x[i] = Convert.ToDouble(Console.ReadLine());
- }
- return x;
- }
- //------------------------------------------
- // showMatrix - method overloads showing results
- // showMatrix - перегрузки разнотипных выводов
- //------------------------------------------
- static void showMatrix(double[,] x)
- {
- Console.WriteLine("\n Result:");
- for (int i = 0; i < x.GetLength(0); i++)
- {
- for (int j = 0; j < x.GetLength(1); j++)
- {
- Console.Write(" {0} ", x[i, j]);
- }
- Console.WriteLine();
- }
- }
- static void showMatrix(double[] x)
- {
- Console.WriteLine("\n Result:");
- for (int i = 0; i < x.Length; i++)
- {
- Console.WriteLine(" {0} ", x[i]);
- }
- }
- }
- // Base class of all iteration methods
- // Общий класс для итерационных методов.
- abstract class SimpleIterations
- {
- public abstract void calculateMatrix();
- }
- /// <summary>
- /// Class Jacobi
- /// Класс отвечает за работу метода Якоби
- /// </summary>
- class Jacobi : SimpleIterations
- {
- // Матрица ответов
- private double[] resultMatrix;
- public double[] ResultMatrix
- {
- get
- {
- if (resultMatrix != null)
- return resultMatrix;
- else
- {
- return new double[3] { 0, 0, 0 };
- }
- }
- }
- // Основная матрица и свободные члены.
- private double[,] matrix;
- private double[] addtional;
- // точность (кол-во итераций)
- private double accuracy;
- // избегаем ошибок с итерациями.
- public double Accuracy
- {
- get
- {
- return accuracy;
- }
- set
- {
- if (value <= 0.0)
- accuracy = 0.1;
- else
- accuracy = value;
- }
- }
- // Конструктор. Получает значения при создании.
- public Jacobi(double[,] Matrix, double[] FreeElements, double Accuracy)
- {
- this.matrix = Matrix;
- this.addtional = FreeElements;
- this.Accuracy = Accuracy;
- }
- // Сам метод рассчета.
- public override void calculateMatrix()
- {
- // общий вид:
- // [x1] [ b1/a11 ] / 0 x x \
- // [x2] = [ b2/a22 ] - | x 0 x |
- // [x3] [ b3/a33 ] \ x x 0 /
- // где x - делится на диагональый элемент первоначальной матрицы.
- // где b - эелементы из свободных членов
- // где а - элементы из матрицы
- // матрица коеффициентов + столбец свободных членов.
- double[,] a = new double[matrix.GetLength(0), matrix.GetLength(1) + 1];
- for (int i = 0; i < a.GetLength(0); i++)
- for (int j = 0; j < a.GetLength(1) - 1; j++)
- a[i, j] = matrix[i, j];
- for (int i = 0; i < a.GetLength(0); i++)
- a[i, a.GetLength(1) - 1] = addtional[i];
- //---------------
- // Метод Якоби.
- //---------------
- // Введем вектор значений неизвестных на предыдущей итерации,
- // размер которого равен числу строк в матрице, т.е. size,
- // причем согласно методу изначально заполняем его нулями
- double[] previousValues = new double[a.GetLength(0)];
- for (int i = 0; i < a.GetLength(0); i++)
- {
- previousValues[i] = 0.0;
- }
- // Будем выполнять итерационный процесс до тех пор,
- // пока не будет достигнута необходимая точность
- while (true)
- {
- // Введем вектор значений неизвестных на текущем шаге
- double[] currentValues = new double[a.GetLength(0)];
- // Посчитаем значения неизвестных на текущей итерации
- // в соответствии с теоретическими формулами
- for (int i = 0; i < a.GetLength(0); i++)
- {
- // Инициализируем i-ую неизвестную значением
- // свободного члена i-ой строки матрицы
- currentValues[i] = a[i, a.GetLength(0)];
- // Вычитаем сумму по всем отличным от i-ой неизвестным
- for (int j = 0; j < a.GetLength(0); j++)
- {
- if (i != j)
- {
- currentValues[i] -= a[i, j] * previousValues[j];
- }
- }
- // Делим на коэффициент при i-ой неизвестной
- currentValues[i] /= a[i, i];
- }
- // Посчитаем текущую погрешность относительно предыдущей итерации
- double differency = 0.0;
- for (int i = 0; i < a.GetLength(0); i++)
- differency += Math.Abs(currentValues[i] - previousValues[i]);
- // Если необходимая точность достигнута, то завершаем процесс
- if (differency < accuracy)
- break;
- // Переходим к следующей итерации, так
- // что текущие значения неизвестных
- // становятся значениями на предыдущей итерации
- previousValues = currentValues;
- }
- resultMatrix = previousValues;
- }
- }
- /// <summary>
- /// Класс Отвечает за работу метода Зейделя.
- /// Class Seidel
- /// </summary>
- class Seidel : SimpleIterations
- {
- // Матрица ответов
- private double[] resultMatrix;
- public double[] ResultMatrix
- {
- get
- {
- if (resultMatrix != null)
- return resultMatrix;
- else
- {
- return new double[3] { 0, 0, 0 };
- }
- }
- }
- // private int t;
- // Основная матрица и свободные члены.
- private double[,] matrix;
- private double[] addtional;
- // точность (кол-во итераций)
- private double accuracy;
- // избегаем ошибок с итерациями.
- public double Accuracy
- {
- get
- {
- return accuracy;
- }
- set
- {
- if (value <= 0.0)
- accuracy = 0.1;
- else
- accuracy = value;
- }
- }
- // Конструктор. Получает значения при создании.
- public Seidel(double[,] Matrix, double[] FreeElements, double Accuracy)
- {
- this.matrix = Matrix;
- this.addtional = FreeElements;
- this.Accuracy = Accuracy;
- }
- // Сам метод рассчета.
- public override void calculateMatrix()
- {
- // общий вид:
- // [x1] [ b1/a11 ] / 0 x x \
- // [x2] = [ b2/a22 ] - | x 0 x |
- // [x3] [ b3/a33 ] \ x x 0 /
- // где x - делится на диагональый элемент первоначальной матрицы.
- // где b - эелементы из свободных членов
- // где а - элементы из матрицы
- // матрица коеффициентов + столбец свободных членов.
- double[,] a = new double[matrix.GetLength(0), matrix.GetLength(1) + 1];
- for (int i = 0; i < a.GetLength(0); i++)
- for (int j = 0; j < a.GetLength(1) - 1; j++)
- a[i, j] = matrix[i, j];
- for (int i = 0; i < a.GetLength(0); i++)
- a[i, a.GetLength(1) - 1] = addtional[i];
- //---------------
- // Метод Зейделя.
- //---------------
- // Введем вектор значений неизвестных на предыдущей итерации,
- // размер которого равен числу строк в матрице, т.е. size,
- // причем согласно методу изначально заполняем его нулями
- double[] previousValues = new double[matrix.GetLength(0)];
- for (int i = 0; i < previousValues.GetLength(0); i++)
- {
- previousValues[i] = 0.0;
- }
- // Будем выполнять итерационный процесс до тех пор,
- // пока не будет достигнута необходимая точность
- while (true)
- {
- // Введем вектор значений неизвестных на текущем шаге
- double[] currentValues = new double[a.GetLength(0)];
- // Посчитаем значения неизвестных на текущей итерации
- // в соответствии с теоретическими формулами
- for (int i = 0; i < matrix.GetLength(0); i++)
- {
- // Инициализируем i-ую неизвестную значением
- // свободного члена i-ой строки матрицы
- currentValues[i] = a[i, a.GetLength(0)];
- // Вычитаем сумму по всем отличным от i-ой неизвестным
- for (int j = 0; j < a.GetLength(0); j++)
- {
- // При j < i можем использовать уже посчитанные
- // на этой итерации значения неизвестных
- if (j < i)
- {
- currentValues[i] -= a[i, j] * currentValues[j];
- }
- // При j > i используем значения с прошлой итерации
- if (j > i)
- {
- currentValues[i] -= a[i, j] * previousValues[j];
- }
- }
- // Делим на коэффициент при i-ой неизвестной
- currentValues[i] /= a[i, i];
- }
- // Посчитаем текущую погрешность относительно предыдущей итерации
- double differency = 0.0;
- for (int i = 0; i < a.GetLength(0); i++)
- differency += Math.Abs(currentValues[i] - previousValues[i]);
- // Если необходимая точность достигнута, то завершаем процесс
- if (differency < accuracy)
- break;
- // Переходим к следующей итерации, так
- // что текущие значения неизвестных
- // становятся значениями на предыдущей итерации
- previousValues = currentValues;
- }
- // результат присваиваем матрице результатов.
- resultMatrix = previousValues;
- }
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д