Merge branch 'master' of https://github.com/MozillaSecurity/octo
This commit is contained in:
commit
80e1a17cf6
3 changed files with 318 additions and 83 deletions
|
@ -40,8 +40,8 @@ var random = {
|
||||||
return Math.exp(this.float() * Math.log(limit));
|
return Math.exp(this.float() * Math.log(limit));
|
||||||
},
|
},
|
||||||
item: function (list) {
|
item: function (list) {
|
||||||
if (!(list instanceof Array || (typeof list != "string" && "length" in list))) {
|
if (!(list instanceof Array || (list !== undefined && typeof list != "string" && list.hasOwnProperty("length")))) {
|
||||||
Utils.traceback();
|
//Utils.traceback();
|
||||||
throw new TypeError("this.item() received a non array type: '" + list + "'");
|
throw new TypeError("this.item() received a non array type: '" + list + "'");
|
||||||
}
|
}
|
||||||
return list[this.number(list.length)];
|
return list[this.number(list.length)];
|
||||||
|
|
|
@ -1,29 +1,54 @@
|
||||||
QUnit.test("MersenneTwister test uniform distribution", function(assert) {
|
QUnit.test("MersenneTwister test uniform distribution", function(assert) {
|
||||||
const N = Math.pow(2, 17), expected = N * 1.35;
|
const N = Math.pow(2, 17), TRIES = 10, XSQ = 293.25; // quantile of chi-square dist. k=255, p=.05
|
||||||
let mt = new MersenneTwister();
|
let mt = new MersenneTwister();
|
||||||
mt.seed(new Date().getTime());
|
mt.seed(Math.random() * 0x100000000);
|
||||||
let data = new Uint32Array(N);
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let data = new Uint32Array(N), sh;
|
||||||
for (let i = 0; i < data.length; ++i) {
|
for (let i = 0; i < data.length; ++i) {
|
||||||
data[i] = mt.int32();
|
data[i] = mt.int32();
|
||||||
}
|
}
|
||||||
for (let sh = 0; sh <= 24; ++sh) {
|
for (sh = 0; sh <= 24; ++sh) {
|
||||||
let bins = new Uint32Array(256);
|
let bins = new Uint32Array(256);
|
||||||
for (let b of data) {
|
for (let b of data) {
|
||||||
++bins[(b >>> sh) & 0xFF];
|
++bins[(b >>> sh) & 0xFF];
|
||||||
}
|
}
|
||||||
let variance = bins.reduce(function(a, v){ return a + Math.pow(v - N / bins.length, 2); }, 0);
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
assert.ok(variance < expected, "Expecting variance to be under " + expected + ", got " + variance);
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 511)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq >= XSQ)
|
||||||
|
break;
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
}
|
}
|
||||||
|
if (sh == 25) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("MersenneTwister test float distribution", function(assert) {
|
QUnit.test("MersenneTwister test float distribution", function(assert) {
|
||||||
const N = Math.pow(2, 17), expected = N * 1.3;
|
const N = Math.pow(2, 17), TRIES = 3, XSQ = 564.7; // quantile of chi-square dist. k=511, p=.05
|
||||||
let mt = new MersenneTwister();
|
let tries = [], mt = new MersenneTwister();
|
||||||
mt.seed(new Date().getTime());
|
mt.seed(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
let bins = new Uint32Array(512);
|
let bins = new Uint32Array(512);
|
||||||
for (let i = 0; i < N; ++i) {
|
for (let i = 0; i < N; ++i) {
|
||||||
++bins[(mt.real2() * bins.length) >>> 0];
|
let tmp = (mt.real2() * bins.length) >>> 0;
|
||||||
|
if (tmp >= bins.length) throw "random.float() >= 1.0";
|
||||||
|
++bins[tmp];
|
||||||
}
|
}
|
||||||
let variance = bins.reduce(function(a, v){ return a + Math.pow(v - N / bins.length, 2); }, 0);
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
assert.ok(variance < expected, "Expecting variance to be under " + expected + ", got " + variance);
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 511)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,24 +1,11 @@
|
||||||
/*
|
|
||||||
QUnit.test("random.init() with no seed value", function(assert) {
|
|
||||||
random.init();
|
|
||||||
assert.ok(random.seed, "random seed is not null.");
|
|
||||||
});
|
|
||||||
|
|
||||||
QUnit.test("random.init() with provided seed", function(assert) {
|
|
||||||
let seed = new Date().getTime();
|
|
||||||
random.init(seed);
|
|
||||||
assert.equal(random.seed, seed, "seed is correct");
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
QUnit.test("random.init() is required", function(assert) {
|
QUnit.test("random.init() is required", function(assert) {
|
||||||
assert.throws(random.number, /undefined/, "twister is uninitialized");
|
assert.throws(random.number, /undefined/, "twister should be uninitialized before random.init()");
|
||||||
random.init(1);
|
random.init(1);
|
||||||
random.number();
|
random.number();
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("random.number() corner cases", function(assert) {
|
QUnit.test("random.number() corner cases", function(assert) {
|
||||||
random.init(new Date().getTime());
|
random.init(Math.random() * 0x100000000);
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
for (let i = 0; i < 100; ++i)
|
for (let i = 0; i < 100; ++i)
|
||||||
sum += random.number(0);
|
sum += random.number(0);
|
||||||
|
@ -32,40 +19,115 @@ QUnit.test("random.number() corner cases", function(assert) {
|
||||||
assert.equal(bins[0] + bins[1], 100);
|
assert.equal(bins[0] + bins[1], 100);
|
||||||
assert.ok(bins[0] > 20);
|
assert.ok(bins[0] > 20);
|
||||||
sum = 0;
|
sum = 0;
|
||||||
for (let i = 0; i < 12; ++i)
|
for (let i = 0; i < 15; ++i)
|
||||||
sum |= random.number();
|
sum |= random.number();
|
||||||
assert.equal(sum>>>0, 0xFFFFFFFF);
|
assert.equal(sum>>>0, 0xFFFFFFFF);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("random.float() uniform distribution", function(assert) {
|
QUnit.test("random.number() uniform distribution", function(assert) {
|
||||||
const N = Math.pow(2, 17), expected = N * 2;
|
const N = Math.pow(2, 17), TRIES = 3, XSQ = 564.7; // quantile of chi-square dist. k=511, p=.05
|
||||||
random.init(new Date().getTime());
|
let tries = [];
|
||||||
let bins = new Uint32Array(512), tmp;
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(512);
|
||||||
for (let i = 0; i < N; ++i) {
|
for (let i = 0; i < N; ++i) {
|
||||||
tmp = (random.float() * bins.length) >>> 0;
|
let tmp = random.number(bins.length);
|
||||||
|
if (tmp >= bins.length) throw "random.number() >= limit";
|
||||||
|
++bins[tmp];
|
||||||
|
}
|
||||||
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 511)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("random.float() uniform distribution", function(assert) {
|
||||||
|
const N = Math.pow(2, 17), TRIES = 3, XSQ = 564.7; // quantile of chi-square dist. k=511, p=.05
|
||||||
|
let tries = [];
|
||||||
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(512);
|
||||||
|
for (let i = 0; i < N; ++i) {
|
||||||
|
let tmp = (random.float() * bins.length) >>> 0;
|
||||||
if (tmp >= bins.length) throw "random.float() >= 1.0";
|
if (tmp >= bins.length) throw "random.float() >= 1.0";
|
||||||
++bins[tmp];
|
++bins[tmp];
|
||||||
}
|
}
|
||||||
let variance = bins.reduce(function(a, v){ return a + Math.pow(v - N / bins.length, 2); }, 0);
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
assert.ok(variance < expected, "Expecting variance to be under " + expected + ", got " + variance);
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 511)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("random.range() uniform distribution", function(assert) {
|
QUnit.test("random.range() uniform distribution", function(assert) {
|
||||||
const N = 10000, expected = N * 2;
|
const N = 1e4, TRIES = 3, XSQ = 66.34; // quantile of chi-square dist. k=49, p=.05
|
||||||
let bins = new Uint32Array(50), tmp;
|
let tries = [];
|
||||||
random.init(new Date().getTime());
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(50);
|
||||||
for (let i = 0; i < N; ++i) {
|
for (let i = 0; i < N; ++i) {
|
||||||
tmp = random.range(0, bins.length - 1);
|
let tmp = random.range(0, bins.length - 1);
|
||||||
if (tmp >= bins.length) throw "random.range() > upper bound";
|
if (tmp >= bins.length) throw "random.range() > upper bound";
|
||||||
++bins[tmp];
|
++bins[tmp];
|
||||||
}
|
}
|
||||||
let variance = bins.reduce(function(a, v){ return a + Math.pow(v - N / bins.length, 2); }, 0);
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
assert.ok(variance < expected, "Expecting variance to be under " + expected + ", got " + variance);
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 49)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("random.range() uniform distribution with offset", function(assert) {
|
||||||
|
const N = 1e4, TRIES = 3, XSQ = 66.34; // quantile of chi-square dist. k=49, p=.05
|
||||||
|
let tries = [];
|
||||||
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(50);
|
||||||
|
for (let i = 0; i < N; ++i) {
|
||||||
|
let tmp = random.range(10, 10 + bins.length - 1) - 10;
|
||||||
|
if (tmp < 0) throw "random.range() < lower bound";
|
||||||
|
if (tmp >= bins.length) throw "random.range() > upper bound";
|
||||||
|
++bins[tmp];
|
||||||
|
}
|
||||||
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 49)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("random.range() PRNG reproducibility", function(assert) {
|
QUnit.test("random.range() PRNG reproducibility", function(assert) {
|
||||||
let seed, result1, result2;
|
let seed, result1, result2;
|
||||||
seed = new Date().getTime();
|
seed = Math.random() * 0x100000000;
|
||||||
for (let t = 0; t < 50; ++t) {
|
for (let t = 0; t < 50; ++t) {
|
||||||
random.init(seed);
|
random.init(seed);
|
||||||
result1 = random.range(1, 20);
|
result1 = random.range(1, 20);
|
||||||
|
@ -78,44 +140,192 @@ QUnit.test("random.range() PRNG reproducibility", function(assert) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("random.choose() with equal distribution", function(assert) {
|
QUnit.test("random.ludOneTo() distribution", function(assert) {
|
||||||
const N = 10000, expected = N * 3;
|
const N = 1e5, TRIES = 3, XSQ = 123.22; // quantile of chi-square dist. k=99, p=.05
|
||||||
let bins = new Uint32Array(3), tmp;
|
let dist = new Uint32Array(100), tries = [];
|
||||||
random.init(new Date().getTime());
|
random.init(Math.random() * 0x100000000);
|
||||||
|
/* build the ideal distribution for comparison
|
||||||
|
* I thought this would be the PDF of the log-normal distribution, but I couldn't get mu & sigma figured out? */
|
||||||
|
for (let i = 0; i < (100 * dist.length); ++i) {
|
||||||
|
dist[Math.floor(Math.exp(i / (100*dist.length) * Math.log(dist.length)))] += N / (dist.length * 100);
|
||||||
|
}
|
||||||
|
assert.equal(dist[0], 0);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(dist.length), xsq = 0;
|
||||||
for (let i = 0; i < N; ++i) {
|
for (let i = 0; i < N; ++i) {
|
||||||
tmp = random.choose([[1, 0], [1, 1], [1, 2]]);
|
let tmp = random.ludOneTo(bins.length)>>>0;
|
||||||
if (tmp >= bins.length) throw "random.choose() > upper bound";
|
if (tmp >= bins.length) throw "random.ludOneTo() > upper bound"; // this could happen..
|
||||||
++bins[tmp];
|
++bins[tmp];
|
||||||
}
|
}
|
||||||
let variance = Math.pow(bins[0] - N / 3, 2) + Math.pow(bins[1] - N / 3, 2) + Math.pow(bins[2] - N / 3, 2);
|
assert.equal(bins[0], 0);
|
||||||
assert.ok(variance < expected, "Expecting variance to be under " + expected + ", got " + variance + " (" + bins + ")");
|
for (let i = 1; i < bins.length; ++i) {
|
||||||
|
xsq += Math.pow(bins[i] - dist[i], 2) / dist[i];
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 99)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("random.choose() with unequal distribution", function(assert) {
|
QUnit.test("random.item() exception cases", function(assert) {
|
||||||
const N = 10000, expected = N * 3;
|
assert.throws(random.item, /non array type/);
|
||||||
let bins = new Uint32Array(3), tmp;
|
assert.throws(function(){ return random.item(1); }, /non array type/);
|
||||||
random.init(new Date().getTime());
|
assert.throws(function(){ return random.item("1"); }, /non array type/);
|
||||||
|
assert.throws(function(){ return random.item({}); }, /non array type/);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("random.item() distribution with list", function(assert) {
|
||||||
|
const N = 1e4, TRIES = 3, XSQ = 5.99; // quantile of chi-square dist. k=2, p=.05
|
||||||
|
let tries = [];
|
||||||
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(3);
|
||||||
for (let i = 0; i < N; ++i) {
|
for (let i = 0; i < N; ++i) {
|
||||||
tmp = random.choose([[1, 0], [2, 1], [1, 2]]);
|
let tmp = random.item([99, 100, 101]) - 99;
|
||||||
if (tmp >= bins.length) throw "random.choose() > upper bound";
|
if (tmp < 0) throw "random.item() < lower bound";
|
||||||
|
if (tmp >= bins.length) throw "random.item() > upper bound";
|
||||||
++bins[tmp];
|
++bins[tmp];
|
||||||
}
|
}
|
||||||
let variance = Math.pow(bins[0] - N / 4, 2) + Math.pow(bins[1] - N / 2, 2) + Math.pow(bins[2] - N / 4, 2);
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
assert.ok(variance < expected, "Expecting variance to be under " + expected + ", got " + variance + " (" + bins + ")");
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 2)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("random.key() distribution", function(assert) {
|
||||||
|
const N = 1e4, TRIES = 3, XSQ = 5.99; // quantile of chi-square dist. k=2, p=.05
|
||||||
|
let tries = [];
|
||||||
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(3);
|
||||||
|
for (let i = 0; i < N; ++i) {
|
||||||
|
let tmp = random.key({99: 0, 100: 0, 101: 0}) - 99;
|
||||||
|
if (tmp < 0) throw "random.key() < lower bound";
|
||||||
|
if (tmp >= bins.length) throw "random.key() > upper bound";
|
||||||
|
++bins[tmp];
|
||||||
|
}
|
||||||
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 2)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("random.bool() distribution", function(assert) {
|
||||||
|
const N = 1e4, TRIES = 3, XSQ = 3.84; // quantile of chi-square dist. k=1, p=.05
|
||||||
|
let tries = [];
|
||||||
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(2);
|
||||||
|
for (let i = 0; i < N; ++i) {
|
||||||
|
let tmp = random.bool();
|
||||||
|
if (tmp === true)
|
||||||
|
tmp = 1;
|
||||||
|
else if (tmp === false)
|
||||||
|
tmp = 0;
|
||||||
|
else
|
||||||
|
assert.ok(false, "unexpected random.bool() result: " + tmp);
|
||||||
|
++bins[tmp];
|
||||||
|
}
|
||||||
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 1)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ludOneTo(limit)
|
XXX
|
||||||
item(list)
|
|
||||||
key(obj)
|
|
||||||
bool()
|
|
||||||
pick(obj)
|
pick(obj)
|
||||||
chance(limit)
|
chance(limit)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QUnit.test("random.choose() with equal distribution", function(assert) {
|
||||||
|
const N = 1e4, TRIES = 3, XSQ = 5.99; // quantile of chi-square dist. k=2, p=.05
|
||||||
|
let tries = [];
|
||||||
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(3);
|
||||||
|
for (let i = 0; i < N; ++i) {
|
||||||
|
let tmp = random.choose([[1, 0], [1, 1], [1, 2]]);
|
||||||
|
if (tmp >= bins.length) throw "random.choose() > upper bound";
|
||||||
|
++bins[tmp];
|
||||||
|
}
|
||||||
|
let xsq = bins.reduce(function(a, v){ let e = N / bins.length; return a + Math.pow(v - e, 2) / e; }, 0);
|
||||||
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 2)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("random.choose() with unequal distribution", function(assert) {
|
||||||
|
const N = 1e4, TRIES = 3, XSQ = 5.99; // quantile of chi-square dist. k=2, p=.05
|
||||||
|
let tries = [];
|
||||||
|
random.init(Math.random() * 0x100000000);
|
||||||
|
for (let attempt = 0; attempt < TRIES; ++attempt) {
|
||||||
|
let bins = new Uint32Array(3);
|
||||||
|
for (let i = 0; i < N; ++i) {
|
||||||
|
let tmp = random.choose([[1, 0], [2, 1], [1, 2]]);
|
||||||
|
if (tmp >= bins.length) throw "random.choose() > upper bound";
|
||||||
|
++bins[tmp];
|
||||||
|
}
|
||||||
|
let xsq = Math.pow(bins[0] - N / 4, 2) / (N / 4) + Math.pow(bins[1] - N / 2, 2) / (N / 2) + Math.pow(bins[2] - N / 4, 2) / (N / 4);
|
||||||
|
/*
|
||||||
|
* XSQ = scipy.stats.chi2.isf(.05, 2)
|
||||||
|
* if xsq > XSQ, the result is biased at 95% significance
|
||||||
|
*/
|
||||||
|
if (xsq < XSQ) {
|
||||||
|
assert.ok(true, "Expected x^2 to be < " + XSQ + ", got " + xsq + " on attempt #" + (attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tries.push(xsq);
|
||||||
|
}
|
||||||
|
assert.ok(false, "Failed in " + TRIES + " attempts to get xsq lower than " + XSQ + ": "+ tries);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
XXX
|
||||||
|
choose(list, flat=true)
|
||||||
weighted(wa)
|
weighted(wa)
|
||||||
use(obj)
|
use(obj)
|
||||||
shuffle(arr)
|
shuffle(arr)
|
||||||
shuffled(arr)
|
shuffled(arr)
|
||||||
subset(list, limit)
|
subset(list, limit)
|
||||||
choose(list, flat=true)
|
|
||||||
pop(arr)
|
pop(arr)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue