Skip to content

Commit

Permalink
+ repetition histogram
Browse files Browse the repository at this point in the history
  • Loading branch information
Hawkynt committed Oct 10, 2024
1 parent 1f8ff92 commit e0daf4c
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ partial class ArbitraryNumberGenerator {
/// </code>
/// </example>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte _PopCount(UInt128 mask) => (byte)(ulong.PopCount((ulong)mask) + ulong.PopCount((ulong)(mask >> 64)));

private static byte _PopCount(UInt128 mask) => (byte)(((ulong)mask).CountSetBits() + ((ulong)(mask >> 64)).CountSetBits());
/// <summary>
/// Calculates the population count (the number of 1-bits) in a 256-bit vector.
/// </summary>
Expand All @@ -37,10 +37,10 @@ partial class ArbitraryNumberGenerator {
/// </example>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ushort _PopCount(Vector256<ulong> mask) {
var pc0 = ulong.PopCount(mask.GetElement(0));
var pc1 = ulong.PopCount(mask.GetElement(1));
var pc2 = ulong.PopCount(mask.GetElement(2));
var pc3 = ulong.PopCount(mask.GetElement(3));
var pc0 = mask.GetElement(0).CountSetBits();
var pc1 = mask.GetElement(1).CountSetBits();
var pc2 = mask.GetElement(2).CountSetBits();
var pc3 = mask.GetElement(3).CountSetBits();

var pc01 = pc0 + pc1;
var pc23 = pc2 + pc3;
Expand Down
36 changes: 1 addition & 35 deletions Randomizer/Statistics/BitCountHistogram.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;

namespace Randomizer.Statistics;

Expand All @@ -10,40 +9,7 @@ internal class BitCountHistogram : IValueTracker {

public void Feed(ulong value) => ++this._ones[value.CountSetBits()];

public void Print() {
const int height = 10;
const int width = 65;
var output = new char[height + 1, width];

// Initialize the array with spaces
for (var y = 0; y < height + 1; ++y)
for (var x = 0; x < width; ++x)
output[y, x] = ' ';

// Write the bit count row
for (var i = 0; i < width; ++i)
output[height, i] = i % 10 == 0 ? i == 0 ? '0' : (char)('A' - 1 + i / 10) : (char)('0' + i % 10);

// Find max to normalize
var max = this._ones.Max();

// Calculate and write the histogram bars
for (var i = 0; i < width; ++i) {
var onesHeight = this._ones[i] * height / max;

for (ulong j = 0; j < onesHeight; ++j)
output[height - 1 - (int)j, i] = '#';
}

// Convert the array to a string and print it
Console.WriteLine("Bit Count Histogram:");
for (var i = 0; i < height + 1; ++i) {
for (var j = 0; j < width; ++j)
Console.Write(output[i, j]);

Console.WriteLine();
}
}
public void Print() => HistogramDrawer.DrawHistogram("Bit Count Histogram", 10, this._ones);

#endregion
}
44 changes: 2 additions & 42 deletions Randomizer/Statistics/BitIndexHistogram.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;

namespace Randomizer.Statistics;
namespace Randomizer.Statistics;

internal class BitIndexHistogram:IValueTracker {
private readonly ulong[] _ones=new ulong[64];
Expand All @@ -14,44 +11,7 @@ public void Feed(ulong value) {
++((value & (1UL << i)) == 0 ? this._zeros : this._ones)[i];
}

public void Print() {
const int height = 10;
const int width = 64;
var output = new char[height * 2 + 1, width];

// Initialize the array with spaces
for (var y = 0; y < height * 2 + 1; ++y)
for (var x = 0; x < width; ++x)
output[y, x] = ' ';

// Write the bit index row
for (var i = 0; i < width; ++i)
output[height, i] = i % 10 == 0 ? i == 0 ? '0' : (char)('A' - 1 + i / 10) : (char)('0' + i % 10);

// Find max to normalize
var max = Math.Max(this._zeros.Max(), this._ones.Max());

// Calculate and write the histogram bars
for (var i = 0; i < width; ++i) {
var onesHeight = this._ones[i] * height/ max;
var zerosHeight = this._zeros[i] * height / max;

for (ulong j = 0; j < onesHeight; ++j)
output[height - 1 - j, i] = '#';

for (ulong j = 0; j < zerosHeight; ++j)
output[height + 1 + j, i] = '#';
}

// Convert the array to a string and print it
Console.WriteLine("Bit Index Histogram:");
for (var i = 0; i < height * 2 + 1; ++i) {
for (var j = 0; j < width; ++j)
Console.Write(output[i, j]);

Console.WriteLine();
}
}
public void Print() => HistogramDrawer.DrawHistogram("Bit Index Histogram", 10, this._ones,this._zeros);

#endregion
}
52 changes: 52 additions & 0 deletions Randomizer/Statistics/HistogramDrawer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Linq;

namespace Randomizer.Statistics;

internal static class HistogramDrawer {

public static void DrawHistogram(string title, int height, ulong[] data, ulong[]? additionalData = null, char character = '#') {
var width = data.Length;
var outputHeight = additionalData == null ? height : height * 2;
var output = new char[outputHeight + 1, width];

// Initialize the array with spaces
for (var y = 0; y < outputHeight + 1; ++y)
for (var x = 0; x < width; ++x)
output[y, x] = ' ';

// Write the bin index row
for (var i = 0; i < width; ++i)
output[height, i] = i % 10 == 0 ? i == 0 ? '0' : (char)('A' - 1 + i / 10) : (char)('0' + i % 10);

// Find max to normalize
var max = data.Max();
if (additionalData != null)
max = Math.Max(max, additionalData.Max());

// Calculate and write the histogram bars for data
for (var i = 0; i < width; ++i) {
var binHeight = data[i] * (ulong)height / max;
for (ulong j = 0; j < binHeight; ++j)
output[height - 1 - (int)j, i] = character;
}

// Calculate and write the histogram bars for additionalData if provided
if (additionalData != null) {
for (var i = 0; i < width; ++i) {
var binHeight = additionalData[i] * (ulong)height / max;
for (ulong j = 0; j < binHeight; ++j)
output[height + 1 + (int)j, i] = character;
}
}

// Convert the array to a string and print it
Console.WriteLine($"{title}:");
for (var i = 0; i < outputHeight + 1; ++i) {
for (var j = 0; j < width; ++j)
Console.Write(output[i, j]);

Console.WriteLine();
}
}
}
15 changes: 15 additions & 0 deletions Randomizer/Statistics/RepetitionHistogram.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Randomizer.Statistics;

internal class RepetitionHistogram : IValueTracker {
private const int NumBins = 64;
private const double ScaleFactor = NumBins / (double)ulong.MaxValue;
private readonly ulong[] _bins = new ulong[NumBins];

#region Implementation of IValueTracker

public void Feed(ulong value) => ++this._bins[(int)(value * ScaleFactor)];

public void Print() => HistogramDrawer.DrawHistogram("Repetition Histogram", 10, this._bins);

#endregion
}
41 changes: 5 additions & 36 deletions Randomizer/Statistics/SpacingHistogram.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;

namespace Randomizer.Statistics;

internal class SpacingHistogram : IValueTracker {
private const int NumBins = 40; // Number of bins for spacing histogram
private const int NumBins = 64;
private const double ScaleFactor = NumBins / (double)ulong.MaxValue;

private readonly ulong[] _bins = new ulong[NumBins];
private ulong? _lastValue;

Expand All @@ -17,43 +18,11 @@ public void Feed(ulong value) {
}

double delta = value - this._lastValue.Value;
var spacingBin = (int)(delta.Abs() / ulong.MaxValue * NumBins);
var spacingBin = (int)(delta.Abs() * ScaleFactor);
++this._bins[spacingBin];
}

public void Print() {
const int height = 10;
var output = new char[height + 1, NumBins];

// Initialize the array with spaces
for (var y = 0; y < height + 1; ++y)
for (var x = 0; x < NumBins; ++x)
output[y, x] = ' ';

// Write the bin index row
for (var i = 0; i < NumBins; ++i)
output[height, i] = i % 10 == 0 ? i == 0 ? '0' : (char)('A' - 1 + i / 10) : (char)('0' + i % 10);

// Find max to normalize
var max = this._bins.Max();

// Calculate and write the histogram bars
for (var i = 0; i < NumBins; ++i) {
var binHeight = this._bins[i] * height / max;

for (ulong j = 0; j < binHeight; ++j)
output[height - 1 - (int)j, i] = '#';
}

// Convert the array to a string and print it
Console.WriteLine("Spacing Histogram:");
for (var i = 0; i < height + 1; ++i) {
for (var j = 0; j < NumBins; ++j)
Console.Write(output[i, j]);

Console.WriteLine();
}
}
public void Print() => HistogramDrawer.DrawHistogram("Spacing Histogram", 10, this._bins);

#endregion
}
3 changes: 2 additions & 1 deletion Randomizer/StatsTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ internal class StatsTracker:IValueTracker {
private readonly IValueTracker[] _trackers = [
new BitIndexHistogram(),
new BitCountHistogram(),
new SpacingHistogram()
new SpacingHistogram(),
new RepetitionHistogram()
];

public void Feed(ulong value) {
Expand Down

0 comments on commit e0daf4c

Please sign in to comment.