Spaces:
Running
Running
File size: 2,678 Bytes
e048104 779968d e048104 60943f3 779968d e048104 779968d 60943f3 779968d e048104 60943f3 e048104 779968d e048104 779968d e048104 779968d 9292daf ab2e84f b26246b 60943f3 779968d 3f34e78 b26246b 3adb9d3 b26246b 3adb9d3 3f34e78 b26246b 4f4a1ca b26246b 779968d b26246b 779968d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | import { useState, useRef } from "react";
import OptimizationPlot from "./OptimizationPlot.tsx";
import Sidebar from "./Sidebar.tsx";
import type { SettingsUi } from "./types.ts";
import usePyodide from "./usePyodide.ts";
const INITIAL_SETTINGS_UI: SettingsUi = {
mode: "Univariate",
functionExpr: "x^2",
algorithm: "Gradient Descent",
x0: "0.5",
y0: "0.5",
learningRate: "0.1",
momentum: "0.0",
};
const INITIAL_XLIM: [number, number] = [-1, 1];
const INITIAL_YLIM: [number, number] = [-1, 1];
export default function App() {
const [settingsUi, setSettingsUi] = useState<SettingsUi>(INITIAL_SETTINGS_UI);
const xlimRef = useRef<[number, number]>(INITIAL_XLIM);
const ylimRef = useRef<[number, number]>(INITIAL_YLIM);
const settings = { ...settingsUi, xlim: xlimRef.current, ylim: ylimRef.current };
function handleSettingsUiChange(newSettings: SettingsUi) {
setSettingsUi(newSettings);
api.sendInit({ ...newSettings, xlim: xlimRef.current, ylim: ylimRef.current });
}
function setAxisLimits(xlim: [number, number], ylim: [number, number]) {
xlimRef.current = xlim;
ylimRef.current = ylim;
api.sendInit({ ...settingsUi, xlim, ylim });
}
function handleRandomInitialPoint() {
const xRange = xlimRef.current[1] - xlimRef.current[0];
const yRange = ylimRef.current[1] - ylimRef.current[0];
const newX0 = (xlimRef.current[0] + Math.random() * xRange * 0.95).toFixed(2);
const newY0 = (ylimRef.current[0] + Math.random() * yRange * 0.95).toFixed(2);
const newSettings = { ...settingsUi, x0: newX0, y0: newY0 };
handleSettingsUiChange(newSettings);
}
const api = usePyodide(settings);
//if (api.isLoading) {
//return <LoadingScreen message="Loading" />;
//}
return (
<div className="grid grid-cols-[1fr_12fr_1fr] lg:h-dvh bg-stone-50">
<div/>
<div className="flex flex-col gap-6 p-6 min-h-0">
<div className="title">Optimization Trajectory Visualizer</div>
{/* <div className="desc"></div> */}
<div className="grid grid-cols-1 lg:grid-cols-[2fr_1fr] gap-12 flex-1 min-h-0 overflow-auto">
<OptimizationPlot
data={api.plotData}
isLoading={api.isLoading}
xlim={xlimRef.current}
ylim={ylimRef.current}
setAxisLimits={setAxisLimits}
/>
<Sidebar
settings={settingsUi}
setSettings={handleSettingsUiChange}
onRandomInitialPoint={handleRandomInitialPoint}
trajectoryValues={api.plotData.trajectoryValues}
onReset={() => api.sendReset()}
onNextStep={() => api.sendNextStep()}
onPrevStep={() => api.sendPrevStep()}
/>
</div>
</div>
<div/>
</div>
);
}
|