Построение графика во время подбора параметра parfor
Этот пример показывает, как выполнить развертку параметра параллельно и прогресс графика во время параллельных вычислений. Можно использовать DataQueue
, чтобы контролировать результаты во время вычислений на параллельном пуле. Можно также использовать DataQueue
с функциями языка параллельного программирования, такими как parfor
, parfeval
и spmd
.
Пример показывает, как выполнить развертку параметра в классической системе, Осцилляторе Ван дер Поля. Эта система может быть выражена как набор ОДУ, зависящих от двух параметров Осциллятора Ван дер Поля, и:
Можно выполнить параллельную развертку параметра по параметрам и использованию цикла parfor
, чтобы узнать средний период при варьировании их. Следующая анимация показывает выполнение этого примера в локальном кластере.
Задайте область значений значений для параметров, которые будут исследоваться. Создайте meshgrid, чтобы составлять различные комбинации параметров.
gridSize = 6; nu = linspace(100, 150, gridSize); mu = linspace(0.5, 2, gridSize); [N,M] = meshgrid(nu,mu);
Объявите, что переменная хранит результаты развертки. Используйте nan
для предварительного выделения, чтобы не строить начальную поверхность. Создайте объемную поверхностную диаграмму визуализировать результаты развертки для каждой комбинации параметров. Подготовьте настройки, такие как заголовок, метки и пределы.
Z = nan(size(N)); c = surf(N, M, 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
, чтобы отправить, промежуточное звено следует из рабочих клиенту. Используйте функцию afterEach
, чтобы задать коллбэк в клиенте, который обновляет поверхность каждый раз, когда рабочий отправляет текущий результат.
D = parallel.pool.DataQueue; D.afterEach(@(x) updateSurface(c, x));
Используйте parfor
, чтобы выполнить параллельную развертку параметра. Дайте рабочим команду решать систему для каждой комбинации параметров в meshgrid и вычислять средний период. Сразу передайте результат обратно каждой итерации клиенту, когда рабочий закончит вычисления.
parfor ii = 1:numel(N) [t, y] = solveVdp(N(ii), M(ii)); l = islocalmax(y(:, 2)); send(D, [ii mean(diff(t(l)))]); end
Starting parallel pool (parpool) using the 'local' profile ... connected to 6 workers.
Если у вас есть доступ к кластеру, можно увеличить вычисление. Для этого удалите предыдущий parpool
и откройте новый с помощью профиля для большего кластера. Код ниже показов кластерный профиль под названием 'MyClusterInTheCloud'
. Чтобы запустить этот код самостоятельно, необходимо заменить 'MyClusterInTheCloud'
на имя кластерного профиля. Настройте количество рабочих. Пример показывает 4 рабочим. Увеличьте размер полного вычисления путем увеличения размера сетки.
gridSize = 25; delete(gcp('nocreate')); parpool('MyClusterInTheCloud',4);
Parallel pool using the 'local' profile is shutting down.
Если при запуске код развертки параметра снова после установки кластерного профиля, то рабочие в кластере вычисляют и отправляют результаты клиенту 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
Starting parallel pool (parpool) using the 'MyClusterInTheCloud' profile ... connected to 4 workers.