Skip to main content
© 2026 ePowerAI — free, open courseware. No login required.
CoursesContact
ePOWERAI
CoursesContact
Week 3: KKT and Sensitivity
Adv. Optimization

Duality & KKT

  1. 01Week 1: Optimality Conditions Revisited
  2. 02Week 2: Lagrangian Duality in Depth
  3. 03Week 3: KKT and Sensitivity

Cones & IPMs

  1. 04Week 4: LP, QP, and Conic Form
  2. 05Week 5: Semidefinite Programming
  3. 06Week 6: Interior-Point Methods
  4. 07Week 7: Proximal Methods and ADMM

Second-order & scale

  1. 08Week 8: Newton and Quasi-Newton
  2. 09Week 9: Variance Reduction
  3. 10Week 10: Large-Batch and Distributed Training

Geometry & training science

  1. 11Week 11: Automatic Differentiation
  2. 12Week 12: Sharpness and SAM
  3. 13Week 13: Landscapes and Implicit Bias

Capstone

  1. 14Week 14: Capstone — Structure Meets Scale
Week 03· Adv. Optimization· Duality & KKT10 min read

Week 3: KKT and Sensitivity

Learning Outcomes
  • Write the four parts of the KKTKarush–Kuhn–Tucker (optimality conditions) system: stationarity, primal feasibility, dual feasibility, complementary slackness
  • Check KKT conditions on a small QP by hand
  • Interpret optimal dual variables as shadows prices — the sensitivity of the optimal value to constraint perturbations
Prerequisites

Background: Week 1 (stationarity, constraint qualifications) and Week 2 (Lagrangian, dual function, weak/strong duality, Slater). KKT is where these pieces lock into one system.

Later weeks: KKT is the grammar of constrained optimisation — it recurs in cone programs (Weeks 4–6), SVM duals (Week 12 context), and the capstone decision flow (Week 14).

  • Also see: Optimization Week 11: Constraints: Projections and Penalties — the practical constraint handling this theory underpins.

The KKT system#

feasible set F ∇f ∇h (active) stationarity: ∇f + Σλᵢ∇hᵢ = 0 primal + dual feasibility complementary slackness: λᵢhᵢ = 0 KKT: gradient balance at the boundary of the feasible set inactive constraints (slack) carry zero multiplier — they do not bind

KKT says that at a constrained optimum the objective gradient is a non-negative combination of the active constraint gradients. Inactive constraints carry zero multiplier — that is complementary slackness, and it is what makes the system solvable.

The Karush–Kuhn–Tucker (KKTKarush–Kuhn–Tucker (optimality conditions)) conditions are the generalisation of "set the derivative to zero" to constrained problems. For the primal

min⁡xf(x)s.t.gi(x)=0,i=1,…,mhj(x)≤0,j=1,…,p\begin{aligned} \min_x &\quad f(x) \\ \text{s.t.} &\quad g_i(x) = 0, \quad i = 1, \ldots, m \\ &\quad h_j(x) \leq 0, \quad j = 1, \ldots, p \end{aligned}xmin​s.t.​f(x)gi​(x)=0,i=1,…,mhj​(x)≤0,j=1,…,p​

with differentiable f,gi,hjf, g_i, h_jf,gi​,hj​, the KKT conditions are:

  1. Stationarity: ∇xL(x,λ,ν)=0\nabla_x \mathcal{L}(x, \lambda, \nu) = 0∇x​L(x,λ,ν)=0, i.e., ∇f(x)+∑i=1mνi∇gi(x)+∑j=1pλj∇hj(x)=0\nabla f(x) + \sum_{i=1}^m \nu_i \nabla g_i(x) + \sum_{j=1}^p \lambda_j \nabla h_j(x) = 0∇f(x)+∑i=1m​νi​∇gi​(x)+∑j=1p​λj​∇hj​(x)=0

  2. Primal feasibility: gi(x)=0  ∀ig_i(x) = 0 \;\forall igi​(x)=0∀i, hj(x)≤0  ∀jh_j(x) \leq 0 \;\forall jhj​(x)≤0∀j

  3. Dual feasibility: λj≥0  ∀j\lambda_j \geq 0 \;\forall jλj​≥0∀j (inequality multipliers nonnegative; equality multipliers νi\nu_iνi​ unrestricted)

  4. Complementary slackness: λj hj(x)=0  ∀j\lambda_j \, h_j(x) = 0 \;\forall jλj​hj​(x)=0∀j

Together, these four conditions are necessary for a local minimum when a constraint qualification holds, and sufficient under convexity (if fff and hjh_jhj​ are convex, gig_igi​ affine, then any KKT point is a global minimum).

Why four parts? Each plays a distinct role:

  • Stationarity says the gradient of the objective is balanced by a linear combination of constraint gradients — constraints "push back" against the objective.
  • Primal feasibility says the point must actually satisfy the constraints.
  • Dual feasibility locks the sign of inequality multipliers (penalties can only push inward from the boundary).
  • Complementary slackness says at most one of λj\lambda_jλj​ and hj(x)h_j(x)hj​(x) can be nonzero: if a constraint is slack (hj(x)<0h_j(x) < 0hj​(x)<0), its multiplier must be zero; if the multiplier is positive, the constraint must be active (hj(x)=0h_j(x) = 0hj​(x)=0).

Complementary slackness#

The product λjhj(x)=0\lambda_j h_j(x) = 0λj​hj​(x)=0 encodes the logic: an inactive constraint does not participate in stationarity. If hj(x)<0h_j(x) < 0hj​(x)<0, then λj=0\lambda_j = 0λj​=0 and λj∇hj(x)\lambda_j \nabla h_j(x)λj​∇hj​(x) vanishes from the stationarity equation. The constraint is invisible to optimality — which makes intuitive sense: if you are inside the feasible region away from the boundary, the wall does not affect where you stand.

Conversely, if λj>0\lambda_j > 0λj​>0, then hj(x)=0h_j(x) = 0hj​(x)=0 — the constraint is binding. The positive multiplier indicates the constraint is "pushing back" against the objective: relaxing it would allow the objective to decrease.

Worked numeric example. Consider

min⁡x  x12+x22s.t.x1+x2≥2,  x1≥0\min_x \; x_1^2 + x_2^2 \quad \text{s.t.} \quad x_1 + x_2 \geq 2, \; x_1 \geq 0minx​x12​+x22​s.t.x1​+x2​≥2,x1​≥0

Rewrite in standard form: h1(x)=2−x1−x2≤0,h2(x)=−x1≤0h_1(x) = 2 - x_1 - x_2 \leq 0, \quad h_2(x) = -x_1 \leq 0h1​(x)=2−x1​−x2​≤0,h2​(x)=−x1​≤0

Lagrangian: L=x12+x22+λ1(2−x1−x2)+λ2(−x1)\mathcal{L} = x_1^2 + x_2^2 + \lambda_1(2 - x_1 - x_2) + \lambda_2(-x_1)L=x12​+x22​+λ1​(2−x1​−x2​)+λ2​(−x1​).

Stationarity: ∂L∂x1=2x1−λ1−λ2=0\frac{\partial \mathcal{L}}{\partial x_1} = 2x_1 - \lambda_1 - \lambda_2 = 0∂x1​∂L​=2x1​−λ1​−λ2​=0 ∂L∂x2=2x2−λ1=0  ⇒  x2=λ1/2\frac{\partial \mathcal{L}}{\partial x_2} = 2x_2 - \lambda_1 = 0 \;\Rightarrow\; x_2 = \lambda_1/2∂x2​∂L​=2x2​−λ1​=0⇒x2​=λ1​/2

From the geometry (smallest circle touching the line x1+x2=2x_1 + x_2 = 2x1​+x2​=2 in the right half-plane), the solution is (1,1)(1, 1)(1,1). At this point:

  • h1(1,1)=0h_1(1,1) = 0h1​(1,1)=0 (active), so λ1≥0\lambda_1 \geq 0λ1​≥0
  • h2(1,1)=−1<0h_2(1,1) = -1 < 0h2​(1,1)=−1<0 (inactive), so complementary slackness forces λ2=0\lambda_2 = 0λ2​=0

With λ2=0\lambda_2 = 0λ2​=0, stationarity gives 2x1=λ12x_1 = \lambda_12x1​=λ1​, so λ1=2\lambda_1 = 2λ1​=2. The multiplier λ1=2\lambda_1 = 2λ1​=2 is positive, confirming h1h_1h1​ is binding. All KKT conditions satisfied.

Worked QP#

A quadratic program (QP) exposes all four KKT parts cleanly:

min⁡x12xTQx+cTxs.t.Ax≤b\begin{aligned} \min_x &\quad \tfrac{1}{2}x^T Q x + c^T x \\ \text{s.t.} &\quad Ax \leq b \end{aligned}xmin​s.t.​21​xTQx+cTxAx≤b​

with Q⪰0Q \succeq 0Q⪰0 (convex QP). The Lagrangian:

L(x,λ)=12xTQx+cTx+λT(Ax−b)\mathcal{L}(x, \lambda) = \tfrac{1}{2}x^T Q x + c^T x + \lambda^T(Ax - b)L(x,λ)=21​xTQx+cTx+λT(Ax−b)

Stationarity: Qx+c+ATλ=0  ⇒  x=−Q−1(c+ATλ)Qx + c + A^T\lambda = 0 \;\Rightarrow\; x = -Q^{-1}(c + A^T\lambda)Qx+c+ATλ=0⇒x=−Q−1(c+ATλ) (if Q≻0Q \succ 0Q≻0).

The KKT conditions reduce to solving for (x,λ)(x, \lambda)(x,λ): Qx+ATλ=−c,Ax≤b,λ≥0,λj(ajTx−bj)=0  ∀jQx + A^T\lambda = -c, \quad Ax \leq b, \quad \lambda \geq 0, \quad \lambda_j(a_j^T x - b_j) = 0 \;\forall jQx+ATλ=−c,Ax≤b,λ≥0,λj​(ajT​x−bj​)=0∀j

This is a linear complementarity problem (LCP) — a mixed system of equations and inequalities. IPM solvers (Week 6) solve essentially this system for successively relaxed complementarity.

Worked 2D QP:

min⁡x,y  12(x2+y2)s.t.x+y≤3,  x≥0\min_{x,y} \; \tfrac{1}{2}(x^2 + y^2) \quad \text{s.t.} \quad x + y \leq 3,\; x \geq 0minx,y​21​(x2+y2)s.t.x+y≤3,x≥0

In standard form: h1=x+y−3≤0h_1 = x + y - 3 \leq 0h1​=x+y−3≤0, h2=−x≤0h_2 = -x \leq 0h2​=−x≤0 (inequality only, no equalities). Q=IQ = IQ=I, c=0c = 0c=0.

At the unconstrained optimum (0,0)(0,0)(0,0), the constraint x≥0x \geq 0x≥0 is active, x+y≤3x + y \leq 3x+y≤3 is slack (0+0−3=−3<00 + 0 - 3 = -3 < 00+0−3=−3<0). Complementary slackness: λ2>0\lambda_2 > 0λ2​>0 possible, λ1=0\lambda_1 = 0λ1​=0 since h1(x,y)<0h_1(x,y) < 0h1​(x,y)<0.

Stationarity: x+λ1∂h1∂x+λ2∂h2∂x=x+λ1−λ2=0x + \lambda_1\frac{\partial h_1}{\partial x} + \lambda_2\frac{\partial h_2}{\partial x} = x + \lambda_1 - \lambda_2 = 0x+λ1​∂x∂h1​​+λ2​∂x∂h2​​=x+λ1​−λ2​=0, and similarly y+λ1=0y + \lambda_1 = 0y+λ1​=0.

With λ1=0\lambda_1 = 0λ1​=0: x−λ2=0x - \lambda_2 = 0x−λ2​=0, y=0y = 0y=0. At (0,0)(0,0)(0,0), λ2=0\lambda_2 = 0λ2​=0 — all multipliers zero. The constraint h2=−xh_2 = -xh2​=−x is active at (0,0)(0,0)(0,0) (that is exactly x=0x = 0x=0) but has a degenerate zero multiplier: the objective's gradient already points away from the boundary, so the constraint does not participate in stationarity. The unconstrained optimum is feasible, so it is the constrained optimum — complementary slackness is satisfied, but this is degeneracy (λ2=0\lambda_2 = 0λ2​=0 with h2=0h_2 = 0h2​=0), not a slack constraint.

Sensitivity / shadow prices#

Interpretation. The optimal dual variable λj∗\lambda_j^*λj∗​ equals the rate of change of the optimal value when the jjj-th constraint bound is perturbed:

∂p∗∂bj≈−λj∗(for Ax≤b, standard form ajTx−bj≤0)\frac{\partial p^*}{\partial b_j} \approx -\lambda_j^* \quad \text{(for $Ax \leq b$, standard form $a_j^T x - b_j \leq 0$)}∂bj​∂p∗​≈−λj∗​(for Ax≤b, standard form ajT​x−bj​≤0)

More precisely, for the perturbed problem min⁡{f(x)∣hj(x)≤uj}\min \{ f(x) \mid h_j(x) \leq u_j \}min{f(x)∣hj​(x)≤uj​}, under suitable conditions:

∂p∗(u)∂uj∣u=0=λj∗\frac{\partial p^*(u)}{\partial u_j}\bigg|_{u=0} = \lambda_j^*∂uj​∂p∗(u)​​u=0​=λj∗​

The sign convention matters: for hj(x)≤0h_j(x) \leq 0hj​(x)≤0 in the standard form, tightening the constraint (making uju_juj​ more negative) increases the optimal value, so the derivative is positive and equals λj∗\lambda_j^*λj∗​.

Shadow price intuition. If λj∗=0\lambda_j^* = 0λj∗​=0, the jjj-th constraint is not binding — relaxing or tightening it by a small amount has no first-order effect on the optimum. If λj∗\lambda_j^*λj∗​ is large, the constraint is expensive: the optimal value is highly sensitive to that constraint's location. In engineering design, shadow prices tell you where to spend resources: relax the constraint with the largest multiplier for the biggest payoff.

Worked example — Factory production.

A simplified production problem: min⁡  −3x1−2x2\min \; -3x_1 - 2x_2min−3x1​−2x2​ (maximise profit) subject to x1+2x2≤8x_1 + 2x_2 \leq 8x1​+2x2​≤8 (labour), 2x1+x2≤62x_1 + x_2 \leq 62x1​+x2​≤6 (materials), x1,x2≥0x_1, x_2 \geq 0x1​,x2​≥0.

Solving: the optimum is at x1=4/3≈1.33x_1 = 4/3 \approx 1.33x1​=4/3≈1.33, x2=10/3≈3.33x_2 = 10/3 \approx 3.33x2​=10/3≈3.33. Both labour and materials constraints are active. Solving the KKT system gives the dual variables λ1∗=1/3≈0.33\lambda_1^* = 1/3 \approx 0.33λ1∗​=1/3≈0.33 (labour), λ2∗=4/3≈1.33\lambda_2^* = 4/3 \approx 1.33λ2∗​=4/3≈1.33 (materials). Interpretation: one extra unit of labour would increase profit by about \0.33;oneextraunitofmaterialsbyabout; one extra unit of materials by about ;oneextraunitofmaterialsbyabout$1.33$. The materials constraint is the bottleneck.

What can go wrong#

KKT is a powerful tool but has sharp edges:

  1. CQ failure. Without a constraint qualification, KKT may not hold at a local minimum. The x2≤0x^2 \leq 0x2≤0 example from Week 1 illustrates this: the minimum exists but no finite multiplier satisfies stationarity because ∇h(x∗)=0\nabla h(x^*) = 0∇h(x∗)=0.

  2. Nonconvex KKT points. KKT conditions are necessary but not sufficient for nonconvex problems. A point can satisfy all four KKT conditions and still be a saddle or a local maximum. Always check second-order conditions or problem structure.

  3. Multiple KKT solutions. Nonconvex problems can have many KKT points — each corresponds to a local minimum, maximum, or saddle. Numerical solvers find a KKT point; which one depends on initialisation.

  4. Degeneracy. When active constraint gradients are nearly linearly dependent, the LICQ is barely satisfied, and the KKT system becomes ill-conditioned. Solvers report this as "numerical difficulties" or "near-degeneracy."

Knowledge Check#

Exercise · Fill in the blank

Complementary slackness requires that for each inequality constraint j, the product λⱼ · hⱼ(x*) equals ____.

Question 1 of 3

Which KKT condition is violated if λⱼ = −2 for an inequality constraint hⱼ(x) ≤ 0?

Stationarity
Primal feasibility
Dual feasibility
Complementary slackness

Browser lab#

Consider the small QP: min⁡x,y  12(x2+y2)\min_{x,y} \; \tfrac{1}{2}(x^2 + y^2)minx,y​21​(x2+y2) subject to x+y≥2x + y \geq 2x+y≥2, x≥0x \geq 0x≥0. Compute the KKT residual at candidate points (x,y,λ1,λ2)(x, y, \lambda_1, \lambda_2)(x,y,λ1​,λ2​) and verify the true KKT point (1,1,1,0)(1, 1, 1, 0)(1,1,1,0).

python · runs in browser
import numpy as np

def kkt_residual(x, y, lam1, lam2):
    """Compute violations of the four KKT conditions for:
       min 0.5*(x^2 + y^2)  s.t.  2 - x - y <= 0,  -x <= 0
       Lagrangian: L = 0.5*(x^2 + y^2) + lam1*(2 - x - y) + lam2*(-x)
    """
    # Stationarity
    stat_x = x - lam1 - lam2
    stat_y = y - lam1
    stat = np.sqrt(stat_x**2 + stat_y**2)

    # Primal feasibility (negative means satisfied for <= 0)
    h1 = 2 - x - y
    h2 = -x
    primal_viol = max(0, h1) + max(0, h2)

    # Dual feasibility
    dual_viol = max(0, -lam1) + max(0, -lam2)

    # Complementary slackness
    comp_viol = abs(lam1 * h1) + abs(lam2 * h2)

    return {
        "stationarity": stat,
        "primal_violation": primal_viol,
        "dual_violation": dual_viol,
        "complementarity_violation": comp_viol,
        "total": stat + primal_viol + dual_viol + comp_viol
    }

# Test candidate points
candidates = [
    ("(0, 0) [infeasible]", 0.0, 0.0, 0.0, 0.0),
    ("(1, 1) [KKT]", 1.0, 1.0, 1.0, 0.0),
    ("(2, 0) [feasible, non-optimal]", 2.0, 0.0, 1.0, 0.0),
    ("(1, 1) [wrong lam]", 1.0, 1.0, 0.0, 0.0),
    ("(0.5, 1.5) [feasible]", 0.5, 1.5, 0.5, 0.0),
]

print(f"{'Point':<28s} {'stat':>8s} {'primal':>8s} {'dual':>8s} {'comp':>8s} {'total':>8s}")
print("-" * 70)
for name, x, y, l1, l2 in candidates:
    res = kkt_residual(x, y, l1, l2)
    print(f"{name:<28s} {res['stationarity']:8.4f} {res['primal_violation']:8.4f} "
          f"{res['dual_violation']:8.4f} {res['complementarity_violation']:8.4f} "
          f"{res['total']:8.4f}")

# Verify KKT point
print(f"\nTrue KKT point: (1, 1) with lam = (1, 0)")
true_res = kkt_residual(1, 1, 1, 0)
print(f"Total KKT residual at true optimum: {true_res['total']:.2e}")

print("Notice: the total KKT residual is exactly 0.00e+00 at (1,1) with λ = (1,0), and ≥ 1.0 at every other test point.")

Key takeaways#

  • The KKT system is four conditions: stationarity, primal feasibility, dual feasibility, and complementary slackness.
  • Complementary slackness λjhj(x)=0\lambda_j h_j(x) = 0λj​hj​(x)=0 says an inactive constraint does not participate in stationarity; a positive multiplier means the constraint binds.
  • For a convex problem with a constraint qualification, KKT is necessary and sufficient for global optimality.
  • The optimal multiplier is a shadow price: ∂p∗/∂uj=λj∗\partial p^* / \partial u_j = \lambda_j^*∂p∗/∂uj​=λj∗​, the marginal value of relaxing that constraint.
  • A zero multiplier means the constraint has no first-order effect; the largest multiplier marks the bottleneck where resources should go.
  • KKT has sharp edges — a failing CQ, nonconvex KKT points, multiple solutions, and degeneracy all break naive use.

Further reading#

  • Stephen Boyd & Lieven Vandenberghe, Convex Optimization (Cambridge University Press, 2004) — the KKT conditions and the sensitivity/shadow-price interpretation.
  • Jorge Nocedal & Stephen Wright, Numerical Optimization (2nd ed., Springer, 2006) — the theory of constrained optimisation, including degeneracy.
  • Dimitri P. Bertsekas, Nonlinear Programming (3rd ed., Athena Scientific, 2016) — the fullest treatment of constraint qualifications.

Reading is free. PDF and ePub unlock with the newsletter. Join once and every lesson opens in this browser.

← Previous
Week 2: Lagrangian Duality in Depth
Next →
Week 4: LP, QP, and Conic Form
On this page
  • The KKT system
  • Complementary slackness
  • Worked QP
  • Sensitivity / shadow prices
  • What can go wrong
  • Knowledge Check
  • Browser lab
  • Key takeaways
  • Further reading