Show Python
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize, linprogThis appendix collects reusable Python functions referenced in the main text. All code uses only the standard scientific Python stack (NumPy, SciPy, Matplotlib) available in the project pixi environment.
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize, linprogdef steepest_descent(f, grad_f, x0, alpha=None, tol=1e-6, max_iter=1000):
"""
Steepest descent with optional exact line search (quadratic) or fixed step.
Returns iterate path and final point.
"""
x = np.array(x0, dtype=float)
path = [x.copy()]
for _ in range(max_iter):
g = grad_f(x)
if np.linalg.norm(g) < tol:
break
if alpha is None:
# Backtracking line search (Armijo)
a = 1.0
c = 0.5
while f(x - a*g) > f(x) - c*a*(g@g):
a *= 0.5
else:
a = alpha
x = x - a*g
path.append(x.copy())
return np.array(path), xdef lagrange_example():
"""Maximize f(x,y) = x + 2y on the unit circle via Lagrange multiplier."""
from scipy.optimize import minimize
# Negate f to minimize
f = lambda x: -(x[0] + 2*x[1])
constraint = {'type': 'eq', 'fun': lambda x: x[0]**2 + x[1]**2 - 1}
res = minimize(f, [0.5, 0.5], constraints=[constraint], method='SLSQP')
x_opt = res.x
lam = -res.jac @ np.linalg.pinv(2*x_opt.reshape(1,-1)) # approx multiplier
return x_opt, lam[0]def lp_simplex_example():
"""
Solve min c^T x s.t. A_ub x <= b_ub, x >= 0
using scipy.optimize.linprog (simplex or interior point).
"""
c = [-1, -1.5] # minimize negative of x1 + 1.5*x2
A_ub = [[1, 1], # x1 + x2 <= 4
[1, 3]] # x1 + 3*x2 <= 6
b_ub = [4, 6]
res = linprog(c, A_ub=A_ub, b_ub=b_ub,
bounds=[(0, None), (0, None)],
method='highs')
return res.x, -res.fun # optimal point, optimal valuedef adam(grad_f, x0, lr=0.001, beta1=0.9, beta2=0.999,
eps=1e-8, n_iter=1000):
"""Adam optimizer for stochastic gradient descent."""
x = np.array(x0, dtype=float)
m, v = np.zeros_like(x), np.zeros_like(x)
path = [x.copy()]
for t in range(1, n_iter+1):
g = grad_f(x)
m = beta1*m + (1-beta1)*g
v = beta2*v + (1-beta2)*g**2
mh = m / (1 - beta1**t)
vh = v / (1 - beta2**t)
x = x - lr * mh / (np.sqrt(vh) + eps)
path.append(x.copy())
return np.array(path), x