use warnings; use strict; # 例 x^2 定積分の近似値 my $a = 0; my $b = 1; my $N = 100; my $Integrand = '$x*$x'; my $Rectangle = &SIMPSONSRULE($a, $b, $N, $Integrand); print "$Rectangle\n"; # シンプソンの公式 Simpson's Rule # 引数 左端a 右端b 分割数 被積分関数 ($a, $b, $N, $Integrand) # 戻り値 シンプソンの公式 ($SimpsonsRule) sub SIMPSONSRULE{ my ($a, $b, $N, $Integrand) = @_; ($a, $b) = ($b, $a) if($a > $b); my $SimpsonsRule = 0; my $h = ($b - $a) / $N; my $Sum = 0; my $SumA = 0; my $SumB = 0; # 分割数の確認 if(($N < 2) || (($N % 2) != 0)){ return 0; } # 計算 $SumA = &INTEGRAND($a, $Integrand); $SumB = &INTEGRAND($b, $Integrand); for(my $i = 1; $i < $N; $i++){ my $x = $a + ($i * $h); my $num = ($i % 2 == 0 ? 2 : 4); my $tmp = &INTEGRAND($x, $Integrand); $Sum += $num * $tmp; } # シンプソンの公式 Simpson's Rule $SimpsonsRule = ($SumA + $Sum + $SumB) * ($h / 3); return $SimpsonsRule; } # 被積分関数 Integrand # 引数 積分変数 被積分関数 (\@Integrand) # 戻り値 被積分関数 ($Integrand) sub INTEGRAND{ my ($x, $Integrand) = @_; my $tmp = eval($Integrand); return $tmp; }