Skip to content

Commit

Permalink
Merge pull request #23 from SarcasticMoose/release/3.0.0
Browse files Browse the repository at this point in the history
Release 3.0.0
  • Loading branch information
SarcasticMoose authored Dec 14, 2024
2 parents f306d2c + db5363b commit fed79e7
Show file tree
Hide file tree
Showing 67 changed files with 1,061 additions and 552 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: Deployment
name: stable

on:
push:
Expand Down
48 changes: 32 additions & 16 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
The MCDA Toolkit is a lightweight .NET tool designed for Multi-Criteria Decision Analysis (MCDA).

## Key feature
- .NET 6+ support
- .NET 6 and .NET Standard 2.0
- Easy to use

## Dependencies
Expand Down Expand Up @@ -57,20 +57,36 @@ This object contains information about the success or failure of the operation.
Before obtaining the ``Value`` from the result object, it is necessary to check that no errors have occurred.

```csharp
var topsis = new Topsis(new McdaMethodOptions()
var matrix = new[,]
{
{3, 6, 4, 20, 2, 30000 },
{4, 4, 6, 15, 2.2, 32000 },
{6, 5, 9, 18, 3, 32100 },
{5, 6, 3, 23, 2.8, 28000 },
{4, 8, 7, 30, 1.5, 29000 },
{8, 3, 6, 35, 1.9, 27000 },
{7, 2, 5, 33, 1.7, 28500 },
{3, 8, 3, 34, 1.6, 30500 },
{8, 4, 8, 40, 2.5, 33000 },
{9, 3, 7, 34, 2, 29800 }
};
double[] weights = [0.1,0.2,0.1,0.2,0.1,0.3];
int[] types = [1,1,1,-1,-1,-1];

var data = new DataProviderBuilder()
.AddWeights(weights)
.AddDecisionCriteria(types)
.AddDecisionMatrix(matrix)
.Build();

var vikor = MethodFactory.CreateVikor(new VikorOptions()
{
NormalizationMethod = NormalizationMethod.MinMax
NormalizationMethod = NormalizationMethod.Vector,
VikorParameters = VikorParameters.Create(0.5)
});
Result<Vector<double>> result = topsis.Calculate(data,weights,types);

if(topsisResult.IsFailed)
{
foreach (var error in topsisResult.Errors)
{
Console.WriteLine(error.Message);
}
return;
}
Vector<double> result.Value;
```
More info about ``Result`` type and pattern at: [Light Results](https://github.com/jscarle/LightResults) and [Fluent Results](https://github.com/altmann/FluentResults)

var vikorResult = vikor.Run(data);

var scores = vikorResult
.Value.Q;
```
48 changes: 17 additions & 31 deletions src/McdaToolkit/Extensions/EnumerableExtentions.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,26 @@
namespace McdaToolkit.Extensions;

internal static class EnumerableExtentions
namespace McdaToolkit.Extensions
{
public static IEnumerable<(T item, int index)> Indexed<T>(this IEnumerable<T> source)
public static class EnumerableExtentions
{
if (source is null)
public static T[,] To2DArray<T>(this IEnumerable<IEnumerable<T>> source)
{
throw new ArgumentNullException();
}
var sourceToArray = source.ToArray();
var rows = sourceToArray.Length;
var cols = sourceToArray[0].Count();
var result = new T[rows, cols];
var i = 0;

var i = 0;
foreach (var item in source)
{
yield return (item, i);
++i;
}
}

public static T[,] To2DArray<T>(this IEnumerable<IEnumerable<T>> 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)
foreach (var row in sourceToArray)
{
result[i, j] = value;
j++;
var j = 0;
foreach (var value in row)
{
result[i, j] = value;
j++;
}
i++;
}
i++;
return result;
}
return result;
}
}
28 changes: 28 additions & 0 deletions src/McdaToolkit/Extensions/MatrixExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using MathNet.Numerics.LinearAlgebra;

namespace McdaToolkit.Extensions;

public static class MatrixExtensions
{
public static Vector<T> GetColMax<T>(this Matrix<T> matrix) where T : struct, IEquatable<T>, IFormattable
{
var maxVector = Vector<T>.Build.Dense(matrix.ColumnCount);

for (int i = 0; i < matrix.ColumnCount; i++)
{
maxVector[i] = matrix.Column(i).Maximum();
}
return maxVector;
}

public static Vector<T> GetColMin<T>(this Matrix<T> matrix) where T : struct, IEquatable<T>, IFormattable
{
var maxVector = Vector<T>.Build.Dense(matrix.ColumnCount);

for (int i = 0; i < matrix.ColumnCount; i++)
{
maxVector[i] = matrix.Column(i).Min();
}
return maxVector;
}
}
7 changes: 7 additions & 0 deletions src/McdaToolkit/Mcda/Factories/Enums/McdaMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace McdaToolkit.Mcda.Factories.Enums;

public enum McdaMethods
{
Topsis = 0,
Vikor = 1
}
45 changes: 45 additions & 0 deletions src/McdaToolkit/Mcda/Factories/MatrixValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using McdaToolkit.Mcda.Providers;
using McdaToolkit.Validation.MatrixValidation;

namespace McdaToolkit.Mcda.Factories;

public class DefaultDataProviderBuilder
{
private double[,] _matrix;

Check warning on line 8 in src/McdaToolkit/Mcda/Factories/MatrixValidator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_matrix' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 8 in src/McdaToolkit/Mcda/Factories/MatrixValidator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_matrix' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 8 in src/McdaToolkit/Mcda/Factories/MatrixValidator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_matrix' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 8 in src/McdaToolkit/Mcda/Factories/MatrixValidator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_matrix' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
private double[] _weigths;

Check warning on line 9 in src/McdaToolkit/Mcda/Factories/MatrixValidator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_weigths' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 9 in src/McdaToolkit/Mcda/Factories/MatrixValidator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_weigths' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
private int[] _criteriaDecision;

Check warning on line 10 in src/McdaToolkit/Mcda/Factories/MatrixValidator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_criteriaDecision' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 10 in src/McdaToolkit/Mcda/Factories/MatrixValidator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_criteriaDecision' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

public DefaultDataProviderBuilder AddDecisionMatrix(double[,] matrix)
{
_matrix = matrix;
return this;
}

public DefaultDataProviderBuilder AddWeights(double[] weights)
{
_weigths = weights;
return this;
}

public DefaultDataProviderBuilder AddDecisionCriteria(int[] criteriaDecision)
{
_criteriaDecision = criteriaDecision;
return this;
}

public McdaInputData Build()
{
var matrixValidationResult = new MatrixValidation(_matrix, _weigths, _criteriaDecision).Validate();
if (matrixValidationResult.IsFailed)
{
throw new ArgumentNullException($"Failed to provide data because of: {string .Join(", ",matrixValidationResult.Errors)}");
}
var provider = new DefaultDataProvider();
var provideResult = provider.ProvideData(_matrix, _weigths, _criteriaDecision);;
if (provideResult.IsFailed)
{
throw new ArgumentNullException($"Failed to provide data because of: {string .Join(", ", provideResult.Errors)}");
}
return provider.GetData();
}
}
36 changes: 36 additions & 0 deletions src/McdaToolkit/Mcda/Factories/MethodFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using McdaToolkit.Mcda.Factories.Enums;
using McdaToolkit.Mcda.Methods.Abstraction;
using McdaToolkit.Mcda.Methods.Topsis;
using McdaToolkit.Mcda.Methods.Vikor;
using McdaToolkit.Normalization.Services.MatrixNormalizator;

namespace McdaToolkit.Mcda.Factories;

public static class MethodFactory
{
private static IMcdaMethod CreateMethod(
McdaMethods method,
IMcdaMethodOptions options)
{
var normalizationMatrixService = new MatrixNormalizatorService(
new NormalizationMethodFactory(),
options.NormalizationMethod);

return method switch
{
McdaMethods.Vikor => new Vikor(normalizationMatrixService,((VikorOptions)options).VikorParameters),
McdaMethods.Topsis => new Topsis(normalizationMatrixService),
_ => throw new ArgumentOutOfRangeException(nameof(method), method, null)
};
}

public static IVikorMethod CreateVikor(VikorOptions options)
{
return (IVikorMethod)CreateMethod(McdaMethods.Vikor, options);
}

public static ITopsisMethod CreateTopsis(TopsisOptions options)
{
return (ITopsisMethod)CreateMethod(McdaMethods.Topsis, options);
}
}
20 changes: 0 additions & 20 deletions src/McdaToolkit/Mcda/Helpers/CheckDataHelper.cs

This file was deleted.

5 changes: 0 additions & 5 deletions src/McdaToolkit/Mcda/Helpers/Errors/WeightNotSumToOneError.cs

This file was deleted.

14 changes: 14 additions & 0 deletions src/McdaToolkit/Mcda/McdaInputData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using MathNet.Numerics.LinearAlgebra;
using McdaToolkit.Mcda.Methods.Abstraction;

namespace McdaToolkit.Mcda;

public record McdaInputData(
Matrix<double> Matrix,
Vector<double> Weights,
int[] Types)
{
public int[] Types { get; } = Types;
public Matrix<double> Matrix { get; } = Matrix;
public Vector<double> Weights { get; } = Weights;
}
14 changes: 14 additions & 0 deletions src/McdaToolkit/Mcda/McdaMethodOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using McdaToolkit.Normalization.Enums;

namespace McdaToolkit.Mcda;

/// <summary>
/// Configuration for mcda methods
/// </summary>
public interface IMcdaMethodOptions
{
/// <summary>
/// Normalization method
/// </summary>
public NormalizationMethod NormalizationMethod { get; set; }
}
17 changes: 0 additions & 17 deletions src/McdaToolkit/Mcda/Methods/Abstraction/ICalculation.cs

This file was deleted.

17 changes: 13 additions & 4 deletions src/McdaToolkit/Mcda/Methods/Abstraction/IMcdaMethod.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
namespace McdaToolkit.Mcda.Methods.Abstraction;
using LightResults;
using McdaToolkit.Mcda.Providers;

public interface IMcdaMethod : ICalculation<double>
namespace McdaToolkit.Mcda.Methods.Abstraction;

public interface IMcdaMethod<out TResult> : IMcdaMethod
where TResult : IResult<IMcdaScore>
{
new TResult Run(McdaInputData data);
}

public interface IMcdaMethod
{

}
IResult Run(McdaInputData data);
}
7 changes: 7 additions & 0 deletions src/McdaToolkit/Mcda/Methods/Abstraction/IMcdaScore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using MathNet.Numerics.LinearAlgebra;

namespace McdaToolkit.Mcda.Methods.Abstraction;

public interface IMcdaScore
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace McdaToolkit.Mcda.Methods.Abstraction;

public interface IMcdaAdditionalParameters
{

}
Loading

0 comments on commit fed79e7

Please sign in to comment.