ADMM
Split a hard problem into an easy smooth piece and an easy kinked piece, solve each alone, and let a price nudge them into agreement. Repeating that deal solves Lasso and distributed fits neither half can solve alone.
Why Does This Exist?
Lasso couples a smooth square with a kinky absolute value, so neither pure gradient descent nor pure thresholding applies. A Lasso with 10,000 features has the same structure repeated 10,000 times, and a distributed fit across 10 machines couples 10 local losses through one consensus variable. Solving jointly wastes the separability that makes each piece easy.
ADMM splits subject to , where is the smooth part, is the possibly nonsmooth part, and is the linear coupling, via the augmented Lagrangian and alternates an solve, a solve, and a price update. Each subproblem uses its best solver while the price negotiates agreement.
This page covers the splitting mechanism and its residuals. Convex structure lives in convex optimization, prices in Lagrangian duality, kinks in subgradients, and optimality certificates in optimality conditions.
The one idea you need first
The scaled form iterates , then , then , where is the penalty pace and is the scaled price. The primal residual measures disagreement and the dual residual measures suboptimality, and both must vanish. Background prices are in Lagrangian duality.
Think of It Like This
Two shops and a mediator
A baker with smooth oven costs and a florist with kinked staffing rules share one storefront window. The mediator proposes a split, each optimizes privately with the current rent added, then the mediator adjusts the rent by the disagreement and repeats.
The baker maps to the smooth solve, the florist maps to the thresholding solve, and the rent maps to the price . Neither shop solves the joint problem. The rent does.
Where it stops: a stubborn fixed rent stalls haggling when one residual dominates. Adaptive rents that rebalance residuals keep the deal moving.
How It Actually Works
For closed convex and , ADMM converges in residual, objective, and dual value. The update is often a ridge-like linear solve, the update is often a proximal soft threshold, and over-relaxation with in often halves iterations. The consensus form gives each machine its own with one global , which is how distributed Lasso and distributed SVM train without moving raw data.
Concretely for Lasso split as subject to , where is the feature matrix, is the target, and is the penalty: solves a linear system, soft-thresholds at , and accumulates .
Worked example
Scalar Lasso with split , where is the least-squares target and is the penalty. The optimum soft-thresholds , since the target exceeds the penalty. Run ADMM with , , , where paces agreement. Updates are and , where is soft thresholding .
Step 1: . Then , which is below , so . Price becomes . Primal residual is .
Step 2: . Then , minus gives . Price becomes . Residual falls to .
Step 3: . Then , minus gives . Price stays . Residual is and both halves sit at , walking up toward the shared with settled at . About 15 such steps land within of .
Code
The point is the check: the same three steps and the same landing, in plain Python.
import math
def soft_threshold(v: float, kappa: float) -> float: return math.copysign(max(abs(v) - kappa, 0.0), v)
def admm_lasso(b: float, lam: float, rho: float, steps: int) -> tuple[float, float, float]: x: float = 0.0 z: float = 0.0 u: float = 0.0 for _ in range(steps): x = (b + rho * (z - u)) / (1.0 + rho) z = soft_threshold(x + u, lam / rho) u = u + x - z return (x, z, u)
x1, z1, u1 = admm_lasso(0.9, 0.5, 1.0, 1)print((round(x1, 4), round(z1, 4), round(u1, 4))) # -> (0.45, 0.0, 0.45)
x2, z2, u2 = admm_lasso(0.9, 0.5, 1.0, 2)print((round(x2, 4), round(z2, 4), round(u2, 4))) # -> (0.225, 0.175, 0.5)
x3, z3, u3 = admm_lasso(0.9, 0.5, 1.0, 3)print((round(x3, 4), round(z3, 4), round(u3, 4))) # -> (0.2875, 0.2875, 0.5)
x50, z50, _ = admm_lasso(0.9, 0.5, 1.0, 50)print((round(x50, 3), round(z50, 3))) # -> (0.4, 0.4)Fifty rounds land both halves at . The price absorbs the threshold shift and parks at .
Watch Out For
Stopping on one residual
Primal small with dual large means the halves agree but prices are wrong, so the point is feasible yet suboptimal. Dual small with primal large means each piece is optimal alone but they disagree, as after step 1 above where and look agreed only if you ignore the gap.
Stop when both sit under tolerance with scaling. If one stalls while the other shrinks, retune instead of iterating.
Fixing rho forever
The default on badly scaled problems imbalances residuals 100-to-1 and crawls toward sideways. Practitioners blame ADMM while the pace parameter idles.
Adapt to balance residuals, the residual-balancing rule. If the ratio exceeds 10 for many steps, rescale and rescale with it, then continue.
The Quick Version
- ADMM splits smooth from kinked and alternates private solves with a price update.
- Scalar Lasso with target and penalty converges both halves to .
- Three steps give , then , then with price .
- The update ridge-solves, the update soft-thresholds, and accumulates the gap.
- Both primal and dual residuals must vanish, and paces them.
- Consensus form distributes learning with per-node solves and one global .
- Adapt and over-relax near for speed.