Skip to content

Commit 13666dd

Browse files
committed
fixed #254: Improve LaTeX parsing for interval notation and enhance Mandelbrot/Julia compilation
1 parent 02e22e9 commit 13666dd

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

CHANGELOG.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
### [Unreleased]
2+
3+
#### Fixed
4+
5+
- **LaTeX parsing: interval notation with `\lbrack`/`\lparen`** — parsing
6+
`\lbrack5,7)` or `\left\lbrack5,7\right)` now correctly produces an
7+
`Interval` expression. Previously, when the open delimiter was a LaTeX
8+
command (e.g., `\lbrack`), the parser incorrectly required the close
9+
delimiter to also be a LaTeX command (e.g., `\rparen` instead of `)`),
10+
causing mismatched-delimiter intervals to fail.
11+
12+
#### Added
13+
14+
- **High-precision Mandelbrot/Julia compilation** — the GPU compilation targets
15+
(GLSL, WGSL) now support three precision tiers for fractal rendering, selected
16+
automatically based on viewport hints:
17+
- **Single float** (zoom < 10^6x): existing implementation, no overhead
18+
- **Emulated double** (zoom 10^6x–10^14x): double-single (float-float)
19+
arithmetic using Dekker/Knuth algorithms, ~48-bit mantissa from two 32-bit
20+
floats
21+
- **Perturbation theory** (zoom > 10^14x): reference orbit computed on CPU at
22+
arbitrary precision via `BigDecimal`, GPU iterates only the small delta from
23+
the reference, with glitch detection and single-float rebase fallback
24+
- **Viewport-aware compile API**`compile()` accepts optional
25+
`hints: { viewport: { center, radius } }`. The compiler auto-selects the
26+
precision strategy and returns `staleWhen` thresholds for cheap staleness
27+
checking by the plot engine.
28+
- **`CompilationResult` extensions** — new optional fields: `staleWhen` (plain
29+
data staleness predicate), `uniforms` (scalar shader uniforms), `textures`
30+
(typed texture data with format/dimensions for GPU upload).
31+
132
### 0.55.3 _2026-03-05_
233

334
#### Improved
@@ -23,8 +54,8 @@
2354
integer-typed
2455
- `Abs` is a no-op when the operand is provably non-negative
2556
- `Power(x, 2)` only expands to `(x * x)` for simple operands (symbols,
26-
literals) — function calls like `Power(Sin(x), 2)` use `pow`/`Math.pow`
27-
to avoid duplicate evaluation
57+
literals) — function calls like `Power(Sin(x), 2)` use `pow`/`Math.pow` to
58+
avoid duplicate evaluation
2859
- Integer `Mod` with non-negative dividend uses plain `%` instead of the
2960
Euclidean double-mod formula
3061
- GPU variable declarations infer `i32`/`int` type for integer-typed locals

src/compute-engine/latex-syntax/parse.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -914,23 +914,20 @@ export class _Parser implements Parser {
914914
this.index = start;
915915
return false;
916916
}
917-
// Check if we matched a LaTeX command variant (e.g., \lbrack for [)
918-
const matchedToken = this.nextToken();
919-
const useLatexCommand = matchedToken.startsWith('\\');
917+
this.nextToken();
920918

921919
// Consume closing brace if we had a braced delimiter \mathopen{(}
922920
if (hasBracedDelimiter && !this.match('<}>')) {
923921
this.index = start;
924922
return false;
925923
}
926924

927-
// Find the corresponding close token variant
928-
const closeTokens = DELIMITER_SHORTHAND[close[0] as string] ?? [
929-
close[0],
930-
];
931-
const closeToken = (closeTokens.find((t) =>
932-
useLatexCommand ? t.startsWith('\\') : !t.startsWith('\\')
933-
) ?? closeTokens[0]) as LatexToken;
925+
// Use the close token exactly as specified in the trigger.
926+
// The matchfix entries already enumerate all delimiter combinations
927+
// (e.g., [/), \lbrack/), [/\rparen, \lbrack/\rparen for intervals),
928+
// so we should not transform the close token based on what format
929+
// the open token was in.
930+
const closeToken = close[0] as LatexToken;
934931

935932
// Build the close boundary: for braced form, expect \mathclose{)}
936933
const closeBoundary = closePrefix

test/playground.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,15 @@ import {
1818
const ce = new ComputeEngine();
1919
const engine = ce;
2020

21-
const mandelbrot = parse('1+\\operatorname{Mandelbrot}(x+yi,200)');
22-
// console.log(compile(mandelbrot, { to: 'glsl' }).run?.({ x: 0.355, y: 0.355 }));
23-
console.log(compile(mandelbrot, { to: 'glsl' }).code);
21+
console.log(parse('x + 2 = \\square').json);
22+
console.log(parse('x + 2 = \\placeholder').json);
23+
24+
parse('[5,7)');
25+
// -> ok, `["Interval", 5, ["Open", 7]]`
26+
parse('\\lbrack5,7)');
27+
// -> error
28+
parse('\\left\\lbrack5,7\\right)');
29+
// -> error
2430

2531
// 1. sin(theta)**2 + cos(theta)**2 → 1 — Clean trig identity, but too simple.
2632
// 2. (alpha**2 - beta**2) / (alpha - beta) → didn't simplify. Engine doesn't cancel the

0 commit comments

Comments
 (0)