#! /usr/bin/env python3 # def ex51 ( ): #*****************************************************************************80 # ## ex51, lab 5 exercise 1. # # Discussion: # # Gradient descent for a function of 1 variable. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 18 April 2019 # # Author: # # John Burkardt # import matplotlib.pyplot as plt import numpy as np import platform print ( '' ) print ( 'ex51:' ) print ( ' Python version: %s' % ( platform.python_version ( ) ) ) print ( ' Seek minimizer of a scalar function f(x).' ) # # Plot f # xvec = np.linspace ( -2.0, 2.0, 101 ) fxvec = f ( xvec ) plt.plot ( xvec, fxvec, linewidth = 3 ) plt.grid ( True ) plt.xlabel ( '<-- X -->' ) plt.ylabel ( '<-- F(X) -->' ) plt.title ( 'Minimize F(X)', fontsize = 16 ) filename = 'ex51_f.png' plt.savefig ( filename ) print ( '' ) print ( ' Graphics saved in "%s"' % ( filename ) ) plt.show ( ) plt.clf ( ) # # Choose a random initial guess. # x = - 2.0 + 4.0 * np.random.rand ( 1 ) x0 = x # # Choose a small learning rate. # r = 0.05 # # Choose a small tolerance for the derivative. # tol = 0.001 # # Loop. # step = 0 while ( tol < abs ( fp ( x ) ) ): step = step + 1 x = x - r * fp ( x ) print ( ' %d %g %g %g' % ( step, x, f ( x ), fp ( x ) ) ) # # Plot f with minimizer # xvec = np.linspace ( -2.0, 2.0, 101 ) fxvec = f ( xvec ) plt.plot ( xvec, fxvec, linewidth = 3 ) plt.plot ( [ x0, x0 ], [ 0, f ( x0 ) ], 'b', linewidth = 3) plt.plot ( x0, 0.0, 'bo', markersize = 10 ) plt.plot ( x0, f ( x0 ), 'bo', markersize = 10 ) plt.plot ( [ x, x ], [ 0, f ( x ) ], 'r', linewidth = 3) plt.plot ( x, 0.0, 'ro', markersize = 10 ) plt.plot ( x, f ( x ), 'ro', markersize = 10 ) plt.grid ( True ) plt.xlabel ( '<-- X -->' ) plt.ylabel ( '<-- F(X) -->' ) plt.title ( 'Initial point in blue, minimizer in red', fontsize = 16 ) filename = 'ex51_minimizer.png' plt.savefig ( filename ) print ( '' ) print ( ' Graphics saved in "%s"' % ( filename ) ) plt.show ( ) plt.clf ( ) # # Terminate. # print ( '' ) print ( 'ex51:' ) print ( ' Normal end of execution.' ) return def f ( x ): #*****************************************************************************80 # ## F evaluates the function to be minimized. # value = 2.0 * x ** 4 - 4.0 * x ** 2 + x + 20.0 return value def fp ( x ): #*****************************************************************************80 # ## FP evaluates the derivative of the function to be minimized. # value = 8.0 * x ** 3 - 8.0 * x + 1.0 return value if ( __name__ == '__main__' ): ex51 ( )