Skip to content

Instantly share code, notes, and snippets.

@YuriiSmolii
Created September 26, 2021 18:19
Show Gist options
  • Save YuriiSmolii/3f4469270f2331960ff41d80b19afaaf to your computer and use it in GitHub Desktop.
Save YuriiSmolii/3f4469270f2331960ff41d80b19afaaf to your computer and use it in GitHub Desktop.
Gaus
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