Реализация метода Гаусса Зейделя - C#
Формулировка задачи:
Доброго времени суток)
Народ есть у кого реализация метода Гаусса-Зейделя на C#?
Нашел на плюсах) только
//Метод Гаусса-Зейделя
void __fastcall TMainForm1::Method_of_Gauss_Zeydel(void)
{
int Iter=0;
double *X0_temp,*X0,*X1;
double epsilon=0.1;
X0_temp=new double[M];
X0=new double[M];
X1=new double[M];
for(int i=0;i<M;i++) X0[i]=random(10)+1.0;
double Rez=0;
do
{
for(int i=0;i<M;i++)
{
Rez=B[i][0];
for(int j=0;j<M;j++)
{
if(i!=j) Rez-=A[i][j]*X0[j];
}
X1[i]=(1.0/A[i][i])*Rez;
X0_temp[i]=X0[i];
X0[i]=X1[i];
Rez=B[i][0];
}
Iter++;
}
while(fabs(X1[0]-X0_temp[0])>epsilon);
for(int i=0;i<M;i++) X[i][0]=X1[i];
delete [] X0_temp;
delete [] X0;
delete [] X1;
}/// <summary>
/// Поиск решения СЛАУ методом Зейделя (итерационный метод)
/// </summary>
/// <param name="mm">Матрица задающая СЛАУ</param>
/// <returns>Вектор решений</returns>
public static Row Zeidel(Matrix mm)
{
Row x = new Row(mm.rowCount);
for (int i = 0; i < mm.rowCount; i++)
x[i] = mm[i, mm.colCount - 1];
Row prev_x = new Row(mm.rowCount);
bool tmp;
int counter = 0;
do
{
counter++;
if (counter > 200)
{
for (int i = 0; i < mm.rowCount; i++)
x[i] = double.NaN;
MessageBox.Show("Произошло зацикливание");
return x;
}
tmp = true;
for (int i = 0; i < mm.rowCount; i++)
{
double var = 0;
for (int j = 0; j < mm.rowCount; j++)
if (i != j)
var += mm[i, j] * x[j];
prev_x[i] = x[i];
x[i] = (mm[i, mm.colCount - 1] - var) / mm[i, i];
tmp = tmp && (Math.Abs(prev_x[i] - x[i]) < Eps);
}
} while (!tmp);
return x;
}/// <summary>
/// Вычисление нормы матрицы ||D||1
/// </summary>
/// <param name="mm">Матрица задающая СЛАУ</param>
/// <returns>Норма матрицы</returns>
public static double MatrixNorma1(Matrix mm)
{
double max_sum = 0;
for (int j = 0; j < mm.colCount - 1; j++)
{
double sum = 0;
for (int i = 0; i < mm.rowCount; i++)
if (i != j)
sum += Math.Abs(mm[i, j] / mm[i,i]);
max_sum = Math.Max(sum,max_sum);
}
return max_sum;
}/// <summary>
/// Класс строки матрицы
/// </summary>
public class Row
{
/// <summary>
/// Массив элементов
/// </summary>
private double[] m;
/// <summary>
/// Длина массива
/// </summary>
public int length;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="length">Длина создаваемого массива</param>
public Row(int length)
{
this.length = length;
m = new double[length];
}
/// <summary>
/// Делает копию класса и данных содержащихся в классе
/// </summary>
/// <returns>копия текущего класса</returns>
public Row Clone()
{
Row tmp = new Row(m.Length);
for (int i = 0; i < m.Length; i++)
tmp[i] = m[i];
return tmp;
}
/// <summary>
/// производит обмен значений двух элементов массива
/// </summary>
/// <param name="i">индекс элемента массива</param>
/// <param name="j">индекс элемента массива</param>
public void Exchange(int i, int j)
{
double tmp = m[i];
m[i] = m[j];
m[j] = tmp;
}
public static Row operator *(double k, Row t)
{
Row tmp = t.Clone();
for (int i = 0; i < tmp.length; i++)
tmp[i] = k * tmp[i];
return tmp;
}
public static Row operator /(Row t, double k)
{
Row tmp = t.Clone();
for (int i = 0; i < tmp.length; i++)
tmp[i] = tmp[i]/k;
return tmp;
}
public static Row operator -(Row t1, Row t2)
{
Row tmp = t1.Clone();
for (int i = 0; i < t1.length; i++)
tmp[i] = t1[i] - t2[i];
return tmp;
}
public static Row operator +(Row t1, Row t2)
{
Row tmp = t1.Clone();
for (int i = 0; i < t1.length; i++)
tmp[i] = t1[i] + t2[i];
return tmp;
}
public double this[int i]
{
set
{
m[i] = value;
}
get
{
return m[i];
}
}
public string ToString()
{
string s = "";
for (int i = 0; i < length; i++)
s += m[i].ToString("F") + " ";
return s.Trim();
}
}
/// <summary>
/// Матрица заданного размера
/// </summary>
public class Matrix
{
/// <summary>
/// Массив строк
/// </summary>
private Row[] rows;
/// <summary>
/// Количество строк
/// </summary>
public int rowCount;
/// <summary>
/// Количество столбцов
/// </summary>
public int colCount;
public string ToString()
{
string s = "";
for (int i = 0; i < rowCount; i++)
s += rows[i].ToString() + " \r\n";
return s.Trim();
}
/// <summary>
/// Клонирует матрицу
/// </summary>
/// <returns>колнированная матрица</returns>
public Matrix Clone()
{
Matrix tmp = new Matrix(colCount, rowCount);
for (int i = 0; i < tmp.rowCount; i++)
tmp[i] = rows[i].Clone();
return tmp;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="colNum">число столбцов</param>
/// <param name="rowNum">число строк</param>
public Matrix(int colNum, int rowNum)
{
rows = new Row[rowNum];
rowCount = rowNum;
colCount = colNum;
for (int i = 0; i < rowNum; i++)
rows[i] = new Row(colNum);
}
/// <summary>
/// Переставить строки местами
/// </summary>
/// <param name="i">номер первой строки</param>
/// <param name="j">номер второй строки</param>
public void ExchangeRows(int i, int j)
{
Row tmp = rows[i];
rows[i] = rows[j];
rows[j] = tmp;
}
/// <summary>
/// Переставить колонки местами
/// </summary>
/// <param name="c1">номер первой колонки</param>
/// <param name="c2">номер второй колонки</param>
public void ExchangeColumns(int c1, int c2)
{
for (int i = 0; i < rowCount; i++)
rows[i].Exchange(c1, c2);
}
/// <summary>
/// Обращение к строке матрицы
/// </summary>
/// <param name="i">номер строки</param>
/// <returns>строку матрицы</returns>
public Row this[int i]
{
set
{
rows[i] = value;
}
get
{
return rows[i];
}
}
/// <summary>
/// Обращение к элементу матрицы
/// </summary>
/// <param name="i">
/// номер строки в которой расположен элемент</param>
/// <param name="j">
/// номер столбца в которой расположен элемент</param>
/// <returns>значение элемента матрицы</returns>
public double this[int i, int j]
{
set
{
rows[i][j] = value;
}
get
{
return rows[i][j];
}
}
}/// <summary>
/// Класс строки матрицы
/// </summary>
public class Row
{
/// <summary>
/// Массив элементов
/// </summary>
private double[] m;
/// <summary>
/// Длина массива
/// </summary>
public int length;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="length">Длина создаваемого массива</param>
public Row(int length)
{
this.length = length;
m = new double[length];
}
/// <summary>
/// Делает копию класса и данных содержащихся в классе
/// </summary>
/// <returns>копия текущего класса</returns>
public Row Clone()
{
Row tmp = new Row(m.Length);
for (int i = 0; i < m.Length; i++)
tmp[i] = m[i];
return tmp;
}
/// <summary>
/// производит обмен значений двух элементов массива
/// </summary>
/// <param name="i">индекс элемента массива</param>
/// <param name="j">индекс элемента массива</param>
public void Exchange(int i, int j)
{
double tmp = m[i];
m[i] = m[j];
m[j] = tmp;
}
public static Row operator *(double k, Row t)
{
Row tmp = t.Clone();
for (int i = 0; i < tmp.length; i++)
tmp[i] = k * tmp[i];
return tmp;
}
public static Row operator /(Row t, double k)
{
Row tmp = t.Clone();
for (int i = 0; i < tmp.length; i++)
tmp[i] = tmp[i]/k;
return tmp;
}
public static Row operator -(Row t1, Row t2)
{
Row tmp = t1.Clone();
for (int i = 0; i < t1.length; i++)
tmp[i] = t1[i] - t2[i];
return tmp;
}
public static Row operator +(Row t1, Row t2)
{
Row tmp = t1.Clone();
for (int i = 0; i < t1.length; i++)
tmp[i] = t1[i] + t2[i];
return tmp;
}
public double this[int i]
{
set
{
m[i] = value;
}
get
{
return m[i];
}
}
public string ToString()
{
string s = "";
for (int i = 0; i < length; i++)
s += m[i].ToString("F") + " ";
return s.Trim();
}
}
/// <summary>
/// Матрица заданного размера
/// </summary>
public class Matrix
{
/// <summary>
/// Массив строк
/// </summary>
private Row[] rows;
/// <summary>
/// Количество строк
/// </summary>
public int rowCount;
/// <summary>
/// Количество столбцов
/// </summary>
public int colCount;
public string ToString()
{
string s = "";
for (int i = 0; i < rowCount; i++)
s += rows[i].ToString() + " \r\n";
return s.Trim();
}
/// <summary>
/// Клонирует матрицу
/// </summary>
/// <returns>колнированная матрица</returns>
public Matrix Clone()
{
Matrix tmp = new Matrix(colCount, rowCount);
for (int i = 0; i < tmp.rowCount; i++)
tmp[i] = rows[i].Clone();
return tmp;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="colNum">число столбцов</param>
/// <param name="rowNum">число строк</param>
public Matrix(int colNum, int rowNum)
{
rows = new Row[rowNum];
rowCount = rowNum;
colCount = colNum;
for (int i = 0; i < rowNum; i++)
rows[i] = new Row(colNum);
}
/// <summary>
/// Переставить строки местами
/// </summary>
/// <param name="i">номер первой строки</param>
/// <param name="j">номер второй строки</param>
public void ExchangeRows(int i, int j)
{
Row tmp = rows[i];
rows[i] = rows[j];
rows[j] = tmp;
}
/// <summary>
/// Переставить колонки местами
/// </summary>
/// <param name="c1">номер первой колонки</param>
/// <param name="c2">номер второй колонки</param>
public void ExchangeColumns(int c1, int c2)
{
for (int i = 0; i < rowCount; i++)
rows[i].Exchange(c1, c2);
}
/// <summary>
/// Обращение к строке матрицы
/// </summary>
/// <param name="i">номер строки</param>
/// <returns>строку матрицы</returns>
public Row this[int i]
{
set
{
rows[i] = value;
}
get
{
return rows[i];
}
}
/// <summary>
/// Обращение к элементу матрицы
/// </summary>
/// <param name="i">
/// номер строки в которой расположен элемент</param>
/// <param name="j">
/// номер столбца в которой расположен элемент</param>
/// <returns>значение элемента матрицы</returns>
public double this[int i, int j]
{
set
{
rows[i][j] = value;
}
get
{
return rows[i][j];
}
}
}Решение задачи: «Реализация метода Гаусса Зейделя»
textual
Листинг программы
public class GaussZeidel
{
public static double epsilon = 0.01; //точность вычисления
public int n, k, N; //N -допустимое число итераций, n - размерность квадратной матрицы коэффицентов, k-количество итераций
public double s, Xi, diff = 1; //s - сумма, величина погрешности
public double[,] matrix; //матрица коэффицентов
public double[] value; //матрица значений
public double[] roots; //матрица корней
public bool diagonal;
public GaussZeidel(double[,] matrix, double[] value, int N, int n, double[] roots)
{
this.matrix = matrix;
this.N = N;
this.value = value;
this.n = n;
this.roots = roots;
}
public bool DiagonallyDominant()
{
for (int i = 0; i < n; i++ )
{
double sum = 0;
for (int j=0; j < n; j++)
{
if (i !=j)
{
sum += Math.Abs(matrix[i, j]);
}
}
if (Math.Abs(matrix[i,i])>=sum)
{
diagonal = true;
break;
}
else
{
diagonal = false;
}
}
return diagonal;
}
public void algoritm()
{
k = 0;
while ((k <= N) && (diff >= epsilon))
{
k = k + 1;
for (int i = 0; i < n; i++)
{
s = 0;
for (int j = 0; j < n; j++)
{
if (i != j)
{
s += matrix[i, j] * roots[j];
}
}
Xi = (value[i] - s) / matrix[i, i];
diff = Math.Abs(Xi - roots[i]);
roots[i] = Xi;
}
}
}
}