Mathematics | ![]() ![]() |
質問と回答とトラブルシュート
この節では、MATLABのODEソルバの使用法やオペレーションについての質問と回答のテーブルをいくつか用意しています。
質問 |
回答 |
ODEソルバは、quad 、または、quadl とどのように異なりますか。 |
quad とquad8 は、 ![]() ![]() ![]() |
未知数の数より方程式が多いときやその逆のとき(未知数の数より方程式が少ない時)、ODEシステムを解くことができますか。
|
できません。 |
質問 |
回答 |
ODE suiteでどのくらいの大きさの問題を解くことができますか。 |
基本的な制限は、メモリサイズとシミュレーション時間です。各ステップ毎に、ノンスティッフな問題に対するソルバは、長さn のベクトルを割り当てます。ここで、n は、システムの方程式の数です。スティッフな問題に対するソルバは、長さn のベクトルを割り当てるだけでなく、n
行 n 列のヤコビアン行列も割り当てます。これらのソルバでは、スパース行列を利用するのが有効です。問題がスティッフでないか、スパースオプションを使った場合は、数千の未知数をもつ問題を解くことができる可能性があります。しかしながら、この場合も結果を維持するためのストレージが問題になります。ソルバに特別な点のみで解を計算させたり、または、出力引数を設定しないでソルバをコールしたり、解をモニタするために出力関数を使ったりすることを試みてください。 |
非常に大きなシステムを解いている時でも、 y の中のほんの2、3の要素のみしか必要でない場合があります。不要な要素をストアしない方法が何かありますか。 |
あります。ユーザが設定する出力関数を作成することで、この問題に対応できます。ソルバの読み込みに出力引数を設定しなかった場合、ソルバは、全ての要素の履歴を保存するための領域を割り当てません。その代わりに、ソルバは、OutputFcn(t,y) を各時間ステップ毎にコールします。特定の要素の履歴を保持するためには、対象となる要素だけをストアする出力関数を記述し、それをプロットするように記述します。 |
積分計算の立ち上がり部分でどのくらいのCPU時間がかかりますか。また、それはどのようにすれば軽減できますか。 |
立ち上がりで、最も時間のかかるのは、問題のスケールに合ったステップサイズを見つけようとすることに依るものです。もし、適切なステップサイズが分かっている場合、プロパティInitialStep を使ってください。例えば、イベントの発生位置を含むループで積分器を繰り返し読み込むとき、イベントの前の最後のステップサイズは、おそらく、つぎの積分計算にとっても適切なスケールと考えられます。例題としては、ballode を見て下さい。 |
質問 |
回答 |
積分が採用した初めのステップサイズが大きすぎて、重要な振る舞いを見失いませんか。 |
プロパティInitialStep
で最初のステップサイズは設定できます。積分器は、この値を、まず利用し、必要ならばさらに小さくします。 |
一定ステップ幅で積分計算できますか。 |
いいえ。 |
質問 |
回答 |
どのようにして、RelTol とAbsTol を決めれば良いでしょうか。 |
RelTol は、相対的な精度を示す許容誤差値で解の正しい桁数をコントロールします。AbsTol は、絶対的な許容誤差値で真の解と計算された値との差をコントロールします。各時間ステップで、解の中のi
番目の要素のエラーe
が次の条件を満たす必要があります。|e(i)| <= max(RelTol*abs(y(i)),AbsTol(i)) 大雑把に言って、このことは、スレッシュホールド AbsTol(i) より小さいものを除いて、すべての解成分で、RelTol の正しい桁をもとうとすることを意味しています。すなわち、ソルバは、AbsTol(i) よりも小さい解に対して、正しい桁数を保証します。もし、問題がスレッシュホールドをもつならば、それをAbsTol として使ってください。
y(i) の値が、小さくて、興味がもてない場合でさえ、y(i)
の中のある正しい桁を得るために、十分小さい AbsTol(i)
に設定しなければなりません。そして、より興味のある要素を精度良く計算できます。 |
コンピュータの計算の精度と同等の精度の答えが欲しいのですが、単純にRelTol をeps にしてはいけないのでしょうか。 |
マシンの精度に近い値を得ることはできますが、その方法では近い値ということだけです。連続な関数を近似しようとするため、ソルバではeps に近い値をRelTol として利用できません。許容誤差値をeps にすると、マシンの計算は、全ての関数が不連続であるとみなすことになります。 |
解のある1つの要素の答えの精度には興味が無いことを設定するには、どのようにすれば良いでしょうか。 |
その要素に対応する絶対許容誤差値を大きくすることができます。許容誤差値がその要素よりも大きいならば、その要素は、正しい桁数には設定されません。他の要素を正確に計算するために、この要素から正しい桁数を設定しなければなりませんが、一般的に、このような操作は自動的に行なわれません。 |
質問 |
回答 |
ライン手法で離散化してPDEを取り扱うことができますか。 |
できます。離散化されたPDEは、ODEのシステムになります。離散化によって、質量行列を含んだ形になるかもしれません。そして、それに対する
MATLAB ODE
ソルバが用意されています。しばしば、システムはステッフになります。これは、ODE
が放物線型や、流体内での化学反応のような非常に異なる時間スケールで生じる現象の場合に期待されるようなものです。このような場合、4つのソルバ、ode15s ,
ode23s , ode23t , ode23tb
が用意されています。このシステムはしばしばスティッフになります。PDEが放物線の型であるときや液体の流動による化学反応のように異なる時間スケールで起こる現象があるときに、この事が予測されます。このような場合、ode15s かode23s を使ってください。普通、多くの方程式がある場合、プロパティJPattern を設定してください。これは、簡単なことですが、非常に計算時間がかかるため上手く行くときと失敗するときで大きな差が出ます。システムがスティッフでないとき、あるいは、それほどスティッフではないときには、ode23 やode45 が、ode15s,
ode23s , ode23t , ode23tb より有効です。1次の放物線-楕円型偏微分方程式は、MATLAB
PDE ソルバ pdepe.
で直接解くことができます。詳細は、偏微分方程式を参照してください。 |
微分代数方程式を解けますか |
はい、ソルバ ode15s
とode23t は、![]() ![]() amp1dae
や hb1dae を参照してください。 |
サンプリングされたデータによるシステムを積分できますか |
直接的には無理です。補間やその他のデータフィッティングの手法を使って関数としてデータを表現しなければなりません。この関数の平滑化には危険があります。スプラインのような区分的多項式で置き換えた場合、一見滑らかにみえますが、ソルバにとっては不連続になっています。微分値が不連続になる点で、ソルバは非常に細かいステップを要求されます。データを表現する滑らかな関数を使用するか、感度的に落ちる低次のソルバ(ode23 , ode23s , ode23t , ode23tb )を使用するかのどちらかを行ってください。 |
遅れを持った微分方程式を解けますか |
直接的には無理です。いくつかのケースでは、1回の遅れ時間より小さな時間ステップで分割してシミュレーションを行うことによって、遅れをもった微分方程式を解くために、初期値問題ソルバを使うことができます。詳細は、[5]を参照してください。 |
最終時間での値は分かっているが、初期値が分からない場合どうしますか。 |
このバージョンのMATLAB ode suiteのode45や他のソルバでは時間について後ろ向きにもにも、前向きにも解くことができるので可能です。ソルバの書式は、つぎのようになります。[t,y] = ode45(odefun,[t0 tf],y0); and the syntax accepts t0 > tf . |
質問 |
回答 |
計算結果が予想していたものと異なります。 |
予想が正しいのであれば、許容誤差値をデフォルトより小さくする必要があります。長すぎる時間間隔で積分した問題や、同様に少し不安定な問題の解を正確に計算するためには、より小さな相対的許容誤差値で計算する必要があります。ある時間において、求めた解のある要素がそれに対応する絶対的許容誤差値よりも小さくなっていないかチェックすべきです。もしそうならば、これらの要素について何桁の精度をもっているかを調べる必要はありません。これらの要素については、この現象は当然で、正確に計算できていない要素のために、それらに依存している他の要素の精度も落ちているかもしれません。 |
プロットが十分滑らかではありません。 |
デフォルトでは、ode45
で4 、その他で1 となっているRefine の値を増やして下さい。Refine を大きくするほど、出力点数は多くなります。計算速度には、Refine の値は、ほとんど影響がありません。 |
計算できたところまでをプロットした結果は良いように見えますが、計算がある値で、止まってしまいました。 |
初めに、計算が止まる点の近くでODE関数が、滑らかかであるかを確認して下さい。そうでなければ、その部分で、もっと小さな時間刻みが必要になっています。tspan の値をODEファイルの滑らかなところでいくつかに分割することも良いかもしれません。
関数は、滑らかで計算が小さなステップ幅で進むのであれば、この問題を解こうとしたのとは別のスティッフソルバを使ってみてください。 ode15s , ode23s , ode23t , ode23tb に変えてシミュレーションしてください。 |
大変多くの時間ステップを使うので積分計算が非常に遅くなります。 |
初めに、tspan にあまり多くの点を設定していないかどうかを調べて下さい。ソルバは、なめらかな計算結果を出力するために必要なだけ多くの時間ステップで計算します。tspan に比べて非常に小さい時間スケールでODE関数が変化している場合、多くの時間ステップが必要になります。積分計算に長い時間がかかることは大きな問題です。tspan を小さくして計算してみて下さい。tspan の上で、ODE関数が目立って変化していないようであれば、その問題がスティッフであろうと考えられます。ode15s , ode23s ,
ode23t , ode23tb
を使ってみてください。最後に、ODE関数が効率よく記述されているかを確かめて下さい。ODE関数で微係数が何回も計算されます。数値積分に要する時間は、ODE関数の計算に非常に大きく関わっています。複雑な計算になっている定数値をODE関数の計算のたびに計算し直すより、むしろ、これらをグローバルに値をストアしておくか、関数の外部で計算しておき、追加の引数として関数に引き渡した方が良いでしょう。 |
時間t で解が急変することが分かっているのに、この点を見失って積分計算を行ってしまいました。ここで
|
時間t で急変することが分かっているのならば、tspan の間隔を[t0
t] と[t tf] の2つに分けて、2回計算するのが良いかもしれません。微分方程式が、周期的な係数、または、解をもっている場合、周期長に最大ステップサイズを設定し、ステップが周期長より大きくならないようにしてください。 |
![]() |
例題:ODE 初期値問題ソルバの適用 | ODE に対する境界値問題 | ![]() |