ドキュメンテーション

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

ode23

ノンスティッフ微分方程式の求解 — 低次数法

構文

  • [t,y] = ode23(odefun,tspan,y0)
  • [t,y] = ode23(odefun,tspan,y0,options)
  • [t,y,te,ye,ie] = ode23(odefun,tspan,y0,options)
  • sol = ode23(___)

説明

[t,y] = ode23(odefun,tspan,y0) は、tspan = [t0 tf] のときに、初期条件 y0 を使用して、微分方程式系 y'=f(t,y)t0 から tf まで積分します。解の配列 y の各行は、列ベクトル t に返される値に対応します。

すべての MATLAB® ODE ソルバーは、y'=f(t,y) の形式の方程式系、あるいは質量行列 M(t,y)y'=f(t,y) を含む問題を解くことができます。ode23s ソルバーは、質量行列が定数である場合にのみ、これを含む問題を解くことができます。ode15s および ode23t は、特異質量行列をもつ方程式、つまり微分代数方程式 (DAE) を解くことができます。odesetMass オプションを使用して質量行列を指定します。

[t,y] = ode23(odefun,tspan,y0,options)options (関数 odeset を使用して作成された引数) で定義された積分設定も使用します。たとえば、AbsTol オプションおよび RelTol オプションを使用して絶対許容誤差と相対許容誤差を指定したり、Mass オプションを使用して質量行列を指定することができます。

[t,y,te,ye,ie] = ode23(odefun,tspan,y0,options) はさらに、(t,y) の関数 (イベント関数) がゼロになる点を求めます。出力の te はイベント時点、ye はイベント時点における解、ie はトリガーされたイベントのインデックスです。

各関数に対して、ゼロで積分を終了するかどうかと、ゼロクロッシングの方向を考慮するかどうかを指定します。これを行うには、myEventFcn@myEventFcn などの関数に 'Events' プロパティを設定し、対応する関数 [value,isterminal,direction] = myEventFcn(t,y) を作成します。詳細については、「ODE のイベント検出」を参照してください。

sol = ode23(___) は、区間 [t0 tf] の任意の点で解を計算する関数 deval で使用できる構造体を返します。前述の構文にある任意の入力引数の組み合わせが使用できます。

すべて折りたたむ

単一解要素をもつシンプルな ODE は、ソルバーの呼び出し内に無名関数として指定できます。この無名関数は、2 つの入力 (t,y) を受け入れなければなりません (いずれかの入力が使用されない場合でも)。

次の ODE を解きます。

$$y' = 2t.$$

時間区間 [0,5] および初期条件 y0 = 0 を使用します。

tspan = [0 5];
y0 = 0;
[t,y] = ode23(@(t,y) 2*t, tspan, y0);

解をプロットします。

plot(t,y,'-o')

ファン デル ポールの方程式は次のように 2 次 ODE です。

$$y''_1 - \mu \left( 1 - y_1^2\right) y'_1+y_1=0,$$

ここで、 $\mu > 0$ はスカラー パラメーターです。 $y'_1 = y_2$ を代入して、この方程式を 1 次 ODE 系として書き換えます。その結果得られる 1 次の ODE は、次のようになります。

$$
\begin{array}{cl}
y'_1 &= y_2\\
y'_2 &= \mu (1-y_1^2) y_2 - y_1.\end{array}
$$

関数ファイル vdp1.m は、 $\mu = 1$ を使用するファン デル ポールの方程式を表します。変数 $y_1$ $y_2$ は、2 要素ベクトル dydt の要素 y(1) と要素 y(2) です。

function dydt = vdp1(t,y)
%VDP1  Evaluate the van der Pol ODEs for mu = 1
%
%   See also ODE113, ODE23, ODE45.

%   Jacek Kierzenka and Lawrence F. Shampine
%   Copyright 1984-2014 The MathWorks, Inc.

dydt = [y(2); (1-y(1)^2)*y(2)-y(1)];

関数 ode23 を使用し、初期値 [2 0] を指定して、時間区間 [0 20] でこの ODE の解を求めます。その結果、出力として時間の列ベクトル t と解の配列 y が得られます。y の各行は、t の対応する行に返される時刻と対応します。y の 1 列目は $y_1$ に対応し、2 列目は $y_2$ に対応します。

[t,y] = ode23(@vdp1,[0 20],[2; 0]);

$y_1$ および $y_2$ の解を t に対してプロットします。

plot(t,y(:,1),'-o',t,y(:,2),'-o')
title('Solution of van der Pol Equation (\mu = 1) with ODE23');
xlabel('Time t');
ylabel('Solution y');
legend('y_1','y_2')

ode23 は、2 つの入力引数 ty を使用する関数にのみ使用できます。しかし、関数の外部で定義した追加のパラメーターを、関数ハンドルを指定するタイミングで渡すことができます。

次の ODE を解きます。

$$y'' = \frac{A}{B} t y.$$

この方程式を 1 次系として書き直すと次のようになります。

$$\begin{array}{cl} y'_1 &= y_2\\ y'_2 &= \frac{A}{B} t y_1.
\end{array}$$

odefcn.m はこの方程式系を 4 つの入力引数 (tyAB) を受け入れる関数として表します。

function dydt = odefcn(t,y,A,B)
dydt = zeros(2,1);
dydt(1) = y(2);
dydt(2) = (A/B)*t.*y(1);

ode23 を使用して ODE を解きます。事前定義された AB の値を odefcn に渡す関数ハンドルを指定します。

A = 1;
B = 2;
tspan = [0 5];
y0 = [0 0.01];
[t,y] = ode23(@(t,y) odefcn(t,y,A,B), tspan, y0);

結果をプロットします。

plot(t,y(:,1),'-o',t,y(:,2),'-.')

ode45 と比較すると、ode23 ソルバーは粗い許容誤差を指定して問題を解く場合により優れています。

中程度にスティッフな ODE を解いて ode45ode23 のパフォーマンスを比較します。

$$y' = -\lambda y$$

ここで、 $\lambda = 1000$ です。この ODE は $\lambda$ が大きくなるにつれて、よりスティッフになるテスト方程式です。odeset を使用してソルバー統計の表示をオンにします。

opts = odeset('Stats','on');
tspan = [0 2];
y0 = 1;
lambda = 1e3;
subplot(1,2,1)
disp('ode45 stats:')
tic, ode45(@(t,y) -lambda*y, tspan, y0, opts), toc
title('ode45')

subplot(1,2,2)
disp(' ')
disp('ode23 stats:')
tic, ode23(@(t,y) -lambda*y, tspan, y0, opts), toc
title('ode23')
ode45 stats:
615 successful steps
35 failed attempts
3901 function evaluations
Elapsed time is 1.919206 seconds.
 
ode23 stats:
822 successful steps
2 failed attempts
2473 function evaluations
Elapsed time is 0.945105 seconds.

この中程度にスティッフな問題の場合、ode23 の方が ode45 よりも実行時間がわずかに短く、失敗したステップも少なくなります。この問題に対して ode45 および ode23 がとるステップ サイズは、精度ではなく方程式の安定性要件によって制限されます。ode23 がとるステップは ode45 のステップよりも負荷が少ないため、ode23 ソルバーはより多くのステップを処理するにもかかわらず速く実行できます。

入力引数

すべて折りたたむ

求解する関数。積分する関数を定義する関数ハンドルとして指定します。

スカラー t および列ベクトル y をとる関数 dydt = odefun(t,y) は、データ型が single または doublef(t,y) に対応する列ベクトル dydt を返さなければなりません。odefun は、ty のいずれかの引数が関数で使用されない場合でも、両方の入力引数を受け入れなければなりません。

たとえば、y'=5y3 を解くには、次の関数を使用します。

function dydt = odefun(t,y)
dydt = 5*y-3;

方程式系の場合、odefun の出力はベクトルです。ベクトルの各要素は 1 つの方程式の解です。たとえば、

y'1=y1+2y2y'2=3y1+2y2

を解くには、次の関数を使用します。

function dydt = odefun(t,y)
dydt = zeros(2,1);
dydt(1) = y(1)+2*y(2);
dydt(2) = 3*y(1)+2*y(2);

関数 odefun に追加パラメーターを指定する方法の詳細については、「関数のパラメーター化」を参照してください。

例: @myFcn

データ型: function_handle

積分区間。ベクトルとして指定します。少なくとも、tspan は開始時点と終了時点を指定する 2 要素ベクトル [t0 tf] でなければなりません。t0tf の間の特定時点における解を取得するには、[t0,t1,t2,...,tf] の形式の長いベクトルを使用します。tspan の要素は、単調増加または単調減少でなければなりません。

ソルバーは、tspan(1) での初期条件 y0 を設定し、tspan(1) から tspan(end) まで積分します。

  • tspan に要素が 2 つある場合 [t0 tf]、ソルバーは区間内の個々の内部積分ステップで計算した解を返します。

  • tspan に 2 個より多い要素 [t0,t1,t2,...,tf] が含まれる場合、ソルバーは指定された各点で計算した解を返します。これはソルバーが tspan(1) から tspan(end) に進むときに使用する内部ステップに影響 "しません"。したがって、ソルバーは必ずしも tspan で指定された各点に正確にステップするとは限りません。しかし、指定された点で出力された解の精度の次数は、各内部ステップで計算された解と同じです。

    中間点をいくつか指定しても計算効率にほとんど影響しませんが、大規模な系の場合はメモリ管理に影響を及ぼす可能性があります。

ソルバーで得られる解は、tspan を 2 要素ベクトルとして指定するか、中間点を含むベクトルとして指定するかによって異なる場合があります。tspan にいくつかの中間点が含まれる場合、これは問題のスケールを示し、ソルバーが使用する初期ステップのサイズに影響を及ぼすことがあります。

例: [1 10]

例: [1 3 5 7 9 10]

データ型: single | double

初期条件。ベクトルとして指定します。odefun に定義された各方程式の初期条件を y0 に含めるために、y0odefun のベクトル出力と同じ長さでなければなりません。

データ型: single | double

オプション構造体。構造体配列として指定します。options 構造体の作成または変更を行うには、関数 odeset を使用します。各 ODE ソルバーと互換性のあるオプションの一覧については、「ODE オプションの概要」を参照してください。

例: options = odeset('RelTol',1e-5,'Stats','on','OutputFcn',@odeplot) は、相対許容誤差 1e-5 を指定し、ソルバー統計の表示をオンにして、解の計算時に解をプロットする出力関数 @odeplot を指定します。

データ型: struct

出力引数

すべて折りたたむ

評価点。列ベクトルとして返されます。

  • tspan に 2 つの要素 [t0 tf] が含まれる場合、t には積分の実行に使用される内部評価点が含まれます。

  • tspan に 2 つより多い要素が含まれる場合、ttspan と同じです。

解。配列として返されます。y の各行は、t の対応する行に返される値での解です。

イベント時点。列ベクトルとして返されます。te のイベント時点は ye に返された解に対応し、ie は発生したイベントを指定します。

イベント時点での解。配列として返されます。te のイベント時点は ye に返された解に対応し、ie は発生したイベントを指定します。

零点イベント関数のインデックス。列ベクトルとして返されます。te のイベント時点は ye に返された解に対応し、ie は発生したイベントを指定します。

評価対象の構造体。構造体配列として返されます。この構造体を関数 deval と共に使用して区間 [t0 tf] の任意の点で解を評価します。構造体配列 sol は、常に以下のフィールドを含みます。

構造体フィールド説明

sol.x

ソルバーによって選択されたステップの行ベクトル。

sol.y

解。各列の sol.y(:,i) には、時点 sol.x(i) での解が含まれます。

sol.solver

ソルバー名。

さらに、Events オプションを指定してイベントが検出された場合、sol は以下のフィールドも含みます。

構造体フィールド説明

sol.xe

イベントが発生した点。sol.xe(end) には、終了イベントの厳密な点 (存在する場合) が含まれます。

sol.ye

sol.xe のイベントに対応する解。

sol.ie

Events オプションに指定された関数により返されるベクトルのインデックス。値は、どのイベントをソルバーが検出したかを示します。

詳細

すべて折りたたむ

アルゴリズム

関数 ode23 もまた、Bogacki と Shampine の陽的 Runge-Kutta (2,3) に基づいています。粗い許容誤差を使用する場合や中程度にスティッフである場合、関数 ode45 より効率的なことがあります。ode23 は単一ステップ ソルバーです [1][2]

参照

[1] Bogacki, P. and L. F. Shampine, “A 3(2) pair of Runge-Kutta formulas,” Appl. Math. Letters, Vol. 2, 1989, pp. 321–325.

[2] Shampine, L. F. and M. W. Reichelt, “The MATLAB ODE Suite,” SIAM Journal on Scientific Computing, Vol. 18, 1997, pp. 1–22.

参考

| | | |

R2006a より前に導入

この情報は役に立ちましたか?