How to use both pswplotbestf and pswplotranges for particleswarm?

20 views (last 30 days)
I've noticed that having both 'pswplotranges' as 'OutputFcn' and 'pswplotbestf' as 'PlotFcn' in the particleswarm option enabled does not work. It appears that it's only possible to get either one of the plots from an optimization. Is there a way to get both? Thank you.
  1 Comment
Ashutosh on 16 Aug 2023
The use of "pswplotranges” as the "OutputFcn” and "pswplotbestf as the "PlotFcn" in the "particleswarm" options does not work is due to way the Particle Swarm Optimization algorithm handles the plotting.
The issue arises when using both options of "pswplotranges" as the "OutputFcn" and " pswplotbestf " as the "PlotFcn". These two functions are designed to generate different types of plots. "pswplotranges" generates a range plot that shows the range of particle positions at each iteration, while "pswplotbestf" generates a plot showing the best function value over iterations.
Since both functions are intended to generate plots, there is a conflict in how they are called and handled by the "particleSwarm" algorithm. The algorithm is designed to handle either an "OutputFcn" or a "PlotFcn", but not both simultaneously. As a result, when both functions are specified, it leads to errors or unexpected behavior.

Sign in to comment.

Accepted Answer

Alan Weiss
Alan Weiss on 17 Aug 2023
The issue is that the pswplotranges output function was written incorrectly, and does not take into account that other plots might be happening at the same time. I will correct this deficiency in future documentation. Meanwhile, here is a corrected version along with a test script showing that the two plots can coexist. The four new lines in pswplotranges have % New comments at the ends.
Alan Weiss
MATLAB mathematical toolbox documentation
fun = @multirosenbrock;
nvar = 4; % A 4-D problem
lb = -10*ones(nvar,1); % Bounds to help the solver converge
ub = -lb;
options = optimoptions(@particleswarm,'OutputFcn',@pswplotranges,'PlotFcn',@pswplotbestf);
rng default % For reproducibility
[x,fval,eflag] = particleswarm(fun,nvar,lb,ub,options)
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
x = 1×4
0.9964 0.9930 0.9835 0.9681
fval = 3.4935e-04
eflag = 1
function stop = pswplotranges(optimValues,state)
stop = false; % This function does not stop the solver
switch state
case 'init'
fig = figure(); % New
set(fig,'numbertitle','off','name','pranges') % New
nplot = size(optimValues.swarm,2); % Number of dimensions
for i = 1:nplot % Set up axes for plot
tag = sprintf('psoplotrange_var_%g',i); % Set a tag for the subplot
semilogy(optimValues.iteration,0,'-k','Tag',tag); % Log-scaled plot
xlabel('Iteration','interp','none'); % Iteration number at the bottom
subplot(nplot,1,1) % Title at the top
title('Log range of particles by component')
setappdata(gcf,'t0',tic); % Set up a timer to plot only when needed
case 'iter'
fig = findobj(0,'Type','figure','Name','pranges'); % New
set(0,'CurrentFigure',fig); % New
nplot = size(optimValues.swarm,2); % Number of dimensions
for i = 1:nplot
% Calculate the range of the particles at dimension i
irange = max(optimValues.swarm(:,i)) - min(optimValues.swarm(:,i));
tag = sprintf('psoplotrange_var_%g',i);
plotHandle = findobj(get(gca,'Children'),'Tag',tag); % Get the subplot
xdata = plotHandle.XData; % Get the X data from the plot
newX = [xdata optimValues.iteration]; % Add the new iteration
plotHandle.XData = newX; % Put the X data into the plot
ydata = plotHandle.YData; % Get the Y data from the plot
newY = [ydata irange]; % Add the new value
plotHandle.YData = newY; % Put the Y data into the plot
if toc(getappdata(gcf,'t0')) > 1/30 % If 1/30 s has passed
drawnow % Show the plot
setappdata(gcf,'t0',tic); % Reset the timer
case 'done'
% No cleanup necessary
function F = multirosenbrock(x)
% This function is a multidimensional generalization of Rosenbrock's
% function. It operates in a vectorized manner, assuming that x is a matrix
% whose rows are the individuals.
% Copyright 2014 by The MathWorks, Inc.
N = size(x,2); % assumes x is a row vector or 2-D matrix
if mod(N,2) % if N is odd
error('Input rows must have an even number of elements')
odds = 1:2:N-1;
evens = 2:2:N;
F = zeros(size(x));
F(:,odds) = 1-x(:,odds);
F(:,evens) = 10*(x(:,evens)-x(:,odds).^2);
F = sum(F.^2,2);

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!