-
Notifications
You must be signed in to change notification settings - Fork 0
/
rosenbrock.py
executable file
·90 lines (68 loc) · 1.74 KB
/
rosenbrock.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize
A = 100
# Rosenbrock function.
def f(xy):
x, y = xy
return A * (y - x**2)**2 + (1 - x)**2
# Gradient.
def f_grad(xy):
x, y = xy
return np.array([
-4 * A * x * (y - x**2) - 2 * (1 - x),
2 * A * (y - x**2),
])
# Hessian.
def f_hessian(xy):
x, y = xy
return np.array([[
-4 * A * (y - x**2) + 8 * A * x**2 + 2,
-4 * A * x,
], [
-4 * A * x,
2 * A,
]])
# Exact minimum.
exact_xy = (1, 1)
# Initial guess.
init_xy = np.array([-0.3, 1.5])
def newton(xy, maxiter=10):
traj = [xy]
for i in range(maxiter):
dxy = np.linalg.solve(f_hessian(xy), -f_grad(xy))
xy = xy + dxy
traj.append(xy)
return xy, traj
def bfgs(xy, maxiter=None):
xy, traj = scipy.optimize.fmin_bfgs(
f,
x0=init_xy,
maxiter=maxiter,
fprime=f_grad,
disp=False, # No convergence message.
retall=True, # Return trajectory.
)
return xy, traj
xy, traj = newton(init_xy)
#xy, traj = bfgs(init_xy)
fig, ax = plt.subplots()
# Contours of logarithm of f(x,y).
xone = np.linspace(-2, 2, 256)
yone = np.linspace(-1, 3, 256)
xx, yy = np.meshgrid(xone, yone)
zz = np.log10(f((xx, yy)))
levels = np.linspace(-3, 3, 25)
contour = ax.contour(xx, yy, zz, levels=levels, cmap='jet', linewidths=0.75)
cbar = fig.colorbar(contour, label=r'$\log_{10} f$')
ax.set_xlabel('x')
ax.set_ylabel('y')
# Trajectory.
ax.plot(*np.array(traj).T, c='k', marker='.')
# Initial guess.
ax.scatter(*init_xy, c='b', zorder=5, label='start')
# Exact minimum.
ax.scatter(*exact_xy, c='r', zorder=5, label='exact')
fig.legend(ncol=2)
fig.savefig('rosenbrock.pdf')