MATLAB Examples

# Particle Swarm Output Function

This example shows how to use an output function for particleswarm. The output function plots the range that the particles occupy in each dimension.

An output function runs after each iteration of the solver. For syntax details, and for the data available to an output function, see the particleswarm options reference pages.

## Custom Plot Function

This output function draws a plot with one line per dimension. Each line represents the range of the particles in the swarm in that dimension. The plot is log-scaled to accommodate wide ranges. If the swarm converges to a single point, then the range of each dimension goes to zero. But if the swarm does not converge to a single point, then the range stays away from zero in some dimensions.

Copy the following code into a file named pswplotranges.m on your MATLAB® path. The code sets up nplot subplots, where nplot is the number of dimensions in the problem.

function stop = pswplotranges(optimValues,state)

stop = false; % This function does not stop the solver
switch state
case 'init'
nplot = size(optimValues.swarm,2); % Number of dimensions
for i = 1:nplot % Set up axes for plot
subplot(nplot,1,i);
tag = sprintf('psoplotrange_var_%g',i); % Set a tag for the subplot
semilogy(optimValues.iteration,0,'-k','Tag',tag); % Log-scaled plot
ylabel(num2str(i))
end
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'
nplot = size(optimValues.swarm,2); % Number of dimensions
for i = 1:nplot
subplot(nplot,1,i);
% 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
end
if toc(getappdata(gcf,'t0')) > 1/30 % If 1/30 s has passed
drawnow % Show the plot
setappdata(gcf,'t0',tic); % Reset the timer
end
case 'done'
% No cleanup necessary
end

## Objective Function

The multirosenbrock function is a generalization of Rosenbrock's function to any even number of dimensions. It has a global minimum of 0 at the point [1,1,1,1,...].

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')
end

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);

## Set Up and Run Problem

Set the multirosenbrock function as the objective function. User four variables. Set a lower bound of -10 and an upper bound of 10 on each variable.

fun = @multirosenbrock;
nvar = 4; % A 4-D problem
lb = -10*ones(nvar,1); % Bounds to help the solver converge
ub = -lb;

Set options to use the output function.

options = optimoptions(@particleswarm,'OutputFcn',@pswplotranges);

Set the random number generator to get reproducible output. Then call the solver.

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 =

0.9964    0.9930    0.9835    0.9681

fval =

3.4935e-04

eflag =

1

## Results

The solver returned a point near the optimum [1,1,1,1]. But the span of the swarm did not converge to zero.