Detect Entropy Levels from Primitive Data Arrays
using System;
using System.Collections.Generic;
public class EntropyGeneric<T>
{
private const double NaturalLogOfTwo = 0.69314718055994530941723212145818;
private readonly Dictionary<T, int> _hist = new Dictionary<T, int>();
private bool _mapStatus;
public EntropyGeneric()
{
_hist.Clear();
_mapStatus = false;
}
public (double entropy, int perfect) Entropy(T[] s)
{
if (_mapStatus)
{
_hist.Clear();
_mapStatus = false;
}
foreach (var c in s)
if (!_hist.ContainsKey(c))
_hist.Add(c, 1);
else
_hist[c] += 1;
_mapStatus = true;
var e = 0.0;
foreach (var v in _hist.Values)
{
if (v <= 0)
continue;
var r = v / (double) s.Length;
e -= r * (Math.Log(r) / NaturalLogOfTwo);
}
return (e, GetSize());
}
private byte[] ConvertTypeByteArray(T[] ia)
{
switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Boolean:
break;
case TypeCode.Char:
break;
case TypeCode.SByte:
break;
case TypeCode.Byte:
break;
case TypeCode.Int16:
break;
case TypeCode.UInt16:
break;
case TypeCode.Int32:
break;
case TypeCode.UInt32:
break;
case TypeCode.Single:
break;
case TypeCode.String:
break;
case TypeCode.Decimal:
break;
case TypeCode.Int64:
break;
case TypeCode.UInt64:
break;
case TypeCode.Double:
break;
case TypeCode.DateTime:
break;
default:
throw new ArgumentException("Type is not a valid primitive.");
}
return ia.GetBytesObject();
}
private int GetSize()
{
var size = 0;
switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Boolean:
size = 8;
break;
case TypeCode.Char:
size = 16;
break;
case TypeCode.SByte:
size = 8;
break;
case TypeCode.Byte:
size = 8;
break;
case TypeCode.Int16:
size = 16;
break;
case TypeCode.UInt16:
size = 16;
break;
case TypeCode.Int32:
size = 32;
break;
case TypeCode.UInt32:
size = 32;
break;
case TypeCode.Single:
size = 32;
break;
case TypeCode.String:
size = 32;
break;
case TypeCode.Decimal:
size = 96;
break;
case TypeCode.Int64:
size = 64;
break;
case TypeCode.UInt64:
size = 64;
break;
case TypeCode.Double:
size = 64;
break;
case TypeCode.DateTime:
size = 64;
break;
default:
throw new ArgumentException("Type is not a valid primitive.");
}
return size;
}
}