mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-11 21:58:37 +00:00
add probabilistic tests for the ? and | mini-notation operators
The tests are probabilistic, so it is possible that if the pseudo-random number generator changes in the future, we might get results that fail. They work for the current PRNG, though, and use boundaries for the number of values of different types such that there should only be about a 1% probability that the tests would fail by chance assuming that the PRNG returns evenly distributed values.
This commit is contained in:
parent
1227d98904
commit
0a558b963d
@ -6,7 +6,6 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
|
||||
import { strict as assert } from 'assert';
|
||||
import { mini } from '../mini.mjs';
|
||||
import '@strudel.cycles/core/euclid.mjs';
|
||||
|
||||
describe('mini', () => {
|
||||
const minV = (v) => mini(v)._firstCycleValues;
|
||||
@ -55,4 +54,39 @@ describe('mini', () => {
|
||||
mini('a?').queryArc(0, 20).map(hap => hap.whole.begin),
|
||||
mini('a').degradeBy(0.5).queryArc(0, 20).map(hap => hap.whole.begin));
|
||||
});
|
||||
// testing things that involve pseudo-randomness, so there's a probability we could fail by chance.
|
||||
// these next few tests work with the current PRNG, and are intended to succeed with p > 0.99 even if the PRNG changes
|
||||
// (as long as the PRNG has a relatively-uniform distribution of values)
|
||||
it('supports degradeBy with default of 50%', () => {
|
||||
const haps = mini('a?').queryArc(0, 1000);
|
||||
assert(459 <= haps.length && haps.length <= 541, 'Number of elements did not fall in 99% confidence interval for binomial with p=0.5');
|
||||
});
|
||||
it('supports degradeBy with an argument', () => {
|
||||
const haps = mini('a?0.8').queryArc(0, 1000);
|
||||
assert(haps.length > 0, 'Should have had at least one element when degradeBy was set at 0.8');
|
||||
assert(haps.length < 230, 'Had too many cycles remaining after degradeBy 0.8');
|
||||
});
|
||||
it('supports the random choice operator ("|") with nesting', () => {
|
||||
const numCycles = 900;
|
||||
const haps = mini('a | [b | c] | [d | e | f]').queryArc(0, numCycles);
|
||||
// Should have about 1/3 a, 1/6 each of b | c, and 1/9 each of d | e | f.
|
||||
// Evaluating this distribution with a chi-squared test.
|
||||
// Note: this just evaluates the overall distribution, not things like correlation/runs of values
|
||||
const observed = haps.reduce((acc, hap) => {
|
||||
acc[hap.value] = (acc[hap.value] || 0) + 1;
|
||||
return acc;
|
||||
}, {});
|
||||
const expected = {
|
||||
a: numCycles / 3, b: numCycles / 6, c: numCycles / 6,
|
||||
d: numCycles / 9, e: numCycles / 9, f: numCycles / 9
|
||||
};
|
||||
let chisq = -numCycles;
|
||||
for (let k in expected) {
|
||||
chisq += observed[k] * observed[k] / expected[k];
|
||||
}
|
||||
// 15.086 is the chisq for 5 degrees of freedom at 99%, so for 99% of uniformly-distributed
|
||||
// PRNG, this test should succeed
|
||||
assert(chisq <= 15.086,
|
||||
chisq + ' was expected to be less than 15.086 under chi-squared test');
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user