最近の更新 (Recent Changes)

2014-01-01
2013-01-04
2012-12-22
2012-12-15
2012-12-09

Wikiガイド(Guide)

サイドバー (Side Bar)


← 前のページに戻る

1.2 ODE モデル

以下に、標準的なODE機能を使った常微分方程式の解き方のモデルを示します。


? ::sys <PrintResultOff>
  <letf 定数の設定>
     ...
  <letf 定数の設定>

  <letf 変数の初期値の設定>

  <print 出力変数名を","で区切って表示>
  ::sys <ODE (#t 初期値 終地 刻み値)


        <letf 微分方程式の計算>
        ::sys <integral #積分値の計算>
 
        ::sys <ODEprint 出力間隔 出力変数値を","で区切って表示>

  >
  ;

このモデルの計算例を示しましょう。これはロケットの打ち上げの説明のときに使ったプログラムです。


? ::sys <PrintResultOff>
  <letf #g = 9.8>            //定数の設定
  <letf #M = 375>            //定数の設定
  <letf #mi = #M>            //定数の設定
  <letf #Isp = 440>          //定数の設定
  <letf #xi = 0>

  <print "t,x,v,a,m">        //出力変数名を","で区切って表示 
  ::sys <ODE (#t 0 200 0.1)   
        <letf #'dm/dt' = -1.575>       // 微分方程式の計算
        ::sys <integral #m #'dm/dt' #mi>   // 積分値の計算

        <letf #v = #Isp * #g * ::sys <log _ <letf _ = #M / #m>>>  // 微分方程式の計算
        ::sys <integral #x #v #xi>                                // 積分値の計算
        ::sys <ODEdiff #a #v>                                     // 微分値の計算

        ::sys <ODEprintf 100 #t "," #x "," #v "," #a "," #m <\_n>> //出力変数値を","で区切って表示 

  >
  ;

この例では、微分方程式が2つ入っています。

ODE機能では、微分方程式はとりあえず値を計算してそれをintegral述語に入れれば計算結果を得ることができるのです。 微分値も同様に簡単にODEdiff述語を使うと計算できます。

最後に計算結果は、","で区切って表示することによって、CSV(Comma Separated Values)形式として、Excelなどの表計算ソフトで読み込んでグラフ化などの処理を行うことができるのです。

次に微分方程式で導関数と同じ変数を使っている場合のモデルについて説明します。

例えば以下の微分方程式を参照してください。


dv
-- = -g - B * v
dt

これは、空気抵抗のあるときの自由落下の式ですが、導関数dv/dtで右辺にvという変数が現れています。

このようなときには先に示したようなモデルではvの値が決められません。

そこで次のようにします。


/* 空気抵抗のある自由落下 */

? ::sys <PrintResultOff>
  <letf #g = 9.8>
  <letf #B = 0.8>
  <letf #xi = 100>
  <letf #vi = 80>
  <setVar var_x #xi>
  <setVar var_v #vi>   // 変数vの初期値をグローバル変数に設定

  ::sys <ODE (#t 0 11 0.1)

        <var_v #v>    // 変数vの値をグローバル変数から取得

        <letf #'dv/dt' = - #g - #B * #v>  // 変数#vを使用
        ::sys <integral #v2 #'dv/dt' #vi>
        ::sys <integral #x2 #v2 #xi>

        <printf #t "," #x2 "," #v2 <\_n>>

        <setVar var_v #v2>  // 次のvに備えて新たに計算した#v2をグローバル変数vに設定する。
  >
  ;


グローバル変数に初期値として設定しておき、ODE述語内では毎回値を取り出して、計算しなおした結果をグローバル変数に設定しなおします。

このようにすることによって、導関数に含まれる変数が、微分方程式内にあっても計算することが可能になります。

これをモデル化すると次のようになります。


? ::sys <PrintResultOff>
  <letf 定数の設定>
     ...
  <letf 定数の設定>

  <letf 変数の初期値の設定>
  <setVar 変数vの初期値をグローバル変数に設定> // ←

  <print 出力変数名を","で区切って表示>
  ::sys <ODE (#t 初期値 終地 刻み値)
       変数の値をグローバル変数から取得        // ←

        <letf 微分方程式の計算>
        ::sys <integral #積分値の計算>
 
        ::sys <ODEprint 出力間隔 出力変数値を","で区切って表示>

        <setVar 上で計算した変数をグローバル変数vに設定する>  // ←
  }
  ;

"// ←"となっている部分を前の例題やモデルと比べて見てください。