The OpenD Programming Language

entropy

Examples

import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;

assert(entropy([0.166667, 0.333333, 0.50]).approxEqual(-1.011404));

assert(entropy!float([0.05, 0.1, 0.15, 0.2, 0.25, 0.25].sliced(3, 2)).approxEqual(-1.679648));

static assert(is(typeof(entropy!float([0.166667, 0.333333, 0.50])) == float));

Entropy of vector

import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;

double[] a = [1.0, 2, 3,  4,  5,  6, 7, 8, 9, 10, 11, 12];
a[] /= 78.0;

auto x = a.sliced;
assert(x.entropy.approxEqual(-2.327497));

Entropy of matrix

import mir.math.common: approxEqual;
import mir.ndslice.fuse: fuse;

double[] a = [1.0, 2, 3,  4,  5,  6, 7, 8, 9, 10, 11, 12];
a[] /= 78.0;

auto x = a.fuse;
assert(x.entropy.approxEqual(-2.327497));

Column entropy of matrix

import mir.algorithm.iteration: all;
import mir.math.common: approxEqual;
import mir.ndslice.fuse: fuse;
import mir.ndslice.topology: alongDim, byDim, map;

double[][] a = [
    [1.0, 2, 3,  4,  5,  6], 
    [7.0, 8, 9, 10, 11, 12]
];
a[0][] /= 78.0;
a[1][] /= 78.0;

auto x = a.fuse;
auto result = [-0.272209, -0.327503, -0.374483, -0.415678, -0.452350, -0.485273];

// Use byDim or alongDim with map to compute entropy of row/column.
assert(x.byDim!1.map!entropy.all!approxEqual(result));
assert(x.alongDim!0.map!entropy.all!approxEqual(result));

// FIXME
// Without using map, computes the entropy of the whole slice
// assert(x.byDim!1.entropy == x.sliced.entropy);
// assert(x.alongDim!0.entropy == x.sliced.entropy);

Can also set algorithm or output type

import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;
import mir.ndslice.topology: repeat;

auto a = [1, 1e100, 1, 1e100].sliced;

auto x = a * 10_000;

assert(x.entropy!"kbn".approxEqual(4.789377e106));
assert(x.entropy!"kb2".approxEqual(4.789377e106));
assert(x.entropy!"precise".approxEqual(4.789377e106));
assert(x.entropy!(double, "precise").approxEqual(4.789377e106));

For integral slices, pass output type as template parameter to ensure output type is correct.

import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;

auto x = [3, 1, 1, 2, 4, 4,
          2, 7, 5, 1, 2, 3].sliced;

auto y = x.entropy;
assert(y.approxEqual(43.509472));
static assert(is(typeof(y) == double));

assert(x.entropy!float.approxEqual(43.509472f));

Arbitrary entropy

import mir.math.common: approxEqual;

assert(entropy(0.25, 0.25, 0.25, 0.25).approxEqual(-1.386294));
assert(entropy!float(0.25, 0.25, 0.25, 0.25).approxEqual(-1.386294));

Meta