The elements in the slice with the average subtracted from them.
Center vector
import mir.algorithm.iteration: all; import mir.math.common: approxEqual; import mir.ndslice.slice: sliced; auto x = [1.0, 2, 3, 4, 5, 6].sliced; assert(x.center.all!approxEqual([-2.5, -1.5, -0.5, 0.5, 1.5, 2.5])); // Can center using different functions assert(x.center!hmean.all!approxEqual([-1.44898, -0.44898, 0.55102, 1.55102, 2.55102, 3.55102])); assert(x.center!gmean.all!approxEqual([-1.99379516, -0.99379516, 0.00620483, 1.00620483, 2.00620483, 3.00620483])); assert(x.center!median.all!approxEqual([-2.5, -1.5, -0.5, 0.5, 1.5, 2.5])); // center operates lazily, if original slice is changed, then auto y = x.center; assert(y.all!approxEqual([-2.5, -1.5, -0.5, 0.5, 1.5, 2.5])); x[0]++; assert(y.all!approxEqual([-1.5, -1.5, -0.5, 0.5, 1.5, 2.5]));
Example of lazy behavior of center
import mir.algorithm.iteration: all; import mir.math.common: approxEqual; import mir.ndslice.allocation: slice; import mir.ndslice.slice: sliced; auto x = [1.0, 2, 3, 4, 5, 6].sliced; auto y = x.center; auto z = x.center.slice; assert(y.all!approxEqual([-2.5, -1.5, -0.5, 0.5, 1.5, 2.5])); x[0]++; // y changes, while z does not assert(y.all!approxEqual([-1.5, -1.5, -0.5, 0.5, 1.5, 2.5])); assert(z.all!approxEqual([-2.5, -1.5, -0.5, 0.5, 1.5, 2.5]));
Center dynamic array
import mir.algorithm.iteration: all; import mir.math.common: approxEqual; auto x = [1.0, 2, 3, 4, 5, 6]; assert(x.center.all!approxEqual([-2.5, -1.5, -0.5, 0.5, 1.5, 2.5]));
Center matrix
import mir.algorithm.iteration: all; import mir.math.common: approxEqual; import mir.ndslice: fuse; auto x = [ [0.0, 1, 2], [3.0, 4, 5] ].fuse; auto y = [ [-2.5, -1.5, -0.5], [ 0.5, 1.5, 2.5] ].fuse; assert(x.center.all!approxEqual(y));
Column center matrix
import mir.algorithm.iteration: all, equal; import mir.math.common: approxEqual; import mir.ndslice: fuse; import mir.ndslice.topology: alongDim, byDim, map; auto x = [ [20.0, 100.0, 2000.0], [10.0, 5.0, 2.0] ].fuse; auto result = [ [ 5.0, 47.5, 999], [-5.0, -47.5, -999] ].fuse; // Use byDim with map to compute average of row/column. auto xCenterByDim = x.byDim!1.map!center; auto resultByDim = result.byDim!1; assert(xCenterByDim.equal!(equal!approxEqual)(resultByDim)); auto xCenterAlongDim = x.alongDim!0.map!center; auto resultAlongDim = result.alongDim!0; assert(xCenterByDim.equal!(equal!approxEqual)(resultAlongDim));
Can also pass arguments to average function used by center
import mir.ndslice.slice: sliced; //Set sum algorithm or output type auto a = [1, 1e100, 1, -1e100]; auto x = a.sliced * 10_000; //Due to Floating Point precision, subtracting the mean from the second //and fourth numbers in `x` does not change the value of the result auto result = [5000, 1e104, 5000, -1e104].sliced; assert(x.center!(mean!"kbn") == result); assert(x.center!(mean!"kb2") == result); assert(x.center!(mean!"precise") == result);
Passing a centered input to variance or standardDeviation with the assumeZeroMean algorithm is equivalent to calculating variance or standardDeviation on the original input.
import mir.algorithm.iteration: all; import mir.math.common: approxEqual; import mir.ndslice.slice: sliced; auto x = [1.0, 2, 3, 4, 5, 6].sliced; assert(x.center.variance!"assumeZeroMean".approxEqual(x.variance)); assert(x.center.standardDeviation!"assumeZeroMean".approxEqual(x.standardDeviation));
Centers slice, which must be a finite iterable.
By default, slice is centered by the mean. A custom function may also be provided using centralTendency.