Skip to content

Commit

Permalink
more statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
ignatandrei committed Oct 12, 2024
1 parent 8d184c5 commit 6f5828d
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
try
{
{
//Console.WriteLine($"Name:{TheAssemblyInfo.GeneratedName}");
Console.WriteLine($"{TheAssemblyInfo.GeneratedNameNice}");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>



<ItemGroup>
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="21.0.2" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
+ "]";
var maxCount = nameCount.Max(it => it.Count);
var yAxis = "[" + string.Join(',', nameCount.Select(it => it.Count).ToArray()) + "]";
StatisticsDisplay statisticsDisplay = new(arr.Statistics());

}
@statisticsDisplay.Render()

<div class="mermaid">
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@
+ "}"
)
);
StatisticsDisplay statisticsDisplay= new (arr.Statistics());

<text>
@statisticsDisplay.Render()

<div id="@nameId" style="height: 100%"></div>
<script type="text/javascript">
var dom = document.getElementById('@nameId');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@inherits RazorBlade.PlainTextTemplate<Statistics<long>>;
@{
var modes= Model.Mode;
var displayMode = true;
if(modes.Length==0 || modes.Length>1)
{
displayMode = false;
}
var mode= modes.First();
var stdDev = Math.Sqrt( Model.Variance);

Check failure on line 10 in src/NetPackageAnalyzer/NetPackageAnalyzerExportHTML/Templates/StatisticsDisplay.cshtml

View workflow job for this annotation

GitHub Actions / build

'Statistics<long>' does not contain a definition for 'Variance' and no accessible extension method 'Variance' accepting a first argument of type 'Statistics<long>' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 10 in src/NetPackageAnalyzer/NetPackageAnalyzerExportHTML/Templates/StatisticsDisplay.cshtml

View workflow job for this annotation

GitHub Actions / build

'Statistics<long>' does not contain a definition for 'Variance' and no accessible extension method 'Variance' accepting a first argument of type 'Statistics<long>' could be found (are you missing a using directive or an assembly reference?)
}
<div>
;Math average: @Model.ArithmeticMean
;Math median: @Model.Median
;Standard Dev: @(stdDev.ToString("0.00"))
@if(displayMode){
<text>
<br />
Math mode: The most encountered value (@mode.Count() times) is @mode.Value
</text>
}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
global using System.IO.Abstractions;
global using NetPackageAnalyzerExportHTML.Templates;
global using NetPackageAnalyzerMetricsMSFT;
global using NPA.Resources;
global using NPA.Resources;
global using Statistical;
12 changes: 8 additions & 4 deletions src/NetPackageAnalyzer/NetPackageAnalyzerTests/TestStatistics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,22 @@ public void TestMean()
public void TestMode()
{
var values = new int[] { 5, 5,100,100,100, 300, 400, 500 };
var mode = StatisticalNumbers<int>.Mode(values);
var modes = StatisticalNumbers<int>.Mode(values);
Assert.AreEqual(1, modes.Count());
var mode = modes.FirstOrDefault();
var res= new int[] { 100 };
Assert.AreEqual(3, mode.Count);
Assert.AreEqual(3, mode.Count());

Check warning on line 32 in src/NetPackageAnalyzer/NetPackageAnalyzerTests/TestStatistics.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 32 in src/NetPackageAnalyzer/NetPackageAnalyzerTests/TestStatistics.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
Assert.AreEqual(res.Length, mode.Values.Length);
for (int i = 0; i < res.Length; i++)
{
Assert.AreEqual(res[i], mode.Values[i]);
}
values = new int[] { 5, 5, 5, 100, 100, 100, 300, 400, 500 };
mode = StatisticalNumbers<int>.Mode(values);
modes = StatisticalNumbers<int>.Mode(values);
Assert.AreEqual(1, modes.Count());
mode = modes.FirstOrDefault();
res = new int[] { 5,100 };
Assert.AreEqual(3, mode.Count);
Assert.AreEqual(3, mode.Count());

Check warning on line 43 in src/NetPackageAnalyzer/NetPackageAnalyzerTests/TestStatistics.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 43 in src/NetPackageAnalyzer/NetPackageAnalyzerTests/TestStatistics.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
Assert.AreEqual(res.Length, mode.Values.Length);
for (int i = 0; i < res.Length; i++)
{
Expand Down
10 changes: 7 additions & 3 deletions src/NetPackageAnalyzer/Statistical/ModeResult.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
namespace Statistical;
public record ModeResult<T>(T[] Values, int Count)
using System.Numerics;

namespace Statistical;
public record ModeResult<T>(T[] Values, T Value)
where T : INumber<T>
{
public static ModeResult<T> Empty { get; } = new ModeResult<T>(Array.Empty<T>(), 0);
public long Count() => Values.Length;
public static ModeResult<T> Empty { get; } = new ModeResult<T>(Array.Empty<T>(), T.Zero);

}
57 changes: 42 additions & 15 deletions src/NetPackageAnalyzer/Statistical/StatisticalNumbers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Numerics;
using System.Drawing;
using System.Numerics;
namespace Statistical;

public static class StatisticalNumbers<T>
Expand Down Expand Up @@ -54,35 +55,61 @@ public static T ArithmeticMean(T[]? values)

}

public static ModeResult<T> Mode(T[]? values)
public static ModeResult<T>[] Mode(T[]? values)
{
var size = values?.Length ?? 0;
if (size == 0)
{
return ModeResult<T>.Empty;
return new[] { ModeResult<T>.Empty };
}
ArgumentNullException.ThrowIfNull(values);

var data = values
.GroupBy(v=>v)
.ToDictionary(v=>v,v=>v.Count());

var max = data.Max(it=>it.Value);
var vals = data
.Where(it => it.Value == max)
.Select(it => it.Key.Key)

var modeWithCount = values
.GroupBy(item => item)
.OrderByDescending(group => group.Count())
.ToArray();
var nr = modeWithCount.First().Count();
var modes = modeWithCount
.Where(group => group.Count() == nr)
.ToArray();

return new ModeResult<T>(vals ?? [] , max);

return modes.Select(
mode =>
{
var vals = values
.Where(it => it == mode.Key)
.ToArray();
return new ModeResult<T>(vals, mode.Key);
}).ToArray();
}
public static T Variance(T[] values)
{
var size = values.Length;
if (values.Length == 0)
return T.Zero;

if (!T.TryParse(size.ToString(), null, out var mid))
{
throw new ArgumentException("Cannot parse the size of the array to T");
};
var avg = ArithmeticMean(values);
var variance = T.Zero;
foreach (var value in values)
{
var val = value - avg;
val= val * val;
variance += val;
}
return variance / mid; // For sample variance
}

}
public record Statistics<T>(T[] values)
where T : INumber<T>, IDivisionOperators<T, T, T>
{
public T Median => StatisticalNumbers<T>.Median(values);
public T ArithmeticMean => StatisticalNumbers<T>.ArithmeticMean(values);
public ModeResult<T> Mode => StatisticalNumbers<T>.Mode(values);
public ModeResult<T>[] Mode => StatisticalNumbers<T>.Mode(values);
}

0 comments on commit 6f5828d

Please sign in to comment.