#! /usr/bin/env python3 # def quartic_gradient1 ( ): #*****************************************************************************80 # ## quartic_gradient1 applies gradient descent to the quartic function. # # Discussion: # # The quartic function is # f(x) = 2.0 * x ** 4 - 4.0 * x ** 2 + x + 20.0 # # We seek a minimizer of f(x) in the range -2 <= x <= 2. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 22 September 2019 # # Author: # # John Burkardt # import matplotlib.pyplot as plt import numpy as np from quartic import quartic from quartic import quartic_df from gradient_descent1 import gradient_descent1 a = -2.0 b = +2.0; print ( '' ) print ( 'quartic_gradient1:' ) print ( ' Seek local minimizer of a scalar function f(x) in [',a,',',b,']' ) # # Plot the function. # xvec = np.linspace ( -2.0, 2.0, 101 ) fxvec = quartic ( xvec ) plt.plot ( xvec, fxvec, linewidth = 3 ) plt.plot ( [ a, b ], [ 0, 0 ], 'k', linewidth = 3 ) plt.grid ( True ) plt.xlabel ( '<-- X -->' ) plt.ylabel ( '<-- F(X) -->' ) plt.title ( 'Quartic function', fontsize = 16 ) filename = 'quartic.png' plt.savefig ( filename ) print ( '' ) print ( ' Graphics saved in "%s"' % ( filename ) ) plt.show ( ) plt.clf ( ) # # Choose a random initial guess. # x0 = a + ( b - a ) * np.random.rand ( ) # # Choose a small learning rate. # r = 0.05 # # Choose a small tolerance for the stepsize. # dxtol = 0.001 # # Choose a small tolerance for the derivative. # dftol = 0.001 # # Maximum number of iterations. # itmax = 100 x, it = gradient_descent1 ( quartic, quartic_df, x0, r, dxtol, dftol, itmax ) print ( '' ) print ( ' ', it, 'gradient descent steps were taken.' ) print ( ' Initial x = ', x0, ' f(x) = ', quartic ( x0 ), ' f\'(x) = ', quartic_df(x0) ) print ( ' Final x = ', x, ' f(x) = ', quartic ( x ), ' f\'(x) = ', quartic_df(x) ) # # Plot the function with initial point and local minimizer # xvec = np.linspace ( a, b, 101 ) fxvec = quartic ( xvec ) plt.plot ( xvec, fxvec, linewidth = 3 ) plt.plot ( [ x0, x0 ], [ 0, quartic ( x0 ) ], 'b', linewidth = 3 ) plt.plot ( x0, 0.0, 'bo', markersize = 10 ) plt.plot ( x0, quartic ( x0 ), 'bo', markersize = 10 ) plt.plot ( [ x, x ], [ 0, quartic ( x ) ], 'r', linewidth = 3 ) plt.plot ( x, 0.0, 'ro', markersize = 10 ) plt.plot ( x, quartic ( x ), 'ro', markersize = 10 ) plt.plot ( [ a, b ], [ 0, 0 ], 'k', linewidth = 3 ) plt.grid ( True ) plt.xlabel ( '<-- X -->' ) plt.ylabel ( '<-- F(X) -->' ) plt.title ( 'Initial point in blue, local minimizer in red', fontsize = 16 ) filename = 'quartic_minimizer.png' plt.savefig ( filename ) print ( '' ) print ( ' Graphics saved in "%s"' % ( filename ) ) plt.show ( ) plt.clf ( ) # # Terminate. # print ( '' ) print ( 'quartic_gradient1:' ) print ( ' Normal end of execution.' ) return if ( __name__ == '__main__' ): quartic_gradient1 ( )