Реализация метода Гаусса Зейделя - 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; } } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д