Automatic differentiation for nonsmooth functions.
abs, max, min, floor — done right.
// Standard AD gives 0 at x=0 for |x| ← WRONG
// Clarke-AD gives the correct subgradient set
∂|x| at x=0 → [-1, 1] ✓
Standard AD silently gives wrong derivatives at abs, max, floor. Clarke-AD returns the correct subgradient set.
Records which branch each nonsmooth function takes. When a kink is crossed, the subgradient becomes a convex set.
Subgradient methods, proximal operators, Tikhonov regularization — all work with nonsmooth objectives.
Standard automatic differentiation (AD) computes derivatives by propagating dual numbers through a computation graph. It works perfectly for smooth functions. But many real-world functions are nonsmooth:
|x| — absolute value has a kink at x=0max(x, 0) — ReLU activation in neural networksfloor(x) — quantization, integer constraintssign(x) — contact mechanics, frictionAt these kinks, standard AD returns wrong answers — usually 0 or an arbitrary one-sided derivative. This breaks gradient-based optimization.
In 1975, Frank Clarke introduced generalized gradients for nonsmooth analysis. Instead of a single derivative at a kink, we get a convex set of possible subgradients:
∂f(x₀) = conv{lim ∇f(xᵢ) : xᵢ → x₀, xᵢ ∉ Ωf}∂f(x₀) = {f'(x₀)} (just the derivative)∂f(x₀) is a convex set (an interval in 1D)
| function | subgradient at x₀ | explanation |
|---|---|---|
|x| at x=0 | [-1, 1] | left = -1, right = +1 |
max(x, 0) at x=0 | [0, 1] | ReLU kink |
min(x, 0) at x=0 | [-1, 0] | flipped ReLU |
floor(x) at integer | [-∞, ∞] | distributional |
Contact/impact mechanics use sign and abs. Standard AD gives wrong forces. Clarke-AD gives correct subgradients for stable simulation.
ReLU networks, hinge loss, quantization — all nonsmooth. Clarke-AD gives honest gradients at kinks for better training.
Saturation, thresholds, argmin compositions are everywhere in control. Clarke-AD handles them correctly.
Subgradient methods, proximal operators, bundle methods — all need correct subgradients. Clarke-AD provides them.
Rust library: Use clarke-core for dual numbers, clarke-nonsmooth for kink detection.
use clarke_nonsmooth::subgrad_abs;let s = subgrad_abs(0.0); // [-1, 1]
Web demo: Open the demo, see subgradients computed live in WASM.
Optimization: Use clarke-opt for subgradient and proximal methods.
The Clarke subgradient at a kink is the convex hull of left and right limits:
∂f(x₀) = conv{∇f(x₀⁻), ∇f(x₀⁺)}
For |x| at x=0:
∂|x|(0) = conv{-1, +1} = [-1, 1]
For composed functions, branch tracking records which path each operation takes.
curl -sSf https://clarke.jesed.dev/install.sh | sh
cargo install clarke-ad --git https://github.com/jesedv/clarke-ad.git
wasm-pack build crates/clarke-wasm --target web
cd ui && npm install && npm run dev