数値積分
使い方
evalf(Int(f, x=a..b, ...))
evalf(Int(f, a..b, ...))
evalf(Int(f, list-of-equations, ...))
evalf(Int(f, list-of-ranges, ...))
evalf(int(f, x=a..b))
パラメータ
f - 代数式または手続き; 被積分項
x - 名前; 積分変数
a, b - 積分区間の端点
list-of-equations - 等式 [x1=a1..b1, ..., xn=an..bn] のリスト
list-of-ranges - 範囲 [a1..b1, ..., an..bn] のリスト
... - (オプション) 0 あるいは複数のオプション (以下に記述)
|
説明
|
|
•
|
数値積分を行うのに最もよく使うコマンドは、evalf(Int(f, x=a..b)) です。ここで、記号積分のルーチンをまず呼び出すことを避けるために、積分のコマンドは不活性形式で表現されます。記号 int の実行に失敗した(未評価の積分が返される)場合には、返された未評価の積分に evalf(int(f, x=a..b)) のような形で evalf を適用することも可能です。
|
•
|
被積分項 f は他の未評価の積分であっても構いません。つまり、重積分がサポートされています。重積分の指定には、階層化された積分ではなく、特別な構文のリスト(以下参照)を用いることもできます。リストを使用しない標準の表記法で表された積分は、階層化された1次元積分の場合を含めて、1 次元の積分といいます。
|
•
|
被積分項 f が手続きまたは Maple 演算子として指定される場合、第 2 番目の引数は範囲 a..b でなければならず、また等式であってはなりません。これはすなわち、積分変数を指定してはならないということです。
|
•
|
infolevel[`evalf/int`] に 1 から 4 までの値が割り当てられると、様々なレベルのユーザ情報が計算中に表示されます。
|
|
|
オプション引数
|
|
•
|
等式として、追加のオプションを指定します(以下に示すように、過去との整合性を保つため、いくつかのオプションでは等式ではなく値で指定を行うこともあります)。オプションは、以下の形式のいずれかをとります:
|
method = <name> or <name>
digits = <posint> or <posint>
epsilon = <numeric>
•
|
指定 method = <name> (または単に <name>) は、特定の数値積分法が適用されることを示します。指定可能な手法は、以下に示します。デフォルトでは、記号と数値の混合法が適用されます。
|
•
|
指定 digits = <posint> (または単に <posint>) は、計算精度の桁数を示します。計算中に、<posint> の正確な桁数へ結果が到達するまで、(たとえ 'epsilon' オプションを用いて大きな許容値が指定されているとしても)保護用の余分な桁数が加えられます。デフォルトでは、Maple の環境変数 Digits が計算精度を指定します。
|
•
|
指定 epsilon = <numeric> は、計算結果に関して許容可能な相対誤差を指定します。ルーチンは、最終結果の相対誤差がこの値の範囲内に収まるように達成されます。最終結果に関してルーチンが達成しようとする相対誤差の許容値は、デフォルトでは以下のようになります。
|
eps = 0.5 * 10^(1-digits)
|
ここで、digits はこの計算について指定された精度を表します。この精度を達成するために、作業中の Digits の値は、必要であれば増加されます。上記のデフォルト値よりも 'epsilon' の値を小さく指定すると、エラーとなります。
|
|
注意: 被積分項によっては、デフォルトの許容値 eps で積分の計算結果を得るためには、(精度の保護用に桁数を余分に用意して計算したとしても)、被積分項を計算して得られる値の精度が不十分なことがあります。このような場合、パラメータ 'epsilon' を用いて( digits の設定に関して)より大きな許容値を指定するのが、有用な方法でしょう。
|
|
|
数値積分複合アルゴリズムの概略(1次元積分)
|
|
•
|
デフォルトの場合(特定の手法が指定されていない場合)、Digits が大き過ぎでなければ (すなわち Digits <= evalhf(Digits) ならば)、解こうとする問題は最初に NAG 積分ルーチンに渡されます。NAG ルーチンはコンパイルされた C ライブラリに含まれており、ハードウェア浮動小数点の速度で操作を実行します。NAG ルーチンが積分を実行できない場合、特異点に関する処理が行われ、修正した問題を NAG ルーチンに送り返す操作が行われるでしょう。NAG ルーチンが問題を解けない場合(例えば、Digits の値が大き過ぎる、あるいはハードウェア浮動小数点の評価を行う関数を伴う被積分項がサポートされていない場合など)には、Maple 本来のルーチンが呼び出されます。
|
•
|
Maple 本来の、記号と数値の混合法は、次のようになっています。デフォルトで適用される数値解法は、Clenshaw-Curtis 積分法(CCquad)です。この方法では収束が遅いと判明した場合には、積分区間内もしくは近傍(おそらく複素平面内)に、特異点が存在しています。この特異点を取り扱うために、記号処理による技法が用いられます。取り除けないような端点における特異性を持つ問題に関しては、適応的2重指数関数求積法 (adaptive double-exponential quadrature method;_Dexp) が適用されます。
|
•
|
特異点が区間内にあると予想される場合、積分区間を分割するために、特異点の位置を特定する試みが行われます。最終的に、それでもうまくいかなければ、区間はいくつかに分割され、 そして_Dexp 法が適用されるか、あるいは既に _Dexp または _Sinc 法が適用されている場合には、適応的ガウス求積法 (adaptive Gaussian quadrature method : _Gquad) が適用されます。
|
•
|
積分の極限に関しては、値 infinity や -infinity が利用可能で、記号-数値法は特異点を取り扱おうとします。用いられる技法には、特異点を取り除く変数変換、特異点の近傍で打ち切られた一般化級数の積分が含まれます。
|
•
|
被積分項 f が手続きまたは Maple の演算子として指定される場合には、特異点の操作は行われません。
|
|
|
重積分の特別な(リスト)構文
|
|
•
|
数値重積分の問題は、階層化された1次元積分を用いて、自然な方法で指定されます。例を以下に示します:
|
evalf( Int(...(Int(Int(f, x1=a1..b1), x2=a2..b2), ...), xn=an..bn) )
|
ここで、被積分項 f は x1, x2, ..., xn に依存します。このような問題は、以下に示すように、2つ目の引数としてリストを持つ、特別な重積分表記を用いて指定することも可能です:
|
evalf( Int(f, [x1=a1..b1, x2=a2..b2, ..., xn=an..bn]) ) .
•
|
追加のオプション引数は、1次元積分の場合と同じように記述されます。また、1 次元積分のように、被積分項 f は、2 つ目の引数が範囲 [a1..b1, a2..b2, ..., an..bn] のリストとなる手続きとして、指定されます。
|
•
|
重積分の問題が、階層化された積分あるいはリスト表記のいずれを用いて記述されても、その引数は、同じ数値重積分ルーチンを実行するように引用されます。
|
|
|
手法の名称
|
|
•
|
オプション引数 method = <name> (または単に <name>) では、以下の手法名が使用可能です。
|
method = _DEFAULT -- 手法を指定しないのと同値;
概要を上述した解法に関する戦略は、1次元積分に
対して適用されます。;
重積分の場合、問題は _cuhre 法に渡されます。
これが失敗した場合、問題は階層化された1次元積分
として取り扱われます。
method = _NoNAG -- NAG ルーチンの呼び出しを中止するように指示;
そうでない場合は _DEFAULT の戦略に従います。
method = _NoMultiple -- 数値重積分ルーチンの呼び出しを中止するように
指示; 重積分は階層化された1次元積分として
計算されます。
|
Maple の手法
|
|
•
|
手法を指定することにより、その手法だけを使用したいことを指示します(この場合、NAG 法や特異点の取り扱いは不要)。
|
method = _CCquad -- Clenshaw-Curtis 求積法
method = _Dexp -- 適応的指数関数法
method = _Gquad -- 適応的ガウス求積法
method = _Sinc -- 適応的 sinc 求積法
method = _NCrule -- 適応的ニュートン・コーツ法 "quanc8"。
"quanc8" (method = _NCrule)は、ここでリスト表示されている
他の Maple の手法とは対照的に、次数の固定された手法で、
高精度(例: Digits > 15)を求める場合には推奨されないことに
注意して下さい。
|
|
NAG 法
|
|
•
|
手法を指定することにより、その手法だけを使用したいことを指示します(この場合、特異点の取り扱いや Maple の手法は不要)。
|
method = _d01ajc -- 有限区間における積分; 挙動の悪い被積分項について
許容される; 適応的ガウス(Gauss)10点公式と適応的
クロンロッド(Kronrod)21点公式を用いる。
method = _d01akc -- 有限区間における振動する被積分項の積分;
適応的ガウス30点公式および適応的クロンロッド61点公式を
用いる。
method = _d01amc -- 準無限/無限区間における積分
|
|
重積分の手法
|
|
•
|
手法を指定することにより、その手法だけを使用したいことを指示します (この場合、階層化された 1 次元積分へ戻すことは行わない)。
|
method = _cuhre -- 超長方形上の重積分;
例えば、積分の極限は有限の定数となります;
次数は 2 から 15; ACM TOM Algorithm 698
method = _MonteCarlo -- 超長方形上のモンテカルロ法;
例えば、積分の極限は有限の定数となります;
低い精度(5桁の精度以下)の場合のみ;
NAG ルーチン 'd01gbc'
|
|
|
例
|
|
>
|
evalf(Int( exp(-x^3)/(x^2+1), x = 0..1 ));
|
| (6.1) |
>
|
evalf(Int( 1/(x^2+1), x = 0..infinity ));
|
| (6.2) |
>
|
evalf(Int( sin(x)*ln(x)*exp(-x^3), x = 0..infinity ));
|
| (6.3) |
次の積分は、高精度で計算されます。
>
|
e1 := 1/GAMMA(x):
Int(e1, x = 0..2) = evalf(Int(e1, x=0..2, digits=20, method=_Dexp));
|
| (6.4) |
>
|
e2 := exp(v-v^2/2)/(1+1/2*exp(v)):
Int(e2, v=0..infinity) = evalf[20]( Int(e2, v=0..infinity) );
|
| (6.5) |
>
|
e3 := 1/(1+ln(1+x)):
Int(e3, x=0..1) = evalf[32]( Int(e3, x=0..1, method=_Gquad) );
|
| (6.6) |
>
|
r := int( sech(x)*exp(-x^2), x = -infinity..infinity );
|
| (6.7) |
| (6.8) |
| (6.9) |
次のコマンドは、記号の引数 x と共に手続き f が呼び出されたので、エラーを返します。
>
|
f := proc(x) if x < 2 then 2*x else x^2 end if; end proc;
|
| (6.10) |
>
|
evalf(Int(f(x), x=0..3));
|
Error, (in f) cannot determine if this expression is true or
false: x < 2
| |
被積分項 f が手続きである場合、次の構文が使用されなくてはなりません。
| (6.11) |
次のコマンドは、未評価の引用符により、f(x) の評価を遅延することにより動作することに注意して下さい。
>
|
evalf(Int('f'(x), x=0..3));
|
| (6.12) |
階層化された1次元積分で表現された重積分
>
|
Int(Int(Int(exp(x+y+z)/((5*x+1)*(10*y+2)*(15*z+3)),
x=0..4), y=0..3), z=0..sqrt(2));
|
| (6.13) |
| (6.14) |
リスト構文を用いた数値重積分の実行
>
|
d := (1 - w^2*x^2*y^2*z^2):
g := d * cos(w*x*y*z) - d * w*x*y*z * sin(w*x*y*z);
|
| (6.15) |
>
|
evalf(Int(g, [w=0..1, x=0..1, y=0..1, z=0..1]));
|
| (6.16) |
低い精度でよい場合の、モンテカルロ法の使用
>
|
h := 1/(2 + sin(Pi*sqrt(87)*(x1+x2+x3+x4+x5+x6)));
|
| (6.17) |
>
|
evalf(Int(h, [x1=-1..1, x2=-1..1, x3=-1..1, x4=-1..1, x5=-1..1, x6=-1..1],
method=_MonteCarlo, epsilon=0.5e-2)):
|
epsilon = 0.5e-2 の場合の、3桁の評価
| (6.18) |
|
|