diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0bd6c70..ef1009b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,3 +9,40 @@ All notable changes to this project will be documented in this file. See [versio
* add vector normalization ([c819676](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/c81967667e032413cdad426a9a5a0e6dfecd6804))
+
+## [2.0.1](https://www.github.com/SarcasticMoose/mcda-toolkit/releases/tag/v2.0.1) (2024-06-12)
+
+### Bug Fixes
+
+* remove redundant casting ([6db1dbc](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/6db1dbc1f88f2e342d8b3d7aa81364d90e4dfab5))
+* update broken project ([ea46d0d](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/ea46d0d1c43ba0c25c957fbc6dd60e70dfd88326))
+
+
+## [2.0.0](https://www.github.com/SarcasticMoose/mcda-toolkit/releases/tag/v2.0.0) (2024-06-12)
+
+### Features
+
+* add enumeration iteration with index ([4c76513](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/4c76513a9100a629accd43f28bd41d33d6e211ea))
+* add generic methods ([7cfd3ea](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/7cfd3eac2afcd59b4c7f2e808eddf9aa926386a5))
+* add versioning ([8db0fc3](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/8db0fc30cd345134a7210b069fb519b193f27bc8))
+
+### Bug Fixes
+
+* fix project ([a9cdc05](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/a9cdc05d72d01901eb0be13aa1772187fabfa083))
+
+### Breaking Changes
+
+* adjust styling,names etc. ([d23c29d](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/d23c29dd9d1f3924f5aabc82b5a3472bc085d9dd))
+
+
+## [1.0.1](https://www.github.com/SarcasticMoose/mcda-toolkit/releases/tag/v1.0.1) (2024-06-03)
+
+
+## [1.0.0](https://www.github.com/SarcasticMoose/mcda-toolkit/releases/tag/v1.0.0) (2024-06-03)
+
+### Features
+
+* add enumeration iteration with index ([5196aa1](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/5196aa1df9c2b86d6a495454b2e3fb9a2a5f3d1d))
+* add generic methods ([d75c45e](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/d75c45e9bb11a8a001be2151ffd8a070d1461fc7))
+* add versioning ([69b93d0](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/69b93d0b2d4669bb7ffb28f3e36fb754280ea352))
+
diff --git a/McdaMethods.sln b/McdaMethods.sln
index 85f515f..bf99a35 100644
--- a/McdaMethods.sln
+++ b/McdaMethods.sln
@@ -1,11 +1,10 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34525.116
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McdaToolkit", "McdaToolkit\McdaToolkit.csproj", "{EC147B8B-336E-4744-8F54-43D1BB0E4FC3}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McdaToolkit", "src\McdaToolkit\McdaToolkit.csproj", "{EC2ACBF0-59C4-4B03-B9AD-54E31E69A791}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McdaToolkit.UnitTests", "McdaToolkit.UnitTests\McdaToolkit.UnitTests.csproj", "{675DE565-59A0-4865-A306-B12FCC64EF1F}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McdaToolkit.UnitTests", "tests\McdaToolkit.UnitTests\McdaToolkit.UnitTests.csproj", "{C16A9430-0ABA-44D5-B9D2-256DEA133D38}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +12,14 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {EC147B8B-336E-4744-8F54-43D1BB0E4FC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EC147B8B-336E-4744-8F54-43D1BB0E4FC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EC147B8B-336E-4744-8F54-43D1BB0E4FC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EC147B8B-336E-4744-8F54-43D1BB0E4FC3}.Release|Any CPU.Build.0 = Release|Any CPU
- {675DE565-59A0-4865-A306-B12FCC64EF1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {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
+ {EC2ACBF0-59C4-4B03-B9AD-54E31E69A791}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC2ACBF0-59C4-4B03-B9AD-54E31E69A791}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC2ACBF0-59C4-4B03-B9AD-54E31E69A791}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC2ACBF0-59C4-4B03-B9AD-54E31E69A791}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C16A9430-0ABA-44D5-B9D2-256DEA133D38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C16A9430-0ABA-44D5-B9D2-256DEA133D38}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C16A9430-0ABA-44D5-B9D2-256DEA133D38}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C16A9430-0ABA-44D5-B9D2-256DEA133D38}.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
deleted file mode 100644
index cb50ca9..0000000
--- a/McdaToolkit.UnitTests/McdaMethodsTests.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-using FluentAssertions;
-using MathNet.Numerics;
-using McdaToolkit.McdaMethods;
-using McdaToolkit.McdaMethods.Errors;
-using McdaToolkit.UnitTests.Helpers;
-using Xunit.Abstractions;
-
-namespace McdaToolkit.UnitTests;
-
-public class McdaMethodsTests
-{
- private readonly ITestOutputHelper _testOutputHelper;
-
- public McdaMethodsTests(ITestOutputHelper testOutputHelper)
- {
- _testOutputHelper = testOutputHelper;
- }
-
- [Fact]
- public void Calculate_TopsisMethod_ShouldBeEqualToExpected()
- {
- var matrix = new double[,]
- {
- { 66, 56, 95 },
- { 61, 55, 166 },
- { 65, 49, 113 },
- { 95, 56, 99 },
- { 63, 43, 178 },
- { 74, 59, 140 },
- };
- double[] weights = new double[]
- {
- 0.4,0.25,0.35
- };
- int[] types = new int[]
- {
- -1,
- -1,
- 1
- };
- double[] expectedTopsisScore = new double[]
- {
- 0.38805147,0.76189759,0.58509479,0.06374247,0.97647059,0.43681786
- };
-
- var topsis = new TopsisMethod();
- var topsisResult = topsis.Calculate(matrix,weights,types);
-
- var final = topsisResult.Value;
-
- final.Enumerate()
- .Select(x => x.Round(8))
- .Should()
- .BeEquivalentTo(expectedTopsisScore);
- }
-
- [Fact]
- public void Calculate_WeightAreNotEqualOne_ShouldReturnResultFail()
- {
- var matrix = new double[,]
- {
- { 66, 56, 95 },
- { 61, 55, 166 },
- { 65, 49, 113 },
- { 95, 56, 99 },
- { 63, 43, 178 },
- { 74, 59, 140 },
- };
- double[] weights = new double[]
- {
- 0.8,0.25,0.35
- };
- int[] types = new int[]
- {
- -1,
- -1,
- 1
- };
-
- var topsis = new TopsisMethod();
- var topsisResult = topsis.Calculate(matrix, weights, types);
-
- topsisResult.IsSuccess.Should().BeFalse();
- topsisResult.HasError();
- }
-
- [Fact]
- public void Calculate_DecisionCriteriaAreNotBetweenMinusOneAndOne_ShouldReturnResultFail()
- {
- var matrix = new double[,]
- {
- { 66, 56, 95 },
- { 61, 55, 166 },
- { 65, 49, 113 },
- { 95, 56, 99 },
- { 63, 43, 178 },
- { 74, 59, 140 },
- };
- double[] weights = new double[]
- {
- 0.4,0.25,0.35
- };
- int[] types = new int[]
- {
- -1,
- -2,
- 1
- };
-
- var topsis = new TopsisMethod();
- var topsisResult = topsis.Calculate(matrix, weights, types);
-
- topsisResult.IsSuccess.Should().BeFalse();
- topsisResult.HasError();
- }
-
- [Fact]
- public void Calculate_DimensionsOfAllMatrixesNotTheSame_ShouldReturnResultFail()
- {
- var matrix = new double[,]
- {
- { 66, 56, 95 },
- { 61, 55, 166 },
- { 65, 49, 113 },
- { 95, 56, 99 },
- { 63, 43, 178 },
- { 74, 59, 140 },
- };
- double[] weights = new double[]
- {
- 0.4,0.25,0.15,0.20
- };
- int[] types = new int[]
- {
- -1,
- -1,
- 1,
- 1
- };
-
- var topsis = new TopsisMethod();
- var topsisResult = topsis.Calculate(matrix, weights, types);
-
- topsisResult.IsSuccess.Should().BeFalse();
- topsisResult.HasError();
- }
-}
\ No newline at end of file
diff --git a/McdaToolkit.UnitTests/NormalizationUnitTests.cs b/McdaToolkit.UnitTests/NormalizationUnitTests.cs
deleted file mode 100644
index 007765a..0000000
--- a/McdaToolkit.UnitTests/NormalizationUnitTests.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using FluentAssertions;
-using MathNet.Numerics.LinearAlgebra;
-using McdaToolkit.Enums;
-using McdaToolkit.Normalization;
-using McdaToolkit.UnitTests.Helpers;
-
-namespace McdaToolkit.UnitTests;
-
-public class NormalizationUnitTests
-{
- private readonly Matrix _matrixToNormalize = Matrix.Build.DenseOfArray(new double[,]
- {
- { 32.57, 14.56, 87.12, 56.34, 47.89 },
- { 93.23, 76.34, 33.78, 25.68, 64.23 },
- { 78.45, 68.92, 45.67, 87.34, 39.45 },
- { 54.12, 34.56, 56.89, 92.56, 81.56 },
- { 21.76, 53.23, 73.21, 65.78, 57.34 },
- { 85.34, 98.45, 38.45, 23.45, 62.89 },
- { 42.68, 27.34, 49.67, 74.12, 53.21 }
- });
-
- private readonly int[] _types = [-1, -1, 1, 1, -1];
-
- [Fact]
- public void Normalize_MinMaxNormalization_ShouldReturnedExpectedValues()
- {
- var expected = new double[][]
- {
- [0.84874773, 1, 1, 0.47590797, 0.79957255],
- [0, 0.26355942, 0, 0.03226740, 0.41154120],
- [0.20680006, 0.35200858, 0.22290964, 0.92446824, 1],
- [0.54722261, 0.76159256, 0.43325834, 1, 0],
- [1, 0.53903922, 0.73922010, 0.61250181, 0.57516029],
- [0.11039597, 0, 0.08755156, 0, 0.44336262],
- [0.70728977, 0.84765765, 0.29790026, 0.73317899, 0.67323676]
- };
- var dataNormalization = new DataNormalizationService(NormalizationMethodEnum.MinMax);
-
- var normalizedMatrix = dataNormalization.NormalizeMatrix(_matrixToNormalize,_types);
-
- var equalityResult = TestHelpers.CheckEquality(normalizedMatrix, expected);
- equalityResult.Should().BeTrue();
- }
-
- [Fact]
- public void Normalize_VectorNormalization_ShouldReturnedExpectedValues()
- {
- var normalizationType = NormalizationMethodEnum.Vector;
- var expected = new double[][]
- {
- [0.80678026, 0.90838501, 0.57002794, 0.32313221, 0.69529318],
- [0.44691814, 0.51965053, 0.22102323, 0.14728497, 0.59132764],
- [0.53459968, 0.56633894, 0.29881974, 0.50092948, 0.74899386],
- [0.67893607, 0.78254024, 0.37223243, 0.53086825, 0.48106309],
- [0.87090999, 0.66506416, 0.47901452, 0.37727434, 0.63516623],
- [0.49372513, 0.38052914, 0.25157913, 0.13449503, 0.59985358],
- [0.74680324, 0.82797021, 0.32499182, 0.42510755, 0.66144393]
- };
- var dataNormalization = new DataNormalizationService(normalizationType);
-
- var normalizedMatrix = dataNormalization.NormalizeMatrix(_matrixToNormalize,_types);
-
- var equalityResult = TestHelpers.CheckEquality(normalizedMatrix, expected);
- equalityResult.Should().BeTrue();
- }
-}
\ No newline at end of file
diff --git a/McdaToolkit/CHANGELOG.md b/McdaToolkit/CHANGELOG.md
deleted file mode 100644
index 9531e4d..0000000
--- a/McdaToolkit/CHANGELOG.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Change Log
-
-All notable changes to this project will be documented in this file. See [versionize](https://github.com/versionize/versionize) for commit guidelines.
-
-
-## [2.0.1](https://www.github.com/SarcasticMoose/mcda-toolkit/releases/tag/v2.0.1) (2024-06-12)
-
-### Bug Fixes
-
-* remove redundant casting ([6db1dbc](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/6db1dbc1f88f2e342d8b3d7aa81364d90e4dfab5))
-* update broken project ([ea46d0d](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/ea46d0d1c43ba0c25c957fbc6dd60e70dfd88326))
-
-
-## [2.0.0](https://www.github.com/SarcasticMoose/mcda-toolkit/releases/tag/v2.0.0) (2024-06-12)
-
-### Features
-
-* add enumeration iteration with index ([4c76513](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/4c76513a9100a629accd43f28bd41d33d6e211ea))
-* add generic methods ([7cfd3ea](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/7cfd3eac2afcd59b4c7f2e808eddf9aa926386a5))
-* add versioning ([8db0fc3](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/8db0fc30cd345134a7210b069fb519b193f27bc8))
-
-### Bug Fixes
-
-* fix project ([a9cdc05](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/a9cdc05d72d01901eb0be13aa1772187fabfa083))
-
-### Breaking Changes
-
-* adjust styling,names etc. ([d23c29d](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/d23c29dd9d1f3924f5aabc82b5a3472bc085d9dd))
-
-
-## [1.0.1](https://www.github.com/SarcasticMoose/mcda-toolkit/releases/tag/v1.0.1) (2024-06-03)
-
-
-## [1.0.0](https://www.github.com/SarcasticMoose/mcda-toolkit/releases/tag/v1.0.0) (2024-06-03)
-
-### Features
-
-* add enumeration iteration with index ([5196aa1](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/5196aa1df9c2b86d6a495454b2e3fb9a2a5f3d1d))
-* add generic methods ([d75c45e](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/d75c45e9bb11a8a001be2151ffd8a070d1461fc7))
-* add versioning ([69b93d0](https://www.github.com/SarcasticMoose/mcda-toolkit/commit/69b93d0b2d4669bb7ffb28f3e36fb754280ea352))
-
diff --git a/McdaToolkit/Enums/NormalizationMethodEnum.cs b/McdaToolkit/Enums/NormalizationMethodEnum.cs
deleted file mode 100644
index fff4dc5..0000000
--- a/McdaToolkit/Enums/NormalizationMethodEnum.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace McdaToolkit.Enums;
-
-public enum NormalizationMethodEnum
-{
- MinMax,
- Vector
-}
\ No newline at end of file
diff --git a/McdaToolkit/Extensions/EnumerableExtentions.cs b/McdaToolkit/Extensions/EnumerableExtentions.cs
deleted file mode 100644
index 4d2848d..0000000
--- a/McdaToolkit/Extensions/EnumerableExtentions.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace McdaToolkit.Extensions;
-
-internal static class EnumerableExtentions
-{
- public static IEnumerable<(T item, int index)> Indexed(this IEnumerable source)
- {
- if (source is null)
- {
- throw new ArgumentNullException();
- }
-
- var i = 0;
- foreach (var item in source)
- {
- yield return (item, i);
- ++i;
- }
- }
-}
\ No newline at end of file
diff --git a/McdaToolkit/McdaMethods/Abstraction/McdaMethod.cs b/McdaToolkit/McdaMethods/Abstraction/McdaMethod.cs
deleted file mode 100644
index 68d5cc7..0000000
--- a/McdaToolkit/McdaMethods/Abstraction/McdaMethod.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using LightResults;
-using MathNet.Numerics.LinearAlgebra;
-using McdaToolkit.McdaMethods.Errors;
-using McdaToolkit.McdaMethods.Helpers;
-using McdaToolkit.McdaMethods.Interfaces;
-
-namespace McdaToolkit.McdaMethods.Abstraction;
-
-public abstract class McdaMethod : IMethod
-{
- private Result InitialErrorsCheck(double[,] matrix, double[] weights, int[] criteriaDirections)
- {
- if (weights == null)
- {
- throw new ArgumentNullException(nameof(weights), "Value cannot be null");
- }
-
- if (criteriaDirections == null)
- {
- throw new ArgumentNullException(nameof(criteriaDirections), "Value cannot be null");
- }
-
- var isWeightsCorrect = CheckDataHelper.IsWeightEqualOne(weights);
-
- if (!isWeightsCorrect)
- {
- return Result.Fail(new WeightNotSumToOneError());
- }
-
- var isCriteriaDecisionCorrect = CheckDataHelper.IsCriteriaDesisionBetweenMinusOneAndOne(criteriaDirections);
-
- if (!isCriteriaDecisionCorrect)
- {
- return Result.Fail(new CriteriaNotBetweenMinusOneAndOne());
- }
-
- var isSizesAreCorrect = CheckDataHelper.IsDataWeightsAndTypesHaveCorrectSizes(matrix, weights, criteriaDirections);
-
- if (!isSizesAreCorrect)
- {
- return Result.Fail(new ArraySizesAreNotEqual());
- }
-
- return Result.Ok();
- }
- public Result> Calculate(double[,] matrix, double[] weights, int[] criteriaDirections)
- {
- var errorsCheckResult = InitialErrorsCheck(matrix,weights, criteriaDirections);
-
- if (errorsCheckResult.IsFailed)
- {
- return Result.Fail>(errorsCheckResult.Errors);
- }
-
- var matrixTypeOfMatrix = Matrix.Build.DenseOfArray(matrix);
- return Calculate(matrixTypeOfMatrix, weights, criteriaDirections);
- }
- protected abstract Result> Calculate(Matrix matrix, double[] weights, int[] criteriaDirections);
-}
\ No newline at end of file
diff --git a/McdaToolkit/McdaMethods/Errors/ArraySizesAreNotEqual.cs b/McdaToolkit/McdaMethods/Errors/ArraySizesAreNotEqual.cs
deleted file mode 100644
index d7ad7b2..0000000
--- a/McdaToolkit/McdaMethods/Errors/ArraySizesAreNotEqual.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using LightResults;
-
-namespace McdaToolkit.McdaMethods.Errors;
-
-public class ArraySizesAreNotEqual() : Error("Columns length of data matrix should be equal length of weights and types arrays");
\ No newline at end of file
diff --git a/McdaToolkit/McdaMethods/Errors/CriteriaNotBetweenMinusOneAndOne.cs b/McdaToolkit/McdaMethods/Errors/CriteriaNotBetweenMinusOneAndOne.cs
deleted file mode 100644
index b7dba8b..0000000
--- a/McdaToolkit/McdaMethods/Errors/CriteriaNotBetweenMinusOneAndOne.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using LightResults;
-
-namespace McdaToolkit.McdaMethods.Errors;
-
-public class CriteriaNotBetweenMinusOneAndOne() : Error("Criteria decision types should be number ∈Z{-1;1}");
\ No newline at end of file
diff --git a/McdaToolkit/McdaMethods/Interfaces/IMethod.cs b/McdaToolkit/McdaMethods/Interfaces/IMethod.cs
deleted file mode 100644
index 4639692..0000000
--- a/McdaToolkit/McdaMethods/Interfaces/IMethod.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using LightResults;
-using MathNet.Numerics.LinearAlgebra;
-
-namespace McdaToolkit.McdaMethods.Interfaces;
-
-public interface IMethod
-{
- Result> Calculate(double[,] matrix, double[] weights, int[] criteriaDirections);
-}
\ No newline at end of file
diff --git a/McdaToolkit/McdaToolkit.csproj b/McdaToolkit/McdaToolkit.csproj
deleted file mode 100644
index 9051825..0000000
--- a/McdaToolkit/McdaToolkit.csproj
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
- enable
- enable
-
-
-
- McdaToolkit
- 2.1.0
- Jakub Tokarczyk
- latest
- README.md
- 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
deleted file mode 100644
index 168504e..0000000
--- a/McdaToolkit/Normalization/DataNormalizationService.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-
-using MathNet.Numerics.LinearAlgebra;
-using McdaToolkit.Enums;
-using McdaToolkit.Extensions;
-using McdaToolkit.Normalization.Interfaces;
-using McdaToolkit.NormalizationMethods.Interfaces;
-namespace McdaToolkit.Normalization;
-
-
-public class DataNormalizationService(NormalizationMethodEnum methodEnum) : IDataNormalization
-{
- private readonly INormalize _method = NormalizationFactory.CreateNormalizationMethod(methodEnum);
-
- public Matrix NormalizeMatrix(Matrix matrix, int[] criteriaTypes)
- {
- foreach (var (col,index) in matrix.EnumerateColumns().Indexed())
- {
- matrix.SetColumn(index,
- criteriaTypes[index] == 1
- ? _method.Normalize(data: col, cost: false)
- : _method.Normalize(data: col, cost: true));
- }
- return matrix;
- }
-}
diff --git a/McdaToolkit/Normalization/Interfaces/IDataNormalization.cs b/McdaToolkit/Normalization/Interfaces/IDataNormalization.cs
deleted file mode 100644
index ef571b4..0000000
--- a/McdaToolkit/Normalization/Interfaces/IDataNormalization.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using MathNet.Numerics.LinearAlgebra;
-
-namespace McdaToolkit.Normalization.Interfaces;
-
-public interface IDataNormalization
-{
- Matrix NormalizeMatrix(Matrix matrix, int[] criteriaTypes);
-}
\ No newline at end of file
diff --git a/McdaToolkit/NormalizationFactory.cs b/McdaToolkit/NormalizationFactory.cs
deleted file mode 100644
index 2c4ce3c..0000000
--- a/McdaToolkit/NormalizationFactory.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Numerics;
-using McdaToolkit.Enums;
-using McdaToolkit.NormalizationMethods;
-using McdaToolkit.NormalizationMethods.Interfaces;
-using McdaToolkit.NormalizationMethods.Types.Linear;
-using McdaToolkit.NormalizationMethods.Types.Sum;
-
-namespace McdaToolkit;
-
-internal static class NormalizationFactory
-{
- public static INormalize CreateNormalizationMethod(NormalizationMethodEnum methodEnum)
- {
- return methodEnum switch
- {
- NormalizationMethodEnum.MinMax => new MinMaxNormalization(),
- NormalizationMethodEnum.Vector => new VectorNormalization(),
- _ => throw new Exception("Not existing normalization")
- };
- }
-}
\ No newline at end of file
diff --git a/McdaToolkit/NormalizationMethods/Interfaces/INormalize.cs b/McdaToolkit/NormalizationMethods/Interfaces/INormalize.cs
deleted file mode 100644
index 8e7ab64..0000000
--- a/McdaToolkit/NormalizationMethods/Interfaces/INormalize.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using MathNet.Numerics.LinearAlgebra;
-
-namespace McdaToolkit.NormalizationMethods.Interfaces;
-
-public interface INormalize where T : struct, IEquatable, IFormattable
-{
- Vector Normalize(Vector data, bool cost);
-}
\ No newline at end of file
diff --git a/McdaToolkit/NormalizationMethods/Types/Sum/VectorNormalization.cs b/McdaToolkit/NormalizationMethods/Types/Sum/VectorNormalization.cs
deleted file mode 100644
index bf2329e..0000000
--- a/McdaToolkit/NormalizationMethods/Types/Sum/VectorNormalization.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using MathNet.Numerics.LinearAlgebra;
-using McdaToolkit.NormalizationMethods.Interfaces;
-
-namespace McdaToolkit.NormalizationMethods.Types.Sum;
-
-public class VectorNormalization : INormalize
-{
- ///
- /// Create normalized vector using vector normalization method
- ///
- /// One-dimensional vector of data to normalize
- /// Describe type of vector, cost or profit
- ///
- /// Return normalized vector
- ///
- public Vector Normalize(Vector data, bool cost)
- {
- var squaresOfSum = data / Math.Sqrt(data.PointwisePower(2).Sum());
-
- if (cost)
- {
- return 1 - squaresOfSum;
- }
-
- return squaresOfSum;
- }
-}
\ No newline at end of file
diff --git a/McdaToolkit/Options/McdaMethodOptions.cs b/McdaToolkit/Options/McdaMethodOptions.cs
deleted file mode 100644
index ebbd381..0000000
--- a/McdaToolkit/Options/McdaMethodOptions.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using McdaToolkit.Enums;
-
-namespace McdaToolkit.Options;
-
-public class McdaMethodOptions
-{
- public NormalizationMethodEnum NormalizationMethodEnum { get; set; } = NormalizationMethodEnum.MinMax;
-}
\ No newline at end of file
diff --git a/src/McdaToolkit/Enums/NormalizationMethod.cs b/src/McdaToolkit/Enums/NormalizationMethod.cs
new file mode 100644
index 0000000..a34afc7
--- /dev/null
+++ b/src/McdaToolkit/Enums/NormalizationMethod.cs
@@ -0,0 +1,10 @@
+namespace McdaToolkit.Enums;
+
+public enum NormalizationMethod
+{
+ MinMax,
+ Vector,
+ Logarithmic,
+ Sum,
+ Max
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Extensions/EnumerableExtentions.cs b/src/McdaToolkit/Extensions/EnumerableExtentions.cs
new file mode 100644
index 0000000..4dd86b9
--- /dev/null
+++ b/src/McdaToolkit/Extensions/EnumerableExtentions.cs
@@ -0,0 +1,40 @@
+namespace McdaToolkit.Extensions;
+
+internal static class EnumerableExtentions
+{
+ public static IEnumerable<(T item, int index)> Indexed(this IEnumerable source)
+ {
+ if (source is null)
+ {
+ throw new ArgumentNullException();
+ }
+
+ var i = 0;
+ foreach (var item in source)
+ {
+ yield return (item, i);
+ ++i;
+ }
+ }
+
+ public static T[,] To2DArray(this IEnumerable> source)
+ {
+ var sourceToArray = source.ToArray();
+ var rows = sourceToArray.Length;
+ var cols = sourceToArray[0].Count();
+ var result = new T[rows, cols];
+ var i = 0;
+
+ foreach (var row in sourceToArray)
+ {
+ var j = 0;
+ foreach (var value in row)
+ {
+ result[i, j] = value;
+ j++;
+ }
+ i++;
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/McdaToolkit/McdaMethods/Helpers/CheckDataHelper.cs b/src/McdaToolkit/Mcda/Helpers/CheckDataHelper.cs
similarity index 78%
rename from McdaToolkit/McdaMethods/Helpers/CheckDataHelper.cs
rename to src/McdaToolkit/Mcda/Helpers/CheckDataHelper.cs
index 0149521..4f141d9 100644
--- a/McdaToolkit/McdaMethods/Helpers/CheckDataHelper.cs
+++ b/src/McdaToolkit/Mcda/Helpers/CheckDataHelper.cs
@@ -1,9 +1,6 @@
-using LightResults;
-using MathNet.Numerics;
-using MathNet.Numerics.LinearAlgebra;
-using McdaToolkit.McdaMethods.Errors;
+using MathNet.Numerics;
-namespace McdaToolkit.McdaMethods.Helpers;
+namespace McdaToolkit.Mcda.Helpers;
public static class CheckDataHelper
{
diff --git a/src/McdaToolkit/Mcda/Helpers/Errors/DecisionCriteriaHaveIncorrectValueError.cs b/src/McdaToolkit/Mcda/Helpers/Errors/DecisionCriteriaHaveIncorrectValueError.cs
new file mode 100644
index 0000000..dcf728e
--- /dev/null
+++ b/src/McdaToolkit/Mcda/Helpers/Errors/DecisionCriteriaHaveIncorrectValueError.cs
@@ -0,0 +1,5 @@
+using LightResults;
+
+namespace McdaToolkit.Mcda.Helpers.Errors;
+
+public class DecisionCriteriaHaveIncorrectValueError() : Error("Criteria decision types should be number ∈Z{-1;1}");
\ No newline at end of file
diff --git a/src/McdaToolkit/Mcda/Helpers/Errors/MatrixColumnLengthNotEqualWeightsVectorLengthError.cs b/src/McdaToolkit/Mcda/Helpers/Errors/MatrixColumnLengthNotEqualWeightsVectorLengthError.cs
new file mode 100644
index 0000000..1c1b64a
--- /dev/null
+++ b/src/McdaToolkit/Mcda/Helpers/Errors/MatrixColumnLengthNotEqualWeightsVectorLengthError.cs
@@ -0,0 +1,5 @@
+using LightResults;
+
+namespace McdaToolkit.Mcda.Helpers.Errors;
+
+public class MatrixColumnLengthNotEqualWeightsVectorLengthError() : Error("Columns length of data matrix should be equal length of weights and types arrays");
\ No newline at end of file
diff --git a/McdaToolkit/McdaMethods/Errors/WeightNotSumToOneError.cs b/src/McdaToolkit/Mcda/Helpers/Errors/WeightNotSumToOneError.cs
similarity index 70%
rename from McdaToolkit/McdaMethods/Errors/WeightNotSumToOneError.cs
rename to src/McdaToolkit/Mcda/Helpers/Errors/WeightNotSumToOneError.cs
index 4c05572..5ddbdae 100644
--- a/McdaToolkit/McdaMethods/Errors/WeightNotSumToOneError.cs
+++ b/src/McdaToolkit/Mcda/Helpers/Errors/WeightNotSumToOneError.cs
@@ -1,5 +1,5 @@
using LightResults;
-namespace McdaToolkit.McdaMethods.Errors;
+namespace McdaToolkit.Mcda.Helpers.Errors;
public class WeightNotSumToOneError() : Error("Sum of weight have to equal 1");
\ No newline at end of file
diff --git a/src/McdaToolkit/Mcda/Methods/Abstraction/ICalculation.cs b/src/McdaToolkit/Mcda/Methods/Abstraction/ICalculation.cs
new file mode 100644
index 0000000..1340658
--- /dev/null
+++ b/src/McdaToolkit/Mcda/Methods/Abstraction/ICalculation.cs
@@ -0,0 +1,17 @@
+using LightResults;
+using MathNet.Numerics.LinearAlgebra;
+
+namespace McdaToolkit.Mcda.Methods.Abstraction;
+
+public interface ICalculation where TValue : struct, IEquatable, IFormattable
+{
+ ///
+ /// Calculate provided data
+ ///
+ /// Data as set of alternatives and theirs attributes
+ /// Data determining relevance of each attribute
+ /// Data that determines the columns is profit or cost
+ /// Vector of processed data in descending order
+ Result> Calculate(IEnumerable> matrix, IEnumerable weights, IEnumerable criteriaDirections);
+}
+
diff --git a/src/McdaToolkit/Mcda/Methods/Abstraction/IMcdaMethod.cs b/src/McdaToolkit/Mcda/Methods/Abstraction/IMcdaMethod.cs
new file mode 100644
index 0000000..799fc81
--- /dev/null
+++ b/src/McdaToolkit/Mcda/Methods/Abstraction/IMcdaMethod.cs
@@ -0,0 +1,6 @@
+namespace McdaToolkit.Mcda.Methods.Abstraction;
+
+public interface IMcdaMethod : ICalculation
+{
+
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Mcda/Methods/Abstraction/McdaMethod.cs b/src/McdaToolkit/Mcda/Methods/Abstraction/McdaMethod.cs
new file mode 100644
index 0000000..adfd888
--- /dev/null
+++ b/src/McdaToolkit/Mcda/Methods/Abstraction/McdaMethod.cs
@@ -0,0 +1,45 @@
+using LightResults;
+using MathNet.Numerics.LinearAlgebra;
+using McdaToolkit.Extensions;
+using McdaToolkit.Mcda.Services;
+
+namespace McdaToolkit.Mcda.Methods.Abstraction;
+
+public abstract class McdaMethod : IMcdaMethod
+{
+ private readonly MatrixCheckerService _matrixCheckerService = new();
+
+ protected abstract Result> RunCalculation(double[,] matrix, double[] weights, int[] criteriaDirections);
+
+ ///
+ public Result> Calculate(IEnumerable> matrix, IEnumerable weights, IEnumerable criteriaDirections)
+ {
+ var convertedMatrix = matrix.To2DArray();
+ var convertedWeights = weights.ToArray();
+ var convertedCriteriaDecision = criteriaDirections.ToArray();
+ var matrixChecked = _matrixCheckerService.ValidateData(convertedMatrix, convertedWeights, convertedCriteriaDecision);
+
+ if (matrixChecked.IsFailed)
+ {
+ return Result.Fail>();
+ }
+ return RunCalculation(convertedMatrix, convertedWeights, convertedCriteriaDecision);
+ }
+
+ ///
+ /// Calculate provided data
+ ///
+ /// Data as set of alternatives and theirs attributes
+ /// Data determining relevance of each attribute
+ /// Data that determines the columns is profit or cost
+ /// Vector of processed data in descending order
+ public Result> Calculate(double[,] matrix,double[] weights,int[] criteriaDirections)
+ {
+ var matrixChecked = _matrixCheckerService.ValidateData(matrix, weights, criteriaDirections);
+ if (matrixChecked.IsFailed)
+ {
+ return Result.Fail>();
+ }
+ return RunCalculation(matrix, weights, criteriaDirections);
+ }
+}
\ No newline at end of file
diff --git a/McdaToolkit/McdaMethods/TopsisMethod.cs b/src/McdaToolkit/Mcda/Methods/Topsis.cs
similarity index 65%
rename from McdaToolkit/McdaMethods/TopsisMethod.cs
rename to src/McdaToolkit/Mcda/Methods/Topsis.cs
index 1ede244..020e68d 100644
--- a/McdaToolkit/McdaMethods/TopsisMethod.cs
+++ b/src/McdaToolkit/Mcda/Methods/Topsis.cs
@@ -1,44 +1,22 @@
using LightResults;
using MathNet.Numerics.LinearAlgebra;
-using McdaToolkit.Enums;
-using McdaToolkit.McdaMethods.Abstraction;
-using McdaToolkit.McdaMethods.Interfaces;
-using McdaToolkit.Normalization;
-using McdaToolkit.Options;
+using McdaToolkit.Mcda.Methods.Abstraction;
+using McdaToolkit.Mcda.Options;
+using McdaToolkit.Normalization.Service;
+using McdaToolkit.Normalization.Service.Abstraction;
-namespace McdaToolkit.McdaMethods;
+namespace McdaToolkit.Mcda.Methods;
-public class TopsisMethod : McdaMethod
+public sealed class Topsis : McdaMethod
{
- private readonly DataNormalizationService _normalizationServiceService;
-
- public TopsisMethod()
- {
- _normalizationServiceService = new DataNormalizationService(NormalizationMethodEnum.MinMax);
- }
-
- public TopsisMethod(McdaMethodOptions options)
- {
- _normalizationServiceService = new DataNormalizationService(options.NormalizationMethodEnum);
- }
+ private readonly IMatrixNormalizationService _normalizationServiceServiceService;
- protected override Result> Calculate(Matrix matrix, double[] weights,
- int[] criteriaDirections)
+ public Topsis(McdaMethodOptions options)
{
- var normalizedMatrix = _normalizationServiceService.NormalizeMatrix(matrix, criteriaDirections);
- var weightedMatrix = WeightedMatrix(normalizedMatrix, weights);
-
- var idealBest = IdealValues(weightedMatrix, true);
- var idealWorst = IdealValues(weightedMatrix, false);
-
- var distanceToBest = CalculateEuclideanDistance(weightedMatrix, idealBest);
- var distanceToWorst = CalculateEuclideanDistance(weightedMatrix, idealWorst);
- var topsisScores = CalculateTopsisScores(distanceToBest, distanceToWorst);
-
- return Result.Ok(topsisScores);
+ _normalizationServiceServiceService = new MatrixNormalizatorService(options.NormalizationMethod);
}
-
- private Matrix WeightedMatrix(Matrix matrix, double[] weights)
+
+ private Matrix WeightedMatrix(Matrix matrix, Vector weights)
{
for (int i = 0; i < matrix.RowCount; i++)
{
@@ -47,7 +25,6 @@ private Matrix WeightedMatrix(Matrix matrix, double[] weights)
matrix[i, j] *= weights[j];
}
}
-
return matrix;
}
@@ -61,8 +38,7 @@ private Vector IdealValues(Matrix matrix, bool pis)
});
}
- private Vector CalculateEuclideanDistance(Matrix matrix,
- Vector ideal)
+ private Vector CalculateEuclideanDistance(Matrix matrix, Vector ideal)
{
return Vector.Build
.DenseOfArray(matrix
@@ -79,4 +55,21 @@ private Vector CalculateTopsisScores(Vector distanceToBest, Vect
{
return distanceToWorst.PointwiseDivide(distanceToBest.Add(distanceToWorst));
}
+
+ protected override Result> RunCalculation(double[,] matrix,double[] weights,int[] criteriaDirections)
+ {
+ var matrixBuilded = Matrix.Build.DenseOfArray(matrix);
+ var weightsBuilded = Vector.Build.DenseOfArray(weights);
+ var normalizedMatrix = _normalizationServiceServiceService.NormalizeMatrix(matrixBuilded, criteriaDirections);
+ var weightedMatrix = WeightedMatrix(normalizedMatrix, weightsBuilded);
+
+ var idealBest = IdealValues(weightedMatrix, true);
+ var idealWorst = IdealValues(weightedMatrix, false);
+
+ var distanceToBest = CalculateEuclideanDistance(weightedMatrix, idealBest);
+ var distanceToWorst = CalculateEuclideanDistance(weightedMatrix, idealWorst);
+ var topsisScores = CalculateTopsisScores(distanceToBest, distanceToWorst);
+
+ return Result.Ok(topsisScores);
+ }
}
\ No newline at end of file
diff --git a/src/McdaToolkit/Mcda/Options/McdaMethodOptions.cs b/src/McdaToolkit/Mcda/Options/McdaMethodOptions.cs
new file mode 100644
index 0000000..a9cd065
--- /dev/null
+++ b/src/McdaToolkit/Mcda/Options/McdaMethodOptions.cs
@@ -0,0 +1,14 @@
+using McdaToolkit.Enums;
+
+namespace McdaToolkit.Mcda.Options;
+
+///
+/// Configuration for Mcda methods
+///
+public record McdaMethodOptions
+{
+ ///
+ /// Current normalization method
+ ///
+ public NormalizationMethod NormalizationMethod { get; set; } = NormalizationMethod.MinMax;
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Mcda/Services/MatrixCheckerService.cs b/src/McdaToolkit/Mcda/Services/MatrixCheckerService.cs
new file mode 100644
index 0000000..83c72ca
--- /dev/null
+++ b/src/McdaToolkit/Mcda/Services/MatrixCheckerService.cs
@@ -0,0 +1,30 @@
+using LightResults;
+using McdaToolkit.Mcda.Helpers;
+using McdaToolkit.Mcda.Helpers.Errors;
+
+namespace McdaToolkit.Mcda.Services;
+
+internal sealed class MatrixCheckerService
+{
+ public Result ValidateData(double[,] matrix, double[] weights, int[] criteriaDirections)
+ {
+ var isWeightsCorrect = CheckDataHelper.IsWeightEqualOne(weights);
+ if (!isWeightsCorrect)
+ {
+ return Result.Fail(new WeightNotSumToOneError());
+ }
+
+ var isCriteriaDecisionCorrect = CheckDataHelper.IsCriteriaDesisionBetweenMinusOneAndOne(criteriaDirections);
+ if (!isCriteriaDecisionCorrect)
+ {
+ return Result.Fail(new DecisionCriteriaHaveIncorrectValueError());
+ }
+
+ var isSizesAreCorrect = CheckDataHelper.IsDataWeightsAndTypesHaveCorrectSizes(matrix, weights, criteriaDirections);
+ if (!isSizesAreCorrect)
+ {
+ return Result.Fail(new MatrixColumnLengthNotEqualWeightsVectorLengthError());
+ }
+ return Result.Ok();
+ }
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/McdaToolkit.csproj b/src/McdaToolkit/McdaToolkit.csproj
new file mode 100644
index 0000000..612999c
--- /dev/null
+++ b/src/McdaToolkit/McdaToolkit.csproj
@@ -0,0 +1,34 @@
+
+
+
+ enable
+ enable
+
+
+
+ McdaToolkit
+ 2.1.0
+ Jakub Tokarczyk
+ latest
+ README.md
+ netstandard2.1;net6.0;net7.0;net8.0
+ © 2024 Jakub Tokarczyk
+ MIT
+ https://github.com/SarcasticMoose/mcda-toolkit
+ icon.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/McdaToolkit/Normalization/Methods/Abstraction/INormalizationMethod.cs b/src/McdaToolkit/Normalization/Methods/Abstraction/INormalizationMethod.cs
new file mode 100644
index 0000000..87ccce5
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Methods/Abstraction/INormalizationMethod.cs
@@ -0,0 +1,9 @@
+namespace McdaToolkit.Normalization.Methods.Abstraction;
+
+///
+/// Marker interface indicates normalization method abstraction
+///
+internal interface INormalizationMethod : IVectorNormalizator
+{
+
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Normalization/Methods/Abstraction/IVectorNormalizator.cs b/src/McdaToolkit/Normalization/Methods/Abstraction/IVectorNormalizator.cs
new file mode 100644
index 0000000..741e3b5
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Methods/Abstraction/IVectorNormalizator.cs
@@ -0,0 +1,19 @@
+using MathNet.Numerics.LinearAlgebra;
+
+namespace McdaToolkit.Normalization.Methods.Abstraction;
+
+///
+/// Vector normalization generic abstraction
+///
+internal interface IVectorNormalizator where T : struct, IEquatable, IFormattable
+{
+ ///
+ /// Normalize provided vector
+ ///
+ /// One-dimensional vector of data to normalize
+ /// Describe type of vector, cost or profit
+ ///
+ /// Return normalized vector
+ ///
+ Vector Normalize(Vector data, bool cost);
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Normalization/Methods/Linear/MaxNormalization.cs b/src/McdaToolkit/Normalization/Methods/Linear/MaxNormalization.cs
new file mode 100644
index 0000000..26848b8
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Methods/Linear/MaxNormalization.cs
@@ -0,0 +1,17 @@
+using MathNet.Numerics.LinearAlgebra;
+using McdaToolkit.Normalization.Methods.Abstraction;
+
+namespace McdaToolkit.Normalization.Methods.Linear;
+
+internal class MaxNormalization : INormalizationMethod
+{
+ ///
+ public Vector Normalize(Vector data, bool cost)
+ {
+ if (cost)
+ {
+ return 1 - data / data.Maximum();
+ }
+ return data / data.Maximum();
+ }
+}
\ No newline at end of file
diff --git a/McdaToolkit/NormalizationMethods/Types/Linear/MinMaxNormalization.cs b/src/McdaToolkit/Normalization/Methods/Linear/MinMaxNormalization.cs
similarity index 59%
rename from McdaToolkit/NormalizationMethods/Types/Linear/MinMaxNormalization.cs
rename to src/McdaToolkit/Normalization/Methods/Linear/MinMaxNormalization.cs
index ea41c07..f04fc5a 100644
--- a/McdaToolkit/NormalizationMethods/Types/Linear/MinMaxNormalization.cs
+++ b/src/McdaToolkit/Normalization/Methods/Linear/MinMaxNormalization.cs
@@ -1,19 +1,20 @@
using MathNet.Numerics.LinearAlgebra;
-using McdaToolkit.NormalizationMethods.Interfaces;
+using McdaToolkit.Normalization.Methods.Abstraction;
-namespace McdaToolkit.NormalizationMethods.Types.Linear;
+namespace McdaToolkit.Normalization.Methods.Linear;
-public class MinMaxNormalization : INormalize
+internal class MinMaxNormalization : INormalizationMethod
{
- private const double MaxError = 1.11e-16;
+ private const double MaxTolerance = 1.11e-16;
+ ///
public Vector Normalize(Vector data, bool cost = false)
{
var max = data.Maximum();
var min = data.Minimum();
var difference = max - min;
- if (Math.Abs(difference) < MaxError)
+ if (Math.Abs(difference) < MaxTolerance)
{
return Vector.Build.Dense(data.Count, _ => 1);
}
diff --git a/src/McdaToolkit/Normalization/Methods/Linear/SumNormalization.cs b/src/McdaToolkit/Normalization/Methods/Linear/SumNormalization.cs
new file mode 100644
index 0000000..8caf5ae
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Methods/Linear/SumNormalization.cs
@@ -0,0 +1,18 @@
+using MathNet.Numerics.LinearAlgebra;
+using McdaToolkit.Normalization.Methods.Abstraction;
+
+namespace McdaToolkit.Normalization.Methods.Linear;
+
+internal class SumNormalization : INormalizationMethod
+{
+ ///
+ public Vector Normalize(Vector data, bool cost)
+ {
+ if (cost)
+ {
+ return 1 / data / data.Sum(x => 1/x);
+ }
+
+ return data / data.Sum();
+ }
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Normalization/Methods/Sum/LogarithmicNormalization.cs b/src/McdaToolkit/Normalization/Methods/Sum/LogarithmicNormalization.cs
new file mode 100644
index 0000000..08732bd
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Methods/Sum/LogarithmicNormalization.cs
@@ -0,0 +1,21 @@
+using MathNet.Numerics.LinearAlgebra;
+using McdaToolkit.Normalization.Methods.Abstraction;
+
+namespace McdaToolkit.Normalization.Methods.Sum;
+
+internal class LogarithmicNormalization : INormalizationMethod
+{
+ ///
+ public Vector Normalize(Vector data, bool cost)
+ {
+ var product = data.Aggregate(1.0,(x,y) => x * y);
+ var exp = data.PointwiseLog() / Math.Log(product);
+
+ if (cost)
+ {
+ return 1 - exp;
+ }
+
+ return exp;
+ }
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Normalization/Methods/Sum/VectorNormalization.cs b/src/McdaToolkit/Normalization/Methods/Sum/VectorNormalization.cs
new file mode 100644
index 0000000..1025015
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Methods/Sum/VectorNormalization.cs
@@ -0,0 +1,18 @@
+using MathNet.Numerics.LinearAlgebra;
+using McdaToolkit.Normalization.Methods.Abstraction;
+
+namespace McdaToolkit.Normalization.Methods.Sum;
+
+internal class VectorNormalization : INormalizationMethod
+{
+ ///
+ public Vector Normalize(Vector data, bool cost)
+ {
+ var squaresOfSum = data / Math.Sqrt(data.PointwisePower(2).Sum());
+ if (cost)
+ {
+ return 1 - squaresOfSum;
+ }
+ return squaresOfSum;
+ }
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Normalization/Service/Abstraction/IMatrixNormalizationService.cs b/src/McdaToolkit/Normalization/Service/Abstraction/IMatrixNormalizationService.cs
new file mode 100644
index 0000000..3444068
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Service/Abstraction/IMatrixNormalizationService.cs
@@ -0,0 +1,10 @@
+using LightResults;
+using McdaToolkit.Enums;
+
+namespace McdaToolkit.Normalization.Service.Abstraction;
+
+internal interface IMatrixNormalizationService : IMatrixNormalizator
+{
+ public NormalizationMethod GetCurrentNormalizationName { get; }
+ public Result ChangeNormalizationMethod(NormalizationMethod newMethod);
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Normalization/Service/Abstraction/IMatrixNormalizator.cs b/src/McdaToolkit/Normalization/Service/Abstraction/IMatrixNormalizator.cs
new file mode 100644
index 0000000..d2b7157
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Service/Abstraction/IMatrixNormalizator.cs
@@ -0,0 +1,17 @@
+using MathNet.Numerics.LinearAlgebra;
+
+namespace McdaToolkit.Normalization.Service.Abstraction;
+
+///
+/// Matrix normalization generic abstraction
+///
+internal interface IMatrixNormalizator where T : struct, IEquatable, IFormattable
+{
+ ///
+ /// Normalize provided matrix
+ ///
+ /// One-dimensional vector of data to normalize
+ /// Describe type of vector, cost or profit
+ /// Return normalized matrix
+ Matrix NormalizeMatrix(Matrix matrix, int[] criteriaTypes);
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Normalization/Service/MatrixNormalizatorService.cs b/src/McdaToolkit/Normalization/Service/MatrixNormalizatorService.cs
new file mode 100644
index 0000000..abcb8f0
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Service/MatrixNormalizatorService.cs
@@ -0,0 +1,42 @@
+using LightResults;
+using MathNet.Numerics.LinearAlgebra;
+using McdaToolkit.Enums;
+using McdaToolkit.Extensions;
+using McdaToolkit.Normalization.Methods.Abstraction;
+using McdaToolkit.Normalization.Service.Abstraction;
+
+namespace McdaToolkit.Normalization.Service;
+
+public sealed class MatrixNormalizatorService : IMatrixNormalizationService
+{
+ private IVectorNormalizator _vectorNormalizatorMethod;
+
+ public MatrixNormalizatorService(NormalizationMethod name)
+ {
+ GetCurrentNormalizationName = name;
+ _vectorNormalizatorMethod = NormalizationMethodFactory.Create(GetCurrentNormalizationName);
+ }
+
+ ///
+ public Matrix NormalizeMatrix(Matrix matrix, int[] criteriaTypes)
+ {
+ foreach (var (col, index) in matrix.EnumerateColumns().Indexed())
+ matrix.SetColumn(columnIndex: index,
+ column: criteriaTypes[index] == 1
+ ? _vectorNormalizatorMethod.Normalize(data: col, cost: false)
+ : _vectorNormalizatorMethod.Normalize(data: col, cost: true));
+ return matrix;
+ }
+
+ public NormalizationMethod GetCurrentNormalizationName { get; }
+
+ public Result ChangeNormalizationMethod(NormalizationMethod newMethod)
+ {
+ if (newMethod == GetCurrentNormalizationName)
+ {
+ return Result.Fail(NormalizationServiceErrors.MethodsEqual());
+ }
+ _vectorNormalizatorMethod = NormalizationMethodFactory.Create(newMethod);
+ return Result.Ok();
+ }
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/Normalization/Service/NormalizationServiceErrors.cs b/src/McdaToolkit/Normalization/Service/NormalizationServiceErrors.cs
new file mode 100644
index 0000000..53679af
--- /dev/null
+++ b/src/McdaToolkit/Normalization/Service/NormalizationServiceErrors.cs
@@ -0,0 +1,8 @@
+using LightResults;
+
+namespace McdaToolkit.Normalization.Service;
+
+public static class NormalizationServiceErrors
+{
+ public static Error MethodsEqual() => new("New method have to be diffrent than current one");
+}
\ No newline at end of file
diff --git a/src/McdaToolkit/NormalizationMethodFactory.cs b/src/McdaToolkit/NormalizationMethodFactory.cs
new file mode 100644
index 0000000..f3d346a
--- /dev/null
+++ b/src/McdaToolkit/NormalizationMethodFactory.cs
@@ -0,0 +1,22 @@
+using McdaToolkit.Enums;
+using McdaToolkit.Normalization.Methods.Abstraction;
+using McdaToolkit.Normalization.Methods.Linear;
+using McdaToolkit.Normalization.Methods.Sum;
+
+namespace McdaToolkit;
+
+internal static class NormalizationMethodFactory
+{
+ public static IVectorNormalizator Create(NormalizationMethod method)
+ {
+ return method switch
+ {
+ NormalizationMethod.MinMax => new MinMaxNormalization(),
+ NormalizationMethod.Vector => new VectorNormalization(),
+ NormalizationMethod.Logarithmic => new LogarithmicNormalization(),
+ NormalizationMethod.Sum => new SumNormalization(),
+ NormalizationMethod.Max => new MaxNormalization(),
+ _ => throw new Exception("Not existing normalization")
+ };
+ }
+}
\ No newline at end of file
diff --git a/tests/McdaToolkit.UnitTests/MatrixCheckerTests.cs b/tests/McdaToolkit.UnitTests/MatrixCheckerTests.cs
new file mode 100644
index 0000000..7927503
--- /dev/null
+++ b/tests/McdaToolkit.UnitTests/MatrixCheckerTests.cs
@@ -0,0 +1,73 @@
+using FluentAssertions;
+using McdaToolkit.Mcda.Helpers.Errors;
+using McdaToolkit.Mcda.Services;
+
+namespace McdaToolkit.UnitTests;
+
+public class MatrixCheckerTests
+{
+ [Fact]
+ public void ValidateData_WeightAreNotEqualOne_ShouldReturnResultFail()
+ {
+ double[,] matrix = {
+ { 66, 56, 95 },
+ { 61, 55, 166 },
+ { 65, 49, 113 },
+ { 95, 56, 99 },
+ { 63, 43, 178 },
+ { 74, 59, 140 },
+ };
+ double[] weights = [0.8,0.25,0.35];
+ int[] types = [-1, -1, 1];
+ var matrixCheckerService = new MatrixCheckerService();
+
+ var result = matrixCheckerService.ValidateData(matrix, weights, types);
+
+ result.IsSuccess.Should().BeFalse();
+ result.HasError();
+ }
+
+ [Fact]
+ public void Calculate_DecisionCriteriaAreNotBetweenMinusOneAndOne_ShouldReturnResultFail()
+ {
+ var matrix = new double[,]
+ {
+ { 66, 56, 95 },
+ { 61, 55, 166 },
+ { 65, 49, 113 },
+ { 95, 56, 99 },
+ { 63, 43, 178 },
+ { 74, 59, 140 },
+ };
+ double[] weights = [0.4,0.25,0.35];
+ int[] types = [-1, -2, 1];
+ var matrixCheckerService = new MatrixCheckerService();
+
+ var result = matrixCheckerService.ValidateData(matrix, weights, types);
+
+ result.IsSuccess.Should().BeFalse();
+ result.HasError();
+ }
+
+ [Fact]
+ public void Calculate_DimensionsOfAllMatrixesNotTheSame_ShouldReturnResultFail()
+ {
+ var matrix = new double[,]
+ {
+ { 66, 56, 95 },
+ { 61, 55, 166 },
+ { 65, 49, 113 },
+ { 95, 56, 99 },
+ { 63, 43, 178 },
+ { 74, 59, 140 },
+ };
+ double[] weights = [0.4,0.25,0.15,0.20];
+ int[] types = [-1, -1, 1, 1];
+ var matrixCheckerService = new MatrixCheckerService();
+
+ var result = matrixCheckerService.ValidateData(matrix, weights, types);
+
+ result.IsSuccess.Should().BeFalse();
+ result.HasError();
+ }
+}
\ No newline at end of file
diff --git a/tests/McdaToolkit.UnitTests/McdaMethodsTests.cs b/tests/McdaToolkit.UnitTests/McdaMethodsTests.cs
new file mode 100644
index 0000000..f92aa6b
--- /dev/null
+++ b/tests/McdaToolkit.UnitTests/McdaMethodsTests.cs
@@ -0,0 +1,40 @@
+using FluentAssertions;
+using MathNet.Numerics;
+using McdaToolkit.Enums;
+using McdaToolkit.Mcda.Methods;
+using McdaToolkit.Mcda.Options;
+
+namespace McdaToolkit.UnitTests;
+
+public class McdaMethodsTests
+{
+ [Fact]
+ public void Calculate_TopsisMethod_ShouldBeEqualToExpected()
+ {
+ var matrix = new double[,]
+ {
+ { 66, 56, 95 },
+ { 61, 55, 166 },
+ { 65, 49, 113 },
+ { 95, 56, 99 },
+ { 63, 43, 178 },
+ { 74, 59, 140 },
+ };
+ double[] weights = [0.4,0.25,0.35];
+ int[] types = [-1, -1, 1];
+ double[] expectedTopsisScore = [0.38805147,0.76189759,0.58509479,0.06374247,0.97647059,0.43681786];
+
+ var topsis = new Topsis(new McdaMethodOptions()
+ {
+ NormalizationMethod = NormalizationMethod.MinMax
+ });
+
+ var topsisResult = topsis.Calculate(matrix,weights,types);
+ var final = topsisResult.Value;
+
+ final.Enumerate()
+ .Select(x => x.Round(8))
+ .Should()
+ .BeEquivalentTo(expectedTopsisScore);
+ }
+}
\ No newline at end of file
diff --git a/McdaToolkit.UnitTests/McdaToolkit.UnitTests.csproj b/tests/McdaToolkit.UnitTests/McdaToolkit.UnitTests.csproj
similarity index 91%
rename from McdaToolkit.UnitTests/McdaToolkit.UnitTests.csproj
rename to tests/McdaToolkit.UnitTests/McdaToolkit.UnitTests.csproj
index b428fc1..961d6a9 100644
--- a/McdaToolkit.UnitTests/McdaToolkit.UnitTests.csproj
+++ b/tests/McdaToolkit.UnitTests/McdaToolkit.UnitTests.csproj
@@ -22,7 +22,7 @@
-
+
diff --git a/tests/McdaToolkit.UnitTests/NormalizationTests.cs b/tests/McdaToolkit.UnitTests/NormalizationTests.cs
new file mode 100644
index 0000000..684143a
--- /dev/null
+++ b/tests/McdaToolkit.UnitTests/NormalizationTests.cs
@@ -0,0 +1,131 @@
+using FluentAssertions;
+using MathNet.Numerics.LinearAlgebra;
+using McdaToolkit.Enums;
+using McdaToolkit.Normalization.Service;
+
+namespace McdaToolkit.UnitTests;
+
+public class NormalizationTests
+{
+ private readonly Matrix _matrixToNormalize = Matrix.Build.DenseOfArray(new[,]
+ {
+ { 32.57, 14.56, 87.12, 56.34, 47.89 },
+ { 93.23, 76.34, 33.78, 25.68, 64.23 },
+ { 78.45, 68.92, 45.67, 87.34, 39.45 },
+ { 54.12, 34.56, 56.89, 92.56, 81.56 },
+ { 21.76, 53.23, 73.21, 65.78, 57.34 },
+ { 85.34, 98.45, 38.45, 23.45, 62.89 },
+ { 42.68, 27.34, 49.67, 74.12, 53.21 }
+ });
+
+ private readonly int[] _types = [-1, -1, 1, 1, -1];
+
+ [Fact]
+ public void Normalize_MinMaxNormalization_ShouldReturnedExpectedValues()
+ {
+ var expected = new double[][]
+ {
+ [0.84874773, 1, 1, 0.47590797, 0.79957255],
+ [0, 0.26355942, 0, 0.03226740, 0.41154120],
+ [0.20680006, 0.35200858, 0.22290964, 0.92446824, 1],
+ [0.54722261, 0.76159256, 0.43325834, 1, 0],
+ [1, 0.53903922, 0.73922010, 0.61250181, 0.57516029],
+ [0.11039597, 0, 0.08755156, 0, 0.44336262],
+ [0.70728977, 0.84765765, 0.29790026, 0.73317899, 0.67323676]
+ };
+ var dataNormalization = new MatrixNormalizatorService(NormalizationMethod.MinMax);
+
+ var normalizedMatrix = dataNormalization.NormalizeMatrix(_matrixToNormalize,_types);
+
+ var equalityResult = TestHelpers.CheckEquality(normalizedMatrix, expected);
+ equalityResult.Should().BeTrue();
+ }
+
+ [Fact]
+ public void Normalize_VectorNormalization_ShouldReturnedExpectedValues()
+ {
+ var normalizationType = NormalizationMethod.Vector;
+ var expected = new double[][]
+ {
+ [0.80678026, 0.90838501, 0.57002794, 0.32313221, 0.69529318],
+ [0.44691814, 0.51965053, 0.22102323, 0.14728497, 0.59132764],
+ [0.53459968, 0.56633894, 0.29881974, 0.50092948, 0.74899386],
+ [0.67893607, 0.78254024, 0.37223243, 0.53086825, 0.48106309],
+ [0.87090999, 0.66506416, 0.47901452, 0.37727434, 0.63516623],
+ [0.49372513, 0.38052914, 0.25157913, 0.13449503, 0.59985358],
+ [0.74680324, 0.82797021, 0.32499182, 0.42510755, 0.66144393]
+ };
+ var dataNormalization = new MatrixNormalizatorService(normalizationType);
+
+ var normalizedMatrix = dataNormalization.NormalizeMatrix(_matrixToNormalize,_types);
+
+ var equalityResult = TestHelpers.CheckEquality(normalizedMatrix, expected);
+ equalityResult.Should().BeTrue();
+ }
+
+ [Fact]
+ public void Normalize_Logarithmic_ShouldReturnedExpectedValues()
+ {
+ var normalizationType = NormalizationMethod.Logarithmic;
+ var expected = new double[][]
+ {
+ [0.87403010, 0.89954564, 0.16128664, 0.14438272, 0.86315596],
+ [0.83599827, 0.83739945, 0.12708112, 0.11624356, 0.85277256],
+ [0.84224030, 0.84123458, 0.13796910, 0.16008394, 0.87001329],
+ [0.85566609, 0.86712382, 0.14590034, 0.16216292, 0.84432373],
+ [0.88861531, 0.85092357, 0.15500620, 0.14993079, 0.85678609],
+ [0.83919604, 0.82785947, 0.13175623, 0.11299010, 0.85351828],
+ [0.86425385, 0.87591345, 0.14100037, 0.15420595, 0.85943008]
+ };
+ var dataNormalization = new MatrixNormalizatorService(normalizationType);
+
+ var normalizedMatrix = dataNormalization.NormalizeMatrix(_matrixToNormalize,_types);
+
+ var equalityResult = TestHelpers.CheckEquality(normalizedMatrix, expected);
+ equalityResult.Should().BeTrue();
+ }
+
+ [Fact]
+ public void Normalize_Sum_ShouldReturnedExpectedValues()
+ {
+ var normalizationType = NormalizationMethod.Sum;
+ var expected = new double[][]
+ {
+ [0.19968511, 0.36006754, 0.22640921, 0.13248054, 0.16546924],
+ [0.06976021, 0.06867413, 0.08778814, 0.06038517, 0.12337416],
+ [0.08290305, 0.07606766, 0.11868812, 0.20537541, 0.20087001],
+ [0.12017266, 0.15169512, 0.14784688, 0.21764996, 0.09715942],
+ [0.29888530, 0.09848926, 0.19025962, 0.15467820, 0.13819885],
+ [0.07620980, 0.05325123, 0.09992463, 0.05514144, 0.12600289],
+ [0.15238388, 0.19175506, 0.12908340, 0.17428928, 0.14892543]
+ };
+ var dataNormalization = new MatrixNormalizatorService(normalizationType);
+
+ var normalizedMatrix = dataNormalization.NormalizeMatrix(_matrixToNormalize,_types);
+
+ var equalityResult = TestHelpers.CheckEquality(normalizedMatrix, expected);
+ equalityResult.Should().BeTrue();
+ }
+
+ [Fact]
+ public void Normalize_Max_ShouldReturnedExpectedValues()
+ {
+ var normalizationType = NormalizationMethod.Max;
+ var expected = new double[][]
+ {
+ [0.65064893, 0.85210767, 1, 0.60868626, 0.41282491],
+ [0, 0.22458101, 0.38774105, 0.27744166, 0.21248161],
+ [0.15853266, 0.29994921, 0.52421947, 0.94360415, 0.51630701],
+ [0.41950016, 0.64895886, 0.65300735, 1, 0],
+ [0.76659873, 0.45931945, 0.84033517, 0.71067416, 0.29695929],
+ [0.08462941, 0, 0.44134527, 0.25334918, 0.22891123],
+ [0.54220744, 0.72229558, 0.57013315, 0.80077787, 0.34759686]
+ };
+ var dataNormalization = new MatrixNormalizatorService(normalizationType);
+
+ var normalizedMatrix = dataNormalization.NormalizeMatrix(_matrixToNormalize,_types);
+
+ var equalityResult = TestHelpers.CheckEquality(normalizedMatrix, expected);
+ equalityResult.Should().BeTrue();
+ }
+}
\ No newline at end of file
diff --git a/McdaToolkit.UnitTests/Helpers/TestHelpers.cs b/tests/McdaToolkit.UnitTests/TestHelpers.cs
similarity index 95%
rename from McdaToolkit.UnitTests/Helpers/TestHelpers.cs
rename to tests/McdaToolkit.UnitTests/TestHelpers.cs
index 298a715..3b4e962 100644
--- a/McdaToolkit.UnitTests/Helpers/TestHelpers.cs
+++ b/tests/McdaToolkit.UnitTests/TestHelpers.cs
@@ -1,7 +1,7 @@
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra;
-namespace McdaToolkit.UnitTests.Helpers;
+namespace McdaToolkit.UnitTests;
public abstract class TestHelpers
{