/*
|
* @author Hong-Phuc Bui
|
* @filename dfhi-random-test
|
* Initial Date 16.12.19
|
*/
|
|
import {expect, test} from "@jest/globals";
|
import * as Rand from "./dfhi-random.js";
|
|
const LONGEST_TIMEOUT = 2*5000; // secs
|
|
test( "uniform distribution with default min = 0", () => {
|
let min = 0,
|
max = 10;
|
let uniformSetupFn = (a,b) => () => Rand.uniform(b);
|
testUniformDistribution(min, max, uniformSetupFn);
|
});
|
|
test("uniform distribution in a rang [min,max)", () => {
|
let max = 10,
|
min = 5;
|
let uniformSetupFn = (a, b) => () => Rand.uniform(a, b);
|
testUniformDistribution(min, max, uniformSetupFn);
|
});
|
|
function testUniformDistribution(min, max, uniformSetupFn) {
|
let randomCount = 1000,
|
dist = {};
|
let uniformFn = uniformSetupFn(min, max);
|
for (let i = 0; i < randomCount; ++i) {
|
let r = uniformFn();
|
expect(r < max).toBeTruthy();
|
expect(min <= r).toBeTruthy();
|
if (dist[r]) {
|
dist[r] += 1;
|
} else {
|
dist[r] = 1;
|
}
|
}
|
let exemplars = max - min; // how many distinct int numbers in [min, max);
|
let means = randomCount/exemplars; // Erwartungswert
|
let epsilon = 0.5;
|
for (let [key, value] of Object.entries(dist) ) {
|
let diff = Math.abs((value-means)/value );
|
expect(diff < epsilon ).toBeTruthy();
|
}
|
}
|
|
test ("bad range of uniform", () => {
|
let max = 10,
|
min = max + 1;
|
try{
|
Rand.uniform(min, max);
|
}catch (error) {
|
expect(error.message).toBe('bad range [11, 10)');
|
}
|
});
|
|
test( "discrete distribution", () => {
|
let p = [0.1, 0.3, 0.6];
|
testDiscreteDist(p);
|
}, LONGEST_TIMEOUT);
|
|
test("discrete random 2", () => {
|
let p = [0.1, 0.5]; // same as [0.1, 0.5, 0.5]
|
testDiscreteDist(p);
|
}, LONGEST_TIMEOUT);
|
|
|
function testDiscreteDist(p) {
|
let countRandom = {};
|
let iteration = 10000;
|
|
for(let count = 0; count < iteration; ++count) {
|
let i = Rand.discrete(p);
|
if (countRandom[i]) {
|
countRandom[i] += 1;
|
} else {
|
countRandom[i] = 1;
|
}
|
}
|
console.log(p);
|
let lastP = 1 - p.reduce( (acc, c) => acc + c );
|
let epsilon = 0.1;
|
for( let [key,count] of Object.entries(countRandom) ) {
|
let testP = p[key] ? p[key] : lastP;
|
let cP = count / iteration,
|
percentDiff = Math.abs(cP - testP) / testP;
|
let msg = `probability of ${key} is ${count} / ${iteration} = ${cP},` +
|
`near by ${testP} with relative error less than ${percentDiff*100}%`
|
expect(percentDiff < epsilon).toBeTruthy();
|
}
|
}
|
|
test("discrete bad distribution", () => {
|
let p = [0.5, 0.5, 0.5]; // same as [0.1, 0.5, 0.5]
|
try {
|
Rand.discrete(p);
|
} catch (error) {
|
expect(error.message).toBe('bad distribution [0.5,0.5,0.5]');
|
}
|
});
|