昨日の続きで(チラシの裏のように)書いてみています。今日は二項分布と正規分布。あとは、累積分布関数の逆関数(norminv
とbinoinv
)に加えてt分布とF分布があると日常的な統計処理には使えそう。(たぶん仕事はSwiftでなくRでやると思うけど)
関数名はMatlabと合わせてあります。
// 円周率 let PI: Double = 3.141592653589793238462643383279 // 階乗(二項係数の計算で使うかと思って作ったら、けっきょく使わなかった) func factorial(_ n: Int) -> Int { if n <= 0 { return 1 } else { var prod = 1 for i in 1...n { prod *= i } return prod } } // 二項係数/組み合わせの数(nCk) func nchoosek(_ n: Int, _ k: Int) -> Int { var prod: Int = 1 if k != 0 { for i in 0...(k-1) { prod *= (n-i) } for i in 1...k { prod /= i } } return prod } // 二項分布の確率密度関数 func binopdf(_ x: Int, _ n: Int, _ p: Double) -> Double { return Double(nchoosek(n, x)) * pow(p, Double(x)) * pow(1-p, Double(n-x)) } // 二項分布の累積分布関数(もっと良い方法があると思う) func binocdf(_ x: Int, _ n: Int, _ p: Double) -> Double { var res = 0.0 for i in 0...x { res += binopdf(i, n, p) } return res } // 正規分布の確率密度関数 func normpdf(_ x: Double, mu: Double, s: Double) -> Double { return normpdf(x) * s + mu } func normpdf(_ x: Double) -> Double { return 1 / sqrt(2.0 * PI) * exp(-x*x/2.0) } // 正規分布の累積分布関数 func normcdf(_ x: Double, _ mu: Double, _ s: Double) -> Double { return (1 + erf(x/sqrt(2))) / 2 } func normcdf(_ x: Double) -> Double { return normcdf(x, 0, 1) }