1 Star 0 Fork 63

雁秋 / C-Sharp

forked from 编程语言算法集 / C-Sharp 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
GaussJordanElimination.cs 4.89 KB
一键复制 编辑 原始数据 按行查看 历史
Daniel Alfonso 提交于 2022-09-27 13:12 . Update xml documentation (#327)
using System;
namespace Algorithms.Numeric
{
/// <summary>
/// Algorithm used to find the inverse of any matrix that can be inverted.
/// </summary>
public class GaussJordanElimination
{
private int RowCount { get; set; }
/// <summary>
/// Method to find a linear equation system using gaussian elimination.
/// </summary>
/// <param name="matrix">The key matrix to solve via algorithm.</param>
/// <returns>
/// whether the input matrix has a unique solution or not.
/// and solves on the given matrix.
/// </returns>
public bool Solve(double[,] matrix)
{
RowCount = matrix.GetUpperBound(0) + 1;
if (!CanMatrixBeUsed(matrix))
{
throw new ArgumentException("Please use a n*(n+1) matrix with Length > 0.");
}
var pivot = PivotMatrix(ref matrix);
if (!pivot)
{
return false;
}
Elimination(ref matrix);
return ElementaryReduction(ref matrix);
}
/// <summary>
/// To make simple validation of the matrix to be used.
/// </summary>
/// <param name="matrix">Multidimensional array matrix.</param>
/// <returns>
/// True: if algorithm can be use for given matrix;
/// False: Otherwise.
/// </returns>
private bool CanMatrixBeUsed(double[,] matrix) => matrix?.Length == RowCount * (RowCount + 1) && RowCount > 1;
/// <summary>
/// To prepare given matrix by pivoting rows.
/// </summary>
/// <param name="matrix">Input matrix.</param>
/// <returns>Matrix.</returns>
private bool PivotMatrix(ref double[,] matrix)
{
for (var col = 0; col + 1 < RowCount; col++)
{
if (matrix[col, col] == 0)
{
// To find a non-zero coefficient
var rowToSwap = FindNonZeroCoefficient(ref matrix, col);
if (matrix[rowToSwap, col] != 0)
{
var tmp = new double[RowCount + 1];
for (var i = 0; i < RowCount + 1; i++)
{
// To make the swap with the element above.
tmp[i] = matrix[rowToSwap, i];
matrix[rowToSwap, i] = matrix[col, i];
matrix[col, i] = tmp[i];
}
}
else
{
// To return that the matrix doesn't have a unique solution.
return false;
}
}
}
return true;
}
private int FindNonZeroCoefficient(ref double[,] matrix, int col)
{
var rowToSwap = col + 1;
// To find a non-zero coefficient
for (; rowToSwap < RowCount; rowToSwap++)
{
if (matrix[rowToSwap, col] != 0)
{
return rowToSwap;
}
}
return col + 1;
}
/// <summary>
/// Applies REF.
/// </summary>
/// <param name="matrix">Input matrix.</param>
private void Elimination(ref double[,] matrix)
{
for (var srcRow = 0; srcRow + 1 < RowCount; srcRow++)
{
for (var destRow = srcRow + 1; destRow < RowCount; destRow++)
{
var df = matrix[srcRow, srcRow];
var sf = matrix[destRow, srcRow];
for (var i = 0; i < RowCount + 1; i++)
{
matrix[destRow, i] = matrix[destRow, i] * df - matrix[srcRow, i] * sf;
}
}
}
}
/// <summary>
/// To continue reducing the matrix using RREF.
/// </summary>
/// <param name="matrix">Input matrix.</param>
/// <returns>True if it has a unique solution; false otherwise.</returns>
private bool ElementaryReduction(ref double[,] matrix)
{
for (var row = RowCount - 1; row >= 0; row--)
{
var element = matrix[row, row];
if (element == 0)
{
return false;
}
for (var i = 0; i < RowCount + 1; i++)
{
matrix[row, i] /= element;
}
for (var destRow = 0; destRow < row; destRow++)
{
matrix[destRow, RowCount] -= matrix[destRow, row] * matrix[row, RowCount];
matrix[destRow, row] = 0;
}
}
return true;
}
}
}
C#
1
https://gitee.com/xyesterday/C-Sharp.git
git@gitee.com:xyesterday/C-Sharp.git
xyesterday
C-Sharp
C-Sharp
master

搜索帮助