最近、私のコードでこの問題が発生しました。「最も簡単な」解決策は、次のことを行うことです。まず、解決策が 0 に達したら、それを 0 に保つ必要があるため、
dx = 1/(1+y*z) - x;
x == 0
to (ケースが評価される場所に注意してください)
if x > 0
dx = 1/(1+y*z) - x;
else % if x <= 0
dx = 0;
end
または多分to(0にならない理由によって異なります)
dxTmp = 1/(1+y*z) - x;
if x > 0
dx = dxTmp;
elseif dxTmp > 0
% x becomes positive again
dx = dxTmp;
else
dx = 0;
end
ただし、これにより一次導関数にジャンプの不連続性が生じることに注意してください。DDE ソルバーがt - delay
この点に近づくと、この不連続性が存在する正確な場所がわからない限り、効率的に解決することはできません (通常、 Matlab にその場所を伝える追加のオプションですが、以下の手順に従う場合は必要ありません)。
この不連続の場所を特定するには、イベントの DDE オプションを使用する必要があります(「イベントの場所のプロパティ」までスクロールします。これらの例も参照できます。これらの例の 1 つは、負の値が許可されていない同様のシステムを実際に扱っています。 ODE の場合 - ODE と DDE のイベントはほとんど同じです)。基本的に、イベントはベクトル出力を持つ Matlab 関数です。ベクトルの各エントリは、変数の何らかの評価です。各ステップで、Matlab はそれらの 1 つが 0 に等しいかどうかをチェックします。それらの 1 つが 0 に等しい場合、DDE は停止し、その時点までの解を返します。その時点から、その部分的な解を履歴として DDE を再起動する必要があります。つまり、実行する代わりに
sol = dde23(ddefun, lags, history, [t0 tEnd], options);
あなたが実行する(通知sol
およびt0
変更)
sol = dde23(ddefun, lags, sol, [tCurrent tEnd], options);
この場合、ベクターのエントリの 1 つになります( 0 に等しいx
ときに DDE を停止するため)。x
また、コード行は別の不連続性を作成するため、いつ0 になるelseif dxTmp <= 0
かのイベントが必要です。つまり、ベクトル出力の別のコンポーネントになります。dxTmp
1/(1+y*z) - x
ODE を再起動すると、Matlab はその時点で不連続性があると自動的に想定するため、Matlab に不連続性があることを伝えることを心配する必要はありません。
次の問題は、Matlab がそれを正しく達成することは決してなくx
、 、y
、z
およびの値X
がわずかに負になることです。したがって、問題が発生する場合は、の値x
(および他の値も同様に) を次のように修正する必要があります。
if x < 0
x = 0;
end
導関数を計算する前に。しかし、これはx
ローカルの値を変更するだけです。x
そのため、最終解の のすべての負の値も 0 に変更したい場合があります。sol
入力する前に変更しようとしないことをお勧めします。私はそれを何度もsol = dde23(ddefun, lags, sol, [tCurrent tEnd], options);
試みましたが、機能させることができませんでした。