Warm tip: This article is reproduced from stackoverflow.com, please click
matlab parallel-processing

Parallel pooling on MATLAB for Bifurcation

发布于 2020-03-27 15:46:00

I'm new to this concept of parallel pooling on MATLAB (I'm using the version 2019 a) and coding. This code that I'm going to share with you was available on the net, with some few modifications that I've made it for my requirements.

Problem Statement: I'm having a non-linear system (Rossler equation) & I have to plot its Bifurcation diagram, I tried to do it normally using for loop but its computation time was too much and my computer got hanged several times, so I got an advice to parallel pool my code in order to come out of this problem. I tried to learn how to parallel pool using MATLAB on the net but still I'm not able to resolve my Issues as there are still some problems since there are 2 parfor loops in my code I'm having problems with Indexing and in assignment of the global parameter (Please note: This code is written for normal execution without using parallel pooling).

I'm attaching my code below here, please excuse if I've mentioned a lot many lines of codes.

clc;
a = 0.2; b = 0.2; global c;
crange = 1:0.05:90; % Range for parameter c
k = 0; tspan = 0:0.1:500; % Time interval for solving Rossler system
xmax = []; % A matrix for storing the sorted value of x1

for c = crange
f = @(t,x) [-x(2)-x(3); x(1)+a*x(2); b+x(3)*(x(1)-c)];
    x0 = [1 1 0]; % initial condition for Rossler system 
    k = k + 1;
    [t,x] = ode45(f,tspan,x0); % call ode() to solve Rossler system
    count = find(t>100); % find all the t values which is >10  
    x = x(count,:);
    j = 1; 
    n = length(x(:,1)); % find the length of vector x1(x in our problem)

    for i=2 : n-1
       % check for the min value in 1st column of sol matrix
       if (x(i-1,1)+eps) < x(i,1) && x(i,1) > (x(i+1,1)+eps)  
           xmax(k,j)=x(i,1); % Sorting the values of x1 in increasing order
           j=j+1;
       end 
    end

    % generating bifurcation map by plotting j-1 element of kth row each time
    if j>1
        plot(c,xmax(k,1:j-1),'k.','MarkerSize',1);
    end 

    hold on;
    index(k)=j-1;    
end
xlabel('Bifuracation parameter c');
ylabel('x max');
title('Bifurcation diagram for c'); 
Questioner
akhil krishnan
Viewed
55
Edric 2020-01-31 17:08

This can be made compatible with parfor by taking a few relatively simple steps. Firstly, parfor workers cannot produce on-screen graphics, so we need to change things to emit a result. In your case, this is not totally trivial since your primary result xmax is being assigned-to in a not-completely-uniform manner - you're assigning different numbers of elements on different loop iterations. Not only that, it appears not to be possible to predict up-front how many columns xmax needs.

Secondly, you need to make some minor changes to the loop iteration to be compatible with parfor, which requires consecutive integer loop iterates.

So, the major change is to have the loop write individual rows of results to a cell array I've called xmax_cell. Outside the parfor loop, it's trivial to convert this back to matrix form.

Putting all this together, we end up with this, which works correctly in R2019b as far as I can tell:

clc;
a = 0.2; b = 0.2;
crange = 1:0.05:90; % Range for parameter c
tspan = 0:0.1:500; % Time interval for solving Rossler system

% PARFOR loop outputs: a cell array of result rows ...
xmax_cell = cell(numel(crange), 1);
% ... and a track of the largest result row
maxNumCols = 0;

parfor k = 1:numel(crange)
    c = crange(k);
    f = @(t,x) [-x(2)-x(3); x(1)+a*x(2); b+x(3)*(x(1)-c)];
    x0 = [1 1 0]; % initial condition for Rossler system
    [t,x] = ode45(f,tspan,x0); % call ode() to solve Rossler system
    count = find(t>100); % find all the t values which is >10
    x = x(count,:);
    j = 1;
    n = length(x(:,1)); % find the length of vector x1(x in our problem)
    this_xmax = [];
    for i=2 : n-1
        % check for the min value in 1st column of sol matrix
        if (x(i-1,1)+eps) < x(i,1) && x(i,1) > (x(i+1,1)+eps)
            this_xmax(j) = x(i,1);
            j=j+1;
        end
    end

    % Keep track of what's the maximum number of columns
    maxNumCols = max(maxNumCols, numel(this_xmax));
    % Store this row into the output cell array.
    xmax_cell{k} = this_xmax;
end

% Fix up xmax - push each row into the resulting matrix.
xmax = NaN(numel(crange), maxNumCols);
for idx = 1:numel(crange)
    this_max = xmax_cell{idx};
    xmax(idx, 1:numel(this_max)) = this_max;
end

% Plot
plot(crange, xmax', 'k.', 'MarkerSize', 1)
xlabel('Bifuracation parameter c');
ylabel('x max');
title('Bifurcation diagram for c');