================================== モデルの計算順序 ================================== Delverでは、算式のロジックを定義することにより生命保険モデルを表現することができますが、 内部では変数・関数間の参照関係を解析し計算順序を定め、計算しています。 * モデルに **循環参照がある場合にはエラー** となります。 モジュール間の参照関係 -------------------------------- **モジュール間で参照関係が循環していてはいけません** * 例えば、モジュールAの変数 -> モジュールBの変数 -> モジュールAの変数 のような参照関係があってはいけません モジュール内の参照関係 -------------------------------- .. hint:: 以下で説明する内容はやや複雑です。モデリングする際には、以下に気をつけていれば問題ありません。 * 循環参照をしておらず、タイムステップごとのループを含めて順序良く計算していくことで計算できること * 配列型の変数を参照する場合に、プログラムに参照の方向を教えるために、 必要に応じて(x-1), (x), (x+1)といったインデックスを使って参照すること 参照方向 ................................ 参照方向には、以下の4種類があります。 .. list-table:: :widths: 5 10 :header-rows: 1 * - 参照 - 説明(タイムステップがxの場合) * - Backward参照 - 配列型の変数をインデックス(x-1)で参照 * - Parallel参照 - 配列型の変数をインデックス(x)で参照 * - Forward参照 - 配列型の変数をインデックス(x+1)で参照 * - Any参照 - 上記以外 * スカラー値の変数や関数への参照は、すべてAny参照になります * 例えば、配列型の変数への参照をv1(0)やv1(x-2)などと記述すると、後方のインデックスしか参照しないにもかかわらず、Any参照になってしまいます 計算が可能な条件 ................................ 変数・関数の参照関係が以下のいずれかであれば、計算することができます。 #. 変数・関数が循環参照していない #. 変数・関数が循環参照しているが、循環している部分が以下の条件をともに満たしている場合 a. Backward参照とParallel参照のみ もしくは Forward参照とParallel参照のみ で構成されている b. Parallel参照のみからなる循環参照が無い * 以下は計算が可能な例です。 :: @range = x @range_last = 100 double[] qx = 0.05 double[] lx = if(x == 0) { 1.0 } else { lx(x-1) - dx(x-1) } double[] dx = lx(x) * qx(x) | この場合は、lx, dxは互いに参照していますが、lxからdxへはBackward参照のみなので、 | タイムステップxが0から100まで、lx -> dx の順に計算していくことができます。