在参数扫描期间绘制parfeval
此示例演示如何执行与的并行参数扫描parfeval
并在计算过程中返回结果DataQueue
对象。
parfeval
不会阻塞MATLAB,所以你可以在计算发生时继续工作。
本例对常微分方程的Lorenz系统进行了参数扫描 而且 ,显示了这个系统的混沌本质。
创建参数网格
定义要在参数扫描中查看的参数范围。
gridSize = 40;sigma = linspace(5, 45, gridSize);rho = linspace(50,100, gridSize);Beta = 8/3;
控件创建参数的2-D网格meshgrid
函数。
[rho,sigma] = meshgrid(rho,sigma);
创建一个图形对象,并设置“可见”
来真正的
这样它就会在活动脚本之外的一个新窗口中打开。要可视化参数扫描的结果,请创建一个曲面图。注意,初始化Z
表面的分量南
创建一个空情节。
图(“可见”,真正的);surface = surf(rho,sigma,NaN(size(sigma)));包含(‘\ρ,“翻译”,“泰克斯”) ylabel (‘\σ’,“翻译”,“泰克斯”)
设置并行环境
方法创建并行工作池parpool
函数。
parpool;
使用'Processes'配置文件启动并行池(parpool)…连接到并行池(工人数:6)。
要从工作线程发送数据,可以创建DataQueue
对象。方法设置一个函数,该函数在工作人员每次发送数据时更新曲面图afterEach
函数。的updatePlot
Function是在示例末尾金宝app定义的支持函数。
Q = parallel.pool.DataQueue;afterEach (Q, @(数据)updatePlot(表面、数据));
执行并行参数扫描
定义了参数之后,就可以执行并行参数扫描了。
parfeval
当你分配工作负载时,工作效率更高。要分配工作负载,请将要查看的参数分组到分区中。对于本例,将其划分为大小一致的分区一步
通过使用冒号操作符(:
).生成的数组分区
包含分区的边界。注意,必须添加最后一个分区的端点。
Step = 100;分区=[1:步骤:数字(西格玛),数字(西格玛)+1]
分区=1×171101 201 301 401 501 601 701 801 901 1001 1101 1201 1301 1401 1501 1601
为了获得最佳性能,请尝试将其划分为以下分区:
与调度分区的开销相比,足够大的计算时间。
足够小,以至于有足够的分区来让所有的工作人员忙碌。
要表示并行工作线程上的函数执行并保存其结果,请使用future对象。
f(1:numel(partitions)-1) = parallel.FevalFuture;
方法将计算卸载给并行工作者parfeval
函数。parameterSweep
是这个脚本末尾定义的一个辅助函数,它在要探索的参数分区上求解Lorenz系统。它有一个输出参数,所以必须指定1
作为输出的数量parfeval
.
为ii = 1:数值(分区)-1 f(ii) = parfeval(@parameterSweep,1,分区(ii),分区(ii+1),西格玛,rho,beta,Q);结束
parfeval
不会阻塞MATLAB,所以你可以在计算发生时继续工作。工作人员并行计算,并将中间结果通过DataQueue
一旦有了它们。
如果你想阻止MATLAB直到parfeval
完成后,使用等待
函数在未来对象上。使用等待
函数在后续代码依赖于的完成时非常有用parfeval
.
等待(f);
后parfeval
完成计算,等待
完成后,您可以执行更多的代码。例如,绘制结果曲面的等高线。使用fetchOutputs
函数检索存储在未来对象中的结果。
results =重塑(fetchOutputs(f),gridSize,[]);contourf(ρ,σ,结果)包含(‘\ρ,“翻译”,“泰克斯”) ylabel (‘\σ’,“翻译”,“泰克斯”)
如果参数扫描需要更多的计算资源,并且您可以访问集群,则可以扩展您的parfeval
计算。有关更多信息,请参见从桌面扩展到集群.
定义Helper函数
定义一个辅助函数,在要探索的参数分区上求解Lorenz系统。将中间结果发送到MATLAB客户端发送
函数在DataQueue
对象。
函数results = parameterscan (first,last,sigma,rho,beta,Q) results = 0 (last-first,1);为2 =第一:持续1 lorenzSystem = @ (t))(σ(ii) * ((2) - (1));A (1)*(rho(ii) - A (3)) - A (2);A (1)* A (2) - * A (3)];[t,a] = ode45(lorenzSystem,[0 100],[1 1 1]);Result = a(end,3);发送(Q, [ii,结果]);Results (ii-first+1) = result;结束结束
定义另一个辅助函数,在新数据到达时更新曲面图。
函数updatePlot(surface,data) surface. zdata (data(1)) = data(2);drawnow (“limitrate”);结束
另请参阅
parpool
|parallel.pool.DataQueue
|afterEach
|parfeval