pdfast
Version:
Fast kernel density estimation library
273 lines (234 loc) • 9.22 kB
JavaScript
'use strict';
var EPS = 1e-8;
var _ = require('lodash');
var rewire = require('rewire');
var expect = require('chai').expect;
var pdfast = rewire('../src');
describe('statistic util', function () {
context('create', function () {
var arr = [1, 1, 1, 2, 3, 3, 6, 6, 6, 6, 6, 6, 9, 9, 9, 9, 12];
context('triangle', function () {
var expected = [
{ x: 1, y: 0.18627450980392157 },
{ x: 2.2222222222222223, y: 0.1372549019607843 },
{ x: 3.4444444444444446, y: 0.029411764705882353 },
{ x: 4.666666666666667, y: 0.08823529411764706 },
{ x: 5.888888888888889, y: 0.17647058823529413 },
{ x: 7.111111111111112, y: 0.14705882352941177 },
{ x: 8.333333333333334, y: 0.11764705882352941 },
{ x: 9.555555555555557, y: 0.058823529411764705 },
{ x: 10.777777777777779, y: 0.0196078431372549 },
{ x: 12, y: 0.0392156862745098 }
];
it('should work', function () {
var result = pdfast.create(arr, {
width: 2,
size: 10,
min: 1,
max: 12
});
var sum = _.reduce(result, function (acc, item) {
return acc + item.y;
}, 0);
expect(sum).closeTo(1, EPS);
result.forEach(function (item, i) {
expect(item.x).closeTo(expected[i].x, EPS);
expect(item.y).closeTo(expected[i].y, EPS);
});
});
it('should return empty array for empty input', function () {
var result = pdfast.create([], {width: 2, size: 10, fast: false});
expect(result).to.deep.equal([]);
});
it('should return 100% accuracy pdf for homogen input', function () {
expect(
pdfast.create([12, 12, 12], {width: 2, size: 10, fast: false})
).to.deep.equal([{x: 12, y: 1}]);
expect(
pdfast.create([-1, -1, -1], {width: 2, size: 10, fast: false})
).to.deep.equal([{x: -1, y: 1}]);
});
});
context('general corner cases', function () {
context('pdf area is 0, because hit is always outside', function () {
var expected = [
{ x: 101, y: 0 },
{ x: 102, y: 0 },
{ x: 103, y: 0 },
{ x: 104, y: 0 },
{ x: 105, y: 0 }
];
it('should work', function () {
var result = pdfast.create(arr, {
width: 2,
size: 5,
min: 101,
max: 105
});
result.forEach(function (item, i) {
expect(item.x).closeTo(expected[i].x, EPS);
expect(item.y).closeTo(expected[i].y, EPS);
});
});
});
});
});
context('getUnifiedMinMax', function () {
context('min and max exist', function () {
it('should return defined min max', function () {
expect(pdfast.getUnifiedMinMax([1, 2, 3], {min: -10, max: 10, width: 2, size: 20})).deep.equal({min: -10, max: 10});
expect(pdfast.getUnifiedMinMax([1, 2, 3], {min: -5, max: 15, width: 2, size: 20})).deep.equal({min: -5, max: 15});
});
});
context('only min exist', function () {
it('should return defined min and find the max', function () {
expect(pdfast.getUnifiedMinMax([1, 2, 3], {min: 0, width: 2, size: 4})).deep.equal({min: 0, max: 7});
expect(pdfast.getUnifiedMinMax([1, 2, 3, 4], {min: -1, width: 2, size: 5})).deep.equal({min: -1, max: 9});
});
});
context('only max exist', function () {
it('should return defined max and find the min', function () {
expect(pdfast.getUnifiedMinMax([1, 2, 3], {max: 4, width: 2, size: 4})).deep.equal({min: -3, max: 4});
expect(pdfast.getUnifiedMinMax([1, 2, 3, 4], {max: 6, width: 2, size: 5})).deep.equal({min: -4, max: 6});
});
});
context('no min or max exist', function () {
it('should return defined max and find the min', function () {
expect(pdfast.getUnifiedMinMax([1, 2, 3], {width: 2, size: 3})).deep.equal({min: -3, max: 7});
expect(pdfast.getUnifiedMinMax([1, 2, 3, 4], {width: 2, size: 5})).deep.equal({min: -2, max: 7});
});
});
});
context('getUnifiedMinMaxMulti', function () {
context('min and max exist', function () {
it('should return defined min max', function () {
expect(pdfast.getUnifiedMinMaxMulti([[1, 2, 3], [2, 5]], {min: -10, max: 10, width: 2, size: 20})).deep.equal({min: -10, max: 10});
expect(pdfast.getUnifiedMinMaxMulti([[1, 2, 3], [2, 5]], {min: -5, max: 15, width: 2, size: 20})).deep.equal({min: -5, max: 15});
});
});
context('only min exist', function () {
it('should return defined min and find the max', function () {
expect(pdfast.getUnifiedMinMaxMulti([[1, 2, 3], [0, 1]], {min: 0, width: 2, size: 4})).deep.equal({min: 0, max: 7});
expect(pdfast.getUnifiedMinMaxMulti([[1, 2, 3], [2, 3], [0, 4]], {min: -1, width: 2, size: 5})).deep.equal({min: -1, max: 9});
});
});
context('only max exist', function () {
it('should return defined max and find the min', function () {
expect(pdfast.getUnifiedMinMaxMulti([[1, 2], [2, 3]], {max: 4, width: 2, size: 4})).deep.equal({min: -3, max: 4});
expect(pdfast.getUnifiedMinMaxMulti([[3, 4], [1], [2, 6]], {max: 6, width: 2, size: 5})).deep.equal({min: -4, max: 6});
});
});
context('no min or max exist', function () {
it('should return defined max and find the min', function () {
expect(pdfast.getUnifiedMinMaxMulti([[1], [2, 3], [2]], {width: 2, size: 3})).deep.equal({min: -3, max: 7});
expect(pdfast.getUnifiedMinMaxMulti([[1, 4], [1, 2, 3, 4]], {width: 2, size: 5})).deep.equal({min: -2, max: 7});
});
});
});
context('generatePartialAreas', function () {
var generatePartialAreas = pdfast.__get__('generatePartialAreas');
var mockFunction = function (x) {
return Math.abs(x);
};
it('should work', function () {
var expected = {
"-3": 1,
"-2": 1.6666666666666665,
"-1": 1.9999999999999998,
"0": 1.9999999999999998,
"1": 2.333333333333333,
"2": 2.9999999999999996,
"3": 3.9999999999999996
};
var result = generatePartialAreas(mockFunction, 3);
_.keys(expected).forEach(function (key) {
expect(result[key]).closeTo(expected[key], EPS);
});
});
});
context('getExpectedValueFromPdf', function () {
it('should return undefined for empty pdf', function () {
expect(
pdfast.getExpectedValueFromPdf([])
).equal(undefined);
});
it('should return expected value for typical pdf', function () {
expect(
pdfast.getExpectedValueFromPdf([{x: 12, y: 1}])
).equal(12);
expect(
pdfast.getExpectedValueFromPdf([
{x: 1, y: 0.2},
{x: 2, y: 0.4},
{x: 3, y: 0.3},
{x: 4, y: 0.075},
{x: 5, y: 0.025}
])
).closeTo(2.3249999999999997, EPS);
});
});
context('getXWithLeftTailArea', function () {
it('should return undefined for empty pdf', function () {
expect(
pdfast.getXWithLeftTailArea([], 12)
).equal(undefined);
});
it('should return the only x for any area for 100% accuracy pdf', function () {
var pdf = [{x: 12, y: 1}];
expect(pdfast.getXWithLeftTailArea(pdf, 0)).equal(12);
expect(pdfast.getXWithLeftTailArea(pdf, 0.5)).equal(12);
expect(pdfast.getXWithLeftTailArea(pdf, 0.8)).equal(12);
expect(pdfast.getXWithLeftTailArea(pdf, 1)).equal(12);
});
it('should return x position where left tail area equals given param', function () {
var pdf = [
{x: 1, y: 0.2},
{x: 2, y: 0.4},
{x: 3, y: 0.3},
{x: 4, y: 0.075},
{x: 5, y: 0.025}
];
expect(pdfast.getXWithLeftTailArea(pdf, 0)).equal(1);
expect(pdfast.getXWithLeftTailArea(pdf, 0.12)).equal(1);
expect(pdfast.getXWithLeftTailArea(pdf, 0.19)).equal(1);
expect(pdfast.getXWithLeftTailArea(pdf, 0.21)).equal(2);
expect(pdfast.getXWithLeftTailArea(pdf, 0.95)).equal(4);
expect(pdfast.getXWithLeftTailArea(pdf, 1)).equal(5);
});
});
context('getPerplexity', function () {
it('should return undefined for empty pdf', function () {
expect(pdfast.getPerplexity([])).equal(undefined);
expect(pdfast.getPerplexity(undefined)).equal(undefined);
expect(pdfast.getPerplexity(null)).equal(undefined);
});
it('should return correct perplexity', function () {
expect(
pdfast.getPerplexity([
{x: 1, y: 0.2},
{x: 2, y: 0.2},
{x: 3, y: 0.2},
{x: 4, y: 0.2},
{x: 5, y: 0.2}
])
).closeTo(5, EPS);
expect(
pdfast.getPerplexity([
{x: 1, y: 0.2},
{x: 2, y: 0.4},
{x: 3, y: 0.3},
{x: 4, y: 0.075},
{x: 5, y: 0.025}
])
).closeTo(3.8041316039860336, EPS);
expect(
pdfast.getPerplexity([
{x: 1, y: 0},
{x: 2, y: 0},
{x: 3, y: 1},
{x: 4, y: 0}
])
).closeTo(1, EPS);
});
});
});