UNPKG

peirce-criterion

Version:

Functions for outlier removal using Peirce's criterion

129 lines (122 loc) 3.6 kB
const { peirce_dev, remove_outliers, separate_outliers } = require('./index.js'); describe('peirce_dev', () => { test('it is a function', () => { expect(typeof peirce_dev).toBe('function'); }); test('it throws if non-numeric parameter is received', () => { for (const [N, k, m] of [[null, 1, 1], [1, null, 1], [1, 1, null]]) { expect(() => peirce_dev(N, k, m)).toThrow('numeric'); } }); test('it returns 0 when N < 2', () => { for (const [N, k, m] of [[0, 1, 1], [1, 1, 1]]) { expect(peirce_dev(N, k, m)).toEqual(0); } }); describe(`it agrees with reference implementation / Peirce's table`, () => { const cases = [{ N: 3, k: 1, m: 1, expected: 1.479, // roughly 1.196 ** 2 }, { N: 10, k: 1, m: 1, expected: 3.525, // roughly 1.878 ** 2 }, { N: 16, k: 2, m: 1, expected: 3.264, // roughly 1.807 ** 2 }]; for (const { N, k, m, expected } of cases) { test(`N=${N}, k=${k}, m=${m} --> ${expected}`, () => { expect(peirce_dev(N, k, m)).toBeCloseTo(expected); }) } }); }); describe('remove_outliers', () => { const groups = [{ description: 'it removes "obvious" single outlier from contrived examples', cases: [{ input: [1, 2, 3, 100], expected: [1, 2, 3], }, { input: [0, 1, 2, 0, 1, 1, 0], expected: [0, 1, 0, 1, 1, 0], }] }, { description: 'it removes multiple "obvious" outliers', cases: [{ input: [100, 100].concat(new Array(20).fill(0)), expected: new Array(20).fill(0), }, { input: [50, 55, 45].concat(new Array(20).fill(0)), expected: new Array(20).fill(0), }] }, { description: 'it does not remove anything in the case of a split', cases: [{ input: [ ...new Array(5).fill(-1), ...new Array(5).fill(1), ], expected: [ ...new Array(5).fill(-1), ...new Array(5).fill(1), ], }] }]; for (const { description, cases } of groups) { describe(description, () => { for (const { input, expected } of cases) { test(`[${input}] -> [${expected}]`, () => expect(remove_outliers(input)).toEqual(expected)); } }); } }); describe('separate_outliers', () => { const groups = [{ description: 'it removes "obvious" single outlier from contrived examples', cases: [{ input: [1, 2, 3, 100], expected: { trimmed: [1, 2, 3], outliers: [100], outlierIndices: [3], }, }, { input: [0, 1, 2, 0, 1, 1, 0], expected: { trimmed: [0, 1, 0, 1, 1, 0], outliers: [2], outlierIndices: [2], }, }] }, { description: 'it does not remove anything in the case of a split', cases: [{ input: [ ...new Array(5).fill(100), ...new Array(6).fill(5000), ], expected: { trimmed: [ ...new Array(5).fill(100), ...new Array(6).fill(5000), ], outliers: [], outlierIndices: [], }, }] }]; for (const { description, cases } of groups) { describe(description, () => { for (const { input, expected } of cases) { test(`[${input}] outliers -> [${expected.outliers}]`, () => { const actual = separate_outliers(input); expect(actual.trimmed).toEqual(expected.trimmed); expect(actual.outliers).toEqual(expected.outliers); expect(actual.outlierIndices).toEqual(expected.outlierIndices); expect(actual.original).toEqual(input); }); } }); } });