import type { Range, Variables } from "./types"; export interface FunctionPreset { name: string; expression: string; // The view it opens with (with one variable, y fits the curve), and where the runs start x: Range; y?: Range; start: number[]; } export const PRESETS: Record = { 1: [ { name: "Quadratic", expression: "x^2", x: [-1.5, 1.5], start: [1] }, { name: "Local minima", expression: "x^2 - 0.1cos(20x)", x: [-1.5, 1.5], start: [1] }, { name: "Plateau", expression: "x^4", x: [-1.5, 1.5], start: [1] }, ], 2: [ { name: "Quadratic bowl", expression: "x^2 + 3y^2", x: [-1.5, 1.5], y: [-1.5, 1.5], start: [1, 1] }, { name: "Small", expression: "(0.05x)^2 + 3(0.05y)^2", x: [-1.5, 1.5], y: [-1.5, 1.5], start: [1, 1] }, { name: "Ackley", expression: "-20exp(-0.2 sqrt(0.5(x^2 + y^2))) - exp(0.5(cos(2 pi x) + cos(2 pi y))) + e + 20", x: [-4, 4], y: [-4, 4], start: [2.6, 1.7] }, { name: "Rastrigin", expression: "20 + (x^2 - 10cos(2 pi x)) + (y^2 - 10cos(2 pi y))", x: [-5.12, 5.12], y: [-5.12, 5.12], start: [3.2, 2.1] }, { name: "Rosenbrock", expression: "(1 - x)^2 + 100(y - x^2)^2", x: [-2, 2], y: [-1, 3], start: [-1.5, 2] }, ], }; export const ALL_PRESETS = [...PRESETS[1], ...PRESETS[2]]; export const CUSTOM = "Custom"; // The function names logic.py allows (ALLOWED_NAMES); none of them contain a y const FUNCTION_NAMES = /asin|acos|atan|sin|cos|tan|sqrt|abs|exp|log|ln|pi/g; // 2 if the function uses y, else 1. Letters side by side multiply ("xy" is // x·y), so any y left once the function names are removed counts. export function detectVariables(expression: string): Variables { return /y/.test(expression.replace(FUNCTION_NAMES, "")) ? 2 : 1; }