Type at least 2 letters. Enter opens the first result, Esc closes.

    Optimization · Lesson 9 · Constraints and nonsmooth problems

    Proximal methods (ISTA, FISTA) and ADMM

    Advanced 75 min 4 interactive figures 5 videos Colab notebook

    Before this lesson: lesson 03 (the step 1/L1/L and the O(1/k)O(1/k) rate), lesson 04 (Nesterov momentum, which FISTA uses), lesson 08 (KKT conditions, projections, the lasso dual); why the ℓ1\ell_1 norm gives sparse solutions (linear algebra 11). Time: about 75 minutes, plus the notebook.


    Why this matters #

    Many objectives in ML and science have the form F(x)=f(x)+g(x)F(x) = f(x) + g(x), with a smooth data term ff and a simple nonsmooth term gg:

    • the lasso 12∥Ax−b∥2+λ∥x∥1\tfrac12\|Ax - b\|^2 + \lambda\|x\|_1 and sparse logistic regression (feature selection);
    • total variation ∥Dx∥1\|Dx\|_1 in imaging, denoising and geophysical inversion;
    • constraints: bounds on physical parameters, nonnegative factors, probability vectors.

    The subgradient method handles the kink of ∣x∣|x| only slowly (error O(1/k)O(1/\sqrt k) after kk steps) and gives no exact zeros. The proximal gradient method keeps the O(1/k)O(1/k) rate of gradient descent, gives exact zeros, and accelerates to O(1/k2)O(1/k^2). ADMM splits a problem into pieces that are each easy. This is how large inverse problems, distributed fitting, and "plug-and-play" priors (a learned denoiser, even a diffusion model, used in place of a proximal step) are solved.

    1. Predict first #

    2. The picture #

    2.1 A smooth part plus a simple part #

    Write F(x)=f(x)+g(x)F(x) = f(x) + g(x), where

    • ff is convex and LL-smooth (lesson 02): its gradient exists and does not change faster than LL;
    • gg is convex but may be nonsmooth or even take the value +∞+\infty, and it is simple: the small problem in section 2.2 has a cheap, exact solution.

    The indicator function of a set CC is ιC(x)=0\iota_C(x) = 0 if x∈Cx \in C and +∞+\infty otherwise. Adding ιC\iota_C to ff turns "minimize ff over CC" into "minimize f+ιCf + \iota_C over everything". So constraints are a special case of a nonsmooth gg.

    Why not use gradient descent with a subgradient of gg (a slope of a supporting line, section 3)? At a kink the subgradient jumps, the step size must shrink to 0, and the iterates jump around 0 without landing on it. The method is slow and the solution is never exactly sparse.

    2.2 The proximal operator #

    The proximal operator of gg with step η>0\eta > 0 is

    prox⁡ηg(v)=arg⁡min⁡u(g(u)+12η∥u−v∥2).\operatorname{prox}_{\eta g}(v) = \arg\min_u \Big( g(u) + \frac{1}{2\eta}\|u - v\|^2 \Big).

    Read it as: move from vv to a point where gg is small, but do not go far. A small η\eta keeps you close to vv; a large η\eta cares mostly about gg. For convex gg the objective in uu is strongly convex, so the minimizer exists and is unique.

    Three cases in one dimension.

    • g=ι[l,h]g = \iota_{[l, h]}, the indicator of an interval: the prox is the closest point of the interval, clip⁡(v,l,h)\operatorname{clip}(v, l, h). A prox generalizes a projection.
    • g(u)=∣u∣g(u) = |u|: the prox moves vv toward 0 by η\eta and stops at 0 if it would cross it. This is soft thresholding:
    Sη(v)=sign⁡(v)max⁡(∣v∣−η,0).S_\eta(v) = \operatorname{sign}(v)\max(|v| - \eta, 0).

    Every v∈[−η,η]v \in [-\eta, \eta] is mapped to exactly 0. This is where exact sparsity comes from.

    • g(u)=c2u2g(u) = \tfrac{c}{2}u^2: the prox is v/(1+ηc)v/(1 + \eta c), a shrinkage by a constant factor. It never reaches 0 unless v=0v = 0.
    Interactive figure: loading…

    Move vv and η\eta. Left: the two parts of the prox objective, g(u)g(u) (violet) and 12η(u−v)2\frac{1}{2\eta}(u - v)^2 (blue, dashed), and their sum (black). The orange point is the minimizer p=prox⁡ηg(v)p = \operatorname{prox}_{\eta g}(v). Right: the prox map v↦pv \mapsto p with the identity dashed. For g=∣u∣g = |u|, the yellow dead zone [−η,η][-\eta, \eta] is sent to exactly 0: the kink at 0 holds the minimizer there. For 12u2\tfrac12 u^2 the map is a line through 0 with slope 1/(1+η)1/(1 + \eta); for the indicator it is a clip.

    Quick check

    What is prox⁡ηg(v)\operatorname{prox}_{\eta g}(v) for g(u)=∣u∣g(u) = |u|, η=1\eta = 1 and v=0.4v = 0.4?

    Quick check

    gg is the indicator of the interval [0,1][0, 1]. What is prox⁡ηg(1.7)\operatorname{prox}_{\eta g}(1.7) for η=0.5\eta = 0.5?

    2.3 Proximal gradient: a gradient step, then a prox step #

    Recall the descent lemma (lesson 02): for an LL-smooth ff and a step η≤1/L\eta \le 1/L, the parabola

    f(u)≤f(x)+∇f(x)⊤(u−x)+12η∥u−x∥2f(u) \le f(x) + \nabla f(x)^\top (u - x) + \frac{1}{2\eta}\|u - x\|^2

    lies above ff and touches it at u=xu = x. Keep gg exact, replace ff by this upper bound, and minimize over uu. Complete the square (the terms that do not depend on uu drop out):

    f(x)+∇f(x)⊤(u−x)+12η∥u−x∥2=12η∥u−(x−η∇f(x))∥2+const.\begin{aligned} &f(x) + \nabla f(x)^\top (u - x) + \frac{1}{2\eta}\|u - x\|^2 \\ &\quad = \frac{1}{2\eta}\big\|u - (x - \eta\nabla f(x))\big\|^2 + \text{const}. \end{aligned}

    So the minimizer of "upper bound of ff" +g+ g is

    x+=prox⁡ηg(x−η∇f(x)).x^+ = \operatorname{prox}_{\eta g}\big(x - \eta \nabla f(x)\big).

    A gradient step on ff, then a prox step on gg. Because we minimize an upper bound of FF that touches FF at xx (this is called majorize–minimize), FF cannot go up: F(x+)≤F(x)F(x^+) \le F(x). In numerical-analysis words, it is a forward (explicit) Euler step on ff and a backward (implicit) Euler step on gg: forward–backward splitting. The implicit step handles the kink of gg stably.

    Projected gradient. If g=ιCg = \iota_C for a closed convex set CC, the prox is the projection PCP_C, and the method becomes projected gradient descent:

    xk+1=PC(xk−η∇f(xk)).x_{k+1} = P_C\big(x_k - \eta \nabla f(x_k)\big).

    Examples of cheap projections: a box (clip each entry), the nonnegative orthant (max⁡(v,0)\max(v, 0), the ReLU), a ball (rescale), the probability simplex (lesson 08).

    Interactive figure: loading…

    Drag the blue start point and press Play. Each step is a gradient step (blue, dashed), which may leave the set, followed by a projection back onto the yellow set CC. The iterates reach the boundary and then slide along it to the constrained minimizer x⋆x^\star (black star). The grey star is the unconstrained minimizer, outside CC. At x⋆x^\star, −∇f(x⋆)-\nabla f(x^\star) (grey arrow) points straight out of CC: no feasible direction goes downhill. Try the disc, and a step ηL\eta L above 2.

    3. Definitions and main results #

    Subgradients and the optimality condition #

    For a convex function gg, a vector ss is a subgradient of gg at xx if

    g(y)≥g(x)+s⊤(y−x)for all y.g(y) \ge g(x) + s^\top (y - x) \quad \text{for all } y .

    The line (or plane) with slope ss through (x,g(x))(x, g(x)) lies below the graph. The set of all subgradients is the subdifferential ∂g(x)\partial g(x). If gg is differentiable at xx, ∂g(x)={∇g(x)}\partial g(x) = \{\nabla g(x)\}. For the absolute value:

    ∂∣x∣={{1}x>0,[−1,1]x=0,{−1}x<0.\partial |x| = \begin{cases} \{1\} & x > 0, \\ [-1, 1] & x = 0, \\ \{-1\} & x < 0. \end{cases}

    At the kink, every slope between −1-1 and 11 gives a supporting line. Two facts we use:

    • A convex FF has a global minimum at x⋆x^\star if and only if 0∈∂F(x⋆)0 \in \partial F(x^\star). (Take s=0s = 0 in the definition: F(y)≥F(x⋆)F(y) \ge F(x^\star) for all yy.)
    • If ff is convex and differentiable, ∂(f+g)(x)=∇f(x)+∂g(x)\partial(f + g)(x) = \nabla f(x) + \partial g(x).

    Lemma (prox optimality) #

    For a closed, proper, convex gg (its graph has no gaps at the boundary, and it is not +∞+\infty everywhere), the minimizer p=prox⁡ηg(v)p = \operatorname{prox}_{\eta g}(v) is unique, and

    p=prox⁡ηg(v)  ⟺  v−pη∈∂g(p).p = \operatorname{prox}_{\eta g}(v) \iff \frac{v - p}{\eta} \in \partial g(p).

    Proof. The prox objective g(u)+12η∥u−v∥2g(u) + \frac{1}{2\eta}\|u - v\|^2 is strongly convex, so it has exactly one minimizer. By the sum rule its subdifferential is ∂g(u)+(u−v)/η\partial g(u) + (u - v)/\eta. The minimizer is where this set contains 0, that is (v−p)/η∈∂g(p)(v - p)/\eta \in \partial g(p). ■\blacksquare

    Soft thresholding from the lemma. Take g=λ∣⋅∣g = \lambda|\cdot| in one dimension and write t=ηλt = \eta\lambda. We need v−u∈t ∂∣u∣v - u \in t\,\partial|u|. Check the three cases:

    1. u>0u > 0: v−u=tv - u = t, so u=v−tu = v - t. This is consistent only if v>tv > t.
    2. u<0u < 0: v−u=−tv - u = -t, so u=v+tu = v + t. Consistent only if v<−tv < -t.
    3. u=0u = 0: we need v∈[−t,t]v \in [-t, t].

    Together: prox⁡t∣⋅∣(v)=sign⁡(v)max⁡(∣v∣−t,0)=St(v)\operatorname{prox}_{t|\cdot|}(v) = \operatorname{sign}(v)\max(|v| - t, 0) = S_t(v). The ℓ1\ell_1 norm is a sum over coordinates, so its prox acts coordinate by coordinate.

    Projection from the definition. If g=ιCg = \iota_C, the prox objective is 12η∥u−v∥2\frac{1}{2\eta}\|u - v\|^2 on CC and +∞+\infty outside. So prox⁡ηιC=PC\operatorname{prox}_{\eta\iota_C} = P_C for every η>0\eta > 0.

    Theorem (minimizers are fixed points) #

    Let ff be convex and differentiable, and gg closed, proper and convex. For any η>0\eta > 0,

    x⋆ minimizes f+g  ⟺  x⋆=prox⁡ηg(x⋆−η∇f(x⋆)).\begin{aligned} &x^\star \text{ minimizes } f + g \\ &\iff x^\star = \operatorname{prox}_{\eta g}\big(x^\star - \eta \nabla f(x^\star)\big). \end{aligned}

    Why it is true (intuition). At a minimizer, the gradient step wants to move by −η∇f(x⋆)-\eta\nabla f(x^\star), and the prox step pulls back by exactly the same amount. The two forces balance, as in the KKT picture of lesson 08.

    Proof.

    1. Apply the lemma with v=x⋆−η∇f(x⋆)v = x^\star - \eta\nabla f(x^\star) and p=x⋆p = x^\star. The fixed-point equation holds if and only if (v−x⋆)/η=−∇f(x⋆)∈∂g(x⋆)(v - x^\star)/\eta = -\nabla f(x^\star) \in \partial g(x^\star).
    2. That is, 0∈∇f(x⋆)+∂g(x⋆)=∂(f+g)(x⋆)0 \in \nabla f(x^\star) + \partial g(x^\star) = \partial(f + g)(x^\star), by the sum rule.
    3. For a convex function, 0∈∂F(x⋆)0 \in \partial F(x^\star) is exactly the condition for a global minimum. ■\blacksquare

    The step η\eta does not change the fixed points; it changes only how fast you reach them. For the lasso, step 1 reads coordinate by coordinate:

    • if xi⋆≠0x_i^\star \ne 0: (A⊤(b−Ax⋆))i=λsign⁡(xi⋆)\big(A^\top(b - Ax^\star)\big)_i = \lambda\operatorname{sign}(x_i^\star);
    • if xi⋆=0x_i^\star = 0: ∣(A⊤(b−Ax⋆))i∣≤λ\big|\big(A^\top(b - Ax^\star)\big)_i\big| \le \lambda.

    These are the lasso KKT conditions. A feature stays at 0 as long as its correlation with the residual is at most λ\lambda.

    ISTA and FISTA for the lasso #

    Let f(x)=12∥Ax−b∥2f(x) = \tfrac12\|Ax - b\|^2, so ∇f(x)=A⊤(Ax−b)\nabla f(x) = A^\top(Ax - b) and L=∥A∥22=λmax⁡(A⊤A)L = \|A\|_2^2 = \lambda_{\max}(A^\top A). Here λ\lambda is the lasso penalty and λmax⁡(⋅)\lambda_{\max}(\cdot) is an eigenvalue. Use the step η=1/L\eta = 1/L, and write F=f+λ∥⋅∥1F = f + \lambda\|\cdot\|_1, F⋆=min⁡xF(x)F^\star = \min_x F(x).

    • ISTA (iterative shrinkage-thresholding):
    xk+1=Sλ/L(xk−1LA⊤(Axk−b)).x_{k+1} = S_{\lambda/L}\Big(x_k - \tfrac1L A^\top(Ax_k - b)\Big).
    • FISTA (Beck and Teboulle, 2009): start with y1=x0y_1 = x_0, t1=1t_1 = 1; for k≥1k \ge 1,
    xk=Sλ/L(yk−1LA⊤(Ayk−b)),tk+1=1+1+4tk22,yk+1=xk+tk−1tk+1(xk−xk−1).\begin{aligned} x_k &= S_{\lambda/L}\Big(y_k - \tfrac1L A^\top(Ay_k - b)\Big), \\ t_{k+1} &= \frac{1 + \sqrt{1 + 4t_k^2}}{2}, \\ y_{k+1} &= x_k + \frac{t_k - 1}{t_{k+1}}(x_k - x_{k-1}). \end{aligned}

    The point yk+1y_{k+1} is a Nesterov extrapolation (lesson 04). The cost per step is the same as for ISTA: one product with AA and one with A⊤A^\top.

    Theorem (rates; Beck and Teboulle 2009, theorems 3.1 and 4.4). Let ff be convex and LL-smooth, gg closed and convex, the step 1/L1/L, and x⋆x^\star any minimizer. Then

    ISTA:F(xk)−F⋆≤L∥x0−x⋆∥22k,FISTA:F(xk)−F⋆≤2L∥x0−x⋆∥2(k+1)2.\begin{aligned} \text{ISTA:}\quad & F(x_k) - F^\star \le \frac{L\|x_0 - x^\star\|^2}{2k}, \\ \text{FISTA:}\quad & F(x_k) - F^\star \le \frac{2L\|x_0 - x^\star\|^2}{(k + 1)^2}. \end{aligned}

    ISTA is monotone: F(xk+1)≤F(xk)F(x_{k+1}) \le F(x_k). If ff is μ\mu-strongly convex, ISTA also converges linearly: ∥xk−x⋆∥2≤(1−μ/L)k∥x0−x⋆∥2\|x_k - x^\star\|^2 \le (1 - \mu/L)^k\|x_0 - x^\star\|^2. FISTA is not monotone: the momentum can overshoot. The ISTA proof is the O(1/k)O(1/k) proof of lesson 03 with ∇f\nabla f replaced by the gradient mapping G(x)=(x−x+)/ηG(x) = (x - x^+)/\eta; the FISTA proof is Nesterov's (Vandenberghe's lectures below). The method still converges for steps η<2/L\eta < 2/L, but the majorize–minimize argument and the bounds above need η≤1/L\eta \le 1/L; if LL is unknown, use backtracking.

    The rates on a 2D example. Take A=diag⁡(1,0.1)A = \operatorname{diag}(1, 0.1), b=(2,0.3)b = (2, 0.3), λ=0.01\lambda = 0.01. Then A⊤A=diag⁡(1,0.01)A^\top A = \operatorname{diag}(1, 0.01), so L=1L = 1, μ=0.01\mu = 0.01 and κ=100\kappa = 100; per coordinate, x⋆=(1.99,2)x^\star = (1.99, 2). From x0=0x_0 = 0:

    • ISTA first reaches F(xk)−F⋆≤10−8F(x_k) - F^\star \le 10^{-8} at k=722k = 722.
    • FISTA first reaches it at k=100k = 100, but then oscillates; it stays below 10−810^{-8} only from k=405k = 405.
    • FISTA with a function-value restart (when a step would raise FF, set tk=1t_k = 1 and redo the step from the previous point; O'Donoghue and Candès 2015) stays below from k=67k = 67.

    Both methods converge linearly here because the problem is strongly convex. The general bounds above ignore μ\mu and promise only k≈4⋅108k \approx 4 \cdot 10^8 (ISTA) and 4⋅1044 \cdot 10^4 (FISTA). They are the right guarantee when μ=0\mu = 0, for example a lasso with more features than samples.

    Interactive figure: loading…

    Drag the start point, move λ\lambda, and press Play. ISTA (blue) and FISTA (violet) minimize a 2D lasso whose contours (grey) have kinks on the axes. At λ=0.2\lambda = 0.2 the minimizer is x⋆=(2,0)x^\star = (2, 0): both methods reach x2=0x_2 = 0 exactly after a finite number of steps. FISTA overshoots past x1=2x_1 = 2 and its curve in the chart goes up and down, but it ends far ahead of ISTA. The dashed lines are the two worst-case bounds. The worked example has κ=3\kappa = 3; there acceleration helps little.

    Quick check

    You run FISTA on a lasso and see F(x8)>F(x7)F(x_8) > F(x_7). What is the most likely explanation?

    The lasso path #

    How does λ\lambda control sparsity? At x=0x = 0 the optimality condition of the lasso reads ∥A⊤b∥∞≤λ\|A^\top b\|_\infty \le \lambda. So for λ≥λmax⁡=∥A⊤b∥∞\lambda \ge \lambda_{\max} = \|A^\top b\|_\infty the solution is exactly 0 (lesson 08, check yourself 6). As λ\lambda decreases, features enter the model one by one, and sometimes one leaves again. The curve λ↦x⋆(λ)\lambda \mapsto x^\star(\lambda) is the lasso path; it is piecewise linear in λ\lambda. Solvers compute it from large to small λ\lambda, starting each fit at the previous solution (warm start).

    Interactive figure: loading…

    Move λ\lambda and watch which coefficients are exactly 0. The curves (colours 1, 2, 3, 4, 5) are the lasso coefficients of a small data set (20 samples, 5 standardized features), computed in your browser by coordinate descent. Right of λmax⁡\lambda_{\max} all are 0. Coefficient 3 enters first, grows, shrinks, is exactly 0 again for λ\lambda between about 0.02 λmax⁡0.02\,\lambda_{\max} and 0.07 λmax⁡0.07\,\lambda_{\max}, and then turns negative: a coefficient can leave the model when correlated features take over.

    ADMM: split the problem into easy pieces #

    ADMM (the alternating direction method of multipliers) solves

    min⁡x,z f(x)+g(z)subject tox−z=0.\min_{x, z}\ f(x) + g(z) \quad \text{subject to} \quad x - z = 0 .

    Make a copy zz of xx, give ff to xx and gg to zz, and force them to agree. The augmented Lagrangian is the Lagrangian of lesson 08 plus a quadratic penalty ρ>0\rho > 0:

    Lρ(x,z,y)=f(x)+g(z)+y⊤(x−z)+ρ2∥x−z∥2.\mathcal L_\rho(x, z, y) = f(x) + g(z) + y^\top(x - z) + \frac{\rho}{2}\|x - z\|^2 .

    ADMM minimizes over xx, then over zz, then takes a gradient ascent step on the multiplier yy. With the scaled dual variable u=y/ρu = y/\rho, the three updates are

    x←arg⁡min⁡xf(x)+ρ2∥x−z+u∥2,z←prox⁡g/ρ(x+u),u←u+x−z.\begin{aligned} x &\leftarrow \arg\min_x f(x) + \tfrac{\rho}{2}\|x - z + u\|^2, \\ z &\leftarrow \operatorname{prox}_{g/\rho}(x + u), \\ u &\leftarrow u + x - z . \end{aligned}

    The vector uu is the running sum of the disagreements x−zx - z: it keeps pushing xx and zz together.

    ADMM for the lasso (Boyd et al. §6.4). With f=12∥Ax−b∥2f = \tfrac12\|Ax - b\|^2 and g=λ∥⋅∥1g = \lambda\|\cdot\|_1:

    x←(A⊤A+ρI)−1(A⊤b+ρ(z−u)),z←Sλ/ρ(x+u),u←u+x−z.\begin{aligned} x &\leftarrow (A^\top A + \rho I)^{-1}\big(A^\top b + \rho(z - u)\big), \\ z &\leftarrow S_{\lambda/\rho}(x + u), \\ u &\leftarrow u + x - z . \end{aligned}
    • The xx-update is a ridge regression with a fixed matrix. Factor A⊤A+ρIA^\top A + \rho I once (Cholesky); then each iteration costs two triangular solves.
    • The zz-update is the soft threshold, so zz is exactly sparse; xx is only close to sparse.
    • Stop when the primal residual ∥xk−zk∥\|x_k - z_k\| and the dual residual ρ∥zk−zk−1∥\rho\|z_k - z_{k-1}\| are both small (Boyd et al. §3.3).

    Convergence (Boyd et al. §3.2). If ff and gg are closed, proper and convex, and the (unaugmented) Lagrangian has a saddle point, then for every ρ>0\rho > 0: xk−zk→0x_k - z_k \to 0, f(xk)+g(zk)→p⋆f(x_k) + g(z_k) \to p^\star, and yk→y⋆y_k \to y^\star. In practice ADMM reaches modest accuracy in a few tens of iterations, but it can be slow to reach high accuracy, and ρ\rho changes the speed (not the solution).

    When splitting is the better tool.

    • The prox of each piece is easy, but the prox of their sum is not: ∥Dx∥1\|Dx\|_1 (total variation, the generalized lasso; split z=Dxz = Dx), or a penalty plus constraints.
    • The data are spread over machines: consensus ADMM fits local models and combines them in the zz-step (Boyd et al. §7–8).
    • The xx-update is cheap to repeat (a cached factorization, an FFT), while gradient steps would be slow because κ\kappa is large.

    When gg has a cheap prox and ff is smooth, FISTA is simpler and has no ρ\rho to tune. When you need high accuracy, use a Newton-type or interior-point method.

    Plug-and-play priors

    In the zz-update, prox⁡g/ρ(v)=arg⁡min⁡zg(z)+ρ2∥z−v∥2\operatorname{prox}_{g/\rho}(v) = \arg\min_z g(z) + \frac{\rho}{2}\|z - v\|^2 is a denoising problem: find a zz close to the noisy vv that the prior gg likes. Plug-and-play ADMM (Venkatakrishnan, Bouman and Wohlberg, 2013) replaces this step by any good denoiser, for example a trained neural network, without ever writing gg down. DiffPIR (Zhu et al., 2023) uses a diffusion model as the denoiser, inside a related splitting method. This is one way to put a learned prior, such as a diffusion model of seismic or climate fields, into a physical inverse problem.

    Quick check

    In ADMM for the lasso, which update produces exact zeros?

    Answers to section 1. (1) u⋆=0u^\star = 0 exactly, because S1(0.4)=0S_1(0.4) = 0 (∣0.4∣≤1|0.4| \le 1). The subgradient method with decreasing steps moves around 0 and comes closer, but in general it never lands exactly on 0. The prox gets there in one step. (2) No. The momentum can overshoot, so F(xk)F(x_k) can go up (section 4 shows it). Only the bound decreases.

    4. Worked example #

    A=(111001)A = \begin{pmatrix} 1 & 1 \\ 1 & 0 \\ 0 & 1 \end{pmatrix}, b=(1,2,−0.5)b = (1, 2, -0.5), λ=1\lambda = 1: the lasso of lesson 08, section 4(c). Here A⊤A=(2112)A^\top A = \begin{pmatrix} 2 & 1 \\ 1 & 2 \end{pmatrix} (eigenvalues 1 and 3) and A⊤b=(3,0.5)A^\top b = (3, 0.5). So L=3L = 3, μ=1\mu = 1, the step is 1/31/3 and the threshold is λ/L=1/3\lambda/L = 1/3. At the start, F(0)=12∥b∥2=12(1+4+0.25)=2.625F(0) = \tfrac12\|b\|^2 = \tfrac12(1 + 4 + 0.25) = 2.625.

    ISTA by hand. ∇f(x)=A⊤Ax−A⊤b\nabla f(x) = A^\top A x - A^\top b.

    • k=1k = 1: ∇f(0)=(−3,−0.5)\nabla f(0) = (-3, -0.5). Gradient step: 0−13(−3,−0.5)=(1,1/6)0 - \tfrac13(-3, -0.5) = (1, 1/6). Threshold by 1/31/3: x1=(1−1/3, 0)=(2/3,0)x_1 = (1 - 1/3,\ 0) = (2/3, 0), because ∣1/6∣≤1/3|1/6| \le 1/3.
    • k=2k = 2: ∇f(x1)=(2⋅23−3, 23−0.5)=(−5/3,1/6)\nabla f(x_1) = (2 \cdot \tfrac23 - 3,\ \tfrac23 - 0.5) = (-5/3, 1/6). Gradient step: (2/3+5/9, −1/18)=(11/9,−1/18)(2/3 + 5/9,\ -1/18) = (11/9, -1/18). Threshold: x2=(8/9,0)x_2 = (8/9, 0).

    The second coordinate stays 0, because ∣−1/18∣≤1/3|-1/18| \le 1/3. On the line x2=0x_2 = 0 the update is x1←x1−13(2x1−3)−13=x1/3+2/3x_1 \leftarrow x_1 - \tfrac13(2x_1 - 3) - \tfrac13 = x_1/3 + 2/3, so xk,1=1−3−kx_{k,1} = 1 - 3^{-k} and xk→x⋆=(1,0)x_k \to x^\star = (1, 0).

    Optimality check (theorem above). ∇f(x⋆)=(2−3, 1−0.5)=(−1,0.5)\nabla f(x^\star) = (2 - 3,\ 1 - 0.5) = (-1, 0.5).

    • Coordinate 1 is nonzero, and −∇1f=1=λsign⁡(1)-\nabla_1 f = 1 = \lambda\operatorname{sign}(1) ✓.
    • Coordinate 2 is zero, and ∣∇2f∣=0.5≤1|\nabla_2 f| = 0.5 \le 1 ✓.

    The optimal value is F⋆=12(0+1+0.25)+1=1.625F^\star = \tfrac12(0 + 1 + 0.25) + 1 = 1.625.

    The rate on this example. On the line x2=0x_2 = 0, F(x)−F⋆=(x1−1)2F(x) - F^\star = (x_1 - 1)^2, so F(xk)−F⋆=9−kF(x_k) - F^\star = 9^{-k} (0.1110.111, 0.01230.0123, …). This is far below the O(1/k)O(1/k) bound L∥x0−x⋆∥2/(2k)=1.5/kL\|x_0 - x^\star\|^2/(2k) = 1.5/k, and even faster than the strongly convex factor 1−μ/L=2/31 - \mu/L = 2/3. The reason: the zero pattern is found at step 1, and then ISTA is gradient descent on the support alone, with curvature (A⊤A)11=2(A^\top A)_{11} = 2 and factor 1−2/3=1/31 - 2/3 = 1/3 per step.

    FISTA by hand. x1=(2/3,0)x_1 = (2/3, 0) as for ISTA. Then t2=(1+5)/2≈1.618t_2 = (1 + \sqrt5)/2 \approx 1.618 and (t1−1)/t2=0(t_1 - 1)/t_2 = 0, so y2=x1y_2 = x_1 and x2=(8/9,0)x_2 = (8/9, 0). Next t3≈2.194t_3 \approx 2.194 and the momentum factor is (t2−1)/t3≈0.282(t_2 - 1)/t_3 \approx 0.282, so y3≈0.889+0.282⋅0.222=0.9515y_3 \approx 0.889 + 0.282 \cdot 0.222 = 0.9515 and x3≈(0.9838,0)x_3 \approx (0.9838, 0), closer than ISTA's 0.96300.9630. But the momentum keeps growing: x4≈1.0083x_4 \approx 1.0083 overshoots, and FF goes up between k=7k = 7 and k=8k = 8 (1.4⋅10−7→4.8⋅10−71.4 \cdot 10^{-7} \to 4.8 \cdot 10^{-7} above F⋆F^\star). With κ=3\kappa = 3, ISTA is even ahead at k=5k = 5 (1.7⋅10−51.7 \cdot 10^{-5} against 5.1⋅10−55.1 \cdot 10^{-5}). Acceleration helps when κ\kappa is large.

    ADMM by hand (ρ=1\rho = 1). Start from x=z=u=0x = z = u = 0. The matrix is A⊤A+I=(3113)A^\top A + I = \begin{pmatrix} 3 & 1 \\ 1 & 3 \end{pmatrix}, with inverse 18(3−1−13)\frac18\begin{pmatrix} 3 & -1 \\ -1 & 3 \end{pmatrix}.

    • x1=18(3−1−13)(3,0.5)=18(8.5,−1.5)=(1.0625,−0.1875)x_1 = \frac18\begin{pmatrix} 3 & -1 \\ -1 & 3 \end{pmatrix}(3, 0.5) = \frac18(8.5, -1.5) = (1.0625, -0.1875).
    • z1=S1(x1+u0)=(0.0625,0)z_1 = S_1(x_1 + u_0) = (0.0625, 0): exactly sparse, while x1x_1 is not.
    • u1=u0+x1−z1=(1,−0.1875)u_1 = u_0 + x_1 - z_1 = (1, -0.1875).

    The iterates converge to x=z=(1,0)x = z = (1, 0) and u=(1,−0.5)u = (1, -0.5). At a fixed point, u⋆=−∇f(x⋆)/ρu^\star = -\nabla f(x^\star)/\rho and u⋆∈(λ/ρ) ∂∥x⋆∥1u^\star \in (\lambda/\rho)\,\partial\|x^\star\|_1: the scaled dual variable is the subgradient that certifies optimality.

    5. In code #

    NumPy checks the hand results; scikit-learn solves the same lasso by coordinate descent. The notebook asks you to write these methods yourself.

    import numpy as np
    from scipy.optimize import minimize_scalar
    from sklearn.linear_model import Lasso
    
    def soft(v, t):                                   # prox of t*|.|: soft thresholding
        return np.sign(v) * np.maximum(np.abs(v) - t, 0)
    
    # (a) soft thresholding, and a brute-force check of one entry
    v = np.array([2.5, -0.3, 0.8, -1.5])
    print(soft(v, 1.0) + 0.0)                         # [ 1.5  0.   0.  -0.5]
    print(round(minimize_scalar(lambda u: abs(u) + 0.5 * (u - 2.5) ** 2).x, 6))   # 1.5
    
    # (b) the worked example: ISTA with step 1/L
    A = np.array([[1.0, 1.0], [1.0, 0.0], [0.0, 1.0]])
    b = np.array([1.0, 2.0, -0.5])
    lam = 1.0
    L = np.linalg.norm(A, 2) ** 2                     # 3.0
    F = lambda x: 0.5 * np.sum((A @ x - b) ** 2) + lam * np.sum(np.abs(x))
    x = np.zeros(2)
    for k in range(3):
        x = soft(x - A.T @ (A @ x - b) / L, lam / L)
        print(k + 1, x.round(4) + 0.0)                # 1 [0.6667 0.]  2 [0.8889 0.]  3 [0.963 0.]
    
    # FISTA: the gap F(x_k) - F* for k = 6..9 goes up between k = 7 and k = 8
    x, y, t, gaps = np.zeros(2), np.zeros(2), 1.0, []
    for k in range(10):
        x_old, x = x, soft(y - A.T @ (A @ y - b) / L, lam / L)
        t_new = (1 + np.sqrt(1 + 4 * t * t)) / 2
        y, t = x + (t - 1) / t_new * (x - x_old), t_new
        gaps.append(F(x) - 1.625)
    print(np.array(gaps[5:9]))                        # [4.53e-06 1.37e-07 4.85e-07 9.62e-08]
    
    # (c) scikit-learn minimizes F/m with alpha = lam/m
    m = A.shape[0]
    x_star = Lasso(alpha=lam / m, fit_intercept=False, tol=1e-12, max_iter=100_000).fit(A, b).coef_
    print(x_star.round(8) + 0.0, F(x_star))           # [1. 0.] 1.625
    
    # (d) x* is a fixed point of the proximal gradient map for every step
    grad = A.T @ (A @ x_star - b)
    print(grad.round(8) + 0.0)                        # [-1.   0.5]
    for a in [1 / 3, 0.1, 1.0]:
        print(soft(x_star - a * grad, a * lam).round(8) + 0.0)   # [1. 0.] each time
    
    # (e) ADMM with rho = 1
    rho = 1.0
    M = np.linalg.inv(A.T @ A + rho * np.eye(2))      # tiny here; in practice factor once (Cholesky)
    x = z = u = np.zeros(2)
    for k in range(100):
        x = M @ (A.T @ b + rho * (z - u))
        z = soft(x + u, lam / rho)
        u = u + x - z
    print(z.round(6) + 0.0, u.round(6) + 0.0)         # [1. 0.] [ 1.  -0.5]
    

    6. Where it shows up #

    • Sparse models and inverse problems. Daubechies, Defrise and De Mol (2004) proved that iterative soft thresholding converges for linear inverse problems with a sparsity penalty. ℓ1\ell_1 and total-variation penalties are standard in compressed sensing, MRI reconstruction, imaging and geophysical inversion.
    • Constraints in training. p.data.clamp_(lo, hi) after each SGD step is projected (stochastic) gradient descent on a box: physical bounds on parameters, nonnegative factors, weight clipping in the original Wasserstein GAN.
    • Weight decay as a prox. The prox of c2∥x∥2\frac{c}{2}\|x\|^2 is x/(1+ηc)x/(1 + \eta c), and decoupled weight decay x←(1−ηc)xx \leftarrow (1 - \eta c)x is its first-order version. AdamW can be read as an approximate proximal method (Zhuang et al., 2022; lesson 06).
    • Unrolled and learned algorithms. LISTA (Gregor and LeCun, 2010) unrolls a few ISTA steps into a network and learns the matrices and thresholds. Plug-and-play ADMM and diffusion-based solvers put a learned denoiser in place of the prox (see the folded block above).
    • Distributed fitting. Consensus ADMM fits one model on data split over many machines; each machine solves its own small problem, and the zz-step averages.
    • Sparse inverse covariance. The graphical lasso estimates a sparse precision matrix with an ℓ1\ell_1 penalty; ADMM is one standard solver (Boyd et al. §6.5).

    7. Common mistakes #

    • Thresholding at λ\lambda instead of step × λ\lambda. ISTA thresholds at λ/L\lambda/L for the step 1/L1/L; ADMM thresholds at λ/ρ\lambda/\rho.
    • Using scikit-learn's alpha as λ\lambda. scikit-learn divides the data term by the number of rows mm: it minimizes 12m∥Ax−b∥2+α∥x∥1\frac{1}{2m}\|Ax - b\|^2 + \alpha\|x\|_1, so α=λ/m\alpha = \lambda/m.
    • Expecting FISTA to be monotone. It is not. Plot FF on a log scale, and restart if needed.
    • Refactoring in every ADMM iteration. A⊤A+ρIA^\top A + \rho I does not change; factor it once. If you change ρ\rho during the run, refactor and rescale uu.
    • Returning ADMM's xx. zz is exactly sparse; xx is only close to sparse.
    • A step above 1/L1/L without a line search. The bounds need η≤1/L\eta \le 1/L. If LL is unknown, use backtracking.

    8. Check yourself #

    1. What is the prox of the indicator of the nonnegative orthant {x:x≥0}\{x : x \ge 0\}?
      AnswerThe projection onto the orthant, max⁡(v,0)\max(v, 0) entry by entry: the ReLU.
    2. Compute prox⁡t∥⋅∥1(v)\operatorname{prox}_{t\|\cdot\|_1}(v) for v=(0.4,−2,1)v = (0.4, -2, 1) and t=0.5t = 0.5.
      Answer(0,−1.5,0.5)(0, -1.5, 0.5). The first entry has ∣0.4∣≤0.5|0.4| \le 0.5, so it becomes exactly 0; the others move toward 0 by 0.5.
    3. Show that the prox of c2∥u∥2\frac{c}{2}\|u\|^2 with step η\eta is v/(1+ηc)v/(1 + \eta c). Can it give exact zeros?
      AnswerThe objective c2∥u∥2+12η∥u−v∥2\frac{c}{2}\|u\|^2 + \frac{1}{2\eta}\|u - v\|^2 is smooth with gradient cu+(u−v)/ηcu + (u - v)/\eta. Setting it to 0 gives u(1+ηc)=vu(1 + \eta c) = v, so u=v/(1+ηc)u = v/(1 + \eta c). It shrinks every entry by the same factor, so an entry is 0 only if it was 0 in vv.
    4. For min⁡f(x)\min f(x) over a closed convex set CC, what does x⋆=PC(x⋆−η∇f(x⋆))x^\star = P_C(x^\star - \eta\nabla f(x^\star)) mean geometrically?
      AnswerA projection satisfies p=PC(v)  ⟺  (v−p)⊤(z−p)≤0p = P_C(v) \iff (v - p)^\top(z - p) \le 0 for all z∈Cz \in C. With p=x⋆p = x^\star and v−p=−η∇f(x⋆)v - p = -\eta\nabla f(x^\star), this gives ∇f(x⋆)⊤(z−x⋆)≥0\nabla f(x^\star)^\top(z - x^\star) \ge 0 for all z∈Cz \in C: no feasible direction decreases ff to first order. Equivalently, −∇f(x⋆)-\nabla f(x^\star) points out of CC (it lies in the normal cone of CC at x⋆x^\star). In the interior of CC it means ∇f(x⋆)=0\nabla f(x^\star) = 0.
    5. L=10L = 10, ∥x0−x⋆∥=1\|x_0 - x^\star\| = 1, and you want F(xk)−F⋆≤10−4F(x_k) - F^\star \le 10^{-4}. After how many iterations do the ISTA and FISTA bounds guarantee it?
      AnswerISTA: 10/(2k)≤10−410/(2k) \le 10^{-4} gives k≥50,000k \ge 50{,}000. FISTA: 20/(k+1)2≤10−420/(k + 1)^2 \le 10^{-4} gives k+1≥2⋅105≈447.2k + 1 \ge \sqrt{2 \cdot 10^5} \approx 447.2, so k≥447k \ge 447.
    6. In ADMM for the lasso, what changes when you increase ρ\rho?
      AnswerThe threshold λ/ρ\lambda/\rho gets smaller, and the xx-update is pulled harder toward z−uz - u. The primal residual ∥x−z∥\|x - z\| tends to get smaller and the dual residual ρ∥zk−zk−1∥\rho\|z_k - z_{k-1}\| larger. The solution does not change, only the speed. You must refactor A⊤A+ρIA^\top A + \rho I, and rescale u=y/ρu = y/\rho if ρ\rho changes during the run.
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. Define the proximal operator prox⁡ηg(v)\operatorname{prox}_{\eta g}(v).

    2. Give the soft-thresholding formula, the prox of t∣⋅∣t|\cdot|.

    3. Compute prox⁡η∣⋅∣(0.4)\operatorname{prox}_{\eta|\cdot|}(0.4) for η=1\eta = 1.

    4. What is the prox of the indicator of a closed convex set CC?

    5. Write the proximal gradient update for F=f+gF = f + g.

    6. What is the subdifferential of ∣x∣|x| at x=0x = 0?

    7. How are the minimizers of f+gf + g related to the proximal gradient map?

    8. State the rates of ISTA and FISTA with step 1/L1/L.

    9. Why is FISTA not monotone?

    10. Name the three ADMM updates for the lasso.

    Open the review →

    9. Interview angle #

    • "Why does ℓ1\ell_1 give exact zeros and ℓ2\ell_2 does not?" — The prox of ℓ1\ell_1 maps the whole interval [−t,t][-t, t] to 0; the prox of ℓ22\ell_2^2 only scales. Geometrically, the ℓ1\ell_1 ball has corners on the axes.
    • "What is a proximal operator?" — arg⁡min⁡ug(u)+12η∥u−v∥2\arg\min_u g(u) + \frac{1}{2\eta}\|u - v\|^2. A projection is the case of an indicator function.
    • "How would you solve a lasso with 10610^6 features?" — Coordinate descent (scikit-learn, glmnet) or FISTA, with a duality-gap stop; ADMM if the data are distributed or the penalty is ∥Dx∥1\|Dx\|_1.
    • "Why is FISTA faster, and what does it cost?" — Nesterov momentum: O(1/k2)O(1/k^2) instead of O(1/k)O(1/k) at the same cost per step, but it is not monotone.
    • "You need x≥0x \ge 0 in PyTorch. Simplest correct method?" — Projected gradient: clamp after each step.
    • "What does ρ\rho do in ADMM?" — It weights the agreement penalty. It changes the speed and the balance of primal and dual residuals, not the solution.

    10. Practice #

    The notebook for this lesson runs in Colab. Each exercise has a check cell and a folded solution.

    1. Soft thresholding and the prox of c2u2\tfrac c2 u^2; check them against brute-force 1D minimization.
    2. Projected gradient onto a box for bound-constrained least squares; compare with scipy.optimize.lsq_linear.
    3. ISTA and FISTA for the lasso on the diabetes data; compare with scikit-learn's Lasso (mind the 1/(2m)1/(2m) scaling), and plot F(xk)−F⋆F(x_k) - F^\star on a log scale.
    4. ADMM for the lasso with one Cholesky factorization, stopping on the primal and dual residuals.
    5. Check the lasso optimality (subgradient) conditions of a solution, coordinate by coordinate.

    11. Watch and read #

    The proximal operator, and projected gradient descent as a special case of proximal gradient.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The lasso, iterative shrinkage-thresholding, and the accelerated version.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    How to compute the prox of the ℓ1 norm, which gives soft thresholding.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Proximal gradient, its convergence analysis, and acceleration, with many examples.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    From dual methods to the augmented Lagrangian and ADMM, with applications.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play