Documentation |
On this page… |
---|
The PlotFcns field of the options structure specifies one or more functions that an optimization function calls at each iteration. Plot functions plot various measures of progress while the algorithm executes. Pass a function handle or cell array of function handles. The structure of a plot function is the same as the structure of an output function. For more information on this structure, see OutputFcns.
Plot functions are specialized output functions (see Output Functions for GlobalSearch and MultiStart). There are two predefined plot functions:
@gsplotbestf plots the best objective function value.
@gsplotfunccount plots the number of function evaluations.
Plot function windows have Pause and Stop buttons. By default, all plots appear in one window.
To use global plot functions:
Write plot functions using the syntax described in OutputFcns.
Set the PlotFcns property of your GlobalSearch or MultiStart object to the function handle of your plot function. You can use multiple plot functions by setting the PlotFcns property to a cell array of function handles.
The built-in plot functions have characteristics that can surprise you.
@gsplotbestf can have plots that are not strictly decreasing. This is because early values can result from local solver runs with negative exit flags (such as infeasible solutions). A subsequent local solution with positive exit flag is better even if its function value is higher. Once a local solver returns a value with a positive exit flag, the plot is monotone decreasing.
@gsplotfunccount might not plot the total number of function evaluations. This is because GlobalSearch can continue to perform function evaluations after it calls the plot function for the last time. For more information, see GlobalSearch AlgorithmProperties for GlobalSearch.
This example plots the number of local solver runs it takes to obtain a better local minimum for MultiStart. The example also uses a built-in plot function to show the current best function value.
The example problem is the same as in Find Global or Multiple Local Minima, with additional bounds.
The example uses persistent variables to store previous best values. The plot function examines the best function value after each local solver run, available in the bestfval field of the optimValues structure. If the value is not lower than the previous best, the plot function adds 1 to the number of consecutive calls with no improvement and draws a bar chart. If the value is lower than the previous best, the plot function starts a new bar in the chart with value 1. Before plotting, the plot function takes a logarithm of the number of consecutive calls. The logarithm helps keep the plot legible, since some values can be much larger than others.
To store local results using nested functions instead of persistent variables, see Example of a Nested Output Function in the MATLAB^{®} Mathematics documentation.
Write the objective function:
function f = sawtoothxy(x,y) [t r] = cart2pol(x,y); % change to polar coordinates h = cos(2*t - 1/2)/2 + cos(t) + 2; g = (sin(r) - sin(2*r)/2 + sin(3*r)/3 - sin(4*r)/4 + 4) ... .*r.^2./(r+1); f = g.*h;
Save sawtoothxy.m as a file in a folder on your MATLAB path.
Write the plot function:
function stop = NumberToNextBest(optimValues, state) persistent bestfv bestcounter stop = false; switch state case 'init' % Initialize variable to record best function value. bestfv = []; % Initialize counter to record number of % local solver runs to find next best minimum. bestcounter = 1; % Create the histogram. bar(log(bestcounter),'tag','NumberToNextBest'); xlabel('Number of New Best Fval Found'); ylabel('Log Number of Local Solver Runs'); title('Number of Local Solver Runs to Find Lower Minimum') case 'iter' % Find the axes containing the histogram. NumToNext = ... findobj(get(gca,'Children'),'Tag','NumberToNextBest'); % Update the counter that records number of local % solver runs to find next best minimum. if ~isequal(optimValues.bestfval, bestfv) bestfv = optimValues.bestfval; bestcounter = [bestcounter 1]; else bestcounter(end) = bestcounter(end) + 1; end % Update the histogram. set(NumToNext,'Ydata',log(bestcounter)) end
Save NumberToNextBest.m as a file in a folder on your MATLAB path.
Create the problem structure and global solver. Set lower bounds of [-3e3,-4e3], upper bounds of [4e3,3e3] and set the global solver to use the plot functions:
problem = createOptimProblem('fmincon',... 'objective',@(x)sawtoothxy(x(1),x(2)),... 'x0',[100,-50],'lb',[-3e3 -4e3],... 'ub',[4e3,3e3],'options',... optimoptions(@fmincon,'Algorithm','sqp')); ms = MultiStart('PlotFcns',{@NumberToNextBest,@gsplotbestf});
Run the global solver for 100 local solver runs:
[x fv] = run(ms,problem,100);
The plot functions produce the following figure (your results can differ, since the solution process is stochastic):
While MultiStart can run in parallel, it does not support global output functions and plot functions in parallel. Furthermore, while local output functions and plot functions run on workers when MultiStart runs in parallel, the effect differs from running serially. Local output and plot functions do not create a display when running on workers. You do not see any other effects of output and plot functions until the worker passes its results to the client (the originator of the MultiStart parallel jobs).
For information on running MultiStart in parallel, see Parallel Computing.