Dslとは?
Dsl (Digital Simulation Library for .Net) は(C# で記述されています) 汎用数値シミュレーション用のクラスライブラリーです。
注意事項: |
---|
※本説明の読者は Microsoft .Net と、少なくとも C# を使用したプログラミングの知識を有しているものとします。 ※メールアドレス表記は SPAM 対策として名前部分が「dsl←半角」となっています。送信の際は半角小文字の「dsl」に変更してください。 |
Dslは数値シミュレーション上の困難なプログラミング作業を簡単にして「計算モデルの構築と解析」という本来の創造活動を支援します。
具体的には
- 計算順序はDslが決定するので利用者は右辺と左辺の関係式を一度記述するだけです。
- 最終的に値を知りたい変数を指定することで、その変数を計算するのに不要な変数・計算式は無視されます。
- 必要に応じてDslは連立方程式を自動的に組み立てて解きます。
- 値を求めたい対象(変数)等の条件が変わればDSLが計算順序と連立方程式を再構築して計算します。
- 静的モデルだけでなく時間に関する常微分方程式を含む動的なシミュレーションに対応しています。
- 動的モデルの場合、定常状態(時間に関する微係数がゼロになる状態)を直接求めることが可能です。
- 各種の数値解法をオブジェクト化した数値計算クラスライブラリー Mol (Math Object Library) for .Net をそのまま利用可能です。
当然ながら、以下のような各種解法(ソルバー・エンジン・ツール)が用意されています。
- 計算順序を決定するためのグラフ処理エンジン
- (非線形)連立方程式を解くために Newton 法
- 常微分方程式を解くために Runge-Kutta 法等の各種積分法
- モデル解析やデバッグ用に変数一覧や折れ線グラフを描く便利な結果の表示用のツールが用意されています。
- グラフ処理は計算順序の決定、不要な変数や計算式の削除、大型の連立方程式をより小型の連続した連立方程式に分解するために用いられます。
- 非線形連立方程式を解く場合「微分係数行列(Jacobian行列)」を作成する必要がありますが、利用者が面倒な微分式を用意する必要はありません(数値微分が適用されます)。
- また、Jacobian行列を係数行列とした線形連立方程式を繰り返し解く必要がありますが、CPUに最適化されたインテル社の インテル® MKL - (代理店) ライブラリー(Mol)による高速解法が採用されています(Jacobian行列の非ゼロ要素が少ない場合、自動的にスパース行列解法(PARDISO)に移行します)。
プログラミング概略
Dslでは以下の2つのオブジェクトが重要です。
Variable(変数)は必ず Processor に登録される必要があります。Processor は登録された Variable を計算順序に従って並べ、連立方程式や常微分方程式を組み立てて解きます。 Variable は値(double Value)、計算式(delegate ComputeValueAt)、属性(USERFLAG Flag)、そして右辺変数の配列を持ちます。 Variable の属性は例えば「値が計算の結果として指定した値になる」とか「値はわかっているので計算不要」等といった性質を指定できます。プログラミングは大体以下のようなスタイルになります(詳細はグラフ処理の項を参照してください)。
以下、最も簡単な Y = X1 + X2 という計算式を例として説明します。 式は Y = X1 + X2 と単純ですが、
-
X1 と X2 の値が分かっている場合に Y の値はいくつか?
-
X2 の値が分かっていて、Y が特定(Wとします)の値になるとき X1 の値はいくつか?
といったことが考えられます。重要なのは Y = X1 + X2 と一度記述するだけで上記2つのケースに対応できるということです。Dslは数式処理システムではありませんので(2番目の例で)一度記述した計算式 Y = X1 + X2 を X1 = Y - X2 と変形することはできません。その代り Y - w = f(X1) => 0 と数値的に解きます。
コードをコピー | |
---|---|
// Processor オブジェクトの作成. Processor pr = new Processor("最も簡単な例"); // "最も単純な例"は pr.Name に設定されます. // 因果関係 Y = X1 + X2 の定義. Variable Y = new Variable(pr,"Y"); // Y を作成すると同時に Processor(=pr) に登録します. Variable X1= new Variable(pr,"X1"); Variable X2= new Variable(pr,"X2"); Y.SetRightSideVariables(X1,X2); // Y の右辺は X1 と X2。以下の ComputeValueAt の記述内、rhsvs で参照されます. // Y = X1 + X2 の定義(delegate で計算式を定義する). // 「Y.Value = X1.Value + X2.Value」 と書いてはいけません(Dsl が計算順序と実際の計算を実行するので). Y.ComputeValueAt = delegate(Processor pr, Variable self,double time,double step) { List<Variable> rhsvs = self.RightSideVariables; // selfは Y、rhsvsは Y の右辺変数の配列(最初は X1、次が X2). return rhsvs[0].Value + rhsvs[1].Value; // X1 + X2 の値を返す( rhsvs[0]は X1、rhsvs[1]は X2). // return X1.Value + X2.Value; と記述してもかまいませんが、上記の記述形式をお勧めします. }; // 各変数のフラグ(Flag)と値の設定. X2.Value = 1.0; X2.Flag = USERFLAG.SET; // X2=1.0 で定数とする. Y.Value = 0.0 ; Y.Flag = USERFLAG.TARGETED; // Y は計算の結果値が 0 になる必要がある. X1.Value = 1.0; X2.Flag = USERFLAG.REQUIRED; // X1 は Y = 0 にするための独立変数。 => Newton 法で方程式(Y(X1)=0)を解く必要あり(初期値 1.0). // 計算順序と連立方程式(この例では1次元の方程式)の組み立. if (gr.DeterminateOrder() == RESULT.OK) { // 成功すれば、計算を実行する. gr.Run(); } |
上の例では Y.Flag = USERFLAG.TARGETEDとして、Yの値を 0 にする X1を(方程式を解いて)求めていますが、 Y.Flag = USERFLAG.REQUIRED;X1.Value = 1.0; X1.Flag = USERFLAG.SET; とすれば、単純に X1+X2 の値を Y に代入するだけで方程式を解く必要がなくなります。重要なのは、利用者は変数(Variable)にフラグを設定するだけで、 計算順序の決定などは Processor オブジェクトが実行することです。
注意事項: |
---|
※オブジェクト指向プログラミングでは「クラス」と「インスタンス」を明確に区別します。しかし、本説明では両者を「オブジェクト」として(特に必要な場合を除いて) 区別せずに同じ用語を用います。 |
グラフ処理とは?
大規模なシミュレーションでは変数が大量になると同時に、与える条件等も複雑になります。 「入力を与えて出力を計算」する、逆に「所望の出力を得るために入力を計算」する場合等、 条件も様々です。与える条件を変えるたびにプログラムを書き換えていたのでは非効率なのは明らかです。 Dsl は大規模で複雑な変数相互の関係と条件を「グラフ処理」を適用して整理、 因果関係を構築、計算順序を決定してから計算を実行します(利用者は右辺と左辺の計算式を一度記述するだけです)。
ここでいう「グラフ」とは左辺変数(複数可)から矢印が出て右辺変数(一個)に入る変数(ノード)同士の接続関係のことです(有向グラフ)。 平面上に描かれるいわゆる折れ線グラフとは違います。
詳細は以下の章(具体的な処理を詳述しています)を参照してください。
注意事項: |
---|
|
インストールとライセンスについて
Dslはクラスライブラリー(DLL)です。 利用者は自身で作成するソフトウェア(EXE・DLL)と同じフォルダに Dsl の DLL をコピーしてください。 ダウンロードした Dsl は評価版ですが、ライセンスを(購入)設定すれば正式利用が可能になります。 購入方法等詳細は こちら を参照してください。