# 対数正規分布 Logarithmic Normal Distribution # 引数 変数 平均 標準偏差 ($X, $Mean, $StandardDeviation) # 戻り値 対数正規分布 (@LogarithmicNormalDistribution) sub LOGARITHMICNORMALDISTRIBUTION{ my ($X, $Mean, $StandardDeviation) = @_; my @LogarithmicNormalDistribution = (); my $SimpsonsRule = 0; # 標準偏差の確認 if(($X < 0) || ($StandardDeviation <= 0)){ return 0; } # 計算 my $PowerSD = $StandardDeviation * $StandardDeviation; my $E = exp($Mean + ($PowerSD / 2)); my $Var = (exp($PowerSD) - 1) * exp((2 * $Mean) + $PowerSD); my $LnE = log($E) / log(exp(1)); my $LnVE = log(1 + ($Var / ($E * $E))) / log(exp(1)); my $LogNormalMean = $LnE - ($LnVE / 2); my $LogNormalStandardDeviation = sqrt($LnVE); # 確率密度関数 Frequency Function $LogarithmicNormalDistribution[0] = &FREQUENCYFUNCTION($X, $LogNormalMean, $LogNormalStandardDeviation); # シンプソンの公式 Simpson's Rule $SimpsonsRule = &SIMPSONSRULE($X, $LogNormalMean, $LogNormalStandardDeviation); # 下側累積確率 Lower Cumulative Distribution $LogarithmicNormalDistribution[1] = $SimpsonsRule; # 上側累積確率 Upper Cumulative Distribution $LogarithmicNormalDistribution[2] = 1 - $SimpsonsRule; return @LogarithmicNormalDistribution; } # 確率密度関数 Frequency Function # 引数 変数 平均 標準偏差 ($X, $Mean, $StandardDeviation) # 戻り値 確率密度関数 (@FrequencyFunction) sub FREQUENCYFUNCTION{ my ($X, $Mean, $StandardDeviation) = @_; my $FrequencyFunction = 0; my $Pi = atan2(1, 1) * 4; # 変数の確認 if($X <= 0){ return 0; } # 計算 my $Ln = log($X) / log(exp(1)); my $Power = ((($Ln - $Mean) / $StandardDeviation) * (($Ln - $Mean) / $StandardDeviation)); # 対数正規分布 Frequency Function $FrequencyFunction = (1 / ($StandardDeviation * $X * sqrt(2 * $Pi))) * exp(-($Power / 2)); return $FrequencyFunction; } # シンプソンの公式 Simpson's Rule # 引数 変数 平均 標準偏差 ($X, $Mean, $StandardDeviation) # 戻り値 シンプソンの公式 (@SimpsonsRule) sub SIMPSONSRULE{ my ($X, $Mean, $StandardDeviation) = @_; my $SimpsonsRule = 0; my $a = 0; my $b = $X; my $N = 10000; my $h = ($b - $a) / $N; my $Sum = 0; my $SumA = 0; my $SumB = 0; # 計算 $SumA = &FREQUENCYFUNCTION($a, $Mean, $StandardDeviation); $SumB = &FREQUENCYFUNCTION($b, $Mean, $StandardDeviation); # 分割数が少ないと値が大きくなるにつれて # エクセルで計算した値と誤差がでる for(my $i = 1; $i < $N; $i++){ my $t = $a + ($i * $h); my $num = ($i % 2 == 0 ? 2 : 4); my $tmp = &FREQUENCYFUNCTION($t, $Mean, $StandardDeviation); $Sum += $num * $tmp; } # シンプソンの公式 Simpson's Rule $SimpsonsRule = ($SumA + $Sum + $SumB) * ($h / 3); return $SimpsonsRule; }