diff --git a/McdaMethods.sln b/McdaMethods.sln index 7f4097e..e6dba29 100644 --- a/McdaMethods.sln +++ b/McdaMethods.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McdaToolkit", "McdaToolkit\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McdaToolkit.UnitTests", "McdaToolkit.UnitTests\McdaToolkit.UnitTests.csproj", "{675DE565-59A0-4865-A306-B12FCC64EF1F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUddsadsada", "TestUddsadsada\TestUddsadsada.csproj", "{C7D4020C-DC44-47E3-BB9C-2D4CCFA88A82}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {675DE565-59A0-4865-A306-B12FCC64EF1F}.Debug|Any CPU.Build.0 = Debug|Any CPU {675DE565-59A0-4865-A306-B12FCC64EF1F}.Release|Any CPU.ActiveCfg = Release|Any CPU {675DE565-59A0-4865-A306-B12FCC64EF1F}.Release|Any CPU.Build.0 = Release|Any CPU + {C7D4020C-DC44-47E3-BB9C-2D4CCFA88A82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7D4020C-DC44-47E3-BB9C-2D4CCFA88A82}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7D4020C-DC44-47E3-BB9C-2D4CCFA88A82}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7D4020C-DC44-47E3-BB9C-2D4CCFA88A82}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/McdaToolkit.UnitTests/McdaMethodsTests.cs b/McdaToolkit.UnitTests/McdaMethodsTests.cs index f67115b..e1d34f6 100644 --- a/McdaToolkit.UnitTests/McdaMethodsTests.cs +++ b/McdaToolkit.UnitTests/McdaMethodsTests.cs @@ -1,6 +1,6 @@ using FluentAssertions; using MathNet.Numerics; -using McdaToolkit.Mcda; +using McdaToolkit.McdaMethods; using McdaToolkit.UnitTests.Helpers; using Xunit.Abstractions; diff --git a/McdaToolkit/Extensions/EnumerableExtentions.cs b/McdaToolkit/Extensions/EnumerableExtentions.cs index cb0ae6f..4d2848d 100644 --- a/McdaToolkit/Extensions/EnumerableExtentions.cs +++ b/McdaToolkit/Extensions/EnumerableExtentions.cs @@ -4,7 +4,11 @@ internal static class EnumerableExtentions { public static IEnumerable<(T item, int index)> Indexed(this IEnumerable source) { - ArgumentNullException.ThrowIfNull(source); + if (source is null) + { + throw new ArgumentNullException(); + } + var i = 0; foreach (var item in source) { diff --git a/McdaToolkit/Mcda/Interfaces/IMethod.cs b/McdaToolkit/Mcda/Interfaces/IMethod.cs deleted file mode 100644 index 5705f4a..0000000 --- a/McdaToolkit/Mcda/Interfaces/IMethod.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace McdaToolkit.Mcda.Interfaces; - -public interface IMethod -{ - MathNet.Numerics.LinearAlgebra.Vector Calculate(double[,] matrix, double[] weights, int[] criteriaDirections); -} \ No newline at end of file diff --git a/McdaToolkit/McdaMethods/Interfaces/IMethod.cs b/McdaToolkit/McdaMethods/Interfaces/IMethod.cs new file mode 100644 index 0000000..0853a6c --- /dev/null +++ b/McdaToolkit/McdaMethods/Interfaces/IMethod.cs @@ -0,0 +1,9 @@ +using MathNet.Numerics.LinearAlgebra; + +namespace McdaToolkit.McdaMethods.Interfaces; + +public interface IMethod +{ + Vector Calculate(double[,] matrix, double[] weights, int[] criteriaDirections); + Vector Calculate(IEnumerable> matrix, double[] weights, int[] criteriaDirections); +} \ No newline at end of file diff --git a/McdaToolkit/McdaMethods/McdaMethod.cs b/McdaToolkit/McdaMethods/McdaMethod.cs new file mode 100644 index 0000000..9869d09 --- /dev/null +++ b/McdaToolkit/McdaMethods/McdaMethod.cs @@ -0,0 +1,21 @@ +using MathNet.Numerics.LinearAlgebra; +using McdaToolkit.McdaMethods.Interfaces; + +namespace McdaToolkit.McdaMethods; + +public abstract class McdaMethod : IMethod +{ + public Vector Calculate(double[,] matrix, double[] weights, int[] criteriaDirections) + { + var matrixTypeOfMatrix = Matrix.Build.DenseOfArray(matrix); + return Calculate(matrixTypeOfMatrix, weights, criteriaDirections); + } + + public Vector Calculate(IEnumerable> matrix, double[] weights, int[] criteriaDirections) + { + var matrixTypeOfMatrix = Matrix.Build.DenseOfRows(matrix); + return Calculate(matrixTypeOfMatrix, weights, criteriaDirections); + } + + protected abstract Vector Calculate(Matrix matrix, double[] weights, int[] criteriaDirections); +} \ No newline at end of file diff --git a/McdaToolkit/Mcda/TopsisMethod.cs b/McdaToolkit/McdaMethods/TopsisMethod.cs similarity index 61% rename from McdaToolkit/Mcda/TopsisMethod.cs rename to McdaToolkit/McdaMethods/TopsisMethod.cs index 5be6233..51fa068 100644 --- a/McdaToolkit/Mcda/TopsisMethod.cs +++ b/McdaToolkit/McdaMethods/TopsisMethod.cs @@ -1,33 +1,27 @@ -using System.Numerics; using MathNet.Numerics.LinearAlgebra; using McdaToolkit.Enums; -using McdaToolkit.Mcda.Interfaces; +using McdaToolkit.McdaMethods.Interfaces; using McdaToolkit.Normalization; using McdaToolkit.Options; -namespace McdaToolkit.Mcda; +namespace McdaToolkit.McdaMethods; -public class TopsisMethod : IMethod +public class TopsisMethod : McdaMethod { private DataNormalizationService _normalizationServiceService; + public TopsisMethod() - { + { _normalizationServiceService = new DataNormalizationService(NormalizationMethodEnum.MinMax); } - - public TopsisMethod(McdaMethodOptions options) - { - _normalizationServiceService = new DataNormalizationService(options.NormalizationMethodEnum); - } - public MathNet.Numerics.LinearAlgebra.Vector Calculate(double[,] matrix, double[] weights, - int[] criteriaDirections) + public TopsisMethod(McdaMethodOptions options) { - var convertedMatrix = Matrix.Build.DenseOfArray(matrix); - return Calculate(convertedMatrix,weights, criteriaDirections); + _normalizationServiceService = new DataNormalizationService(options.NormalizationMethodEnum); } - private MathNet.Numerics.LinearAlgebra.Vector Calculate(Matrix? matrix, double[] weights, int[] criteriaDirections) + protected override Vector Calculate(Matrix matrix, double[] weights, + int[] criteriaDirections) { var normalizedMatrix = _normalizationServiceService.NormalizeMatrix(matrix, criteriaDirections); var weightedMatrix = WeightedMatrix(normalizedMatrix, weights); @@ -41,6 +35,7 @@ private MathNet.Numerics.LinearAlgebra.Vector Calculate(Matrix? return topsisScores; } + private Matrix WeightedMatrix(Matrix matrix, double[] weights) { for (int i = 0; i < matrix.RowCount; i++) @@ -50,20 +45,24 @@ private Matrix WeightedMatrix(Matrix matrix, double[] weights) matrix[i, j] *= weights[j]; } } + return matrix; } - private MathNet.Numerics.LinearAlgebra.Vector IdealValues(Matrix matrix, bool pis) + + private Vector IdealValues(Matrix matrix, bool pis) { - return MathNet.Numerics.LinearAlgebra.Vector.Build + return Vector.Build .Dense(matrix.ColumnCount, i => { var columnValues = matrix.Column(i).ToArray(); return pis ? columnValues.Max() : columnValues.Min(); }); } - private MathNet.Numerics.LinearAlgebra.Vector CalculateEuclideanDistance(Matrix matrix, MathNet.Numerics.LinearAlgebra.Vector ideal) + + private Vector CalculateEuclideanDistance(Matrix matrix, + Vector ideal) { - return MathNet.Numerics.LinearAlgebra.Vector.Build + return Vector.Build .DenseOfArray(matrix .EnumerateRows() .Select(row => row @@ -73,9 +72,9 @@ private MathNet.Numerics.LinearAlgebra.Vector CalculateEuclideanDistance .Sum()) .ToArray()); } - private MathNet.Numerics.LinearAlgebra.Vector CalculateTopsisScores(MathNet.Numerics.LinearAlgebra.Vector distanceToBest, MathNet.Numerics.LinearAlgebra.Vector distanceToWorst) + + private Vector CalculateTopsisScores(Vector distanceToBest, Vector distanceToWorst) { - return distanceToWorst - .PointwiseDivide(distanceToBest.Add(distanceToWorst)); + return distanceToWorst.PointwiseDivide(distanceToBest.Add(distanceToWorst)); } -} +} \ No newline at end of file diff --git a/McdaToolkit/McdaToolkit.csproj b/McdaToolkit/McdaToolkit.csproj index 990ee77..5047265 100644 --- a/McdaToolkit/McdaToolkit.csproj +++ b/McdaToolkit/McdaToolkit.csproj @@ -1,12 +1,19 @@ - net8.0 enable enable + + McdaToolkit 1.0.1 + Jakub Tokarczyk + latest + netstandard2.1;net6.0;net7.0;net8.0 + © 2024 Jakub Tokarczyk + MIT + https://github.com/SarcasticMoose/mcda-toolkit - + diff --git a/McdaToolkit/Normalization/DataNormalizationService.cs b/McdaToolkit/Normalization/DataNormalizationService.cs index ad04b3e..82e299d 100644 --- a/McdaToolkit/Normalization/DataNormalizationService.cs +++ b/McdaToolkit/Normalization/DataNormalizationService.cs @@ -13,7 +13,7 @@ public class DataNormalizationService(NormalizationMethodEnum methodEnum) : IDat { private readonly INormalizationMethod _method = NormalizationFactory.CreateNormalizationMethod(methodEnum); - public Matrix NormalizeMatrix(Matrix? matrix, int[] criteriaTypes) + public Matrix NormalizeMatrix(Matrix matrix, int[] criteriaTypes) { var normalizedMatrix = Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount); diff --git a/McdaToolkit/Normalization/Interfaces/IDataNormalization.cs b/McdaToolkit/Normalization/Interfaces/IDataNormalization.cs index 5431713..ef571b4 100644 --- a/McdaToolkit/Normalization/Interfaces/IDataNormalization.cs +++ b/McdaToolkit/Normalization/Interfaces/IDataNormalization.cs @@ -4,5 +4,5 @@ namespace McdaToolkit.Normalization.Interfaces; public interface IDataNormalization { - Matrix NormalizeMatrix(Matrix? matrix, int[] criteriaTypes); + Matrix NormalizeMatrix(Matrix matrix, int[] criteriaTypes); } \ No newline at end of file diff --git a/McdaToolkit/NormalizationMethods/MinMaxNormalization.cs b/McdaToolkit/NormalizationMethods/MinMaxNormalization.cs index b00a9f4..99107e8 100644 --- a/McdaToolkit/NormalizationMethods/MinMaxNormalization.cs +++ b/McdaToolkit/NormalizationMethods/MinMaxNormalization.cs @@ -1,19 +1,18 @@ -using System.Numerics; using McdaToolkit.NormalizationMethods.Interfaces; +using MathNet.Numerics.LinearAlgebra; namespace McdaToolkit.NormalizationMethods; public class MinMaxNormalization : INormalizationMethod { - public MathNet.Numerics.LinearAlgebra.Vector Normalize(MathNet.Numerics.LinearAlgebra.Vector data, bool cost = false) + public Vector Normalize(MathNet.Numerics.LinearAlgebra.Vector data, bool cost = false) { var max = data.Maximum(); var min = data.Minimum(); var difference = max - min; - if (Math.Abs(difference) < 1.11e-16) { - return MathNet.Numerics.LinearAlgebra.Vector.Build.Dense(data.Count, (i) => 1); + return Vector.Build.Dense(data.Count, (i) => 1); } if (cost)