commented out tests are now explained
This commit is contained in:
parent
4f5a1ff946
commit
3ff810ee1b
49
packages/squiggle-lang/__tests__/TS/PointSet_test.ts
Normal file
49
packages/squiggle-lang/__tests__/TS/PointSet_test.ts
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { errorValueToString } from "../../src/js/index";
|
||||
import { testRun, failDefault, expectErrorToBeBounded } from "./TestHelpers";
|
||||
import * as fc from "fast-check";
|
||||
|
||||
describe("Mean of mixture is weighted average of means", () => {
|
||||
test("mx(beta(a,b), lognormal(m,s), [x,y])", () => {
|
||||
fc.assert(
|
||||
fc.property(
|
||||
fc.float({ min: 1e-1 }), // alpha
|
||||
fc.float({ min: 1 }), // beta
|
||||
fc.float(), // mu
|
||||
fc.float({ min: 1e-1 }), // sigma
|
||||
fc.float({ min: 1e-7 }),
|
||||
fc.float({ min: 1e-7 }),
|
||||
(a, b, m, s, x, y) => {
|
||||
let squiggleString = `mean(mx(beta(${a},${b}), lognormal(${m},${s}), [${x}, ${y}]))`;
|
||||
let res = testRun(squiggleString);
|
||||
switch (res.tag) {
|
||||
case "Error":
|
||||
expect(errorValueToString(res.value)).toEqual(
|
||||
"<I wonder if test cases will find this>"
|
||||
);
|
||||
break;
|
||||
case "Ok":
|
||||
let weightDenom = x + y;
|
||||
let betaWeight = x / weightDenom;
|
||||
let lognormalWeight = y / weightDenom;
|
||||
let betaMean = 1 / (1 + b / a);
|
||||
let lognormalMean = m + s ** 2 / 2;
|
||||
if (res.value.tag == "number") {
|
||||
expectErrorToBeBounded(
|
||||
res.value.value,
|
||||
betaWeight * betaMean + lognormalWeight * lognormalMean,
|
||||
1,
|
||||
-1
|
||||
);
|
||||
} else {
|
||||
expect(res.value.value).toEqual("some error message");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
failDefault();
|
||||
break;
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
import { Distribution } from "../../src/js/index";
|
||||
import { expectErrorToBeBounded, failDefault } from "./TestHelpers";
|
||||
import * as fc from "fast-check";
|
||||
|
||||
// Beware: float64Array makes it appear in an infinite loop.
|
||||
|
@ -126,80 +127,49 @@ describe("SampleSet: cdf", () => {
|
|||
// });
|
||||
// });
|
||||
|
||||
// This should be true, but I can't get it to work.
|
||||
// describe("SampleSet: mean is mean", () => {
|
||||
// test("mean(samples(xs)) sampling twice as widely as the input", () => {
|
||||
// fc.assert(
|
||||
// fc.property(
|
||||
// fc.float64Array({ minLength: 10, maxLength: 100000 }),
|
||||
// (xs) => {
|
||||
// let ys = Array.from(xs);
|
||||
// let n = ys.length;
|
||||
// let dist = new Distribution(
|
||||
// { tag: "SampleSet", value: ys },
|
||||
// { sampleCount: 2 * n, xyPointLength: 4 * n }
|
||||
// );
|
||||
//
|
||||
// expect(dist.mean().value).toBeCloseTo(
|
||||
// ys.reduce((a, b) => a + b, 0.0) / n
|
||||
// );
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
// });
|
||||
//
|
||||
// test("mean(samples(xs)) sampling half as widely as the input", () => {
|
||||
// fc.assert(
|
||||
// fc.property(
|
||||
// fc.float64Array({ minLength: 10, maxLength: 100000 }),
|
||||
// (xs) => {
|
||||
// let ys = Array.from(xs);
|
||||
// let n = ys.length;
|
||||
// let dist = new Distribution(
|
||||
// { tag: "SampleSet", value: ys },
|
||||
// { sampleCount: Math.floor(5 / 2), xyPointLength: 4 * n }
|
||||
// );
|
||||
//
|
||||
// expect(dist.mean().value).toBeCloseTo(
|
||||
// ys.reduce((a, b) => a + b, 0.0) / n
|
||||
// );
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
// });
|
||||
// test("mean(samples(xs)) sampling twice as widely as the input", () => {
|
||||
// fc.assert(
|
||||
// fc.property(
|
||||
// fc.float64Array({ minLength: 10, maxLength: 100000 }),
|
||||
// (xs) => {
|
||||
// let ys = Array.from(xs);
|
||||
// let n = ys.length;
|
||||
// let dist = new Distribution(
|
||||
// { tag: "SampleSet", value: ys },
|
||||
// { sampleCount: 2 * n, xyPointLength: 4 * n }
|
||||
// );
|
||||
// let mean = dist.mean()
|
||||
// if (typeof mean.value == "number") {
|
||||
// expectErrorToBeBounded(mean.value, ys.reduce((a, b) => a + b, 0.0) / n, 5e-1, 1)
|
||||
// } else {
|
||||
// failDefault()
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
// });
|
||||
//
|
||||
// test("mean(samples(xs)) sampling half as widely as the input", () => {
|
||||
// fc.assert(
|
||||
// fc.property(
|
||||
// fc.float64Array({ minLength: 10, maxLength: 100000 }),
|
||||
// (xs) => {
|
||||
// let ys = Array.from(xs);
|
||||
// let n = ys.length;
|
||||
// let dist = new Distribution(
|
||||
// { tag: "SampleSet", value: ys },
|
||||
// { sampleCount: Math.floor(n / 2), xyPointLength: 4 * n }
|
||||
// );
|
||||
// let mean = dist.mean()
|
||||
// if (typeof mean.value == "number") {
|
||||
// expectErrorToBeBounded(mean.value, ys.reduce((a, b) => a + b, 0.0) / n, 5e-1, 1)
|
||||
// } else {
|
||||
// failDefault()
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
// });
|
||||
|
||||
// describe("Mean of mixture is weighted average of means", () => {
|
||||
// test("mx(beta(a,b), lognormal(m,s), [x,y])", () => {
|
||||
// fc.assert(
|
||||
// fc.property(
|
||||
// fc.float({ min: 1e-1 }), // alpha
|
||||
// fc.float({ min: 1 }), // beta
|
||||
// fc.float(), // mu
|
||||
// fc.float({ min: 1e-1 }), // sigma
|
||||
// fc.float({ min: 1e-7 }),
|
||||
// fc.float({ min: 1e-7 }),
|
||||
// (a, b, m, s, x, y) => {
|
||||
// let squiggleString = `mean(mx(beta(${a},${b}), lognormal(${m},${s}), [${x}, ${y}]))`;
|
||||
// let res = testRun(squiggleString);
|
||||
// switch (res.tag) {
|
||||
// case "Error":
|
||||
// expect(errorValueToString(res.value)).toEqual(
|
||||
// "<I wonder if test cases will find this>"
|
||||
// );
|
||||
// case "Ok":
|
||||
// let betaWeight = x / (x + y);
|
||||
// let lognormalWeight = y / (x + y);
|
||||
// let betaMean = 1 / (1 + b / a);
|
||||
// let lognormalMean = m + s ** 2 / 2;
|
||||
// expect(res.value).toEqual({
|
||||
// tag: "number",
|
||||
// value: betaWeight * betaMean + lognormalWeight * lognormalMean,
|
||||
// });
|
||||
// default:
|
||||
// expect("mean returned").toBe(`something other than a number`);
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
import {
|
||||
run,
|
||||
squiggleExpression,
|
||||
errorValueToString,
|
||||
errorValue,
|
||||
result,
|
||||
} from "../../src/js/index";
|
||||
import { errorValueToString } from "../../src/js/index";
|
||||
import { testRun } from "./TestHelpers";
|
||||
import * as fc from "fast-check";
|
||||
|
||||
|
|
|
@ -13,5 +13,24 @@ export function testRun(x: string): any {
|
|||
}
|
||||
|
||||
export function failDefault() {
|
||||
expect("be reached").toBe("codepath should never be");
|
||||
expect("be reached").toBe("codepath should never");
|
||||
}
|
||||
|
||||
/**
|
||||
* This appears also in `TestHelpers.res`. According to https://www.math.net/percent-error, it computes
|
||||
* absolute error when numerical stability concerns make me not want to compute relative error.
|
||||
* */
|
||||
export function expectErrorToBeBounded(
|
||||
received: number,
|
||||
expected: number,
|
||||
epsilon: number,
|
||||
digits: number
|
||||
) {
|
||||
let distance = Math.abs(received - expected);
|
||||
let expectedAbs = Math.abs(expected);
|
||||
let normalizingDenom = Math.max(expectedAbs, 1);
|
||||
let error = distance / normalizingDenom;
|
||||
expect(Math.round(10 ** digits * error) / 10 ** digits).toBeLessThanOrEqual(
|
||||
epsilon
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user