私は最近、私のいくつかのコードでこの問題を抱えていました。「最も簡単なのソリューションは、ソリューションが0に達すると、まず、あなたは は、このように(x == 0
ケースが評価された予告)
if x > 0
dx = 1/(1+y*z) - x;
else % if x <= 0
dx = 0;
end
に
dx = 1/(1+y*z) - x;
を変更する、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
注ただし、これは一次導関数にジャンプ不連続部を作成すること(それが0になることはありませんできる理由に応じて)、WHIに
それともDDEソルバーがこの点の近くにt - delay
を持つポイントに達すると、この不連続点が正確な場所を知らない限り、それを非常に効率的には解決しません(通常はMatlabにどこにあるかを伝える余分なオプションを使用しますが、以下の手順に従うと、それは必要ありません)。
この不連続箇所を特定するには、というDDEオプションを使用する必要があります(「イベントの場所プロパティ」までスクロールしてください)。examplesを見ることもできます。これらの例の1つは、値はODEでは使用できません - ODEとDDEのイベントはほとんど同じです)。基本的に、イベントはベクトル出力を持つMatlab関数です。ベクトルの各エントリは、変数のいくつかまたは他の評価です。各ステップでMatlabはeqauls 0のうちの1つが0かどうかをチェックします。そのうちの1つが0の場合、DDEが停止し、その部分解を使用してDDEを履歴として再起動する必要があります。
sol = dde23(ddefun, lags, history, [t0 tEnd], options);
あなたは、ベクトルのエントリの一つは(あなたがx
が0に等しいときDDEを停止したいと)x
になるだろう。この場合、(予告sol
とt0
変更)
sol = dde23(ddefun, lags, sol, [tCurrent tEnd], options);
を実行します。また、コードelseif dxTmp <= 0
の行は別の不連続を作成するため、dxTmp
が0になるイベント、つまり1/(1+y*z) - x
がベクター出力の別のコンポーネントになるイベントが必要です。
ODEを再起動すると、Matlabはその時点で不連続性があると自動的に判断します。そのため、Matlabにはそこに存在することを心配する必要はありません。
次の問題は、Matlabのは非常に右のそれを達成したことがない、x
、y
、z
とX
の値は若干のマイナスになるということです。問題を作成するために起こっている場合はこのように、あなたは、デリバティブを計算する前に
if x < 0
x = 0;
end
でx
の値(同様に他の値)を補正することになるでしょう。しかし、これはローカルでx
の値を変更するだけです。したがって、の最終的なソリューションのx
のすべての負の値を0に変更することもできます。 をsol = dde23(ddefun, lags, sol, [tCurrent tEnd], options);
に入力する前にそれを変更しようとしないことをお勧めします。私はその試みをいくつか試してみました。
は、単純にはode45を使用して、その結果、時間ベクトルに遅延コンポーネントを追加することが可能です...あなたは非遅延入力 – Rasman
から遅延入力を分離することができた場合、これは可能ですか?私はそうは思わない。 'dde23'を使う全理由は、依存関係があるからです.Xは1時間前のYの値に依存しています。 – dumbmatter
あなたの方程式を投稿できますか? – Rasman