1import numpy as np
2import numpy.linalg as npla
3import scipy.optimize as spopt
4
5
6def fun(x):
7 '''
8 Funcao de Rosenbrock
9 '''
10 return sum(100.*(x[1:]-x[:-1]**2.)**2. + (1.-x[:-1])**2.)
11
12
13def grad(x):
14 xm = x[1:-1]
15 xm_m1 = x[:-2]
16 xm_p1 = x[2:]
17 der = np.zeros_like(x)
18 der[1:-1] = 200*(xm-xm_m1**2) - 400*(xm_p1 - xm**2)*xm - 2*(1-xm)
19 der[0] = -400*x[0]*(x[1]-x[0]**2) - 2*(1-x[0])
20 der[-1] = 200*(x[-1]-x[-2]**2)
21
22 return der
23
24def hess(x):
25 x = np.asarray(x)
26 H = np.diag(-400*x[:-1],1) - np.diag(400*x[:-1],-1)
27 diagonal = np.zeros_like(x)
28 diagonal[0] = 1200*x[0]**2-400*x[1]+2
29 diagonal[-1] = 200
30 diagonal[1:-1] = 202 + 1200*x[1:-1]**2 - 400*x[2:]
31 H = H + np.diag(diagonal)
32
33 return H
34
35
36n = 2
37
38
39maxiter = 100000
40
41tol = 1e-10
42
43
44x = np.zeros(n)
45
46for k in range(maxiter):
47
48
49 d = npla.solve (hess(x),-grad(x))
50
51
52 alpha = spopt.line_search(fun, grad, x, d)[0]
53
54
55 x = x + alpha * d
56
57 nad = npla.norm(alpha * d)
58 nfun = npla.norm(fun(x))
59
60 print(f"{k+1}: {alpha:1.2e} {nad:1.2e} {nfun:1.2e}")
61
62 if ((nfun < tol) or np.isnan(nfun)):
63 break