# ロンバーグ積分 Romberg's Method # 引数 左端a 右端b 分割数 被積分関数 ($a, $b, $N, \@Integrand) # 戻り値 ロンバーグ積分 ($RombergsMethod) sub ROMBERGSMETHOD{ my ($a, $b, $N, $Integrand) = @_; ($a, $b) = ($b, $a) if($a > $b); my $RombergsMethod = 0; my @Romberg = (); my $Sum = 0; my $h = 0; my $Power4 = 0; my $Count = @$Integrand - 1; # 配列数と分割数の確認 if(($Count < 0) || ($N < 2)){ return 0; } # (0, 0) $Romberg[0] = (($b - $a) / 2) * (&INTEGRAND($a, $Integrand) + &INTEGRAND($b, $Integrand)); # 計算 for(my $i = 1; $i < $N; $i++){ $Power4 = (4 ** $i); for(my $j = $i; $j >= 0; $j--){ if($i == $j){ $Sum = 0; $h = ($b - $a) / (2 ** $j); for(my $k = 1; $k <= (2 ** ($i - 1)); $k++){ $Sum += &INTEGRAND($a + (((2 * $k) - 1) * $h), $Integrand); } # ($i, 0) $Romberg[$j] = ($Romberg[$j - 1] / 2) + ($Sum * $h); }else { # リチャードソンの補外 Richardson's Extrapolation $Romberg[$j] = (($Power4 * $Romberg[$j + 1]) - ($Romberg[$j])) / ($Power4 - 1); } } } # ロンバーグ積分 Romberg's Method $RombergsMethod = $Romberg[0]; return $RombergsMethod; } # 被積分関数 Integrand # 引数 変数 被積分関数 ($X, \@Integrand) # 戻り値 被積分関数 ($Function) sub INTEGRAND{ my ($X, $Integrand) = @_; my $Function = 0; my $Degree = @$Integrand - 1; for(my $i = 0; $i <= $Degree; $i++){ $Function += $$Integrand[$i] * ($X ** ($Degree - $i)); } return $Function; }