import { useEffect, useState } from "react"; import { InputField } from "@elvis/ui"; import { SUPPORTED_ALGORITHMS, type SettingsUi } from "./types"; export const DEFAULT_HYPERPARAMETERS = { "Gradient Descent": { learningRate: "0.1", momentum: "0.0" }, "Nesterov": { learningRate: "0.1", momentum: "0.1" }, "Adam": { learningRate: "0.1", beta1: "0.9", beta2: "0.999", epsilon: "1e-8" }, "Adagrad": { learningRate: "0.1", epsilon: "1e-8" }, "RMSProp": { learningRate: "0.1", beta: "0.9", epsilon: "1e-8" }, "Adadelta": { beta: "0.9", epsilon: "1e-3" }, "Newton": {} } export default function AlgorithmControls({ settings, setSettings, onRandomInitialPoint, showInitialPoint = true }: { settings: SettingsUi; setSettings: (settings: SettingsUi) => void; onRandomInitialPoint?: () => void; showInitialPoint?: boolean; }) { function updateSettings(key: keyof SettingsUi, value: string) { if (key === "algorithm") { const defaults = DEFAULT_HYPERPARAMETERS[value as keyof typeof DEFAULT_HYPERPARAMETERS]; setSettings({ mode: settings.mode, functionExpr: settings.functionExpr, x0: settings.x0, y0: settings.y0, algorithm: value as SettingsUi["algorithm"], ...defaults }); } else { setSettings({ ...settings, [key]: value }); } } const [initialPointInput, setInitialPointInput] = useState(() => [settings.x0 ?? "", settings.y0 ?? ""].filter((part) => part !== "").join(", ") ); useEffect(() => { if (settings.mode === "Bivariate") { setInitialPointInput([settings.x0 ?? "", settings.y0 ?? ""].filter((part) => part !== "").join(", ")); } }, [settings.mode, settings.x0, settings.y0]); function handleInitialPointChange(value: string) { setInitialPointInput(value); if (settings.mode === "Bivariate") { const parts = value.split(",").map((part) => part.trim()); const [xValue, yValue] = parts; setSettings({ ...settings, x0: xValue ?? "", y0: yValue ?? settings.y0 ?? "", }); } else { updateSettings("x0", value); } } return <>
{showInitialPoint && (settings.mode === "Bivariate" ? (
handleInitialPointChange(event.target.value)} className="h-10 w-full rounded border border-stone-300 px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-stone-400" />
) : (
updateSettings("x0", event.target.value)} className="h-10 w-full rounded border border-stone-300 px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-stone-400" />
))}
{["Gradient Descent", "Nesterov", "Adam", "Adagrad", "RMSProp"].includes(settings.algorithm) && ( <> updateSettings("learningRate", value)} /> )} {["Gradient Descent", "Nesterov"].includes(settings.algorithm) && ( <> updateSettings("momentum", value)} /> )} {settings.algorithm === "Adam" && ( <> updateSettings("beta1", value)} /> updateSettings("beta2", value)} /> )} {["RMSProp", "Adadelta"].includes(settings.algorithm) && ( <> updateSettings("beta", value)} /> )} {["Adam", "Adagrad", "RMSProp", "Adadelta"].includes(settings.algorithm) && ( <> updateSettings("epsilon", value)} /> )}
; }