Численный метод Якоби. С 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;
        }
 
 
 
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 3.9 из 5