EntropyEx.cs

Generic Entropy Class

using System;
using System.Collections.Generic;
using System.Text;
public class EntropyEx<T>
{
    private const    double             NaturalLogOfTwo = 0.69314718055994530941723212145818;
    private readonly Dictionary<T, int> _histograpm     = new Dictionary<T, int>();
    private          bool               _histograpmStatus;
    private readonly int                _size;
    public EntropyEx()
    {
        _histograpm.Clear();
        _histograpmStatus = false;
        _size             = GetSize();
    }
    public double Entropy(string str)
    {
        var s = str.GetBytes(Encoding.Default);
        var histograpmL = new Dictionary<byte, int>();
        foreach (var c in s)
            if (!histograpmL.ContainsKey(c))
                histograpmL.Add(c, 1);
            else
                histograpmL[c] += 1;
        var e = 0.0;
        foreach (var v in histograpmL.Values)
        {
            if (v <= 0)
                continue;
            var r = v             / (double)s.Length;
            e -= r * (Math.Log(r) / NaturalLogOfTwo);
        }
        return e / 8 * 100.0;
    }
    public double Entropy(T[] s)
    {
        if (_histograpmStatus)
        {
            _histograpm.Clear();
            _histograpmStatus = false;
        }
        foreach (var c in s)
            if (!_histograpm.ContainsKey(c))
                _histograpm.Add(c, 1);
            else
                _histograpm[c] += 1;
        _histograpmStatus = true;
        var e = 0.0;
        foreach (var v in _histograpm.Values)
        {
            if (v <= 0)
                continue;
            var r = v             / (double) s.Length;
            e -= r * (Math.Log(r) / NaturalLogOfTwo);
        }
        return e / _size * 100.0;
    }
    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.GetBytes();
    }
    private int GetSize()
    {
        var size = 0;
        switch (Type.GetTypeCode(typeof(T)))
        {
            case TypeCode.Boolean:
                size = 1;
                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 = 192;
                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 within this context.");
        }
        return size;
    }
}