diff --git a/parallelMatrixMultiplication/TestsForMatrixMultiplication/TestsForMatrixMultiplication.cs b/parallelMatrixMultiplication/TestsForMatrixMultiplication/TestsForMatrixMultiplication.cs new file mode 100644 index 0000000..8cc6bb1 --- /dev/null +++ b/parallelMatrixMultiplication/TestsForMatrixMultiplication/TestsForMatrixMultiplication.cs @@ -0,0 +1,223 @@ +namespace TestsForMatrixMultiplication; + +using parallelMatrixMultiplication; + +public class Tests +{ + [Test] + public void MultiplyMatricesOfSizeThreeByThree() + { + var listOfValues = new List + { + new int[3] { 1, 2, 3 }, + new int[3] { 4, 5, 6 }, + new int[3] { 7, 8, 9 }, + }; + + var listOfCorrectValues = new List + { + new int[3] { 30, 36, 42 }, + new int[3] { 66, 81, 96 }, + new int[3] { 102, 126, 150 }, + }; + + var firstMatrix = Matrix.Create(3, 3, listOfValues); + var secondMatrix = Matrix.Create(3, 3, listOfValues); + var correctMatrix = Matrix.Create(3, 3, listOfCorrectValues); + + var resultMatrix = Matrix.ParallelMultiply(firstMatrix, secondMatrix); + Assert.True(Matrix.AreEquals(resultMatrix, correctMatrix)); + } + + [Test] + public void MultiplyMatricesOfBigSize() + { + var listOfValuesFirstMatrix = new List {}; + var listOfValuesSecondMatrix = new List {}; + var listOfCorrectValues = new List {}; + + for (int i = 0; i < 10000; i++) + { + listOfValuesFirstMatrix.Add(new int[10000]); + listOfValuesSecondMatrix.Add(new int[1]); + listOfCorrectValues.Add(new int[1]); + for (int j = 0; j < 10000; ++j) + { + listOfValuesFirstMatrix[i][j] = 1; + } + listOfValuesSecondMatrix[i][0] = 1; + listOfCorrectValues[i][0] = 10000; + } + + var firstMatrix = Matrix.Create(10000, 10000, listOfValuesFirstMatrix); + var secondMatrix = Matrix.Create(10000, 1, listOfValuesSecondMatrix); + var correctMatrix = Matrix.Create(10000, 1, listOfCorrectValues); + + var resultMatrix = Matrix.ParallelMultiply(firstMatrix, secondMatrix); + Assert.True(Matrix.AreEquals(resultMatrix, correctMatrix)); + } + + [Test] + public void MultiplyMatricesOfDifferentSizes() + { + var listOfValuesFirstMatrix = new List + { + new int[3] { 1, 2, 3 }, + new int[3] { 4, 5, 6 }, + new int[3] { 7, 8, 9 }, + }; + + var listOfValuesSecondMatrix = new List + { + new int[1] { 1 }, + new int[1] { 2 }, + new int[1] { 3 }, + }; + + var listOfCorrectValues = new List + { + new int[1] { 14 }, + new int[1] { 32 }, + new int[1] { 50 }, + }; + + var firstMatrix = Matrix.Create(3, 3, listOfValuesFirstMatrix); + var secondMatrix = Matrix.Create(3, 1, listOfValuesSecondMatrix); + var correctMatrix = Matrix.Create(3, 1, listOfCorrectValues); + + var resultMatrix = Matrix.ParallelMultiply(firstMatrix, secondMatrix); + Assert.True(Matrix.AreEquals(resultMatrix, correctMatrix)); + } + + [Test] + public void MultiplyOfNotSquareMatrices() + { + var listOfValuesFirstMatrix = new List + { + new int[5] { 1, 2, 3, 4, 5 }, + new int[5] { 6, 7, 8, 9, 10 }, + }; + + var listOfValuesSecondMatrix = new List + { + new int[1] { 1 }, + new int[1] { 2 }, + new int[1] { 3 }, + new int[1] { 4 }, + new int[1] { 5 }, + }; + + var listOfCorrectValues = new List + { + new int[1] { 55 }, + new int[1] { 130 }, + }; + + var firstMatrix = Matrix.Create(2, 5, listOfValuesFirstMatrix); + var secondMatrix = Matrix.Create(5, 1, listOfValuesSecondMatrix); + var correctMatrix = Matrix.Create(2, 1, listOfCorrectValues); + + var resultMatrix = Matrix.ParallelMultiply(firstMatrix, secondMatrix); + Assert.True(Matrix.AreEquals(resultMatrix, correctMatrix)); + } + + [Test] + public void MultiplyMatricesWithNegativeNumbers() + { + var listOfValuesFirstMatrix = new List + { + new int[5] { 1, 2, -3, 4, 5 }, + new int[5] { 6, -7, 8, 9, 10 }, + }; + + var listOfValuesSecondMatrix = new List + { + new int[1] { 1 }, + new int[1] { 2 }, + new int[1] { 3 }, + new int[1] { -4 }, + new int[1] { 5 }, + }; + + var listOfCorrectValues = new List + { + new int[1] { 5 }, + new int[1] { 30 }, + }; + + var firstMatrix = Matrix.Create(2, 5, listOfValuesFirstMatrix); + var secondMatrix = Matrix.Create(5, 1, listOfValuesSecondMatrix); + var correctMatrix = Matrix.Create(2, 1, listOfCorrectValues); + + var resultMatrix = Matrix.ParallelMultiply(firstMatrix, secondMatrix); + Assert.True(Matrix.AreEquals(resultMatrix, correctMatrix)); + } + + [Test] + public void MultiplyMatricesWithZero() + { + var listOfValuesFirstMatrix = new List + { + new int[5] { 1, 2, 0, 4, 5 }, + new int[5] { 6, 0, 8, 9, 10 }, + }; + + var listOfValuesSecondMatrix = new List + { + new int[1] { 1 }, + new int[1] { 2 }, + new int[1] { 0 }, + new int[1] { 0 }, + new int[1] { 5 }, + }; + + var listOfCorrectValues = new List + { + new int[1] { 30 }, + new int[1] { 56 }, + }; + + var firstMatrix = Matrix.Create(2, 5, listOfValuesFirstMatrix); + var secondMatrix = Matrix.Create(5, 1, listOfValuesSecondMatrix); + var correctMatrix = Matrix.Create(2, 1, listOfCorrectValues); + + var resultMatrix = Matrix.ParallelMultiply(firstMatrix, secondMatrix); + Assert.True(Matrix.AreEquals(resultMatrix, correctMatrix)); + } + + [Test] + public void MultiplyMatricesWithWrongData() + { + var listOfCorrectValues = new List + { + new int[1] { 30 }, + new int[1] { 56 }, + }; + + var correctMatrix = Matrix.Create(2, 1, listOfCorrectValues); + Assert.Throws(() => Matrix.Multiplication(Path.Combine(TestContext.CurrentContext.TestDirectory, + "TestsForMatrix", "firstCorrectMatrix.txt"), + Path.Combine(TestContext.CurrentContext.TestDirectory, + "TestsForMatrix", "incorrectMatrix.txt"), + Path.Combine(TestContext.CurrentContext.TestDirectory, + "TestsForMatrix", "resultMatrix.txt"))); + } + + [Test] + public void CompareParalelAndConsistentMultiply() + { + var listOfValues = new List + { + new int[3] { 1, 2, 3 }, + new int[3] { 4, 5, 6 }, + new int[3] { 7, 8, 9 }, + }; + + var firstMatrix = Matrix.Create(3, 3, listOfValues); + var secondMatrix = Matrix.Create(3, 3, listOfValues); + + var resultMatrixFromParallelMultiply = Matrix.ParallelMultiply(firstMatrix, secondMatrix); + var resultMatrixFromConsistentMultiply = Matrix.ConsistentMultiply(firstMatrix, secondMatrix); + Assert.True(Matrix.AreEquals(resultMatrixFromParallelMultiply, resultMatrixFromConsistentMultiply)); + } +} \ No newline at end of file diff --git a/parallelMatrixMultiplication/TestsForMatrixMultiplication/TestsForMatrixMultiplication.csproj b/parallelMatrixMultiplication/TestsForMatrixMultiplication/TestsForMatrixMultiplication.csproj new file mode 100644 index 0000000..4e2539d --- /dev/null +++ b/parallelMatrixMultiplication/TestsForMatrixMultiplication/TestsForMatrixMultiplication.csproj @@ -0,0 +1,23 @@ + + + + net7.0 + enable + enable + + false + + + + + + + + + + + + + + + diff --git a/parallelMatrixMultiplication/TestsForMatrixMultiplication/Usings.cs b/parallelMatrixMultiplication/TestsForMatrixMultiplication/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/parallelMatrixMultiplication/TestsForMatrixMultiplication/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file diff --git a/parallelMatrixMultiplication/TestsForMatrixMultiplication/bin/Debug/net7.0/TestsForMatrix/firstCorrectMatrix.txt b/parallelMatrixMultiplication/TestsForMatrixMultiplication/bin/Debug/net7.0/TestsForMatrix/firstCorrectMatrix.txt new file mode 100644 index 0000000..3d1d616 --- /dev/null +++ b/parallelMatrixMultiplication/TestsForMatrixMultiplication/bin/Debug/net7.0/TestsForMatrix/firstCorrectMatrix.txt @@ -0,0 +1,3 @@ +1 2 3 +4 5 6 +5 6 7 \ No newline at end of file diff --git a/parallelMatrixMultiplication/TestsForMatrixMultiplication/bin/Debug/net7.0/TestsForMatrix/incorrectMatrix.txt b/parallelMatrixMultiplication/TestsForMatrixMultiplication/bin/Debug/net7.0/TestsForMatrix/incorrectMatrix.txt new file mode 100644 index 0000000..96233ef --- /dev/null +++ b/parallelMatrixMultiplication/TestsForMatrixMultiplication/bin/Debug/net7.0/TestsForMatrix/incorrectMatrix.txt @@ -0,0 +1,3 @@ +1 2 a +3 4 5 +6 7 8 \ No newline at end of file diff --git a/parallelMatrixMultiplication/TestsForMatrixMultiplication/bin/Debug/net7.0/TestsForMatrix/resultMatrix.txt b/parallelMatrixMultiplication/TestsForMatrixMultiplication/bin/Debug/net7.0/TestsForMatrix/resultMatrix.txt new file mode 100644 index 0000000..e69de29 diff --git a/parallelMatrixMultiplication/parallelMatrixMultiplication.sln b/parallelMatrixMultiplication/parallelMatrixMultiplication.sln new file mode 100644 index 0000000..009b334 --- /dev/null +++ b/parallelMatrixMultiplication/parallelMatrixMultiplication.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33403.182 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "parallelMatrixMultiplication", "parallelMatrixMultiplication\parallelMatrixMultiplication.csproj", "{E4C7CC35-FD7C-4BA7-B1C5-EF752CDAA263}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsForMatrixMultiplication", "TestsForMatrixMultiplication\TestsForMatrixMultiplication.csproj", "{F6D3443D-537C-44C2-9988-5B3D10652CE1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E4C7CC35-FD7C-4BA7-B1C5-EF752CDAA263}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4C7CC35-FD7C-4BA7-B1C5-EF752CDAA263}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4C7CC35-FD7C-4BA7-B1C5-EF752CDAA263}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4C7CC35-FD7C-4BA7-B1C5-EF752CDAA263}.Release|Any CPU.Build.0 = Release|Any CPU + {F6D3443D-537C-44C2-9988-5B3D10652CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6D3443D-537C-44C2-9988-5B3D10652CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6D3443D-537C-44C2-9988-5B3D10652CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6D3443D-537C-44C2-9988-5B3D10652CE1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4E527157-F298-4A47-B122-6710A34A14E1} + EndGlobalSection +EndGlobal diff --git a/parallelMatrixMultiplication/parallelMatrixMultiplication/InvalidFileException.cs b/parallelMatrixMultiplication/parallelMatrixMultiplication/InvalidFileException.cs new file mode 100644 index 0000000..ae70dc3 --- /dev/null +++ b/parallelMatrixMultiplication/parallelMatrixMultiplication/InvalidFileException.cs @@ -0,0 +1,11 @@ +namespace parallelMatrixMultiplication; +/// +/// Exception for errors with file +/// +public class InvalidFileException : Exception +{ + public InvalidFileException() { } + public InvalidFileException(string message) : base(message) {} + public InvalidFileException(string message, Exception inner) + : base(message, inner) {} +} \ No newline at end of file diff --git a/parallelMatrixMultiplication/parallelMatrixMultiplication/Matrix.cs b/parallelMatrixMultiplication/parallelMatrixMultiplication/Matrix.cs new file mode 100644 index 0000000..2e372c9 --- /dev/null +++ b/parallelMatrixMultiplication/parallelMatrixMultiplication/Matrix.cs @@ -0,0 +1,270 @@ +namespace parallelMatrixMultiplication; +using System; +using System.Diagnostics; +using System.Threading; + +/// +/// A class for multiplying matrices +/// +public static class Matrix +{ + /// + /// Function for creating matrices + /// + /// Number of rows + /// Number of columns + /// List with data + /// Returns the created matrix + /// Throws an exception if the number of items + /// in the list does not match the size of the matrix + public static int[][] Create(int sizeRows, int sizeColumns, List numbersForMatrix) + { + if (numbersForMatrix.Count * numbersForMatrix[0].Length != sizeColumns * sizeRows) + { + throw new ArgumentException(); + } + + var matrix = new int[sizeRows][]; + for (int i = 0; i < sizeRows; i++) + { + matrix[i] = new int[sizeColumns]; + } + + for (int i = 0; i < sizeRows; ++i) + { + for (int j = 0; j < sizeColumns; ++j) + { + matrix[i][j] = numbersForMatrix[i][j]; + } + } + + return matrix; + } + + /// + /// The function compares matrices + /// + public static bool AreEquals(int[][] firstMatrix, int[][] secondMatrix) + { + if (firstMatrix.Length != secondMatrix.Length) + { + return false; + } + + for (int i = 0; i < firstMatrix.Length; ++i) + { + if (firstMatrix[i].Length != secondMatrix[i].Length) + { + return false; + } + for (int j = 0; j < firstMatrix[i].Length; ++j) + { + if (firstMatrix[i][j] != secondMatrix[i][j]) + { + return false; + } + } + } + return true; + } + + /// + /// Multiplies matrices by a sequential algorithm + /// + /// The resulting matrix + public static int[][] ConsistentMultiply(int[][] firstMatrix, int[][] secondMatrix) + { + var resultMatrix = new int[firstMatrix.Length][]; + + for (int i = 0; i < firstMatrix.Length; ++i) + { + resultMatrix[i] = new int[secondMatrix[0].Length]; + } + + for (int i = 0; i < firstMatrix.Length; ++i) + { + for (int j = 0; j < secondMatrix[0].Length; ++j) + { + for (var k = 0; k < firstMatrix[0].Length; ++k) + { + resultMatrix[i][j] += firstMatrix[i][k] * secondMatrix[k][j]; + } + } + } + return resultMatrix; + } + + private static int[][] ConvertMatrixToTransposedOne(int[][] matrix) + { + var transposedMatrix = new int[matrix[0].Length][]; + for (int i = 0; i < matrix[0].Length; i++) + { + transposedMatrix[i] = new int[matrix.Length]; + } + + for (int i = 0; i < transposedMatrix.Length; ++i) + { + for (int j = 0; j < transposedMatrix[i].Length; ++j) + { + transposedMatrix[i][j] = matrix[j][i]; + } + } + return transposedMatrix; + } + + private static void Multiply(int start, int end, int[][] firstMatrix, int[][] transposedMatrix, int[][] resultMatrix) + { + while (start < end) + { + for (int i = 0; i < transposedMatrix.Length; i++) + { + for (int k = 0; k < transposedMatrix[0].Length; ++k) + { + resultMatrix[start][i] += firstMatrix[start][k] * transposedMatrix[i][k]; + } + } + start++; + } + } + + /// + /// Parallel matrix multiplication function + /// + /// Returns the calculated matrix + public static int[][] ParallelMultiply(int[][] firstMatrix, int[][] secondMatrix) + { + var resultMatrix = new int[firstMatrix.Length][]; + + for(int i = 0; i < firstMatrix.Length; ++i) + { + resultMatrix[i] = new int[secondMatrix[0].Length]; + } + + var threadCounts = Environment.ProcessorCount; + + if (threadCounts > firstMatrix.Length) + { + threadCounts = firstMatrix.Length; + } + + var numberOfRowsForThreads = firstMatrix.Length / threadCounts; + var remains = firstMatrix.Length % threadCounts; + var threads = new Thread[threadCounts]; + + int start = 0; + int end = 0; + + var transposedMatrix = ConvertMatrixToTransposedOne(secondMatrix); + + for (int i = 0; i < threadCounts; i++) + { + end = i == 0 ? numberOfRowsForThreads + remains : end + numberOfRowsForThreads; + int localStart = start; + int localEnd = end; + threads[i] = new Thread(() => Multiply(localStart, localEnd, firstMatrix, transposedMatrix, resultMatrix)); + start = end; + } + + foreach (var thread in threads) + { + thread.Start(); + } + + foreach (var thread in threads) + { + thread.Join(); + } + + return resultMatrix; + } + + private static int[][] ReadFromFile(string filePath) + { + var allLines = File.ReadAllLines(filePath); + var matrix = new int[allLines.Length][]; + var sizeColumns = 0; + + for (int i = 0; i < matrix.Length; i++) + { + var stringOfDigits = allLines[i].Trim().Split(' '); + matrix[i] = new int[stringOfDigits.Length]; + var sizeLine = 0; + for (int j = 0; j < stringOfDigits.Length; ++j) + { + var result = 0; + bool isCorrectResult = int.TryParse(stringOfDigits[j].Trim(), out result); + if (!isCorrectResult) + { + throw new InvalidFileException(); + } + matrix[i][j] = result; + if (i == 0) + { + sizeColumns++; + } + sizeLine++; + } + if (sizeLine != sizeColumns) + { + throw new InvalidFileException(); + } + } + return matrix; + } + + private static void WriteResultToFile(string filePath, int[][] matrix) + { + var streamForWrite = new StreamWriter(filePath); + for (int i = 0; i < matrix.Length; ++i) + { + for (int j = 0; j < matrix[i].Length; ++j) + { + streamForWrite.Write(matrix[i][j]); + streamForWrite.Write(' '); + } + streamForWrite.Write('\n'); + } + streamForWrite.Close(); + } + + /// + /// A function that receives files with matrices at the input, and a calculated matrix at the output + /// + public static void Multiplication(string firstFile, string secondFile, string resultFile) + { + var firstMatrix = ReadFromFile(firstFile); + var secondMatrix = ReadFromFile(secondFile); + var resultMatrix = ParallelMultiply(firstMatrix, secondMatrix); + WriteResultToFile(resultFile, resultMatrix); + } + + /// + /// Multiplies matrices by successive multiplication + /// + public static long CompareMultiplication(string firstFile, string secondFile) + { + var firstMatrix = ReadFromFile(firstFile); + var secondMatrix = ReadFromFile(secondFile); + + var stopwatchParallelMultiplication = new Stopwatch(); + stopwatchParallelMultiplication.Start(); + var resultMatrixFromParallelMultiplication = ParallelMultiply(firstMatrix, secondMatrix); + stopwatchParallelMultiplication.Stop(); + + var result = stopwatchParallelMultiplication.ElapsedMilliseconds; + + var stopwatchConsistentMultiplication = new Stopwatch(); + stopwatchConsistentMultiplication.Start(); + var resultMatrixFromConsistentMultipliaction = ConsistentMultiply(firstMatrix, secondMatrix); + stopwatchConsistentMultiplication.Stop(); + + result -= stopwatchConsistentMultiplication.ElapsedMilliseconds; + + if (!AreEquals(resultMatrixFromConsistentMultipliaction, resultMatrixFromParallelMultiplication)) + { + throw new MultiplyException(); + } + + return result; + } +} \ No newline at end of file diff --git a/parallelMatrixMultiplication/parallelMatrixMultiplication/MultiplyException.cs b/parallelMatrixMultiplication/parallelMatrixMultiplication/MultiplyException.cs new file mode 100644 index 0000000..8d38a06 --- /dev/null +++ b/parallelMatrixMultiplication/parallelMatrixMultiplication/MultiplyException.cs @@ -0,0 +1,13 @@ +namespace parallelMatrixMultiplication; + +/// +/// An exception is thrown when the results of parallel and sequential multiplication do not match +/// +public class MultiplyException : Exception +{ + public MultiplyException() {} + + public MultiplyException(string? message) : base(message) {} + + public MultiplyException(string? message, Exception? innerException) : base(message, innerException) {} +} \ No newline at end of file diff --git a/parallelMatrixMultiplication/parallelMatrixMultiplication/Program.cs b/parallelMatrixMultiplication/parallelMatrixMultiplication/Program.cs new file mode 100644 index 0000000..c0f9173 --- /dev/null +++ b/parallelMatrixMultiplication/parallelMatrixMultiplication/Program.cs @@ -0,0 +1,49 @@ +using parallelMatrixMultiplication; + +Console.WriteLine("Write first file name"); +var firstFile = Console.ReadLine(); +Console.WriteLine("Write second file name"); +var secondFile = Console.ReadLine(); +Console.WriteLine("Write name file where will be result"); +var resultFile = Console.ReadLine(); +Console.WriteLine("Write file path for create table"); +var tableFile = Console.ReadLine(); + +if (tableFile == null) +{ + Console.WriteLine("Неверно прописан путь для tableFile"); + return; +} +if (resultFile == null) +{ + Console.WriteLine("Неверно прописан путь для resulFile"); + return; +} +if (secondFile == null) +{ + Console.WriteLine("Неверно прописан путь для secondFile"); + return; +} +if (firstFile == null) +{ + Console.WriteLine("Неверно прописан путь для firstFile"); + return; +} + +Matrix.Multiplication(firstFile, secondFile, resultFile); + +StandartDeviationAndMathExpectation.CreateTableWithResults(tableFile); + +var resultCompare = Matrix.CompareMultiplication(firstFile, secondFile); +if (resultCompare < 0) +{ + Console.Write("Параллельное перемножение матриц медленнее, чем последовательное на "); + Console.Write(resultCompare); + Console.WriteLine(" миллисекунд"); +} +if (resultCompare > 0) +{ + Console.Write("Последовательное перемножение матриц медленнее, чем параллельное на "); + Console.Write(resultCompare); + Console.WriteLine(" миллисекунд"); +} \ No newline at end of file diff --git a/parallelMatrixMultiplication/parallelMatrixMultiplication/StandartDeviationAndMathExpectation.cs b/parallelMatrixMultiplication/parallelMatrixMultiplication/StandartDeviationAndMathExpectation.cs new file mode 100644 index 0000000..4b97258 --- /dev/null +++ b/parallelMatrixMultiplication/parallelMatrixMultiplication/StandartDeviationAndMathExpectation.cs @@ -0,0 +1,184 @@ +using System.Diagnostics; + +using parallelMatrixMultiplication; + +/// +/// A class for measuring the standard deviation and mathematical expectation +/// +public static class StandartDeviationAndMathExpectation +{ + private static int n = 10; + + private static double GetStandartDeviation(int n, double[] arrayForStandardDeviation, double mathExpectation) + { + double summaryForStandartDeviation = 0; + for (int i = 0; i < n; i++) + { + summaryForStandartDeviation += Math.Pow(arrayForStandardDeviation[i] - mathExpectation, 2); + } + + return Math.Round(Math.Sqrt(summaryForStandartDeviation / (n - 1)), 3); + } + + private static double GetMathExpectation(int[][] firstMatrix, int[][] secondMatrix, + double[] arrayForStandardDeviation, int n, bool isConsistentMultiply) + { + double summary = 0; + for (int i = 0; i < n; i++) + { + var stopWatch = new Stopwatch(); + stopWatch.Start(); + if (isConsistentMultiply) + { + var resultMatrix = Matrix.ConsistentMultiply(firstMatrix, secondMatrix); + } + else + { + var resultMatrix = Matrix.ParallelMultiply(firstMatrix, secondMatrix); + } + stopWatch.Stop(); + arrayForStandardDeviation[i] = stopWatch.ElapsedMilliseconds; + summary += arrayForStandardDeviation[i]; + } + return summary / n; + } + + private static void MultiplyMatricesOfSizeTwoHundredAndFiftyByTwoHundredAndFifty(string filePath) + { + var listOfValuesFirstMatrix = new List { }; + var listOfValuesSecondMatrix = new List { }; + + for (int i = 0; i < 250; i++) + { + listOfValuesFirstMatrix.Add(new int[250]); + listOfValuesSecondMatrix.Add(new int[250]); + for (int j = 0; j < 250; ++j) + { + listOfValuesFirstMatrix[i][j] = 1; + listOfValuesSecondMatrix[i][j] = 1; + } + } + + var firstMatrix = Matrix.Create(250, 250, listOfValuesFirstMatrix); + var secondMatrix = Matrix.Create(250, 250, listOfValuesSecondMatrix); + + var arrayForStandardDeviationMultiThreaded = new double[n]; + var arrayForStandardDeviationSingleThreaded = new double[n]; + double mathExpectationMultiThreaded = GetMathExpectation(firstMatrix, secondMatrix, + arrayForStandardDeviationMultiThreaded, n, false); + double mathExpectationSingleThreaded = GetMathExpectation(firstMatrix, secondMatrix, + arrayForStandardDeviationSingleThreaded, n, true); + var standardDeviationMultiThreaded = GetStandartDeviation(n, arrayForStandardDeviationMultiThreaded, mathExpectationMultiThreaded); + var standardDeviationSingleThreaded = GetStandartDeviation(n, arrayForStandardDeviationSingleThreaded, mathExpectationSingleThreaded); + var streamForWrite = new StreamWriter(filePath, true); + streamForWrite.Write("250x250\nи 250x250\t\t"); + streamForWrite.Write(mathExpectationMultiThreaded); + streamForWrite.Write("\t\t "); + streamForWrite.Write(standardDeviationMultiThreaded); + streamForWrite.Write(" "); + streamForWrite.Write(mathExpectationSingleThreaded); + streamForWrite.Write(" "); + streamForWrite.WriteLine(standardDeviationSingleThreaded); + streamForWrite.Write('\n'); + streamForWrite.Close(); + } + + private static void MultiplyMatricesOfBigSize(string filePath) + { + var listOfValuesFirstMatrix = new List { }; + var listOfValuesSecondMatrix = new List { }; + + for (int i = 0; i < 10000; i++) + { + listOfValuesFirstMatrix.Add(new int[10000]); + listOfValuesSecondMatrix.Add(new int[1]); + for (int j = 0; j < 10000; ++j) + { + listOfValuesFirstMatrix[i][j] = 1; + } + listOfValuesSecondMatrix[i][0] = 1; + } + + var firstMatrix = Matrix.Create(10000, 10000, listOfValuesFirstMatrix); + var secondMatrix = Matrix.Create(10000, 1, listOfValuesSecondMatrix); + + var arrayForStandardDeviationMultiThreaded = new double[n]; + var arrayForStandardDeviationSingleThreaded = new double[n]; + double mathExpectationMultiThreaded = GetMathExpectation(firstMatrix, secondMatrix, + arrayForStandardDeviationMultiThreaded, n, false); + double mathExpectationSingleThreaded = GetMathExpectation(firstMatrix, secondMatrix, + arrayForStandardDeviationSingleThreaded, n, true); + var standardDeviationMultiThreaded = GetStandartDeviation(n, arrayForStandardDeviationMultiThreaded, mathExpectationMultiThreaded); + var standardDeviationSingleThreaded = GetStandartDeviation(n, arrayForStandardDeviationSingleThreaded, mathExpectationSingleThreaded); + var streamForWrite = new StreamWriter(filePath, true); + streamForWrite.Write("10000x10000\nи 10000x1\t\t"); + streamForWrite.Write(mathExpectationMultiThreaded); + streamForWrite.Write("\t\t "); + streamForWrite.Write(standardDeviationMultiThreaded); + streamForWrite.Write(" "); + streamForWrite.Write(mathExpectationSingleThreaded); + streamForWrite.Write(" "); + streamForWrite.WriteLine(standardDeviationSingleThreaded); + streamForWrite.Write('\n'); + streamForWrite.Close(); + } + + private static void MultiplyMatricesOfFiveHundredOnFiveHundredSize(string filePath) + { + var listOfValuesFirstMatrix = new List { }; + var listOfValuesSecondMatrix = new List { }; + + for (int i = 0; i < 500; i++) + { + listOfValuesFirstMatrix.Add(new int[500]); + listOfValuesSecondMatrix.Add(new int[500]); + for (int j = 0; j < 500; ++j) + { + listOfValuesFirstMatrix[i][j] = 1; + listOfValuesSecondMatrix[i][j] = 1; + } + } + + var firstMatrix = Matrix.Create(500, 500, listOfValuesFirstMatrix); + var secondMatrix = Matrix.Create(500, 500, listOfValuesSecondMatrix); + + var arrayForStandardDeviationMultiThreaded = new double[n]; + var arrayForStandardDeviationSingleThreaded = new double[n]; + double mathExpectationMultiThreaded = GetMathExpectation(firstMatrix, secondMatrix, + arrayForStandardDeviationMultiThreaded, n, false); + double mathExpectationSingleThreaded = GetMathExpectation(firstMatrix, secondMatrix, + arrayForStandardDeviationSingleThreaded, n, true); + var standardDeviationMultiThreaded = GetStandartDeviation(n, arrayForStandardDeviationMultiThreaded, mathExpectationMultiThreaded); + var standardDeviationSingleThreaded = GetStandartDeviation(n, arrayForStandardDeviationSingleThreaded, mathExpectationSingleThreaded); + var streamForWrite = new StreamWriter(filePath, true); + streamForWrite.Write("500x500\nи 500x500\t\t"); + streamForWrite.Write(mathExpectationMultiThreaded); + streamForWrite.Write("\t\t "); + streamForWrite.Write(standardDeviationMultiThreaded); + streamForWrite.Write(" "); + streamForWrite.Write(mathExpectationSingleThreaded); + streamForWrite.Write(" "); + streamForWrite.WriteLine(standardDeviationSingleThreaded); + streamForWrite.Write('\n'); + streamForWrite.Close(); + } + + /// + /// The function calculates the mathematical expectation and the standard deviation + /// + /// The file where the results are recorded + public static void CreateTableWithResults(string filePath) + { + var streamForWrite = new StreamWriter(filePath); + streamForWrite.Write("В файле представлены: математическое ожидание и среднеквадратичное отклонение\n"); + streamForWrite.WriteLine("-----------------------------------------------------------------------------"); + streamForWrite.Write("Размеры матриц\tμ+parallelization\t" + + "σ+parallelization" + + "\tμ\tσ\n"); + streamForWrite.WriteLine("-----------------------------------------------------------------------------"); + streamForWrite.Close(); + MultiplyMatricesOfSizeTwoHundredAndFiftyByTwoHundredAndFifty(filePath); + MultiplyMatricesOfBigSize(filePath); + MultiplyMatricesOfFiveHundredOnFiveHundredSize(filePath); + } +} diff --git a/parallelMatrixMultiplication/parallelMatrixMultiplication/parallelMatrixMultiplication.csproj b/parallelMatrixMultiplication/parallelMatrixMultiplication/parallelMatrixMultiplication.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/parallelMatrixMultiplication/parallelMatrixMultiplication/parallelMatrixMultiplication.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/parallelMatrixMultiplication/tableFile.txt b/parallelMatrixMultiplication/tableFile.txt new file mode 100644 index 0000000..3b86ac4 --- /dev/null +++ b/parallelMatrixMultiplication/tableFile.txt @@ -0,0 +1,13 @@ +В файле представлены: математическое ожидание и среднеквадратичное отклонение +----------------------------------------------------------------------------- +Размеры матриц μ+parallelization σ+parallelization μ σ +----------------------------------------------------------------------------- +250x250 +и 250x250 16,4 3,169 57,5 0,707 + +10000x10000 +и 10000x1 94,2 13,122 343,4 1,713 + +500x500 +и 500x500 105,8 3,259 477,4 4,195 +