numir.stats

Various statistics functions on ndslice. (e.g., bincount, var, logsumexp)

  • Declaration

    enum auto isBincountable(T);

    bincountable type is a one-dimentional slice with unsigned elements

  • Declaration

    pure nothrow @safe auto bincount(T)(T xs, size_t minlength = 0) if (isBincountable!T);

    Count number of occurrences of each value in slice of non-negative ints.

    Parameters

    T xs

    input slice

    size_t minlength

    a minimum number of bins for the output array

    Return Value

    size_t slice of number of ocurrence

    TODO: support @nogc

  • Declaration

    pure nothrow @safe auto bincount(T, W)(T xs, W weights, size_t minlength = 0) if (isBincountable!T && isSlice!W);

    Count weighted number of occurrences of each value in slice of non-negative ints. Note that empty weight causes compiler error.

    Parameters

    T xs

    input slice

    W weights

    weights slice of the same length as xs

    size_t minlength

    a minimum number of bins for the output array

    Return Value

    slice like weights of weighted number of ocurrences

    TODO: support @nogc

    Examples

    1. import numir : bincount; import mir.ndslice : sliced, iota, fuse; auto ys = [0, 1, 1, 0, 1].sliced!size_t; assert(ys.bincount == [2, 3]); assert(ys.bincount(iota(ys.length)) == [0+3, 1+2+4]); assert(ys.bincount([[1, 0], [-1, 0], [-1, 0], [1, 0], [-1, 0]].fuse) == [[2, 0], [-3,0]]); assert([].sliced!size_t.bincount == [].sliced!size_t); assert([].sliced!size_t.bincount([].sliced!double) == [].sliced!double);

  • Declaration

    pure nothrow @nogc @safe auto gmean(S)(S slice) if (isSlice!S);

    Computes the geometric mean of a slice. The product in gmean is computed in logarithms to avoid FP overflows.

    Parameters

    S slice

    input slice

    Return Value

    geometric mean of slice

  • Declaration

    pure nothrow @nogc @safe auto gmean(S, Seed)(S slice, Seed seed) if (isSlice!S);

    Computes the geometric mean of a slice.

    Parameters

    S slice

    input slice

    Seed seed

    seed used to calculate product (should be 1 in most cases)

    Return Value

    geometric mean of slice

    Examples

    Geometric mean of vector

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; static immutable x = [1.1, 0.99, 1.01, 1.2, 0.9, 1.05]; auto y = x.sliced.gmean; assert(approxEqual(y, 1.037513));

    Examples

    Geometric mean of matrix

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; static immutable x = [1.1, 0.99, 1.01, 1.2, 0.9, 1.05]; auto y = x.sliced(2, 3).gmean; assert(approxEqual(y, 1.037513));

    Examples

    Column geometric mean of matrix

    1. import mir.ndslice.slice : sliced; import mir.ndslice.topology : alongDim, byDim, map; import numir : approxEqual; static immutable x = [1.1, 0.99, 1.01, 1.2, 0.9, 1.05]; static immutable y = [1.148913, 0.943928, 1.029806]; // Use byDim or alongDim with map to compute mean of row/column. assert(approxEqual(x.sliced(2, 3).byDim!1.map!gmean, y.sliced)); assert(approxEqual(x.sliced(2, 3).alongDim!0.map!gmean, y.sliced));

    Examples

    Geometric mean of vector with seed

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; enum l = 2.0 ^^ (double.max_exp - 1); enum s = 2.0 ^^ -(double.max_exp - 1); static immutable x = [l, l, l, s, s, s, 0.8 * 2.0 ^^ 10]; real seed = 1; auto y = x.sliced.gmean(seed); assert(approxEqual(y, (0.8 * 2.0 ^^ 10) ^^ (1.0 / 7.0)));

  • Declaration

    template hmean(sumTemplateArgs...)

    Computes the harmonic mean of a slice.

    Parameters

    sumTemplateArgs

    template arguments to pass to mir.math.sum (to compute the harmonic mean)

    See Also

    Examples

    Harmonic mean of vector

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; static immutable x = [20.0, 100.0, 2000.0, 10.0, 5.0, 2.0]; auto y = x.sliced.hmean; assert(approxEqual(y, 6.97269));

    Examples

    Harmonic mean of matrix

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; static immutable x = [20.0, 100.0, 2000.0, 10.0, 5.0, 2.0]; auto y = x.sliced(2, 3).hmean; assert(approxEqual(y, 6.97269));

    Examples

    Column harmonic mean of matrix

    1. import mir.ndslice.slice : sliced; import mir.ndslice.topology : alongDim, byDim, map; import numir : approxEqual; static immutable _x = [20.0, 100.0, 2000.0, 10.0, 5.0, 2.0]; auto x = _x.sliced(2, 3); static immutable _y = [13.33333, 9.52381, 3.996004]; auto y = _y.sliced; // Use byDim or alongDim with map to compute mean of row/column. assert(approxEqual(x.byDim!1.map!hmean, y)); assert(approxEqual(x.alongDim!0.map!hmean, y));

    Examples

    Can also pass arguments to hmean

    1. import mir.ndslice.slice: sliced; import mir.ndslice.topology: map, repeat; import std.math : approxEqual; //Set sum algorithm or output type static immutable _x = [1, 1e100, 1, -1e100]; auto x = _x.sliced * 10_000; assert(approxEqual(x.hmean!"kbn", 20_000)); assert(approxEqual(x.hmean!"kb2", 20_000)); assert(approxEqual(x.hmean!"precise", 20_000)); assert(approxEqual(x.hmean!(double, "precise"), 20_000.0));

    • Declaration

      auto hmean(S)(S slice) if (isFloatingPoint!(DeepElementType!S));

      Parameters

      S slice

      input slice

      Return Value

      harmonic mean of slice

  • Declaration

    template center(sumTemplateArgs...)

    Lazily centers a slice.

    Parameters

    sumTemplateArgs

    template arguments to pass to mir.math.sum (to compute the mean of the slice)

    See Also

    Examples

    Center vector

    1. import mir.ndslice.slice : sliced; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable result = [-2.4375, -1.4375, -0.9375, -0.4375, 1.0625, 1.8125, -0.4375, 5.0625, 2.5625, -1.4375, -0.9375, -2.4375]; assert(x.sliced.center == result.sliced);

    Examples

    Center matrix

    1. import mir.ndslice.slice : sliced; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable result = [-2.4375, -1.4375, -0.9375, -0.4375, 1.0625, 1.8125, -0.4375, 5.0625, 2.5625, -1.4375, -0.9375, -2.4375]; assert(x.sliced(2, 6).center == result.sliced(2, 6));

    • Declaration

      auto center(S)(S slice) if (isSlice!S);

      Parameters

      S slice

      input slice

      Return Value

      centered slice

  • Declaration

    template moment(sumTemplateArgs...)

    Computes the n-th central moment of a slice.

    Parameters

    sumTemplateArgs

    template arguments to pass to mir.math.sum (to compute the mean of the slice and the relevant moment)

    See Also

    Examples

    2nd central moment of vector

    1. import std.math : approxEqual; import mir.ndslice.slice : sliced; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; // FIXME assert(approxEqual(x.sliced.moment(2), 54.76563 / 12)); assert(approxEqual(x.sliced.moment(2.0), 54.76563 / 12));

    Examples

    2nd central moment of matrix

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; assert(approxEqual(x.sliced(2, 6).moment(2.0), 54.76563 / 12));

    Examples

    Row 2nd central moment of matrix

    1. import mir.ndslice.slice : sliced; import mir.ndslice.topology : byDim, alongDim, map; import std.math : approxEqual; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable y = [2.092014, 6.722222]; // Use byDim or alongDim with map to compute moment of row/column. assert(approxEqual(x.sliced(2, 6).byDim!0.map!(a => a.moment(2.0)), y.sliced)); assert(approxEqual(x.sliced(2, 6).alongDim!1.map!(a => a.moment(2.0)), y.sliced));

    • Declaration

      auto moment(S, Order)(S slice, in Order order) if (isSlice!S);

      Parameters

      S slice

      input slice

      Order order

      order of moment

      Return Value

      n-th central moment of slice

  • var

    Declaration

    template var(sumTemplateArgs...)

    Computes the variance of a slice.

    Parameters

    sumTemplateArgs

    template arguments to pass to mir.math.sum (to compute the mean & variance of the slice)

    See Also

    Examples

    Variance of vector

    1. import std.math : approxEqual; import mir.ndslice.slice : sliced; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; assert(approxEqual(x.sliced.var, 54.76563 / 12)); assert(approxEqual(x.sliced.var(false), 54.76563 / 11)); assert(approxEqual(x.sliced.var(true), 54.76563 / 12));

    Examples

    Variance of matrix

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; assert(approxEqual(x.sliced(2, 6).var, 54.76563 / 12)); assert(approxEqual(x.sliced(2, 6).var(false), 54.76563 / 11)); assert(approxEqual(x.sliced(2, 6).var(true), 54.76563 / 12));

    Examples

    Row variance of matrix

    1. import mir.ndslice.slice : sliced; import mir.ndslice.topology : alongDim, byDim, map; import numir : approxEqual; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable y = [2.092014, 6.722222]; // Use byDim or alongDim with map to compute variance of row/column. assert(approxEqual(x.sliced(2, 6).byDim!0.map!(a => a.var(true)), y.sliced)); assert(approxEqual(x.sliced(2, 6).alongDim!1.map!(a => a.var(true)), y.sliced));

    Examples

    Compute variance tensors along specified dimention of tensors with the negative dim support

    1. import mir.ndslice : alongDim, iota, map, as; import numir : var; /* [[1, 2], [3, 4]] */ auto x = iota([2, 2], 1).as!double; static immutable v0 = [1.0, 1.0]; static immutable v1 = [0.25, 0.25]; /* [[1, 2, 3], [4, 5, 6]] */ auto y = iota([2, 3], 1).as!double; static immutable v2 = [2.25, 2.25, 2.25]; // static foreach (faster; [true, false]) { assert(x.alongDim!0.map!var == v0); assert(x.alongDim!(-2).map!var == v0); assert(x.alongDim!1.map!var == v1); assert(x.alongDim!(-1).map!var == v1); assert(y.alongDim!0.map!var == v2); assert(y.alongDim!(-2).map!var == v2); }

    • var

      Declaration

      auto var(S)(S slice, bool isPopulation = true) if (isSlice!S);

      Parameters

      S slice

      input slice

      bool isPopulation

      true (default) if computing population variance, false otherwise

      Return Value

      variance of slice

  • std

    Declaration

    template std(sumTemplateArgs...)

    Computes the standard deviation of a slice.

    Parameters

    sumTemplateArgs

    template arguments to pass to mir.math.sum (to compute the mean & variance of the slice)

    See Also

    Examples

    Standard deviation of vector

    1. import std.math : approxEqual; import mir.ndslice.slice : sliced; import mir.math.common : sqrt; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; assert(approxEqual(x.sliced.std, sqrt(54.76563 / 12))); assert(approxEqual(x.sliced.std(false), sqrt(54.76563 / 11))); assert(approxEqual(x.sliced.std(true), sqrt(54.76563 / 12)));

    Examples

    Standard deviation of matrix

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; import mir.math.common : sqrt; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; assert(approxEqual(x.sliced(2, 6).std, sqrt(54.76563 / 12))); assert(approxEqual(x.sliced(2, 6).std(false), sqrt(54.76563 / 11))); assert(approxEqual(x.sliced(2, 6).std(true), sqrt(54.76563 / 12)));

    Examples

    Row standard deviation of matrix

    1. import mir.ndslice.slice : sliced; import mir.ndslice.topology : alongDim, byDim, map; import mir.math.common : sqrt; import numir : approxEqual; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable y = [sqrt(2.092014), sqrt(6.722222)]; // Use byDim or alongDim or alongDim with map to compute variance of row/column. assert(approxEqual(x.sliced(2, 6).byDim!0.map!(a => a.std(true)), y.sliced)); assert(approxEqual(x.sliced(2, 6).alongDim!1.map!(a => a.std(true)), y.sliced));

    • std

      Declaration

      auto std(S)(S slice, bool isPopulation = true) if (isSlice!S);

      Parameters

      S slice

      input slice

      bool isPopulation

      true (default) if computing population standard deviation, false otherwise

      Return Value

      standard deviation of slice

  • Declaration

    template zscore(sumTemplateArgs...)

    Computes the zscore of a slice.

    Parameters

    sumTemplateArgs

    template arguments to pass to mir.math.sum (to compute the mean & standard deviation of the slice)

    See Also

    Examples

    Z-score of vector

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable resultSample = [-1.09241, -0.64424, -0.42016, -0.19607, 0.47618, 0.812307, -0.19607, 2.268858, 1.148434, -0.64424, -0.42016, -1.09241]; static immutable resultPop = [-1.14099, -0.67289, -0.43884, -0.20479, 0.497354, 0.848427, -0.20479, 2.369745, 1.199501, -0.67289, -0.43884, -1.14099]; assert(approxEqual(x.sliced.zscore, resultPop.sliced)); assert(approxEqual(x.sliced.zscore(false), resultSample.sliced)); assert(approxEqual(x.sliced.zscore(true), resultPop.sliced));

    Examples

    Z-score of matrix

    1. import mir.ndslice.slice : sliced; import std.math : approxEqual; static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable _resultSample = [-1.09241, -0.64424, -0.42016, -0.19607, 0.47618, 0.812307, -0.19607, 2.268858, 1.148434, -0.64424, -0.42016, -1.09241]; auto resultSample = _resultSample.sliced(2, 6); static immutable _resultPop = [-1.14099, -0.67289, -0.43884, -0.20479, 0.497354, 0.848427, -0.20479, 2.369745, 1.199501, -0.67289, -0.43884, -1.14099]; auto resultPop = _resultPop.sliced(2, 6); auto y1 = x.sliced(2, 6).zscore; assert(approxEqual(y1[0], resultPop[0])); assert(approxEqual(y1[1], resultPop[1])); auto y2 = x.sliced(2, 6).zscore(false); assert(approxEqual(y2[0], resultSample[0])); assert(approxEqual(y2[1], resultSample[1])); auto y3 = x.sliced(2, 6).zscore(true); assert(approxEqual(y3[0], resultPop[0])); assert(approxEqual(y3[1], resultPop[1]));

    • Declaration

      auto zscore(S)(S slice, bool isPopulation = true) if (isSlice!S);

      Parameters

      S slice

      input slice

      bool isPopulation

      true (default) if computing population standard deviation, false otherwise

      Return Value

      zscore of slice

  • Declaration

    template logsumexp(sumTemplateArgs...)

    Computes the log of the sum of exponentials of input elements.

    Parameters

    sumTemplateArgs

    template arguments to pass to mir.math.sum (to compute the mean & standard deviation of the slice)

    Examples

    1. // logsumexp example from doctest https://github.com/scipy/scipy/blob/maintenance/1.0.x/scipy/special/_logsumexp.py import mir.ndslice : iota, map, sliced, as; import mir.math.common : log, exp; import mir.math.sum; import std.math : approxEqual; { auto x = iota(10).as!double; assert(logsumexp(x).approxEqual(9.4586297444267107)); assert(log(sum(map!exp(x))).approxEqual(logsumexp(x))); } { auto x = iota(0).as!double; assert(sum(x) == 0); assert(logsumexp(x) == -double.infinity); assert(log(sum(map!exp(x))).approxEqual(logsumexp(x))); } { auto a = iota(10).as!double; auto b = iota([10], 10, -1).as!double; assert(logsumexp(a, b).approxEqual(9.9170178533034665)); assert(log(sum(map!exp(a) * b)).approxEqual(logsumexp(a, b))); } { auto a = iota(0).as!double; auto b = iota(0).as!double; assert(logsumexp(a, b) == -double.infinity); assert(log(sum(map!exp(a) * b)).approxEqual(logsumexp(a, b))); }

    • Declaration

      auto logsumexp(A)(A a) if (isSlice!A);

      Params a = input slice

      Return Value

      log-sum-exp value. if a is empty, this function returns -inf as mir.math.sum([]) does too.

    • Declaration

      auto logsumexp(A, B)(A a, B b) if (isSlice!A && isSlice!B);

      Params a = input slice b = scaling factor slice for exp(a) must have the same shape to b

      Return Value

      log-sum-exp value. if a is empty, this function returns -inf as mir.math.sum([]) does too.