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)(Txs
, size_tminlength
= 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)(Txs
, Wweights
, size_tminlength
= 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 asxs
size_t
minlength
a minimum number of bins for the output array
Return Value
slice like
weights
of weighted number of ocurrencesTODO: support @nogc
Examples
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)(Sslice
) if (isSlice!S);Computes the geometric mean of a
slice
. The product ingmean
is computed in logarithms to avoid FP overflows.Parameters
S
slice
input
slice
Return Value
geometric mean of
slice
See Also
@9il comment https://github.com/libmir/numir/pull/24#discussion_r168958617
-
Declaration
pure nothrow @nogc @safe auto
gmean
(S, Seed)(Sslice
, Seedseed
) 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
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
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
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
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
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
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
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
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)(Sslice
) 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
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
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)(Sslice
) 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 vectorimport 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 matriximport 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 matriximport 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)(Sslice
, in Orderorder
) if (isSlice!S);Parameters
S
slice
input
slice
Order
order
order
ofmoment
Return Value
n-th central
moment
ofslice
-
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)
TODO: merge fast implementation in https://github.com/libmir/numir/pull/22#issuecomment-366526194
See Also
Examples
Variance of vector
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
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
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
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); }
-
Declaration
auto
var
(S)(Sslice
, boolisPopulation
= true) if (isSlice!S);Parameters
S
slice
input
slice
bool
isPopulation
true
(default) if computing population variance,false
otherwiseReturn Value
variance of
slice
-
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
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
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
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));
-
Declaration
auto
std
(S)(Sslice
, boolisPopulation
= true) if (isSlice!S);Parameters
S
slice
input
slice
bool
isPopulation
true
(default) if computing population standard deviation,false
otherwiseReturn 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
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
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)(Sslice
, boolisPopulation
= true) if (isSlice!S);Parameters
S
slice
input
slice
bool
isPopulation
true
(default) if computing population standard deviation,false
otherwiseReturn Value
zscore
ofslice
-
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
// 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)(Aa
) if (isSlice!A);Params
a
= input sliceReturn Value
log-sum-exp value. if
is empty, this function returns -inf as mir.math.sum([]) does too.a
-
Declaration
auto
logsumexp
(A, B)(Aa
, Bb
) if (isSlice!A && isSlice!B);Params
a
= input sliceb
= scaling factor slice forexp(
must have the same shape toa
)b
Return Value
log-sum-exp value. if
is empty, this function returns -inf as mir.math.sum([]) does too.a