Skip to content

Commit

Permalink
WIP: Fix logarithmic domain complexity issues
Browse files Browse the repository at this point in the history
refs: #244, #348
  • Loading branch information
frostburn committed Jun 15, 2024
1 parent d2f7fb2 commit 4748fc2
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 9 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
},
"dependencies": {
"moment-of-symmetry": "^0.8.1",
"xen-dev-utils": "^0.9.0"
"xen-dev-utils": "github:xenharmonic-devs/xen-dev-utils#fix-decimal-fracs"
},
"engines": {
"node": ">=12.0.0"
Expand Down
9 changes: 8 additions & 1 deletion src/monzo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1827,7 +1827,14 @@ export class TimeMonzo {
}
const vector = [];
for (let i = 0; i < other.primeExponents.length; ++i) {
vector.push(this.primeExponents[i].add(other.primeExponents[i]));
try {
vector.push(this.primeExponents[i].add(other.primeExponents[i]));
} catch {
return new TimeReal(
this.timeExponent.valueOf() + other.timeExponent.valueOf(),
this.valueOf() * other.valueOf()
);
}
}
try {
const residual = this.residual.mul(other.residual);
Expand Down
12 changes: 12 additions & 0 deletions src/parser/__tests__/expression.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2409,6 +2409,18 @@ describe('SonicWeave expression evaluator', () => {
const {interval} = parseSingle(String.raw`\\\P1 tmpr 12@`);
expect(interval.totalCents()).toBe(-1500);
});

it('coerces too accurate cents too real', () => {
const interval = evaluate('1234.56789012345678901') as Interval;
expect(interval.value).toBeInstanceOf(TimeReal);
expect(interval.valueOf()).toBeCloseTo(2.04);
});

it('coerces too accurate monzos to real', () => {
const ronzo = evaluate('[1.234567890123456780901>') as Interval;
expect(ronzo.value).toBeInstanceOf(TimeReal);
expect(ronzo.valueOf()).toBeCloseTo(2.3531);
});
});

describe('Poor grammar / Fun with "<"', () => {
Expand Down
30 changes: 30 additions & 0 deletions src/parser/__tests__/source.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1991,4 +1991,34 @@ describe('SonicWeave parser', () => {
'Index out of range.'
);
});

it('can handle too complex multiplication resulting from too accurate prime mappings', () => {
const scale = expand(`
14/13
8/7
44/35
4/3
99/70
99/65
396/245
2178/1225
66/35
9801/4900
(* Commas = 1716/1715, 2080/2079 *)
PrimeMapping(1200., 1902.0236738027506, 2786.2942222449124, 3369.11433503606, 4151.361209675464, 4440.252343874884)
cents(£, 3)
`);
expect(scale).toEqual([
'128.862',
'230.886',
'395.953',
'497.976',
'600.',
'728.862',
'830.886',
'995.953',
'1097.976',
'1200.',
]);
});
});
38 changes: 34 additions & 4 deletions src/parser/expression.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Fraction, gcd} from 'xen-dev-utils';
import {Fraction, PRIMES, gcd} from 'xen-dev-utils';
import {
NedjiLiteral,
IntegerLiteral,
Expand Down Expand Up @@ -662,7 +662,18 @@ export class ExpressionVisitor {

protected visitComponent(component: VectorComponent) {
// XXX: This is so backwards...
return new Fraction(formatComponent(component));
const str = formatComponent(component);
try {
return new Fraction(str);
} catch {
if (component.separator === '/') {
return (
(component.left / parseInt(component.right)) *
10 ** (component.exponent ?? 0)
);
}
return parseFloat(str);
}
}

protected upLift(
Expand Down Expand Up @@ -703,7 +714,21 @@ export class ExpressionVisitor {
}
}
} else {
value = new TimeMonzo(ZERO, exponents);
let valid = true;
for (const exponent of exponents) {
if (typeof exponent === 'number') {
valid = false;
}
}
if (valid) {
value = new TimeMonzo(ZERO, exponents as Fraction[]);
} else {
let num = 1;
for (let i = 0; i < exponents.length; ++i) {
num *= PRIMES[i] ** exponents[i].valueOf();
}
value = new TimeReal(0, num);
}
}
const result = this.upLift(value, node);
if (steps.d !== 1) {
Expand All @@ -719,6 +744,11 @@ export class ExpressionVisitor {

protected visitValLiteral(node: ValLiteral) {
const val = node.components.map(this.visitComponent);
for (const component of val) {
if (typeof component === 'number') {
throw new Error('Invalid val literal.');
}
}
let value: TimeMonzo;
let equave = TWO_MONZO;
if (node.basis.length) {
Expand All @@ -729,7 +759,7 @@ export class ExpressionVisitor {
value = valToTimeMonzo(val, subgroup);
equave = subgroup[0];
} else {
value = new TimeMonzo(ZERO, val);
value = new TimeMonzo(ZERO, val as Fraction[]);
}
return new Val(value, equave, node);
}
Expand Down

0 comments on commit 4748fc2

Please sign in to comment.