Построение графика во время подбора параметра 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, чтобы выбрать результаты во время развертки параметра

Создайте 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.

Смотрите также