controls whether the input is modified in place, default is false
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]));