Gradient Walker
Pick a function f(x), a starting x, and a learning rate η. The walker steps in the direction of −f'(x) — vanilla gradient descent — until the update drops below 1e-4 (converged) or maxSteps is reached. The trajectory of x-values traces out as a polyline, the tangent at the current step is overlaid on the curve, and a transport bar plays, pauses, scrubs, or replays the descent.
y = x². Step 0 of 26. x = 3.000, f(x) = 9.000, slope = 6.000. Status: running.
y = x²step 00 / 26
x = 3.000f(x) = 9.000f'(x) = 6.000η = 0.150
Customize
Function
x^2
Walk
3.00
0.15
Playback
Installation
npx shadcn@latest add https://craftbits.dev/r/gradient-walker.jsonUsage
import { GradientWalker } from "@craft-bits/core";
<GradientWalker
defaultActiveFunction="x^2"
defaultStartX={3}
learningRate={0.15}
/>Drive playback from outside the component:
const [step, setStep] = useState(0);
const [playing, setPlaying] = useState(true);
<GradientWalker
defaultActiveFunction="x^2"
defaultStartX={3}
learningRate={0.1}
currentStep={step}
onCurrentStepChange={setStep}
playing={playing}
onPlayingChange={setPlaying}
/>Watch convergence into a local minimum on the double-well x⁴ − x²:
<GradientWalker
defaultActiveFunction="x^4-x^2"
defaultStartX={1.2}
learningRate={0.1}
maxSteps={80}
/>Understanding the component
- Five built-in functions, each with analytical derivative.
x²,x² + 2x + 1(offset bowl),sin(x),x⁴ − x²(double well — two local minima!),½x² + 0.3·sin(2x)(wavy bowl). Every derivative is the exact closed form, so the walker's step direction is the true gradient. - Whole walk is precomputed. Given the active function, start, learning rate, and max steps, the full trajectory is simulated once and stored. Scrubbing by
currentStepis O(1); the convergence check (|x_new − x_old| < 1e-4) is built in. - Trajectory is drawn cumulatively. Every visited point is a small dot fading from muted into accent toward the current step; a thin accent polyline connects them. The current step gets a larger walker dot and a short tangent line whose slope is
f'(x). - Convergence ring. When the walker's final step is below
1e-4, acb-successring lights up around the dot and the legend reads "converged". - Autoplay uses
setTimeout. The interval isplaySpeedms (default 400). The effect cleans up on unmount, pause, or step change — no orphaned timers. Reduced-motion users have autoplay disabled and the walker snaps to the final step on mount. - Controlled and uncontrolled, four times.
activeFunction,startX,playing, andcurrentStepeach ship avalue+onChangepair for controlled use, or adefault*prop for uncontrolled. - Domain guards keep the walker on screen. If a step would leave the visible
range, the simulator stops there — a too-aggressive learning rate gracefully truncates the trail instead of crashing.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
functions | readonly FunctionDef[] | five built-ins | Selectable function list. |
activeFunction | string | — | Controlled active function. |
defaultActiveFunction | string | first entry of functions | Uncontrolled initial active function. |
startX | number | — | Controlled starting x. |
defaultStartX | number | range[1] − ¼ × span | Uncontrolled initial starting x. |
learningRate | number | 0.1 | Gradient-descent learning rate η. |
maxSteps | number | 50 | Maximum number of steps simulated. |
playing | boolean | — | Controlled play state. |
defaultPlaying | boolean | false | Uncontrolled initial play state. |
currentStep | number | — | Controlled current step index. |
defaultCurrentStep | number | 0 | Uncontrolled initial step. |
range | readonly [number, number] | [-4, 4] | Visible x-axis domain. |
playSpeed | number | 400 | Milliseconds between autoplay steps. |
transition | Transition | SPRINGS.snap | Spring for the walker dot / tangent. |
className | string | — | Merged onto the root <div> via cn(). |
Accessibility
- The whole figure is
role="figure"witharia-label="Gradient descent walker on <function>". - An
aria-live="polite"summary above the chart announces the current step,x,f(x),f'(x), and status (running/stopped/converged) whenever the step or function changes. - The play / pause button uses
aria-pressedso screen readers track the toggle state. - Step controls (
‹/›) and the scrubber each carry explicitaria-labels. - The function picker is a
role="radiogroup"ofrole="radio"buttons, each taggeddata-state="on" | "off". - Animation respects
prefers-reduced-motion: reduce— autoplay is disabled, the walker snaps to the final step on mount, and all springs collapse to an instant swap.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/math/GradientWalker.tsx). Reframed the lesson primitive into a general 1-D gradient-descent visualizer: stripped the lesson-specific stage state machine, narration, success badges, andSvgLabel/ChallengeBtndependencies; generalized to controlled / uncontrolled state pairs across four axes; added a five-function built-in roster (including a double-well to demonstrate local minima); added a precomputed-trajectory simulator with explicit convergence detection.