MATLAB Answers

While loop inside another while loop

26 views (last 30 days)
Antonio Alves
Antonio Alves on 20 Feb 2021
Answered: Jan on 21 Feb 2021
I'm trying to make a bifurcation map for the logistic model using while loops but it isn't working quite as I expected. The code is:
x = input('Initial condition');
rmin = input('Minimal r');
rmax = input('Maximal r');
h = input('Step size');
nf = input('Iteraction number');
k = input('Transient duration');
m = 1;
r = rmin;
while r <= rmax+h
while m <= nf
n = [0:m];
x(m+1) = r*x(m)*(1-x(m));
m = m+1;
end
R = r*ones(1, nf);
hold on
figure 1
plot (R(k+1:nf), x(k+1:nf), '.')
hold off
r = r+h;
end
The inside while gives the x vector for the initial r, but won't update itself with the other r values generated by the external while loops. I end up with a plot, in wich all the r values have the same associated x like the following picture:
I shoud be getting a graphic like this:
Is there a way to make it with the while loops or something similar?

Answers (2)

Jan
Jan on 21 Feb 2021
Edited: Jan on 21 Feb 2021
The main problem of your code is, that you increase m in the inner loop, but do not reset it to 1 inside the outer loop. So you append new x values, but you draw the same part x(k+1:nf) repeatedly. Move m = 1 inside the outer loop.
The editor warns already, that the line "n = [0:m];" is a waste of time only, because n is not used anywhere.
With the small changes and FOR loops for a simplification:
rmin = 2.8;
rmax = 4.0;
h = 0.01;
nf = 2e3;
k = 1e3;
x0 = 0.5;
figure; % Not figure(1): Integer figure numbers are outdated since 1999.
axes('NextPlot', 'add', ... % same as: hold on
'XLim', [rmin, rmax], 'YLim', [0, 1]);
x = zeros(1, nf); % Pre-allocate
x(1) = x0; % Is not overwritten inside the loops!
for r = rmin:h:rmax
for m = 1:nf - 1
x(m + 1) = r * x(m) * (1 - x(m));
end
plot(r, x(k+1:nf), 'r.');
% plot(r, unique(round(x(k+1:nf), 6)), 'r.'); % Much faster!
drawnow;
end

Jan
Jan on 21 Feb 2021
The code of my other questions spends the most time for updating the figure. Even closing the figure finally takes several seconds.
A version, which draws to a an array, which is displayed as image:
function Bifurcation
% x = input('Initial condition');
% rmin = input('Minimal r');
% rmax = input('Maximal r');
% h = input('Step size');
% nf = input('Iteraction number');
% k = input('Transient duration');
rmin = 2.8;
rmax = 4.0;
n = 2e3;
trans = 1e3;
x0 = 0.5;
W = 800;
WStep = (rmax - rmin) / W;
H = 500;
HLim = [0, 1];
HVec = linspace(HLim(1), HLim(2), H);
Img = ones(H, W, 3);
FigH = figure();
AxesH = axes(FigH, 'NextPlot', 'add', ... % same as: hold on
'XLim', [1, W], 'YLim', [1, H], ...
'TickDir', 'out');
ImgH = image(AxesH, Img);
x = zeros(1, n); % Pre-allocate
x(1) = x0; % Is not overwritten inside the loops!
for iW = 1:W
r = rmin + (iW - 1) * WStep;
for m = 1:n - 1
x(m + 1) = r * x(m) * (1 - x(m));
end
% Slow graphics with different line objects:
% plot(r, x(k+1:n), 'r.');
% plot(r, unique(round(x(trans+1:n), 4)), 'r.'); % Much faster!
q = histc(x(trans:n), HVec);
m = (q ~= 0);
maxq = max(q(m));
Img(m, iW, :) = repmat(1 - (q(m) / maxq), [1, 1, 3]);
ImgH.CData = Img;
drawnow;
end
end

Community Treasure Hunt

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

Start Hunting!