Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restructure-refactor-improve #10

Closed
wants to merge 7 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: added errors
feat: added conversion for 2D arrays
feat: added support for icon to upload with nuget package

docs: improved documentation
refactor: changed some names to be more precise
refactor: adjusted namespacing
SarcasticMoose committed Aug 13, 2024
commit 767771aef187bc882d91faade3973c123cc4ee7e
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace McdaToolkit.Enums;

public enum NormalizationMethodEnum
public enum NormalizationMethod
{
MinMax,
Vector,
21 changes: 21 additions & 0 deletions src/McdaToolkit/Extensions/EnumerableExtentions.cs
Original file line number Diff line number Diff line change
@@ -16,4 +16,25 @@ internal static class EnumerableExtentions
++i;
}
}

public static T[,] To2DArray<T>(this IEnumerable<IEnumerable<T>> source)
{
var sourceToArray = source.ToArray();
var rows = sourceToArray.Length;
var cols = sourceToArray.First().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;
}
}
19 changes: 19 additions & 0 deletions src/McdaToolkit/Mcda/Abstraction/ICalculation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Collections;
using LightResults;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;

namespace McdaToolkit.Mcda.Abstraction;

public interface ICalculation<TValue> where TValue : struct, IEquatable<TValue>, IFormattable
{
/// <summary>
/// Calculate provided data
/// </summary>
/// <param name="matrix">Data as set of alternatives and theirs attributes</param>
/// <param name="weights">Data determining relevance of each attribute</param>
/// <param name="criteriaDirections">Data that determines the columns is profit or cost</param>
/// <returns>Vector of processed data in descending order</returns>
Result<Vector<TValue>> Calculate(IEnumerable<IEnumerable<TValue>> matrix, IEnumerable<TValue> weights, IEnumerable<int> criteriaDirections);
}

9 changes: 9 additions & 0 deletions src/McdaToolkit/Mcda/Abstraction/IMcdaMethod.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace McdaToolkit.Mcda.Abstraction;

/// <summary>
/// Marker interface indicates mcda method abstraction
/// </summary>
public interface IMcdaMethod : ICalculation<double>
{

}
90 changes: 90 additions & 0 deletions src/McdaToolkit/Mcda/Abstraction/McdaMethod.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using LightResults;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using McdaToolkit.Extensions;
using McdaToolkit.Mcda.Contracts;
using McdaToolkit.Mcda.Errors;
using McdaToolkit.Mcda.Helpers;

namespace McdaToolkit.Mcda.Abstraction;

public abstract class McdaMethod : IMcdaMethod
{
#region Private methods
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();
}
private Result CheckMatrix(double[,] matrix, double[] weights, int[] criteriaDirections)
{
var errorsCheckResult = InitialErrorsCheck(matrix,weights, criteriaDirections);

return errorsCheckResult.IsFailed ? errorsCheckResult : Result.Ok();
}
private MatrixDto PrepareMatrix(IEnumerable<IEnumerable<double>> matrix, IEnumerable<double> weights, IEnumerable<int> criteriaDirections)
{
var matrix2D = matrix.To2DArray();
var weightsArray = weights.ToArray();
var criteriaDirectionsArray = criteriaDirections.ToArray();

return new(matrix2D, weightsArray, criteriaDirectionsArray);
}
#endregion

#region Protected methods
protected abstract Result<Vector<double>> RunCalculation(Matrix<double> matrix, Vector<double> weights, int[] criteriaDirections);
#endregion

#region Public methods
/// <inheritdoc cref="ICalculation.Calculate"/>
public Result<Vector<double>> Calculate(IEnumerable<IEnumerable<double>> matrix, IEnumerable<double> weights, IEnumerable<int> criteriaDirections)
{
var matrixDto = PrepareMatrix(matrix, weights, criteriaDirections);
return Calculate(matrixDto.Matrix, matrixDto.Weights, matrixDto.CriteriaDecision);
}
/// <inheritdoc cref="ICalculation.Calculate"/>
public Result<Vector<double>> Calculate(double[,] matrix, double[] weights, int[] criteriaDirections)
{
var checkMatrixResult = CheckMatrix(matrix,weights,criteriaDirections);
if (checkMatrixResult.IsFailed)
{
return Result<Vector<double>>.Fail(new Error());
}

var finalMatrix = Matrix.Build.DenseOfArray(matrix);
var weightsVector = Vector.Build.DenseOfArray(weights);
return RunCalculation(finalMatrix,weightsVector,criteriaDirections);
}
#endregion
}
8 changes: 8 additions & 0 deletions src/McdaToolkit/Mcda/Contracts/MatrixDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace McdaToolkit.Mcda.Contracts;

internal record MatrixDto(double[,] Matrix, double[] Weights, int[] CriteriaDecision)
{
public double[,] Matrix { get; } = Matrix;
public double[] Weights { get; } = Weights;
public int[] CriteriaDecision { get; } = CriteriaDecision;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using LightResults;

namespace McdaToolkit.McdaMethods.Errors;
namespace McdaToolkit.Mcda.Errors;

public class ArraySizesAreNotEqual() : Error("Columns length of data matrix should be equal length of weights and types arrays");
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using LightResults;

namespace McdaToolkit.McdaMethods.Errors;
namespace McdaToolkit.Mcda.Errors;

public class CriteriaNotBetweenMinusOneAndOne() : Error("Criteria decision types should be number ∈Z{-1;1}");
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using LightResults;

namespace McdaToolkit.McdaMethods.Errors;
namespace McdaToolkit.Mcda.Errors;

public class WeightNotSumToOneError() : Error("Sum of weight have to equal 1");
Original file line number Diff line number Diff line change
@@ -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
{
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
using LightResults;
using MathNet.Numerics.LinearAlgebra;
using McdaToolkit.Enums;
using McdaToolkit.McdaMethods.Abstraction;
using McdaToolkit.Normalization;
using McdaToolkit.Normalization.Interfaces;
using McdaToolkit.Mcda.Abstraction;
using McdaToolkit.Normalization.Service;
using McdaToolkit.Normalization.Service.Abstraction;
using McdaToolkit.Options;

namespace McdaToolkit.McdaMethods;
namespace McdaToolkit.Mcda.Methods;

public class TopsisMethod : McdaMethod
public sealed class Topsis : McdaMethod
{
private readonly IDataNormalization _normalizationServiceService;

public TopsisMethod()
{
_normalizationServiceService = new DataNormalizationService(NormalizationMethodEnum.MinMax);
}

public TopsisMethod(McdaMethodOptions options)
private readonly IMatrixNormalizationService _normalizationServiceServiceService;

public Topsis(McdaMethodOptions options)
{
_normalizationServiceService = new DataNormalizationService(options.NormalizationMethodEnum);
_normalizationServiceServiceService = new MatrixNormalizatorService(options.NormalizationMethod);
}

protected override Result<Vector<double>> Calculate(Matrix<double> matrix, double[] weights,
int[] criteriaDirections)
protected override Result<Vector<double>> RunCalculation(Matrix<double> matrix, Vector<double> weights, int[] criteriaDirections)
{
var normalizedMatrix = _normalizationServiceService.NormalizeMatrix(matrix, criteriaDirections);
var normalizedMatrix = _normalizationServiceServiceService.NormalizeMatrix(matrix, criteriaDirections);
var weightedMatrix = WeightedMatrix(normalizedMatrix, weights);

var idealBest = IdealValues(weightedMatrix, true);
@@ -38,7 +31,7 @@ protected override Result<Vector<double>> Calculate(Matrix<double> matrix, doubl
return Result.Ok(topsisScores);
}

private Matrix<double> WeightedMatrix(Matrix<double> matrix, double[] weights)
private Matrix<double> WeightedMatrix(Matrix<double> matrix, Vector<double> weights)
{
for (int i = 0; i < matrix.RowCount; i++)
{
59 changes: 0 additions & 59 deletions src/McdaToolkit/McdaMethods/Abstraction/McdaMethod.cs

This file was deleted.

9 changes: 0 additions & 9 deletions src/McdaToolkit/McdaMethods/Interfaces/IMethod.cs

This file was deleted.

2 changes: 2 additions & 0 deletions src/McdaToolkit/McdaToolkit.csproj
Original file line number Diff line number Diff line change
@@ -15,10 +15,12 @@
<Copyright>© 2024 Jakub Tokarczyk</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryUrl>https://github.com/SarcasticMoose/mcda-toolkit</RepositoryUrl>
<PackageIcon>icon.png</PackageIcon>
</PropertyGroup>

<ItemGroup Label="Resources">
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
<None Include="..\..\Images\icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup Label="Dependencies">
25 changes: 0 additions & 25 deletions src/McdaToolkit/Normalization/DataNormalizationService.cs

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace McdaToolkit.Normalization.Methods.Abstraction;

/// <summary>
/// Marker interface indicates normalization method abstraction
/// </summary>
internal interface INormalizationMethod : IVectorNormalizator<double>
{

}
Loading