MATLAB 2019a中Rossler方程分岔图并行池化实现问题咨询
Let's break down the issues you're facing with parfor and fix your code step by step. The main roadblocks to converting your serial code to parallel are:
- Global variable
c: Parallel loops don’t play nicely with global variables—each worker needs its own isolated value, and globals create unexpected cross-worker dependencies. - Non-sliceable array
xmax: Your current indexingxmax(k,j)isn’t compatible withparforbecause parallel iterations run in arbitrary order, and MATLAB can’t safely split this array across workers. - In-loop plotting: Plotting inside
parforis inefficient and can cause conflicts with the main thread’s figure—better to compute all data first, then plot in one go.
Step 1: Ditch the Global Variable
Instead of relying on global c, pass the current c value directly into your ODE anonymous function. This makes each iteration self-contained, which is critical for parallel execution.
Step 2: Use Parallel-Friendly Storage
A cell array is perfect here—each worker can write to its own cell without indexing conflicts. We’ll also track corresponding c values so we can map results correctly later.
Step 3: Compute First, Plot Later
Move all plotting logic outside the parallel loop. This eliminates overhead from workers fighting over the same figure and keeps your code organized.
Modified Parallel Code
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 xmax_cell = cell(size(crange)); % Cell array to store xmax for each c c_values = crange; % Track c values for plotting % Initialize parallel pool (MATLAB auto-starts one if none exists) parpool; parfor idx = 1:length(crange) c = crange(idx); % ODE function with current c (no global needed!) f = @(t,x) [-x(2)-x(3); x(1)+a*x(2); b+x(3)*(x(1)-c)]; x0 = [1 1 0]; % Initial condition [t,x] = ode45(f, tspan, x0); % Ignore transient behavior (matches your comment: t > 100) count = find(t > 100); x = x(count,:); n = size(x,1); xmax_list = []; for i = 2:n-1 % Detect local maxima in x(1) if (x(i-1,1) + eps) < x(i,1) && x(i,1) > (x(i+1,1) + eps) xmax_list = [xmax_list; x(i,1)]; end end xmax_cell{idx} = xmax_list; end % Plot all computed data figure; hold on; for idx = 1:length(crange) c = c_values(idx); xmax_list = xmax_cell{idx}; if ~isempty(xmax_list) plot(c, xmax_list, 'k.', 'MarkerSize', 1); end end xlabel('Bifurcation parameter c'); ylabel('x max'); title('Bifurcation diagram for c'); hold off; % Clean up parallel pool (optional, MATLAB auto-closes on exit) delete(gcp);
Key Notes for R2019a:
- No globals: The anonymous function
fcaptures the currentcvalue from theparforiteration, so each worker runs with its own unique ODE setup. - Cell array safety:
xmax_celluses the loop indexidxas the cell key, which MATLAB allows for parallel write access without conflicts. - Transient fix: I noticed your original code had
t>10instead oft>100(matching your comment)—I kept the comment’s intent, but adjust this if it was a typo. - Pool initialization: If you get a prompt to enable parallel computing, follow the on-screen steps to activate the Parallel Computing Toolbox.
内容的提问来源于stack exchange,提问作者akhil krishnan

