-1732.947060918
-0.5
--
```python
#
# Author: Michael D. Johnson
# Date: 13 March 2015
# Email: michael.d.johnson@ucsf.edu
#
import numpy as np
# define the value of the target function
def f(x):
return x**2 + x - 2
# set the initial guess for the variables
def x0():
return [1,2,3,4]
# apply a method of steepest descent to find the minimum value of the function
# returns an array with the best values found and also returns the number of iterations
# required to find the minima.
def steepest_descent(f=f, x0=x0(), epsilon=1e-24, maxiters=100):
"""
Applies a method of steepest descent to find the minimum value of the function.
f: The target function to minimize (default is f(x) = x^2 + x - 2).
x0: Initial guess for the variables (default is [1,2,3,4]).
epsilon: Tolerance to be used in determining whether an acceptable minimum value has been found.
maxiters: Maximum number of iterations allowed (default is 100).
Returns: A list containing the best values found and also returns the number of iterations required to find the minima.
"""
# set up the variables needed for the algorithm
x = x0()
H = np.zeros((len(x), len(x)))
d = None
i = 0
while True:
i += 1
# evaluate the function at the current point
fval = f(x)
if fval < epsilon:
break
# calculate the gradient of the function at the current point
g = np.zeros((len(x),))
for j in range(len(x)):
g[j] = (f(np.append(x, -1)) - f(np.delete(x, j)))/(2*(-1)**j)
# update the Hessian matrix if it has been calculated previously
if d is not None:
H += np.outer(g,g).reshape((len(x),len(x)))/i
# update the direction vector
if d is None:
d = -g
else:
H_inv = np.linalg.pinv(H)
g = f(x) - np.outer(d, x).reshape((1, len(x)))
d = np.dot(H_inv, g)
# update the variables
x -= d
return x, i
# calculate the inverse Hessian matrix using a limited memory algorithm
def invHessian(H):
"""
Calculates the inverse Hessian matrix using a limited memory algorithm.
Returns: The inverse Hessian matrix.
"""
# get the dimensions of the Hessian matrix
n = len(H)
# initialize the variables needed for the limited memory algorithm
L = np.eye(n)
r = np.zeros((n,1))
for k in range(5): # limited number of iterations
L_inv = np.linalg.pinv(L)
r = np.dot(L_inv, np.outer(H, r)) + np.outer(L, np.eye(n))
L = np.dot(L, L_inv)
return L
# calculate the inverse Hessian matrix and then use it to find a minimum value of the function
def min_func_with_Hessian(f=f, x0=x0(), epsilon=1e-24, maxiters=100):
"""
Calculates the inverse Hessian matrix and then uses it to find a minimum value of the function.
f: The target function to minimize (default is f(x) = x^2 + x - 2).
x0: Initial guess for the variables (default is [1,2,3,4]).
epsilon: Tolerance to be used in determining whether an acceptable minimum value has been found.
maxiters: Maximum number of iterations allowed (default is 100).
Returns: A list containing the best values found and also returns the number of iterations required to find the minima.
"""
# evaluate the function at the initial point
fval = f(x0())
# calculate the Hessian matrix
H = np.zeros((len(x0()), len(x0())))
for j in range(len(x0())):
for i in range(j+1, len(x0())):
x = x0()
x[i] = -1
H[j][i] = (f(np.append(x, -1)) - f(np.delete(x, i)))/(2*(-1)**j)
H = np.dot(H.T, H)/len(x0())
# calculate the inverse Hessian matrix
L = invHessian(H)
# apply a method of steepest descent to find the minimum value of the function
x, i = steepest_descent(f=f, x0=x0(), epsilon=epsilon, maxiters=maxiters)
return x, i
# calculate the inverse Hessian matrix and then use it to find a global minimum value of the function
def min_func_with_Hessian_global(f=f, x0=x0(), epsilon=1e-24, maxiters=100):
"""
Calculates the inverse Hessian matrix and then uses it to find a global minimum value of the function.
f: The target function to minimize (default is f(x) = x^2 + x - 2).
x0: Initial guess for the variables (default is [1,2,3,4]).
epsilon: Tolerance to be used in determining whether an acceptable minimum value has been found.
maxiters: Maximum number of iterations allowed (default is 100).
Returns: A list containing the best values found and also returns the number of iterations required to find the minima.
"""
# evaluate the function at the initial point
fval = f(x0())
# calculate the Hessian matrix
H = np.zeros((len(x0()), len(x0())))
for j in range(len(x0())):
for i in range(j+1, len(x0())):
x = x0()
x[i] = -1
H[j][i] = (f(np.append(x, -1)) - f(np.delete(x, i)))/(2*(-1)**j)
H = np.dot(H.T, H)/len(x0())
# calculate the inverse Hessian matrix
L = invHessian(H)
# apply a method of steepest descent to find the minimum value of the function
x, i = steepest_descent(f=f, x0=x0(), epsilon=epsilon, maxiters=maxiters)
# check if this is the global minimum
while True:
i += 1
x, fval = min_func_with_Hessian(f=f, x0=x, epsilon=epsilon/i, maxiters=maxiters)
if fval > i*epsilon/i:
break
return x, i
```