NORMDIST TRUNC ROUND 함수 구현

admin의 아바타

# ------------------------------------------------------------------------------
# NORMDIST : 정규분포함수
# TRUNC : 소수점이하 (특정위치이하) 버리기
# ROUND : 특정위치에서 반올림

# ------------------------------------------------------------------------------
proc ROUND {number {num_digits 0}} {
        if { $num_digits } {
                return [expr {round(pow(10,$num_digits)*$number)/pow(10,$num_digits)}]
        } else {
                return [expr int([expr {round(pow(10,$num_digits)*$number)/pow(10,$num_digits)}]])]
        }
}

# ------------------------------------------------------------------------------
proc TRUNC {number {num_digits 0}} {
        if { $num_digits >= 0 } {
                set number [format "%f" $number]
                set i [string first "." $number]
                set e [expr $i+$num_digits]
                if { $num_digits == 0 } {
                        return [string range $number 0 $i-1]
                } else {
                        return [string range $number 0 $e]
                }
        } else {
                return $number
        }
}

# ------------------------------------------------------------------------------
#https://sites.google.com/site/softwareincidentanalysis/Downhome/statistics-1/ccdfnormaldistribution
proc NORMDIST {x mean std cumulative} {
        if { $cumulative } {
                return [___Phi2 $x $mean $std]
        } else {
                set tmp [expr 1/((sqrt(2*3.141592)*$std))]
                return [expr $tmp * exp(-.5 * pow(($x-$mean)/$std,2))]
        }
}

proc tcl::mathfunc::erf {z} {
        set t [expr 1.0 / (1.0 + 0.5 * abs($z))]
        #use Horner's method
        set ans [expr 1 - $t * exp( -$z*$z - 1.26551223 + $t * ( 1.00002368 + $t * ( 0.37409196 +$t * ( 0.09678418 + $t * (-0.18628806 + $t * ( 0.27886807 + $t * (-1.13520398 + $t * ( 1.48851587 + $t * (-0.82215223 + $t * ( 0.17087277))))))))))]
        if { $z >= 0 } {
                return $ans
        } else {
                return -$ans
        }
}

proc Phi {z} {
        return [expr 0.5 * (1.0 + erf($z / (sqrt(2.0))))]
}

proc Phi2 {z mu sigma} {
        return [Phi [expr ($z - $mu) / $sigma]]
}