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 { Distribution } from "../../src/js/index";
|
||||||
|
import { expectErrorToBeBounded, failDefault } from "./TestHelpers";
|
||||||
import * as fc from "fast-check";
|
import * as fc from "fast-check";
|
||||||
|
|
||||||
// Beware: float64Array makes it appear in an infinite loop.
|
// Beware: float64Array makes it appear in an infinite loop.
|
||||||
|
@ -126,6 +127,7 @@ describe("SampleSet: cdf", () => {
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
// This should be true, but I can't get it to work.
|
||||||
// describe("SampleSet: mean is mean", () => {
|
// describe("SampleSet: mean is mean", () => {
|
||||||
// test("mean(samples(xs)) sampling twice as widely as the input", () => {
|
// test("mean(samples(xs)) sampling twice as widely as the input", () => {
|
||||||
// fc.assert(
|
// fc.assert(
|
||||||
|
@ -138,10 +140,12 @@ describe("SampleSet: cdf", () => {
|
||||||
// { tag: "SampleSet", value: ys },
|
// { tag: "SampleSet", value: ys },
|
||||||
// { sampleCount: 2 * n, xyPointLength: 4 * n }
|
// { sampleCount: 2 * n, xyPointLength: 4 * n }
|
||||||
// );
|
// );
|
||||||
//
|
// let mean = dist.mean()
|
||||||
// expect(dist.mean().value).toBeCloseTo(
|
// if (typeof mean.value == "number") {
|
||||||
// ys.reduce((a, b) => a + b, 0.0) / n
|
// expectErrorToBeBounded(mean.value, ys.reduce((a, b) => a + b, 0.0) / n, 5e-1, 1)
|
||||||
// );
|
// } else {
|
||||||
|
// failDefault()
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
// )
|
// )
|
||||||
// );
|
// );
|
||||||
|
@ -156,47 +160,13 @@ describe("SampleSet: cdf", () => {
|
||||||
// let n = ys.length;
|
// let n = ys.length;
|
||||||
// let dist = new Distribution(
|
// let dist = new Distribution(
|
||||||
// { tag: "SampleSet", value: ys },
|
// { tag: "SampleSet", value: ys },
|
||||||
// { sampleCount: Math.floor(5 / 2), xyPointLength: 4 * n }
|
// { sampleCount: Math.floor(n / 2), xyPointLength: 4 * n }
|
||||||
// );
|
// );
|
||||||
//
|
// let mean = dist.mean()
|
||||||
// expect(dist.mean().value).toBeCloseTo(
|
// if (typeof mean.value == "number") {
|
||||||
// ys.reduce((a, b) => a + b, 0.0) / n
|
// 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 {
|
import { errorValueToString } from "../../src/js/index";
|
||||||
run,
|
|
||||||
squiggleExpression,
|
|
||||||
errorValueToString,
|
|
||||||
errorValue,
|
|
||||||
result,
|
|
||||||
} from "../../src/js/index";
|
|
||||||
import { testRun } from "./TestHelpers";
|
import { testRun } from "./TestHelpers";
|
||||||
import * as fc from "fast-check";
|
import * as fc from "fast-check";
|
||||||
|
|
||||||
|
|
|
@ -13,5 +13,24 @@ export function testRun(x: string): any {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function failDefault() {
|
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