use warnings; use strict; # 例 1/(1+(25*($x*$x))) 定積分の近似値 my $N = 100; my $Integrand = '1/(1+(25*($x*$x)))'; my $TrapezoidalRule = &TRAPEZOIDALRULE($N, $Integrand); print "$TrapezoidalRule\n"; # 台形公式 Trapezoidal Rule # 引数 左端a 右端b 分割数 被積分関数 ($N, \@Integrand) # 戻り値 台形公式 ($TrapezoidalRule) sub TRAPEZOIDALRULE{ my ($N, $Integrand) = @_; my $TrapezoidalRule = 0; my $X = 0; my $Sum = 0; my $TempA = 0; my $TempB = 0; my $TempC = 0; my $Pi = atan2(1, 1) * 4; my $h = (2 * $Pi) / $N; my $HyperbolicSine = 0; my $Pi_2 = $Pi / 2; my $N_2 = int(($N / 2) + 0.5); # 分割数の確認 if($N < 2){ return 0; } # 計算 for(my $i = -$N_2; $i <= $N_2; $i++){ $HyperbolicSine = &HYPERBOLICSINE($i * $h); $X = &HYPERBOLICSINE($Pi_2 * $HyperbolicSine); $TempA = &INTEGRAND($X, $Integrand); $TempB = &HYPERBOLICCOSINE($Pi_2 * $HyperbolicSine); $TempC = &HYPERBOLICCOSINE($i * $h); $Sum += ($TempA * $TempB * $TempC); } # 台形公式 Trapezoidal Rule $TrapezoidalRule = (($Pi * $h) / 2) * $Sum; return $TrapezoidalRule; } # 被積分関数 Integrand # 引数 積分変数 被積分関数 (\@Integrand) # 戻り値 被積分関数 ($Integrand) sub INTEGRAND{ my ($x, $Integrand) = @_; my $tmp = eval($Integrand); return $tmp; } # 双曲線正弦 Hyperbolic Sine # 引数 値 ($X) # 戻り値 双曲線正弦 ($HyperbolicSine) sub HYPERBOLICSINE{ my ($X) = @_; my $HyperbolicSine = 0; # 双曲線正弦 Hyperbolic Sine $HyperbolicSine = (exp($X) - exp(-$X)) / 2; return $HyperbolicSine; } # 双曲線余弦 Hyperbolic Cosine # 引数 値 ($X) # 戻り値 双曲線余弦 ($HyperbolicCosine) sub HYPERBOLICCOSINE{ my ($X) = @_; my $HyperbolicCosine = 0; # 双曲線余弦 Hyperbolic Cosine $HyperbolicCosine = (exp($X) + exp(-$X)) / 2; return $HyperbolicCosine; }