DAS_2024_1/yakovleva_yulia_lab_6/CalcMatrixDeterminant/CalcMatrixDeterminant/Program.cs
2024-10-27 13:04:11 +04:00

139 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Diagnostics;
using System.Threading.Tasks;
class Program
{
// Вычисление детерминанта методом Гаусса
public static double SequentialDeterminant(double[,] matrix)
{
int n = matrix.GetLength(0);
double det = 1;
for (int i = 0; i < n; i++)
{
int pivot = i;
for (int j = i + 1; j < n; j++)
{
if (Math.Abs(matrix[j, i]) > Math.Abs(matrix[pivot, i]))
pivot = j;
}
if (Math.Abs(matrix[pivot, i]) < 1e-10)
return 0;
if (i != pivot)
{
SwapRows(matrix, i, pivot);
det = -det;
}
det *= matrix[i, i];
for (int j = i + 1; j < n; j++)
{
matrix[i, j] /= matrix[i, i];
}
for (int j = i + 1; j < n; j++)
{
for (int k = i + 1; k < n; k++)
{
matrix[j, k] -= matrix[j, i] * matrix[i, k];
}
}
}
return det;
}
// Вычисление детерминанта с параллельными вычислениями
public static double ParallelDeterminant(double[,] matrix, int threads = 1)
{
int n = matrix.GetLength(0);
double det = 1;
for (int i = 0; i < n; i++)
{
int pivot = i;
for (int j = i + 1; j < n; j++)
{
if (Math.Abs(matrix[j, i]) > Math.Abs(matrix[pivot, i]))
pivot = j;
}
if (Math.Abs(matrix[pivot, i]) < 1e-10)
return 0;
if (i != pivot)
{
SwapRows(matrix, i, pivot);
det = -det;
}
det *= matrix[i, i];
for (int j = i + 1; j < n; j++)
{
matrix[i, j] /= matrix[i, i];
}
Parallel.For(i + 1, n, new ParallelOptions { MaxDegreeOfParallelism = threads }, j =>
{
for (int k = i + 1; k < n; k++)
{
matrix[j, k] -= matrix[j, i] * matrix[i, k];
}
});
}
return det;
}
private static void SwapRows(double[,] matrix, int row1, int row2)
{
int n = matrix.GetLength(1);
for (int i = 0; i < n; i++)
{
double temp = matrix[row1, i];
matrix[row1, i] = matrix[row2, i];
matrix[row2, i] = temp;
}
}
// Запуск и замер времени
public static void Benchmark(int size)
{
var random = new Random();
double[,] matrix = new double[size, size];
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
matrix[i, j] = random.NextDouble();
var stopwatch = new Stopwatch();
// Обычный алгоритм
stopwatch.Start();
double detSeq = SequentialDeterminant((double[,])matrix.Clone());
stopwatch.Stop();
Console.WriteLine($"Обычный алгоритм, размер {size}x{size}: {stopwatch.ElapsedMilliseconds} мс");
// Параллельный алгоритм с разным количеством потоков
int[] threadCounts = { 1, 2, 4, 8 };
foreach (var threads in threadCounts)
{
stopwatch.Restart();
double detPar = ParallelDeterminant((double[,])matrix.Clone(), threads);
stopwatch.Stop();
Console.WriteLine($"Параллельный алгоритм, потоки: {threads}, размер {size}x{size}: {stopwatch.ElapsedMilliseconds} мс");
}
}
public static void Main()
{
int[] sizes = { 100, 300, 500 };
foreach (var size in sizes)
{
Benchmark(size);
}
}
}