diff --git a/hw1-conjugate-gradient/optimizer.py b/hw1-conjugate-gradient/optimizer.py index 5b9aa27e..3282633b 100644 --- a/hw1-conjugate-gradient/optimizer.py +++ b/hw1-conjugate-gradient/optimizer.py @@ -1,57 +1,71 @@ import numpy as np import matplotlib.pyplot as plt +from matplotlib import cm from mpl_toolkits.mplot3d import Axes3D import scipy.optimize +# Global variables (in capital letters) +# Initial guess to minimizer +GUESS = np.array([4,4]) + +# This array will contain the steps of the minimizer on its way to the minimum +STEPS = GUESS.reshape(-1,2) + +# This function fills the STEPS array, and is used as input to scipy.optimize.minimize def my_callback(xk): - mystring = str(xk[0]) + "\t" + str(xk[1]) + "\n" - with open("minimize_steps.txt", "a") as myfile: - myfile.write(mystring) + global STEPS + STEPS = np.vstack((STEPS, np.array(xk))) -def find_minimum(func): - result = scipy.optimize.minimize(func, x0 = np.array([4.0, 4.0]), method='BFGS', callback=my_callback) +# This function returns the minimum value of the function func given as input +# The second input is the initial guess of the minimum +def find_minimum(func, guess): + result = scipy.optimize.minimize(func, x0 = guess, method='BFGS', callback=my_callback) return result.x -# This function implements S(x) given in the exercise sheet +# This function implements S(x) as given in the exercise sheet def quadratic_function(x): # create column vector of input array x.reshape(-1, 1) # create matrix and vector coefficients of S(x) given in exercise sheet mat = np.array([[4, 0], [1, 3]]) vec = np.array([0, 1]).transpose() # return S(x) return (x.transpose() @ mat) @ x - x.transpose() @ vec -find_minimum(quadratic_function) - - +# This function plots the S(x) surface and includes the path taken by the minimizer def plotting(): - fig = plt.figure() + fig = plt.figure(figsize=(14,8)) axe = fig.add_subplot(111, projection="3d") num_of_points = 100 xmax = ymax = -10 xmin = ymin = 10 X, Y = np.meshgrid(np.linspace(xmin,xmax,num_of_points), np.linspace(ymin,ymax,num_of_points)) Z = np.zeros_like(X) for i in range(0,num_of_points): for j in range(0, num_of_points): Z[i,j] = quadratic_function( np.array([X[i,j], Y[i,j]]) ) - axe.plot_surface(X, Y, Z) - #axe.view_init(orientation=30) - #axe.contourf(X,Y,Z) + sp = axe.plot_surface(X, Y, Z, cmap=cm.coolwarm) + axe.view_init(60, 100) + fig.colorbar(sp) - step = np.loadtxt("minimize_steps.txt") - step_value = np.zeros(step.shape[0]) - for i in range(0, step.shape[0]): - step_value[i] = quadratic_function( np.array([step[i, 0], step[i, 1]]) ) - axe.plot(step[:,0], step[:,1], step_value, 'r*--') - #axe.plot(step[:,0], step[:,1], 'r*--') + step_value = np.zeros(STEPS.shape[0]) + for i in range(0, STEPS.shape[0]): + step_value[i] = quadratic_function( np.array([STEPS[i, 0], STEPS[i, 1]]) ) + axe.plot(STEPS[:,0], STEPS[:,1], step_value, 'r*--') + axe.set_xlabel('x', fontsize=15) + axe.set_ylabel('y', fontsize=15) + axe.set_zlabel(' S(x,y)', fontsize=15) + axe.zaxis.set_rotate_label(False) + plt.savefig("plot.png") plt.show() +result = find_minimum(quadratic_function, GUESS) +print("The (approximated) minimum value is found at position (x,y) = ", result) +print("The (approximated) minimum value is ", quadratic_function(result)) plotting()