concept-collection / fastandaccurate
Default to star-hard; extend the mfs sweep into its conditioning-limited regime
Jeremy Magland <jmagland@flatironinstitute.org> committed commit 3452f1b85abc parent 2f05269 Browse files
5 changed files+20−9
scripts/check-app.mjsmodified+6−3View file
@@ -101,9 +101,12 @@ try {
101101 failures++;
102102 } else {
103103 const err = parseFloat(m[1]);
104- // mfs at its default n on star-medium should be far below 1e-6.
105- if (!(err < 1e-6)) {
106- console.error(`FAIL: in-browser mfs error ${err} not < 1e-6`);
104+ // The default instance is the hard one, where every method still has
105+ // a sizeable error at a moderate n, so this is a sanity bound rather
106+ // than an accuracy claim: it separates a real solve from a broken or
107+ // placeholder one (which would give an O(1) error or NaN).
108+ if (!(err > 0 && err < 1e-2)) {
109+ console.error(`FAIL: in-browser solve error ${err} not in (0, 1e-2)`);
107110 failures++;
108111 } else {
109112 console.log(`in-browser solve ok (rel max error ${m[1]})`);
src/app/pages/ProblemPage.tsxmodified+2−1View file
@@ -1,5 +1,6 @@
11 import { useEffect, useMemo, useState } from "react";
22 import {
3+ DEFAULT_INSTANCE,
34 INSTANCES,
45 getInstance,
56 PROBLEM_ID,
@@ -35,7 +36,7 @@ interface LocalRun {
3536 }
3637
3738 export function ProblemPage({ problemId }: { problemId: string }) {
38- const [instanceId, setInstanceId] = useState(INSTANCES[1].id);
39+ const [instanceId, setInstanceId] = useState(DEFAULT_INSTANCE);
3940 const [committed, setCommitted] = useState<ResultFile[] | null>(null);
4041 const [committedError, setCommittedError] = useState<string | null>(null);
4142 const [loaded, setLoaded] = useState<ResultFile[]>([]);
src/problems/laplace2d/spec.tsmodified+4−0View file
@@ -54,6 +54,10 @@ export const INSTANCES: Laplace2dInstance[] = [
5454 },
5555 ];
5656
57+/** The instance a visitor sees first: the one that separates the methods
58+ * most sharply. */
59+export const DEFAULT_INSTANCE = "star-hard";
60+
5761 export function getInstance(id: string): Laplace2dInstance {
5862 const inst = INSTANCES.find((i) => i.id === id);
5963 if (!inst) throw new Error(`Unknown instance: ${id}`);
src/solvers/index.tsmodified+7−4View file
@@ -28,13 +28,16 @@ export const SOLVERS: SolverManifest[] = [
2828 "Represents the solution as n logarithmic point charges on a curve " +
2929 "a fixed distance 0.3 outside the boundary, with strengths found by " +
3030 "collocation at n boundary points. Converges geometrically when the " +
31- "data continues harmonically past the charge curve; stagnates when " +
32- "it does not (the star-hard instance). Ill-conditioning caps the " +
33- "attainable accuracy near 1e-10 in exchange for very small n.",
31+ "data continues harmonically past the charge curve, reaching machine " +
32+ "precision on the easier instances with far less work than the " +
33+ "integral-equation methods. When the data's singularities sit inside " +
34+ "that curve, as on star-hard, convergence is lost: more charges keep " +
35+ "helping only until the system's ill-conditioning takes over, and the " +
36+ "error settles near 1e-6 however far the sweep is pushed.",
3437 version: "1.0.0",
3538 backend: "cpu",
3639 runtime: "numbl",
37- sweepN: [8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256],
40+ sweepN: [8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768],
3841 },
3942 {
4043 id: "nystrom-dlp",
test/solver-test.tsmodified+1−1View file
@@ -33,7 +33,7 @@ const solverSources: Record<string, MatlabSources> = {
3333 // beyond the data's singularities there, and if it suddenly reached high
3434 // accuracy the instance would no longer be testing what the spec says.
3535 const mustReach: Record<string, Record<string, number>> = {
36- mfs: { "disk-easy": 1e-12, "star-medium": 1e-12, "star-hard": 1e-2 },
36+ mfs: { "disk-easy": 1e-12, "star-medium": 1e-12, "star-hard": 1e-4 },
3737 "nystrom-dlp": { "disk-easy": 1e-10, "star-medium": 1e-10, "star-hard": 1e-8 },
3838 };
3939 const mustNotReach: Record<string, Record<string, number>> = {