Javaでの重積分
重積分とは
重積分は、1変数関数の定積分を多変数関数に拡張したもので、特定の領域における関数の値を積分する数学的手法です。 例えば、2次元の重積分は以下のように定義されます:
\[ \int_a^b \int_c^d f(x, y) \, dy \, dx \]
これは、領域 \([a, b] \times [c, d]\) における関数 \(f(x, y)\) の値を積分することを意味します。 Javaでは、数値積分を用いてこれを近似計算することが一般的です。
数値積分による重積分
数値積分は、関数の正確な解析的積分が難しい場合に使用される手法です。 Javaでは、以下のようなアルゴリズムを使って重積分を計算できます:
- 台形公式
- シンプソン法
- モンテカルロ法
台形公式による重積分
台形公式は、積分領域を台形で近似する方法です。1次元の場合、次のように定義されます:
\[ \int_a^b f(x) \, dx \approx \frac{b-a}{2} \big( f(a) + f(b) \big) \]
これを2次元に拡張すると、以下のようになります:
\[ \int_a^b \int_c^d f(x, y) \, dy \, dx \approx \sum_{i=0}^{n_x} \sum_{j=0}^{n_y} w_x[i] \, w_y[j] \, f(x_i, y_j) \]
ここで、\(w_x[i]\) と \(w_y[j]\) は重み、\(x_i\) と \(y_j\) は評価点を表します。
シンプソン法による重積分
シンプソン法は、台形公式よりも高精度な近似を提供する方法です。 1次元では次のように計算されます:
\[ \int_a^b f(x) \, dx \approx \frac{b-a}{6} \big( f(a) + 4f(\frac{a+b}{2}) + f(b) \big) \]
これを重積分に拡張すると、以下のような計算が可能です。
詳細な計算は、評価点の選択と重みの適切な組み合わせを考慮する必要があります。
モンテカルロ法による重積分
モンテカルロ法は、ランダムサンプリングを用いて積分値を近似する方法です。 特に、積分領域が複雑な形状を持つ場合に有効です。
アルゴリズムの概要は以下の通りです:
- 積分領域内でランダムに点を生成する。
- 関数値を評価する。
- 評価値の平均に領域の体積を掛ける。
例えば、以下のように近似できます:
\[ \int_a^b \int_c^d f(x, y) \, dy \, dx \approx \frac{1}{N} \sum_{i=1}^N f(x_i, y_i) \]
実装例
以下に、台形公式を用いた2次元の重積分の実装例を示します:
import java.util.function.BiFunction;
public class DoubleIntegral {
public static double integrate(BiFunction f,
double ax, double bx, int nx,
double ay, double by, int ny) {
double dx = (bx - ax) / nx;
double dy = (by - ay) / ny;
double sum = 0.0;
for (int i = 0; i <= nx; i++) {
double x = ax + i * dx;
for (int j = 0; j <= ny; j++) {
double y = ay + j * dy;
double weight = ((i == 0 || i == nx) ? 0.5 : 1.0) *
((j == 0 || j == ny) ? 0.5 : 1.0);
sum += weight * f.apply(x, y);
}
}
return sum * dx * dy;
}
public static void main(String[] args) {
BiFunction function = (x, y) -> Math.sin(x) * Math.cos(y);
double result = integrate(function, 0, Math.PI, 100, 0, Math.PI / 2, 100);
System.out.println("重積分の結果: " + result);
}
}
このコードでは、関数 \(f(x, y) = \sin(x) \cos(y)\) の積分を計算しています。