Main Content

本页采用了机器翻译。点击此处可查看最新英文版本。

使用 parfor 进行参数扫描时的绘图

并行执行参数扫描,并在并行计算过程中绘制进度。

您可以使用 DataQueue 来监视并行池计算期间的结果。您还可以将 DataQueue 与并行语言功能(例如 parforparfevalspmd)一起使用。

该示例展示了如何对经典系统范德波尔振荡器执行参数扫描。该系统可以表示为一组依赖于两个范德波尔振荡器参数 μν 的 ODE:

x˙=νy

y˙=μ(1-x2)y-x

您可以使用 parfor 循环对参数 μν 执行并行参数扫描,以找出改变它们时 y 的平均周期。下面的动画展示了此示例在本地集群中的执行。

设置参数扫描值

定义要探索的参数的值范围。创建一个网格来解释参数的不同组合。

gridSize = 6;
mu = linspace(100, 150, gridSize);
nu = linspace(0.5, 2, gridSize);
[M,N] = meshgrid(mu,nu);

准备表面图来可视化结果

声明一个变量来存储扫描结果。使用 nan 进行预分配,以避免绘制初始表面。创建曲面图来可视化每个参数组合的扫描结果。准备标题、标签和限制等设置。

Z = nan(size(N));
c = surf(M, N, Z);
xlabel('\mu Values','Interpreter','Tex')
ylabel('\nu Values','Interpreter','Tex')
zlabel('Mean Period of  y')
view(137, 30)
axis([100 150 0.5 2 0 500]);

设置 DataQueue 以在参数扫描期间获取结果

创建一个 DataQueue 来将中间结果从工作进程发送到客户端。使用 afterEach 函数在客户端中定义一个回调,每次工作进程发送当前结果时更新表面。

D = parallel.pool.DataQueue;
D.afterEach(@(x) updateSurface(c, x));

执行参数扫描并绘制结果

使用 parfor 执行并行参数扫描。指导工作进程对网格中每个参数组合求解系统,并计算平均周期。当工作进程完成计算时立即将每次迭代的结果发送回客户端。

parfor ii = 1:numel(N)
    [t, y] = solveVdp(M(ii), N(ii));
    l = islocalmax(y(:, 2));
    send(D, [ii mean(diff(t(l)))]);
end
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 6).

扩展到集群

如果您可以访问集群,那么您可以扩大您的计算规模。为此,请删除前一个 parpool,然后使用更大集群的配置文件打开一个新的。下面的代码显示了一个名为 'MyClusterInTheCloud' 的集群配置文件。要自己运行此代码,您必须将 'MyClusterInTheCloud' 替换为您的集群配置文件的名称。调整工作进程数量。该示例有 4 个工作进程。通过增加网格的大小来增加整体计算的规模。

gridSize = 25;
delete(gcp('nocreate'));
parpool('MyClusterInTheCloud',4);
Starting parallel pool (parpool) using the 'MyClusterInTheCloud' profile ...
Connected to the parallel pool (number of workers: 4).

如果在设置集群配置文件后再次运行参数扫描代码,则集群中的工作进程将计算并在结果可用时将结果发送到 MATLAB 客户端。下面的动画展示了此示例在集群中的执行。

辅助函数

创建一个辅助函数来定义方程组,并在其上应用求解器。

function [t, y] = solveVdp(mu, nu)
f = @(~,y) [nu*y(2); mu*(1-y(1)^2)*y(2)-y(1)];
[t,y] = ode23s(f,[0 20*mu],[2; 0]);
end

为 DataQueue 声明一个函数,使用来自工作进程的结果来更新图表。

function updateSurface(s, d)
s.ZData(d(1)) = d(2);
drawnow('limitrate');
end

另请参阅

|

相关主题