values
import mir.math.common: approxEqual; import mir.ndslice.slice: sliced; assert(gmean([1.0, 2, 3]).approxEqual(1.81712059)); assert(gmean!float([1, 2, 3, 4, 5, 6].sliced(3, 2)).approxEqual(2.99379516)); static assert(is(typeof(gmean!float([1, 2, 3])) == float));
Geometric mean of vector
import mir.math.common: approxEqual; import mir.ndslice.slice: sliced; auto x = [3.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 2.0].sliced; assert(x.gmean.approxEqual(2.36178395));
Geometric mean of matrix
import mir.math.common: approxEqual; import mir.ndslice.fuse: fuse; auto x = [ [3.0, 1.0, 1.5, 2.0, 3.5, 4.25], [2.0, 7.5, 5.0, 1.0, 1.5, 2.0] ].fuse; assert(x.gmean.approxEqual(2.36178395));
Column gmean of matrix
import mir.algorithm.iteration: all; import mir.math.common: approxEqual; import mir.ndslice.fuse: fuse; import mir.ndslice.topology: alongDim, byDim, map; auto x = [ [3.0, 1.0, 1.5, 2.0, 3.5, 4.25], [2.0, 7.5, 5.0, 1.0, 1.5, 2.0] ].fuse; auto result = [2.44948974, 2.73861278, 2.73861278, 1.41421356, 2.29128784, 2.91547594]; // Use byDim or alongDim with map to compute mean of row/column. assert(x.byDim!1.map!gmean.all!approxEqual(result)); assert(x.alongDim!0.map!gmean.all!approxEqual(result)); // FIXME // Without using map, computes the mean of the whole slice // assert(x.byDim!1.gmean.all!approxEqual(result)); // assert(x.alongDim!0.gmean.all!approxEqual(result));
Can also set output type
import mir.math.common: approxEqual; import mir.ndslice.slice: sliced; import mir.ndslice.topology: repeat; auto x = [5120.0, 7340032, 32, 3758096384].sliced; assert(x.gmean!float.approxEqual(259281.45295212)); auto y = uint.max.repeat(2); assert(y.gmean!float.approxEqual(cast(float) uint.max));
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 = [5, 1, 1, 2, 4, 4, 2, 7, 5, 1, 2, 10].sliced; auto y = x.gmean; static assert(is(typeof(y) == double)); assert(x.gmean!float.approxEqual(2.79160522));
gean works for user-defined types, provided the nth root can be taken for them
static struct Foo { float x; alias x this; } import mir.math.common: approxEqual; import mir.ndslice.slice: sliced; auto x = [Foo(1.0), Foo(2.0), Foo(3.0)].sliced; assert(x.gmean.approxEqual(1.81712059));
Compute gmean tensors along specified dimention of tensors
import mir.algorithm.iteration: all; import mir.math.common: approxEqual; import mir.ndslice.fuse: fuse; import mir.ndslice.topology: alongDim, iota, map; auto x = [ [1.0, 2, 3], [4.0, 5, 6] ].fuse; assert(x.gmean.approxEqual(2.99379516)); auto result0 = [2.0, 3.16227766, 4.24264069]; assert(x.alongDim!0.map!gmean.all!approxEqual(result0)); assert(x.alongDim!(-2).map!gmean.all!approxEqual(result0)); auto result1 = [1.81712059, 4.93242414]; assert(x.alongDim!1.map!gmean.all!approxEqual(result1)); assert(x.alongDim!(-1).map!gmean.all!approxEqual(result1)); auto y = [ [ [1.0, 2, 3], [4.0, 5, 6] ], [ [7.0, 8, 9], [10.0, 9, 10] ] ].fuse; auto result3 = [ [2.64575131, 4.0, 5.19615242], [6.32455532, 6.70820393, 7.74596669] ]; assert(y.alongDim!0.map!gmean.all!approxEqual(result3));
Arbitrary gmean
import mir.math.common: approxEqual; assert(gmean(1.0, 2, 3).approxEqual(1.81712059)); assert(gmean!float(1, 2, 3).approxEqual(1.81712059));