Events for dsolve[numeric] - dsolve,numeric のイベント
|
使い方
|
|
dsolve(..., numeric, events=eventlist)
dsolve(..., numeric, events=eventlist, discrete_variables=discvars)
dsolve(..., numeric, events=eventlist, event_maxiter=miter)
dsolve(..., numeric, events=eventlist, event_pre=mode)
|
|
パラメータ
|
|
eventslist
|
-
|
イベントのリスト (後述)
|
discvars
|
-
|
離散変数の集合
|
miter
|
-
|
1 つのトリガに対するイベントの最大繰り返し回数
|
mode
|
-
|
pre の動作モード; iteration (デフォルト), initial, assignment, change のいずれか。
|
|
|
|
|
説明
|
|
•
|
イベントは、離散変数と組み合わせることにより、dsolve/numeric で停止条件やリセット条件、ゼロ次ホールドなど ODE または DAE システムのシミュレーションで発生するほとんどのイベントを処理するための仕組みに利用できます。
|
|
|
イベントの仕様
|
|
•
|
イベントは dsolve[numeric] を呼び出すときのオプション events=[event1,event2,...] で指定します。各イベントは [trigger,action] の対のリストです。ここで、trigger はイベントのトリガ (発動条件) を表し、action はイベントがトリガされたら (発動したら) 実行するアクションを表します。
|
•
|
記述の trigger 部分には以下のオプション値が指定できます。
|
–
|
[f(t,y(t))=0,c(t,y(t))<0]: 条件付きトリガによる根検出
|
–
|
[f(t,y(t))=0,And(c1(t,y(t))>0,c2(t,y(t))>0)]: 条件付き複合トリガによる根検出
|
–
|
[0,c(t,y(t))<0]: 条件付きトリガによる離散イベント
|
–
|
[0,And(c1(t,y(t))>0,c2(t,y(t))>0)]: 条件付き複合トリガによる離散イベント
|
–
|
f(t,y(t))=lo..hi: 式が範囲外になると発動する範囲トリガ
|
–
|
t=start: t=start に発動する時限トリガ
|
–
|
t=[start,delta]: t=..., start-delta, start, start+delta, start+2*delta, ... に発動する時限タイマ
|
•
|
トリガの発動が連続変数に基づくようなイベントでは、積分処理中(いわゆる前縁上で)に条件が満たされると、トリガが発動します。これはつまり、トリガが発動するには連続条件が開始点以降で満たされる必要があることを意味しています。開始点で条件が満たされてもトリガは発動しません。
|
•
|
離散イベント (rootfind 部分がゼロまたは離散変数のみで構成されている) では、トリガは連続トリガ (下記参照) によって開始された繰り返しイベントの中でのみ発動することができます。
|
•
|
記述の action 部分には以下のオプション値が指定できます。
|
–
|
halt: 発動した場合は、停止メッセージとともに積分を停止します。
|
–
|
none: 何もしませんが、適応型プロットモードではトリガ点に強制的に点が含まれることになります (たとえば、適応型 odeplot 出力の range オプション) 。
|
–
|
u(t)=-u(t): 発動した場合はステートメントを実行します。
|
–
|
[u(t)=-u(t), y(t)=-y(t)]: 発動した場合はステートメントを実行します。
|
–
|
[If(y(t)<0,y(t)=-y(t),halt)]: 発動した場合は条件付きでステートメントを実行します。
|
•
|
trigger の条件には論理演算 Not, And, Or, Xor, および Implies を不活性形式(すなわち大文字)で指定できます。action にはこれらや If 条件文、pre 演算子 (下記を参照)、halt または none を指定できます。なお、action 内に方程式が指定されている場合は割り当てと見なされます。また、action には問題の従属変数および独立変数と異なる名前が付いている限り、関連する計算で使用されている一時的変数も指定できます。さらに、問題における導関数より次数が 1 つ下までの導関数の値も指定できます。すなわち、y(t) の 2 次 ODE では diff(y(t),t) まで指定できます。以下は y(t) の 2 次 ODE に対して指定できる有効なアクションの例です。
[t1=sqrt(y(x)^2+diff(y(t),t)^2), x(t)=x(t)*t1, y(t)=y(t)*t1]
|
|
|
離散変数
|
|
•
|
離散変数は dsolve[numeric] での ODE / DAE の数値演算の一部として離散データを保持する手段です。離散変数にはスイッチが ON なのか OFF なのかを示す単純なブール型のフラグから特定の条件が何回満たされたかを数える整数値やゼロ次ホールドに必要な連続データのサンプルまで保持できます。
|
•
|
離散変数の値は連続でなく、関連の微分方程式が存在しないため、イベントでのみ変更できます。その結果、dsolve[numeric] への入力としての離散変数の導関数はあり得ません。
|
•
|
離散変数はその値がイベント処理内で変更される可能性があるため、独立変数を基に定義します。したがって、離散変数は独立変数の関数として宣言される必要があります。これらは discrete_variables=[v1,v2,...] オプションを介して dsolve[numeric] に指定できます。ここで任意の i の vi は従属変数 (たとえば u(t)) でも、型宣言を伴った従属変数 (u(t)::integer) でもかまいません。現在使用できる型は boolean, integer, および float です。注意: 離散変数の型がデフォルトの float 以外の場合は明示的に宣言することが強く推奨されます。
|
•
|
また不要であっても、離散変数には入力システムにおける初期値が与えられていることが必要です。
|
•
|
秒間隔でサンプリングした連続従属変数 y(t) の離散変数をゼロ次ホールドのために使用するにはたとえば、discrete_variables=[u(t)::float], events=[[t=[0,1/2],u(t)=y(t)]] および u(t) に対する初期条件を指定します。
|
•
|
ブール型として宣言された離散変数はイベント構造の条件文で直接使用できます。たとえば、u(t) がブール型として宣言されている場合の条件文の書式は If(u(t),...) になります。
|
|
|
繰り返しイベント
|
|
•
|
たとえば、根の検出や固定または一連のタイミングでトリガを発動させる連続的な条件に基づいているイベントがトリガを発動できるのは常に 1 回のみですが、離散変数に基づいてトリガを発動するイベントはそうではありません。
|
•
|
離散変数に基づいたイベントはイベント処理内に簡単なアルゴリズムを組んだりするために使用できます。ただしこの場合、イベントが開始されるには開始点で条件が満たされるか、(たとえば、符号の変化や特定の時間になるなどの) 継続的なイベントによって発動される必要があることにご注意ください。
|
•
|
このため、一連のイベントの実行順が重要になりますが、これらは単に入力された events に指定されている順に実行されます。イベントが繰り返し処理内でトリガを発動している場合、そのイベントはイベントのカウンタが event_maxiter に到達するまで繰り返し発生します。event_maxiter オプションは、意外と簡単に発生するイベントの無限ループを防ぐための手段として用意されています。このオプションには任意の正整数が設定できますが、オプションを無効にすることはできません。
|
|
|
pre 変数
|
|
•
|
シミュレーションにおけるイベント処理で一般的に必要とされるもう一つの仕組みは特定の変数の前の値を知る手段です。これは、変数の値が変更されたか確認したり、ブール変数が真から偽または偽から真に変わったのかを確認するために使用できます。
|
•
|
dsolve[numeric] のイベント処理では、この仕組みに pre 演算子を使用しています。pre の値は他のイベントによるため、イベント処理外では意味を成しません。たとえば、u(t) の値がイベント処理内で変更されたかどうかを検出するための条件は u(t)<>pre(u(t)) と記述できます。
|
•
|
pre を使用する場合には気を付ける必要がある点がいくつかあり、これらは pre によって参照される値のタイミングに関係しています。タイミングを指定するオプション値は 4 つあり、オプション引数 event_pre で指定します。
|
–
|
iteration (デフォルト) : pre(u(t)) は現在の繰り返し処理開始時の u(t) の値を参照します。
|
–
|
initial: pre(u(t)) は現在の位置のイベントが開始されたときの u(t) の値 (この値は繰り返しイベント内でこの先も不変) を参照します。
|
–
|
assignment: pre(u(t)) は現在の位置の繰り返しイベントが開始されてから u(t) に対して行われた最後の割り当ての前の u(t) 値を参照します。
|
–
|
change: pre(u(t)) は現在の位置のイベントが開始されてから u(t) に対して行われた最後の非自明的な割り当ての前の u(t) 値を参照します。
|
|
|
対話機能
|
|
•
|
本リリースのプロシージャ形式の ODE / DAE の数値解においてイベントを処理する機能の中には、以前の停止条件で提供されていた機能の拡張版であるものが多数含まれています。これらの例として、たとえば、停止を発動したイベントを取得する機能や継続的な停止を取り消して数値積分を継続する機能、イベントの有効化・無効化機能などを挙げることができます。
|
|
例
|
|
上向きと下向きでゼロを通過するときの解に対応する2つのイベントが定義されている単振子を想定します。
>
|
|
| (8.1.1) |
eventstatus を使用すると、どのイベントが有効で、どのイベントが無効か取得することができます。
>
|
|
| (8.1.2) |
正の向きに積分すると、積分は Pi あたりでイベント #2 によって停止されます。
>
|
|
Warning, cannot evaluate the solution further right of 3.1415926, event #2 triggered a halt
| |
| (8.1.3) |
>
|
|
| (8.1.4) |
このイベントを取り消して積分を続けると、積分は 2*Pi あたりでイベント #1 によって停止されます。
>
|
|
>
|
|
Warning, cannot evaluate the solution further right of 6.2831854, event #1 triggered a halt
| |
| (8.1.5) |
>
|
|
| (8.1.6) |
今度はこのイベントを取り消して積分を続けると、3*Pi あたりで再度イベント #2 による積分の停止が期待されますが、イベントが無効にされていると積分は停止されません。
>
|
|
>
|
|
>
|
|
| (8.1.7) |
>
|
|
| (8.1.8) |
更にもう一つのイベントも無効にし、任意の時点まで積分を続けることもできます。
>
|
|
>
|
|
| (8.1.9) |
>
|
|
| (8.1.10) |
イベントが再度有効にされると、プロシージャは今まで一度も呼び出されたことがなく、イベントも取り消されたことがないかのように問題は初期値にリセットされます。
>
|
|
>
|
|
| (8.1.11) |
>
|
|
Warning, cannot evaluate the solution further right of 3.1415926, event #2 triggered a halt
| |
| (8.1.12) |
>
|
|
| (8.1.13) |
>
|
|
Warning, cannot evaluate the solution further left of -3.1415926, event #2 triggered a halt
| |
| (8.1.14) |
>
|
|
| (8.1.15) |
•
|
複数のイベントが定義されている場合に停止を取り消すと、イベント処理は最後に実行されたイベントの直後から再開されることにご注意ください。つまり、たとえば停止を発動したイベント #2 が取り消された場合、イベント処理はイベント #3 から再開されます。
|
|
|
|