The OpenD Programming Language

robustScale

Members

Functions

robustScale
auto robustScale(Slice!(Iterator, N, kind) slice, double low_quartile)
auto robustScale(SliceLike x, double low_quartile)

Parameters

quantileAlgo

algorithm for calculating quantile (default: QuantileAlgo.type7)

allowModifySlice

controls whether the input is modified in place, default is false

Examples

robustScale vector

import mir.algorithm.iteration: all, findIndex;
import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;

static immutable input = [100.0, 16, 12, 13, 15, 12, 16, 9, 3, -100];
auto x = input.dup.sliced;
auto y = x.robustScale;

assert(y.all!approxEqual([14.583333, 0.583333, -0.083333, 0.083333, 0.416667, -0.083333, 0.583333, -0.583333, -1.583333, -18.750000]));
assert(x.robustScale(0.15).all!approxEqual([8.02752, 0.321101, -0.0458716, 0.0458716, 0.229358, -0.0458716, 0.321101, -0.321101, -0.87156, -10.3211]));

// When allowModifySlice = true, this modifies both the original input and
// the order of the output
auto yCopy = y.idup;
auto z = x.robustScale!true;
size_t j;
foreach(i, ref e; input) {
    j = x.findIndex!(a => a == e);
    assert(z[j].approxEqual(yCopy[i]));
}

robustScale dynamic array

import mir.algorithm.iteration: all;
import mir.math.common: approxEqual;

auto x = [100.0, 16, 12, 13, 15, 12, 16, 9, 3, -100];
assert(x.robustScale.all!approxEqual([14.583333, 0.583333, -0.083333, 0.083333, 0.416667, -0.083333, 0.583333, -0.583333, -1.583333, -18.750000]));

robustScale matrix

import mir.algorithm.iteration: all;
import mir.math.common: approxEqual;
import mir.ndslice.fuse: fuse;

auto x = [
    [100.0, 16, 12, 13,   15], 
    [ 12.0, 16,  9,  3, -100]
].fuse;

assert(x.robustScale.all!approxEqual([[14.583333, 0.583333, -0.083333, 0.083333, 0.416667], [-0.083333, 0.583333, -0.583333, -1.583333, -18.750000]]));

Column robustScale matrix

import mir.algorithm.iteration: all, equal;
import mir.math.common: approxEqual;
import mir.ndslice.fuse: fuse;
import mir.ndslice.topology: alongDim, byDim, map;

auto x = [
    [100.0, 16, 12, 13,   15], 
    [ 12.0, 16,  9,  3, -100]
].fuse;

auto result = [
    [28.333333, 0.333333, -1.0, -0.666667,  0.0], 
    [ 0.333333, 0.777778,  0.0, -0.666667, -12.111111]
].fuse;

// Use byDim with map to scale by row/column.
auto xRobustScaleByDim = x.byDim!0.map!robustScale;
auto resultByDim = result.byDim!0;
assert(xRobustScaleByDim.equal!(equal!approxEqual)(resultByDim));

auto xRobustScaleAlongDim = x.alongDim!1.map!robustScale;
auto resultAlongDim = result.alongDim!1;
assert(xRobustScaleAlongDim.equal!(equal!approxEqual)(resultAlongDim));

Can control QuantileAlgo and output type

import mir.algorithm.iteration: all;
import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;
import mir.ndslice.topology: repeat;

//Set `QuantileAlgo` algorithm or output type
auto x = [100.0, 16, 12, 13, 15, 12, 16, 9, 3, -100].sliced;

assert(x.robustScale!("type9").all!approxEqual([11.864407, 0.474576, -0.0677966, 0.0677966, 0.338983, -0.0677966, 0.474576, -0.474576, -1.288136, -15.254237]));
assert(x.robustScale!("type1").all!approxEqual([12.500000, 0.500000, -0.0714286, 0.0714286, 0.357143, -0.0714286, 0.500000, -0.500000, -1.357143, -16.071429]));
assert(x.robustScale!(float, "type6").all!approxEqual([10.294118f, 0.411765f, -0.0588235f, 0.0588235f, 0.294118f, -0.0588235f, 0.411765f, -0.411765f, -1.117647f, -13.235294f]));

auto y = [uint.max, uint.max / 2, uint.max / 3].sliced;
assert(y.robustScale!"type1".all!approxEqual([0.75, 0, -0.25]));

auto z = [ulong.max, ulong.max / 2, ulong.max / 3].sliced;
assert(z.robustScale!(ulong, "type1").all!approxEqual([0.75, 0, -0.25]));

Meta