6

MATLAB には、解が非負になるように制約するode45というパラメーターがあります。彼らは、このメソッドがどのように機能するか、そして y_i が負になるたびに y_i を 0 に設定することは一般的に機能しないため、愚かなことではないことについての論文を書きました。NonNegative

現在、MATLAB にはdde23遅延微分方程式を解くための機能もありNonNegativeますが、この積分器に相当するパラメーターはありません。

ode45残念ながら、私は既存のODE システムに遅延を追加する任務を負っていNonNegativeます。

どのように進めればよいですか?

編集:

これが役立つかどうかはわかりませんが...

私のシステムの DDE 部分は基本的に次のようになります。

 dx = 1/(1+y*z) - x;
 dy = (y*z)^2/(1+(y*z)^2) - y;
 dz = X - z;

ここでX(3 番目の式の大文字の変数) は の遅延バージョンですxx次に、との方程式にいくつかの項を追加して、この DDE システムを既存の (およびより大きな) ODE システムにリンクしz、結合したシステムをすべて統合します。

4

3 に答える 3

2

あなたには難しい問題があり、ワンステップの解決策があるかどうかはわかりません。代わりの答えを喜んで提供してくれる人に称賛を提供できれば幸いです。

遅延の長さに応じて、1つのオプションは、方程式を数回実行し、各反復でxの古い値を最新の更新に渡すことです。

たとえば、遅延が1時間だとします。最初の1時間で、NonNegativeのフラグを付けてode45を実行します。値をTimeパラメーターとともに新しいマトリックスに格納し、アルゴリズムを再実行します。今回は、古いソリューションマトリックスと古い時間マトリックスの2つの入力パラメーターを追加してください。

dx = 1/(1+y*z) - x; 
dy = (y*z)^2/(1+(y*z)^2) - y;
tindex = find(told>t,1) -1 % find the upper index which best approximates t
X = xold(tindex) + (xold(tindex+1)-xold(tindex))*(t-told(tindex))/(told(tindex+1)-told(tindex)) % or interpolation method of your choosing
dz = X - z;

今度は洗って、すすぎ、そして繰り返します。ode45の例3に示すように、Xは準時間依存の項になっていることに注意してください。

于 2011-08-08T21:07:29.213 に答える
2

最近、私のコードでこの問題が発生しました。「最も簡単な」解決策は、次のことを行うことです。まず、解決策が 0 に達したら、それを 0 に保つ必要があるため、

dx = 1/(1+y*z) - x; 

x == 0to (ケースが評価される場所に注意してください)

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かのイベントが必要です。つまり、ベクトル出力の別のコンポーネントになります。dxTmp1/(1+y*z) - x

ODE を再起動すると、Matlab はその時点で不連続性があると自動的に想定するため、Matlab に不連続性があることを伝えることを心配する必要はありません。

次の問題は、Matlab がそれを正しく達成することは決してなくx、 、yzおよびの値Xがわずかに負になることです。したがって、問題が発生する場合は、の値x(および他の値も同様に) を次のように修正する必要があります。

if x < 0
  x = 0;
end

導関数を計算する前に。しかし、これはxローカルの値を変更するだけです。xそのため、最終解の のすべての負の値も 0 に変更したい場合があります。sol入力する前に変更しようとしないことをお勧めします。私はそれを何度もsol = dde23(ddefun, lags, sol, [tCurrent tEnd], options);試みましたが、機能させることができませんでした。

于 2013-12-02T02:12:09.203 に答える
-2

最適化を設定するために使用する、はるかに簡単な答えがあります。createOptimProblemこのメソッドを使用してすべてのパラメーターの境界を含める必要がありますが、パラメーターを強制的に正のままにするのは簡単です。

詳細はこちら: http://www.mathworks.com/help/gads/createoptimproblem.html

于 2015-04-09T16:26:57.557 に答える