Scilabで二重積分
\begin{equation}
\int_{x_0}^{x_1}f(x)\mathrm{d}x
\end{equation}
このブログでも数値積分タグにいくつかの例を見つけることができます。しかしながら、2変数の数値積分はこれまで行ってきませんでした。
\begin{equation}
\int\int f(x,y) \mathrm{d}x\mathrm{d}y
\end{equation}
Scilabには二重積分を計算することが可能な
int2d
が存在します。今回は高校数学の美しい物語で解析的に解かれている二重積分を数値的に計算してみます。積分範囲が長方形領域の場合
積分範囲が長方形の領域の場合、すなわち以下のような式で表すことができる場合は、簡単に数値積分できます。
\begin{equation}
\int_{x_0}^{x_1}\int_{y_0}^{y_1}f(x,y)\mathrm{d}x\mathrm{d}y
\end{equation}
Scilabの
int2d
では長方形領域を2つの三角形のパッチワークとして与えます。積分範囲を
int2d
に渡すために行列XとYを用意します。それぞれ2つの三角形の頂点のx座標とy座標を与えます。\begin{equation}
X =
\begin{pmatrix}
x_{0} & x_{0} \\
x_{1} & x_{1} \\
x_{1} & x_{0} \\
\end{pmatrix},
Y =
\begin{pmatrix}
y_{0} & y_{0} \\
y_{0} & y_{1} \\
y_{1} & y_{1} \\
\end{pmatrix}
\end{equation}
実際に以下の積分を計算して見ます。
\begin{equation}
\int_{0}^{\pi}\int_{0}^{R}x^4 \sin(y)\mathrm{d}x\mathrm{d}y
\end{equation}
clear;
r = 1;
// *** 積分する関数の定義 ***
function z = func(x,y)
z = (x .^ 4) * sin(y)
endfunction
// 積分範囲
x0 = 0; x1 = r;
y0 = 0; y1 = %pi;
// *** 二重積分 ***
X = [x0, x0;
x1, x1;
x1, x0];
Y = [y0, y0;
y0, y1;
y1, y1];
// 数値解
I = int2d(X, Y, func)
// 解析解
A = 2*(r^5)/5
数値化解と解析解が同じ値になることが確認できます。
積分範囲が三角形の組み合わせで表せる場合
積分範囲が長方形の場合は2つの三角形の組み合わせで表現されますが、より複雑な形状の場合も任意の個数の三角形の組み合わせで表現できるはずです。今回は逆に簡単になってしまいますが、1個の三角形で表現できる例を計算します。
\begin{equation}
\int \int_D xy^2 \mathrm{d}x\mathrm{y}
\end{equation}
積分領域が三角形ひとつ分なので、与える行列は3行1列になります。
\begin{equation}
X =
\begin{pmatrix}
x_{0} \\
x_{1} \\
x_{1} \\
\end{pmatrix},
Y =
\begin{pmatrix}
y_{1} \\
y_{0} \\
y_{1} \\
\end{pmatrix}
\end{equation}
この計算を行うScilabスクリプトは以下のようになります。
clear;
// *** 積分する関数の定義 ***
function z = func(x,y)
z = x .* (y .^ 2)
endfunction
// *** 二重積分 ***
X = [0;
1;
1];
Y = [1;
0;
1];
// 数値解
I = int2d(X, Y, func)
// 解析解
A = 3/20
このスクリプトも数値解と解析解が同じに値になることが分かります。
同様にしてN個の三角形の組み合わせで表現される積分範囲の場合3行N列の行列で指定することができます。
更に複雑な積分領域の場合
どんなに複雑な積分領域の形状であっても三角形のパッチワークで表現できるはずですが、現実的には大変です。そこでOctaveの精義―フリーの高機能数値計算ツールを使いこなすで紹介されている方法を試してみましたが、現状うまく行っていません。上手く行っていませんがとりあえず方法だけは紹介します。
具体的にはScilabの論理演算で条件分岐の考え方を使って積分領域外では値がゼロになるように被積分関数の定義を行います。
\begin{equation}
\int\int_D -\frac{1}{(2x + y + 1)^2}\mathrm{d}x\mathrm{d}y
\end{equation}
clear;
// *** 積分する関数の定義 ***
function z = func(x,y)
region = y >= x .^ 2
z = - 1 ./ ((2 * x + y + 1) .^ 2) .* region
endfunction
// *** 二重積分 ***
X = [0;
1;
1];
Y = [0;
0;
1];
// 数値解
I = int2d(X, Y, func)
// 解析解
A = (1/3) * log(4) - 1/2
原理的にはこのスクリプトでよいはずですが、実際には正しく計算してくれません。Scilab 6.0ではエラーで停止します。Scilab 5.5.2ではそれっぽい値を返しますが、解析解の値とはかなりずれた値となっており、不正確です。
関連エントリ
参考URL
付録
このエントリで使用したファイルを添付します。ファイル名末尾の".txt"を削除して、"_"を"."に変更すれば使えるはずです。(参考:ねがてぃぶろぐの付録)
参考文献/使用機器
フィードバック
↑ 電子工作ブログランキング参加中です。1クリックお願いします。
コメント・トラックバックも歓迎です。 ↓
↓ この記事が面白かった方は「拍手」をお願いします。