xen-dev-utils
Version:
Utility functions used by the Scale Workshop ecosystem
108 lines • 6.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const approximation_1 = require("../approximation");
const conversion_1 = require("../conversion");
const primes_1 = require("../primes");
(0, vitest_1.describe)('Odd limit approximator', () => {
(0, vitest_1.it)('can approximate tau in the 15-odd-limit', () => {
const approximation = (0, approximation_1.approximateOddLimit)((0, conversion_1.valueToCents)(2 * Math.PI), 15)[0];
(0, vitest_1.expect)(approximation.equals('44/7')).toBeTruthy();
(0, vitest_1.expect)(approximation.valueOf()).toBeCloseTo(2 * Math.PI);
});
(0, vitest_1.it)('can approximate e in the 21-odd-limit', () => {
const approximations = (0, approximation_1.approximateOddLimit)((0, conversion_1.valueToCents)(Math.E), 21);
(0, vitest_1.expect)(approximations[0].equals('19/7')).toBeTruthy();
(0, vitest_1.expect)(approximations[0].valueOf()).toBeCloseTo(Math.E);
(0, vitest_1.expect)(approximations[7].equals('21/8')).toBeTruthy();
(0, vitest_1.expect)(approximations[7].valueOf()).toBeCloseTo(Math.E, 0);
});
});
(0, vitest_1.describe)('Prime limit approximator', () => {
(0, vitest_1.it)('can approximate pi in the 11-limit', () => {
const approximation = (0, approximation_1.approximatePrimeLimit)((0, conversion_1.valueToCents)(Math.PI), primes_1.PRIMES.indexOf(11), 3)[0];
(0, vitest_1.expect)(approximation.equals('12544/3993')).toBeTruthy();
(0, vitest_1.expect)(approximation.valueOf()).toBeCloseTo(Math.PI);
});
(0, vitest_1.it)('can approximate pi in the 13-limit with a small sized result', () => {
const approximations = (0, approximation_1.approximatePrimeLimit)((0, conversion_1.valueToCents)(Math.PI), primes_1.PRIMES.indexOf(13), 3, 15, 4);
(0, vitest_1.expect)(approximations).toHaveLength(4);
});
(0, vitest_1.it)('can approximate the square root of two in the 7-limit within maximum error', () => {
const approximationsAndErrors = (0, approximation_1.approximatePrimeLimitWithErrors)(600, primes_1.PRIMES.indexOf(7), 5, 10);
(0, vitest_1.expect)(approximationsAndErrors).toHaveLength(28);
approximationsAndErrors.forEach(([approximation, error]) => {
const cents = (0, conversion_1.valueToCents)(approximation.valueOf());
const calculatedError = Math.abs(cents - 600);
(0, vitest_1.expect)(error).toBeCloseTo(calculatedError);
(0, vitest_1.expect)(calculatedError).toBeLessThanOrEqual(10);
});
});
(0, vitest_1.it)('has somewhat sane default behavior', () => {
(0, vitest_1.expect)(() => (0, approximation_1.approximatePrimeLimit)((0, conversion_1.valueToCents)(Math.PI), 8, 2)).not.toThrow();
});
});
(0, vitest_1.describe)('Convergent calculator', () => {
(0, vitest_1.it)('calculates the convergents of pi', () => {
const convergents = (0, approximation_1.getConvergents)(Math.PI, undefined, 10);
(0, vitest_1.expect)(convergents).toHaveLength(10);
(0, vitest_1.expect)(convergents[0].equals(3)).toBeTruthy();
(0, vitest_1.expect)(convergents[1].equals('22/7')).toBeTruthy();
(0, vitest_1.expect)(convergents[2].equals('333/106')).toBeTruthy();
(0, vitest_1.expect)(convergents[3].equals('355/113')).toBeTruthy();
(0, vitest_1.expect)(convergents[4].equals('103993/33102')).toBeTruthy();
(0, vitest_1.expect)(convergents[5].equals('104348/33215')).toBeTruthy();
(0, vitest_1.expect)(convergents[6].equals('208341/66317')).toBeTruthy();
(0, vitest_1.expect)(convergents[7].equals('312689/99532')).toBeTruthy();
(0, vitest_1.expect)(convergents[8].equals('833719/265381')).toBeTruthy();
(0, vitest_1.expect)(convergents[9].equals('1146408/364913')).toBeTruthy();
});
(0, vitest_1.it)('calculates the semiconvergents of pi', () => {
const semiconvergents = (0, approximation_1.getConvergents)(Math.PI, undefined, 13, true);
(0, vitest_1.expect)(semiconvergents).toHaveLength(13);
(0, vitest_1.expect)(semiconvergents[0].equals(3)).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[1].equals('13/4')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[2].equals('16/5')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[3].equals('19/6')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[4].equals('22/7')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[5].equals('179/57')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[6].equals('201/64')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[7].equals('223/71')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[8].equals('245/78')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[9].equals('267/85')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[10].equals('289/92')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[11].equals('311/99')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[12].equals('333/106')).toBeTruthy();
let error = Infinity;
semiconvergents.forEach(semiconvergent => {
const newError = Math.abs(Math.PI - semiconvergent.valueOf());
(0, vitest_1.expect)(newError).toBeLessThan(error);
error = newError;
});
});
(0, vitest_1.it)('calculates the non-monotonic semiconvergents of pi', () => {
const semiconvergents = (0, approximation_1.getConvergents)(Math.PI, undefined, 5, true, true);
(0, vitest_1.expect)(semiconvergents).toHaveLength(5);
(0, vitest_1.expect)(semiconvergents[0].equals(3)).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[1].equals(4)).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[2].equals('7/2')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[3].equals('10/3')).toBeTruthy();
(0, vitest_1.expect)(semiconvergents[4].equals('13/4')).toBeTruthy();
});
(0, vitest_1.it)('calculates convergents for 1\\5', () => {
(0, vitest_1.expect)(() => (0, approximation_1.getConvergents)(1.148698354997035, undefined, 256, true, false)).not.toThrow();
});
});
(0, vitest_1.describe)('Radical approximator', () => {
(0, vitest_1.it)("finds Ramanujan's approximation to pi", () => {
const { index, radicand } = (0, approximation_1.approximateRadical)(Math.PI);
(0, vitest_1.expect)(index).toBe(4);
(0, vitest_1.expect)(radicand.toFraction()).toBe('2143/22');
});
(0, vitest_1.it)('works with a random value without crashing', () => {
const value = Math.random() * 1000 - 100;
const { index, radicand } = (0, approximation_1.approximateRadical)(value);
(0, vitest_1.expect)(radicand.valueOf() ** (1 / index) / value).toBeCloseTo(1);
});
});
//# sourceMappingURL=approximation.spec.js.map