Created
September 26, 2021 18:19
-
-
Save YuriiSmolii/3f4469270f2331960ff41d80b19afaaf to your computer and use it in GitHub Desktop.
Gaus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace Gaussian_Elimination | |
{ | |
public class Solve_equation | |
{ | |
readonly int dimension; | |
readonly double[,] leftMatrix; | |
readonly double[] rightVector; | |
double[] solutionX; | |
public Solve_equation(int Dimension, double[,] LeftMatrix, double[] RightVector, double[] SolutionX) | |
{ | |
this.dimension = Dimension; | |
this.leftMatrix = LeftMatrix; | |
this.rightVector = RightVector; | |
this.solutionX = SolutionX; | |
} | |
public void solve() | |
{ | |
BackwardSubstitution(ForwardElimination()); | |
} | |
private void WriteEquationFuntion() | |
{ | |
var rowCount = rightVector.Length; | |
if(rowCount!= leftMatrix.GetLength(0)) | |
{ | |
throw new Exception(); | |
} | |
for (int i = 0; i < rowCount; ++i) | |
{ | |
for (int j = 0; j < leftMatrix.GetLength(1); ++j) | |
{ | |
Console.Write($"{leftMatrix[i, j],8:F4}"); | |
} | |
Console.WriteLine($" | {rightVector[i],8:F4}"); | |
} | |
} | |
private void WriteEquationFuntion(double[,] LeftMatrix, double[] RightVector) | |
{ | |
var rowCount = RightVector.Length; | |
if (rowCount != LeftMatrix.GetLength(0)) | |
{ | |
throw new Exception(); | |
} | |
for (int i = 0; i < rowCount; ++i) | |
{ | |
for (int j = 0; j < LeftMatrix.GetLength(1); ++j) | |
{ | |
Console.Write($"{LeftMatrix[i, j],8:F4}"); | |
} | |
Console.WriteLine($" | {RightVector[i],8:F4}"); | |
} | |
} | |
private Tuple<double[,], double[]> ForwardElimination() | |
{ | |
//Console.WriteLine("Initial"); | |
//WriteEquationFuntion(); | |
//Console.WriteLine(); | |
var matrixA = leftMatrix; | |
var vectorB = rightVector; | |
for (int i = 0; i < dimension - 1; ++i) | |
{ | |
for (int j = i + 1; j < dimension; ++j) | |
{ | |
var s = matrixA[j, i] / matrixA[i, i]; | |
for (int k = i; k < dimension; ++k) | |
{ | |
matrixA[j, k] -= matrixA[i, k] * s; | |
} | |
vectorB[j] -= vectorB[i] * s; | |
} | |
} | |
//Console.WriteLine("After forward elimination"); | |
//WriteEquationFuntion(leftMatrix, vectorB); | |
//Console.WriteLine(); | |
var result = new Tuple<double[,], double[]>(matrixA, vectorB); | |
return result; | |
} | |
private void BackwardSubstitution(Tuple<double[,], double[]> forwardMatrix) | |
{ | |
for (int i = dimension - 1; i >= 0; --i) | |
{ | |
var vec = forwardMatrix.Item2; | |
var mat = forwardMatrix.Item1; | |
var s = vec[i]; | |
for (int j = i + 1; j < dimension; ++j) | |
{ | |
s -= mat[i, j] * solutionX[j]; | |
} | |
solutionX[i] = s / mat[i, i]; | |
} | |
//.WriteLine("After Backward Substitution"); | |
//WriteEquationFuntion(forwardMatrix.Item1, forwardMatrix.Item2); | |
//Console.WriteLine(); | |
Console.WriteLine("Solved"); | |
Console.WriteLine(string.Join("\r\n", solutionX.Select(x => $"{x,8:F4}"))); | |
} | |
} | |
public class ParallelSolve_equation | |
{ | |
readonly int dimension; | |
readonly double[,] leftMatrix; | |
readonly double[] rightVector; | |
double[] solutionX; | |
readonly int numberOfThreads; | |
public ParallelSolve_equation(int Dimension, double[,] LeftMatrix, double[] RightVector, double[] SolutionX, int numberOfThreads) | |
{ | |
this.dimension = Dimension; | |
this.leftMatrix = LeftMatrix; | |
this.rightVector = RightVector; | |
this.solutionX = SolutionX; | |
this.numberOfThreads = numberOfThreads; | |
} | |
public void solve() | |
{ | |
BackwardSubstitution(ParallelForwardElimination()); | |
} | |
private void WriteEquationFuntion() | |
{ | |
var rowCount = rightVector.Length; | |
if(rowCount!= leftMatrix.GetLength(0)) | |
{ | |
throw new Exception(); | |
} | |
for (int i = 0; i < rowCount; ++i) | |
{ | |
for (int j = 0; j < leftMatrix.GetLength(1); ++j) | |
{ | |
Console.Write($"{leftMatrix[i, j],8:F4}"); | |
} | |
Console.WriteLine($" | {rightVector[i],8:F4}"); | |
} | |
} | |
private void WriteEquationFuntion(double[,] LeftMatrix, double[] RightVector) | |
{ | |
var rowCount = RightVector.Length; | |
if (rowCount != LeftMatrix.GetLength(0)) | |
{ | |
throw new Exception(); | |
} | |
for (int i = 0; i < rowCount; ++i) | |
{ | |
for (int j = 0; j < LeftMatrix.GetLength(1); ++j) | |
{ | |
Console.Write($"{LeftMatrix[i, j],8:F4}"); | |
} | |
Console.WriteLine($" | {RightVector[i],8:F4}"); | |
} | |
} | |
private Tuple<double[,], double[]> ParallelForwardElimination() | |
{ | |
//Console.WriteLine("Initial"); | |
//WriteEquationFuntion(); | |
//Console.WriteLine(); | |
var matrixA = leftMatrix; | |
var vectorB = rightVector; | |
for (int i = 0; i < dimension - 1; ++i) | |
{ | |
for (int j = i + 1; j < dimension; ++j) | |
{ | |
var s = matrixA[j, i] / matrixA[i, i]; | |
var Indexes = Enumerable.Range(0, dimension); | |
Parallel.ForEach(Indexes, new ParallelOptions() { MaxDegreeOfParallelism = numberOfThreads }, k => | |
{ | |
matrixA[j, k] -= matrixA[i, k] * s; | |
}); | |
vectorB[j] -= vectorB[i] * s; | |
} | |
} | |
//Console.WriteLine("After forward elimination"); | |
//(leftMatrix, vectorB); | |
//Console.WriteLine(); | |
var result = new Tuple<double[,], double[]>(matrixA, vectorB); | |
return result; | |
} | |
private void BackwardSubstitution(Tuple<double[,], double[]> forwardMatrix) | |
{ | |
for (int i = dimension - 1; i >= 0; --i) | |
{ | |
var vec = forwardMatrix.Item2; | |
var mat = forwardMatrix.Item1; | |
var s = vec[i]; | |
for (int j = i + 1; j < dimension; ++j) | |
{ | |
s -= mat[i, j] * solutionX[j]; | |
} | |
solutionX[i] = s / mat[i, i]; | |
} | |
//Console.WriteLine("After Backward Substitution"); | |
//WriteEquationFuntion(forwardMatrix.Item1, forwardMatrix.Item2); | |
//Console.WriteLine(); | |
Console.WriteLine("Solved"); | |
Console.WriteLine(string.Join("\r\n", solutionX.Select(x => $"{x,8:F4}"))); | |
} | |
} | |
class MainClass | |
{ | |
public static void Main(string[] args) | |
{ | |
CalcMatrixTest(); | |
} | |
public static void CalcMatrixTest() | |
{ | |
const int Dimension0 = 4; | |
double[,] matrixA0 = new double[Dimension0, Dimension0] | |
{ | |
{2, 3, 1, 4}, | |
{4, 1, -3, -2}, | |
{-1, 2, 2, 1}, | |
{3, -4, 4, 3} | |
}; | |
double[] vectorB0 = new double[Dimension0] | |
{ | |
10, | |
0, | |
4, | |
6 | |
}; | |
double[] InitialSolution0 = new double[Dimension0] | |
{ | |
0, | |
0, | |
0, | |
0 | |
}; | |
const int Dimension = 5; | |
Random a = new Random(); | |
double[,] matrixA = new double[Dimension, Dimension]; | |
for (int i = 0; i < Dimension; i++) | |
{ | |
for (int j = 0; j < Dimension; j++) | |
{ | |
matrixA[i, j] = a.Next(10); | |
} | |
} | |
double[] vectorB = new double[Dimension]; | |
for (int i = 0; i < Dimension; i++) | |
{ | |
vectorB[i] = a.Next(10); | |
} | |
double[] InitialSolution = new double[Dimension]; | |
for (int i = 0; i < Dimension; i++) | |
{ | |
InitialSolution[i] = 0; | |
} | |
var thread = Convert.ToInt32(Console.ReadLine()); | |
var calcMatrix2 = new Solve_equation(Dimension, matrixA, vectorB, InitialSolution); | |
var sw2 = Stopwatch.StartNew(); | |
calcMatrix2.solve(); | |
sw2.Stop(); | |
Console.WriteLine($"Secuental took {sw2.ElapsedMilliseconds} ms"); | |
var calcMatrix = new ParallelSolve_equation(Dimension, matrixA, vectorB, InitialSolution, thread); | |
var sw = Stopwatch.StartNew(); | |
calcMatrix.solve(); | |
sw.Stop(); | |
Console.WriteLine($"Parallel took {sw.ElapsedMilliseconds} ms"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment