1

単純なifループを使用して、odeスクリプト内のパラメーター値を変更しています。これは私が書いた同じ問題を示すスクリプトの例です。したがって、最初に機能するバージョンは次のとおりです。

function aah = al(t,x)

if (t>10000 && t<10300)
    ab = [0; 150];
else
    ab = [150; 0];
end

aah = [ab];

これは、を使用して実行できます

t = [0:1:10400];
x0 = [0,0];
[t,x] = ode23tb(@al, t,x0);

と視覚化

plot(t,x(:,1))
plot(t,x(:,2))

わかりました、それは良いバージョンです。今、あなたがするのがtをに変更することだけなら

t = [0:1:12000];

全部が爆破します。グラフを平均化するのはMATLABだと思うかもしれませんが、それは

x(10300,2) 

コードが変更されていないため、どちらの場合も答えは同じであるはずです。しかし、この2番目のバージョンは0を出力しますが、これは間違っています。

一体何が起こっているのですか?誰かアイデアがありますか?

助けてくれてありがとう

4

1 に答える 1

3

関数は一定であるため(10000 <t <10300を除く)、内部ソルバーは非常に大きな時間ステップ(デフォルトでは合計時間の10%)でシステムの解決を開始します。(適応常微分方程式ソルバーでは、システムが一定の場合、高次と低次の解は同じ解を与え、(推定)誤差はゼロになります。したがって、ソルバーは現在の時間ステップで十分であると想定します。)tspan開始時間と終了時間の2つの要素だけで与えるかどうかを確認してください。

t = [0 12000];

通常、tspanはソルバーの内部時間ステップには影響しません。ソルバーは、内部の時間ステップでシステムを解き、tspanユーザーが指定したとおりに補間します。したがって、内部タイムステップが残念ながら間隔[10000、10300]を「飛び越え」た場合、ソルバーは間隔を認識しません。

したがって、最大ステップサイズを300よりも比較的小さく設定することをお勧めします。

options = odeset('MaxStep', 10);
[t, x] = ode23tb(@al, t, x0, options);

常に小さなステップサイズで解きたくない場合(および関数が一定でない場合を「知っている」場合)は、個別に解く必要があります。

t1 = [0 9990];
t2 = [9990 10310];
t3 = [10310 12000];

[T1, x1] = ode23tb(@al, t1, x0);
[T2, x2] = ode23tb(@al, t2, x1(end,:));
[T3, x3] = ode23tb(@al, t3, x2(end,:));

T = [T1; T2(2:end); T3(2:end)];
x = [x1; x2(2:end,:); x3(2:end,:)];
于 2012-11-22T03:56:38.970 に答える