using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lab1
{
class GaussJordan
{
// Исходная матрица
public double[,] _Omatrix = new double[,]
{
{ 1, 0, -3, 4 },
{ 3, 5, 6, 9 },
{ 1, 1, 2, 2 },
{ 0, 3, -1, 2 }
};
// Единичная матрица
public double[,] _Fmatrix = new double[,]
{
{ 1, 0, 0 ,0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 }
};
public double[] data;
public double e;
public int k;
// Копия исходной матрицы
public double[,] _Smatrix;
public double[] _own;
public double[] own;
public double own2;
// Получение копии иходной матрицы для дальнейшей работы с ней
public void cloneMatrix()
{
_Smatrix = new double[_Omatrix.GetLength(0), _Omatrix.GetLength(0)];
_Smatrix = (double[,])_Omatrix.Clone();
}
// Преобразование в нормальный вид
public void conversion()
{
double[] Ostr = new double[_Omatrix.GetLength(0)];
double[] Fstr = new double[_Omatrix.GetLength(0)];
try
{
for (int p = _Omatrix.GetLength(0) - 1; p >= 0; p--)
{
for (int i = _Omatrix.GetLength(0) - 1; i >= 0; i--)
{
if (_Omatrix[i, i] == 0)
{
int k;
for (k = _Omatrix.GetLength(0) - 1; k >= 0; k--)
{
if (_Omatrix[k, i] != 0)
{
break;
}
}
for (int j = _Omatrix.GetLength(0) - 1; j >= 0; j--)
{
Ostr[j] = _Omatrix[i, j];
_Omatrix[i, j] = _Omatrix[k, j];
_Omatrix[k, j] = Ostr[j];
Fstr[j] = _Fmatrix[i, j];
_Fmatrix[i, j] = _Fmatrix[k, j];
_Fmatrix[k, j] = Fstr[j];
}
}
}
}
}
catch { }
}
// Получение обратной матрицы
public void zeroing()
{
for (int j = 0; j < _Omatrix.GetLength(0); j++)
{
for (int i = 0; i < _Omatrix.GetLength(0); i++)
{
if (_Omatrix[j, j] != 0)
{
for (int k = 0; k < _Omatrix.GetLength(0); k++)
{
_Fmatrix[j, k] /= _Omatrix[j, j];
}
for (int k = _Omatrix.GetLength(0) - 1; k >= j; k--)
{
_Omatrix[j, k] /= _Omatrix[j, j];
}
}
if (i != j)
{
for (int k = 0; k < _Omatrix.GetLength(0); k++)
{
_Fmatrix[i, k] -= _Omatrix[i, j] * _Fmatrix[j, k];
}
for (int k = _Omatrix.GetLength(0) - 1; k >= j; k--)
{
_Omatrix[i, k] -= _Omatrix[i, j] * _Omatrix[j, k];
}
}
}
}
}
// Получение максимального собственного значения / собственных векторов
public void eigenvalues()
{
// Массив собственных векторов
own = new double[_Omatrix.GetLength(0)];
_own = new double[_Omatrix.GetLength(0)];
// Приближение собственного вектора
for (int i = 0; i < _Omatrix.GetLength(0); i++)
{
own[i] = 1;
_own[i] = 1;
}
// Точность вычисления
double E = 0.0001;
// Точка входа
e = 1;
data = new double[3];
data[2] = 0;
// Начальный шаг итерации
k = 0;
// Итерации по нахождению масимального собственного значения
while (E < e)
{
data[0] = _own.Max();
for (int i = 0; i < _own.Length; i++)
{
own[i] = _own[i];
}
own2 = data[2];
for (int i = 0; i < _Smatrix.GetLength(0); i++)
{
double sum = 0;
for (int j = 0; j < _Smatrix.GetLength(0); j++)
{
sum += _Smatrix[i, j] * own[j];
}
_own[i] = sum;
}
data[1] = _own.Max();
e = Math.Abs(data[1] / data[0] - data[2]);
data[2] = Math.Abs(data[1] / data[0]);
k++;
}
}
public void prepare()
{
double sum = 0;
for (int i = 0; i < own.Length; i++)
{
sum += Math.Pow(own[i] , 2);
}
sum = Math.Sqrt(sum);
for (int i = 0; i < own.Length; i++)
{
own[i] /= sum;
}
}
}
class Program
{
static void Main(string[] args)
{
// Создаем экземпляр класса
GaussJordan method = new GaussJordan();
// Копируем исходную матрицу
method.cloneMatrix();
Console.WriteLine("Первоначальная матрица:"); Console.WriteLine();
for (int i = 0; i < method._Omatrix.GetLength(0); i++)
{
for (int j = 0; j < method._Omatrix.GetLength(1); j++)
{
Console.Write(" {0} ", method._Omatrix[i, j]);
}
Console.WriteLine();
}
Console.WriteLine(); Console.WriteLine();
// Приведение матрицы к нормальному виду
method.conversion();
// Получение обратной матрицы
method.zeroing();
// Получение собственных значений
method.eigenvalues();
Console.WriteLine("Обратная матрица:"); Console.WriteLine();
for (int i = 0; i < method._Omatrix.GetLength(0); i++)
{
for (int j = 0; j < method._Omatrix.GetLength(1); j++)
{
Console.Write(" {0}\t", method._Fmatrix[i, j]);
}
Console.WriteLine();
}
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("Собственные вектора: \n");
for (int i = 0; i < method._own.GetLength(0); i++)
{
Console.WriteLine(" {0} \n", method._own[i]);
}
Console.WriteLine();
Console.WriteLine("Собственное значение: {0}", method.data[2]);
Console.WriteLine();
Console.WriteLine("Кол. итераций: {0}", method.k);
Console.WriteLine();
Console.WriteLine("Точность приближения: {0}", method.e);
Console.WriteLine();
Console.WriteLine("--------------------------------------------------------------------");
Console.WriteLine();
Console.WriteLine("Собственные вектора: \n");
method.prepare();
for (int i = 0; i < method.own.GetLength(0); i++)
{
Console.WriteLine(" {0} \n", method.own[i]);
}
Console.WriteLine();
Console.WriteLine("Второе по величине собственное значение: {0}", method.own2);
Console.WriteLine();
Console.WriteLine("Кол. итераций: {0}", method.k - 1);
Console.ReadKey();
}
}
}