gmean

  1. gmeanType!F gmean(Range r)
  2. gmeanType!Range gmean(Range r)
  3. gmeanType!F gmean(F[] ar)
    @fmamath
    gmean
    (
    F
    )
    (
    scope const F[] ar...
    )
    if (
    isFloatingPoint!F
    )

Parameters

ar F[]

values

Examples

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));

Meta