import numpy as np
+# Calculate function value in point x
def function_g(x, H, b, c):
return -b.T.dot(x) + 0.5 * x.T.dot(H.dot(x)) + (1/12) * x.T.dot(_C(x,c).dot(x))
+# Create matrix C(x)
def _C(x, c):
A = np.zeros( (len(c), len(c)) )
for i in xrange(0, len(c)):
A[i][i] = c[i]*(x[i])**2
return A
+# Calculate gradient of g in point x
def gradient_g(x, H, b, c):
return -b.T + 0.5 * H.dot(x) + 0.5 * H.T.dot(x) + (1/3) * x.T.dot(_C(x,c))
+# Calculate hessian of g in point x
def hessian_g(x, H, b, c):
return 0.5 * H.T + 0.5 * H + _C(x,c)
from enthought.mayavi import mlab
-from function import function_g, gradient_g
+from function import function_g, gradient_g, _C
import generate
import surf
import numpy as np
import matplotlib.pyplot as plt
+import time
from numpy.linalg import norm
def steepest_iter(x, alpha, grad_f):
return x - alpha * grad_f(x)
-H = generate.spdmatrix(2, 3)
-b = generate.vector(2, -1, 1)
-c = generate.vector(2, -3, 3)
+def optimal_step(x, H, b, c, grad_f):
+ pk = -grad_f(x)
+ Cpk = _C(pk, c)
+ Cxk = _C(x, c)
-alpha = 0.1
-xiter = np.array([0, 0])
+ coeff = [0] * 4
+
+ coeff[0] = (1.0/3.0) * pk.T.dot(Cpk.dot(pk))
+ coeff[1] = x.T.dot(Cpk.dot(pk))
+ coeff[2] = pk.T.dot(H.dot(pk)) + pk.T.dot(Cxk.dot(pk))
+ coeff[3] = (1.0/3.0) * pk.T.dot(Cxk.dot(x)) + pk.T.dot(H.dot(x)) - b.T.dot(pk)
+
+ roots = np.roots(coeff)
+
+ for a in roots:
+ if abs(a.imag) < 0.0000001:
+ return a.real
+
+ return 0.1
+
+#H = generate.spdmatrix(2, 3)
+#b = generate.vector(2, 0.01, 1)
+#c = generate.vector(2, 0.01, 3)
+
+H = np.array([ (2.06810668,-1.51172618), (-1.51172618, 3.95629853)])
+b = np.array([-0.09229406, 0.38657143])
+c = np.array([ 0.12659127, 2.42818636])
+
+xiter = np.array([1.5, 1.5])
x0_norm = norm(gradient_g(xiter, H, b, c))
-tolerance = 0.01
+tolerance = 0.001
relative_residual = norm(gradient_g(xiter, H, b, c)) / x0_norm
relative_residuals = []
function_values = []
-while relative_residual > tolerance:
+maxiter = 0
+
+while relative_residual > tolerance and maxiter < 100:
+ maxiter += 1
+
+ alpha = optimal_step(xiter, H, b, c, lambda x: gradient_g(x, H, b, c))
+
relative_residual = norm(gradient_g(xiter, H, b, c)) / x0_norm
relative_residuals.append(relative_residual)
function_values.append(function_g(xiter, H, b, c))
xiter = steepest_iter(xiter, alpha, lambda x: gradient_g(x, H, b, c))
+
z = function_g(xiter, H, b, c)
- p = mlab.points3d([xiter[0]], [xiter[1]], [z], scale_factor=0.05)
+ p = mlab.points3d([xiter[0]], [xiter[1]], [z], scale_factor=0.05,
+ color=(maxiter % 2, maxiter % 2, maxiter % 2))
+
print xiter
-X, Y, Z = surf.surf(H, b, c, xiter[0]-2, xiter[0]+2, xiter[1]-2, xiter[1]+2, -10, 3)
+X, Y, Z = surf.surf(H, b, c, xiter[0]-1, xiter[0]+1, xiter[1]-1, xiter[1]+1, -10, 3)
plt.figure(1)
ax = plt.subplot(211)