ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

parfor を使用したパラメーター スイープ中のプロット

この例では、パラメーター スイープを並列実行して、並列計算中に進行状況をプロットする方法を説明します。DataQueue を使用して、並列プールでの計算中に結果を監視できます。DataQueueparforparfevalspmd などの並列言語機能と共に使用できます。この例では、古典的なシステムであるファン デル ポール振動子でパラメーター スイープを実行する方法を説明します。このシステムは、2 つのファン デル ポール振動子パラメーター、 に依存する一連の ODE として表現できます。

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

クラスターへのスケール アップ

クラスターにアクセスできる場合、スケール アップできます。これを行うには、前回の parpool を削除し、より大きいクラスター用のプロファイルを使用して新しいものを開きます。以下のコードは、'MyClusterInTheCloud' という名前のクラスター プロファイルを示します。このコードを実行するには、'MyClusterInTheCloud' を自分のクラスター プロファイルの名前に置き換えなければなりません。ワーカー数を調整します。この例では、4 個のワーカーが示されています。グリッドのサイズを大きくして、計算全体のサイズを大きくします。

gridSize = 25;
delete(gcp('nocreate'));
parpool('MyClusterInTheCloud',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
Starting parallel pool (parpool) using the 'MyClusterInTheCloud' profile ...
connected to 4 workers.

参考