├── AUTHORS ├── CITATION ├── CONTRIBUTORS ├── LICENSE ├── bayes ├── REFERENCES ├── ToDo ├── _tst │ ├── 00_test.go │ ├── 01_test.go │ ├── 02_test.go │ ├── 03_test.go │ ├── 04_test.go │ ├── 05_test.go │ ├── Michelson.csv │ ├── R │ ├── betabinexch_test.go │ ├── betaselect_test.go │ ├── bfexch_test.go │ ├── check_test.go │ ├── ctable_indep_test.go │ ├── ctable_test.go │ ├── discint_test.go │ ├── gibbs_test.go │ ├── histprior_test.go │ ├── howardprior_test.go │ ├── logctablepost_test.go │ ├── logisticpost_test.go │ ├── logpoissgamma_test.go │ ├── logpoissnormal_test.go │ ├── mnormt_onesided_test.go │ ├── mnormt_twosided_test.go │ ├── normal_normal_mix_test.go │ ├── normpostsim_test.go │ ├── pbetat_test.go │ ├── pdisc_test.go │ └── poissgamexch_test.go ├── beta_hdi_qtl.go ├── betabinexch.go ├── betaselect.go ├── bfexch.go ├── binom_p.go ├── binom_p_diff.go ├── cri.go ├── ctable.go ├── ctable_indep.go ├── deviance.go ├── discint.go ├── doc.go ├── e_cdf.go ├── e_qtl.go ├── fmin.go ├── fn.go ├── gibbs.go ├── hdi_qtl.go ├── histprior.go ├── howardprior.go ├── lin_reg.go ├── logctablepost.go ├── logisticpost.go ├── logisticpost.go.orig ├── logpoissgamma.go ├── logpoissnormal.go ├── mnormt_onesided.go ├── mnormt_twosided.go ├── multinom_p.go ├── normal_diff.go ├── normal_mu.go ├── normal_normal_mix.go ├── normpostsim.go ├── p_null_smp.go ├── pbetat.go ├── pdisc.go ├── poissgamexch.go ├── poisson.go └── util.go ├── cmd ├── binomProportionBayes │ └── binomProportionBayes.go └── poissonRateBayes │ └── poissonRateBayes.go ├── doc.go ├── dst ├── BUGS ├── REFERENCES ├── ToDo ├── _tst │ ├── 00_test.go │ ├── 09_test.go │ ├── 10_test.go │ ├── 11_test.go │ ├── 12_test.go │ ├── 13_test.go │ ├── beta_test.go │ ├── betaqtl_test.go │ ├── binom_test.go │ ├── cauchy_test.go │ ├── fqtl_test.go │ ├── gamma_test.go │ ├── hyper_test.go │ ├── hypergeom_test.go │ ├── igamma_test.go │ ├── levy_test.go │ ├── logistic_test.go │ ├── lognorm_test.go │ ├── negbinom_test.go │ ├── next_test.go │ ├── poisson_test.go │ ├── polya_test.go │ ├── qtl_test.go │ ├── rpoisson_test.go │ ├── stat_test.go │ └── template_test.txt ├── bd0.go ├── bernoulli.go ├── beta-mu-nu.go ├── beta-mu-sigma.go ├── beta.go ├── beta4.go ├── binomial.go ├── cauchy.go ├── chisq.go ├── choice.go ├── crp.go ├── dirichlet.go ├── doc.go ├── exp.go ├── f.go ├── fn.go ├── gamma.go ├── gamma_aux.go ├── gamma_aux_ln.go ├── gamma_qtl.go ├── geom0.go ├── geom1.go ├── hypergeom.go ├── igamma.go ├── iwishart.go ├── levy.go ├── logistic.go ├── lognormal.go ├── matrix_normal.go ├── matrix_t.go ├── multinomial.go ├── mv_normal.go ├── negbinom.go ├── normal.go ├── pareto.go ├── pareto_II.go ├── pareto_gen.go ├── pareto_single.go ├── pareto_tap.go ├── planck.go ├── poisson.go ├── poisson_rnd.go ├── polya.go ├── range.go ├── ratio_gaussian.go ├── stirlerr.go ├── t.go ├── uniform.go ├── wishart.go ├── yule.go ├── z.go ├── zeta.go └── zipf-mandelbrot.go └── stat ├── REFERENCES ├── _tst ├── 00_test.go ├── agostino_test.go ├── anscombe_test.go ├── bonett_test.go ├── cov_test.go ├── jarque_test.go └── moments_test.go ├── agostino.go ├── anscombe.go ├── binom_ci.go ├── bonett.go ├── cov.go ├── doc.go ├── fn.go ├── jarque.go ├── moments.go ├── raw2central.go.new ├── sample_mean_var.go ├── var.go └── vector.go /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of Probab authors for copyright purposes. 2 | 3 | # Names should be added to this file as 4 | # Name or Organization 5 | 6 | Peter A. Cejchan 7 | John Asmuth 8 | -------------------------------------------------------------------------------- /CITATION: -------------------------------------------------------------------------------- 1 | Cejchan, P.A., Asmuth, J.. (2012 ). Probab: A library of probability distribution functions, and Bayesian inference. (https://code.google.com/p/probab/) -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This is the official list of people who can contribute 2 | # (and typically have contributed) code to the Probab repository. 3 | # Also includes authors of the original code that has been modified / rewritten here. 4 | # Names should be added to this file like so: 5 | # Name 6 | 7 | Peter A. Cejchan 8 | John Asmuth < jasmuth@gmail.com > 9 | Morten Welinder 10 | Catherine Loader -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The Probab Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /bayes/REFERENCES: -------------------------------------------------------------------------------- 1 | Aitkin M 2007: Statistical Inference: An Integrated Bayesian/Likelihood Approach (Chapman & Hall/CRC Monographs on Statistics & Applied Probability) ISBN-10: 1420093436 | ISBN-13: 978-1420093438 2 | Albert J 2009 Bayesian Computation with R. Springer. ISBN: 978-0-387-92297-3 (Print) 978-0-387-92298-0 (Online) 3 | Bolstad WM 2007: Introduction to Bayesian Statistics, 2nd Edition. Wiley. ISBN: 978-0-470-14115-1. 4 | Bolstad WM 2009: Understanding Computational Bayesian Statistics. John Wiley & Sons ISBN 978-0470046098 5 | Kruschke J 2011: Doing Bayesian Data Analysis: A Tutorial Introduction with R and BUGS. Elsevier / Academic Press. ISBN: 978-0-12-381485-2. 6 | 7 | 8 | -------------------------------------------------------------------------------- /bayes/ToDo: -------------------------------------------------------------------------------- 1 | remove / replace all _For| At functions and update testfiles accordingly 2 | rejection sampling: Link & Barker, 2010: 56 3 | sampling from posterior (both analytic and empiric) 4 | 5 | -------------------------------------------------------------------------------- /bayes/_tst/00_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | func check(x, y float64) bool { 4 | const acc float64 = 1e-2 // accuracy 5 | var z float64 6 | if x/y > 1.00 { 7 | z = y / x 8 | } else { 9 | z = x / y 10 | } 11 | if 1-z > acc { 12 | return false 13 | } 14 | return true 15 | } 16 | -------------------------------------------------------------------------------- /bayes/_tst/04_test.go: -------------------------------------------------------------------------------- 1 | // 2 | package bayes 3 | 4 | import ( 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | // Normal posterior test against Bolstad:normnp 10 | func TestNormalPosterior2(t *testing.T) { 11 | fmt.Println("Normal posterior test against Bolstad:201") 12 | 13 | // func NormMuSingle_PMF_DPri(y, sigma float64, mu, prior []float64) (post []float64) 14 | known := []float64{0.1238, 0.1991, 0.2493, 0.2431, 0.1847} 15 | mu := []float64{2.0, 2.5, 3.0, 3.5, 4.0} 16 | prior := []float64{0.2, 0.2, 0.2, 0.2, 0.2} 17 | 18 | // check 19 | n := len(mu) 20 | post := NormMuSingle_PMF_DPri(3.2, 1, mu, prior) 21 | for i := 0; i < n; i++ { 22 | x := post[i] 23 | y := known[i] 24 | if !check(x, y) { 25 | t.Error() 26 | fmt.Println(i, x, y) 27 | } 28 | } 29 | } 30 | 31 | func TestNormalPosterior3(t *testing.T) { 32 | fmt.Println("Normal posterior test against Bolstad:203") 33 | // func NormMu_PMF_DPri(nObs int, samp_mean, sigma float64, mu []float64, prior []float64) (post []float64) 34 | known := []float64{3.855124e-01, 4.561038e-01, 1.546041e-01, 3.753619e-03, 2.611027e-05} 35 | mu := []float64{2.0, 2.5, 3.0, 3.5, 4.0} 36 | prior := []float64{0.1, 0.2, 0.4, 0.2, 0.1} 37 | 38 | // check 39 | n := len(mu) 40 | post := NormMu_PMF_DPri(5, 2.04, 1, mu, prior) 41 | for i := 0; i < n; i++ { 42 | x := post[i] 43 | y := known[i] 44 | if !check(x, y) { 45 | t.Error() 46 | fmt.Println(i, x, y) 47 | } 48 | } 49 | } 50 | 51 | func TestNormalPosterior4(t *testing.T) { 52 | fmt.Println("Normal posterior test against Bolstad:210, Flat prior") 53 | // func NormMu_Qtl_FPri(nObs int, ȳ, σ, p float64) float64 { 54 | alpha := []float64{0.005, 0.01, 0.025, 0.05, 0.5, 0.95, 0.975, 0.99, 0.995} 55 | known := [...]float64{30.51272, 30.65677, 30.86832, 31.05026, 32, 32.94974, 33.13168, 33.34323, 33.48728} 56 | 57 | // check 58 | for i := 0; i < 9; i++ { 59 | x := NormMu_Qtl_FPri(12, 32, 2, alpha[i]) 60 | y := known[i] 61 | if !check(x, y) { 62 | t.Error() 63 | fmt.Println(i, x, y) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /bayes/_tst/05_test.go: -------------------------------------------------------------------------------- 1 | // Test Bolstad 2007 2 | package bayes 3 | 4 | import ( 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | func TestNormalMuDiffPosterior2(t *testing.T) { 10 | fmt.Println("Normal posterior test against Michelson data: Bolstad:242 known variances") 11 | 12 | // func NormalMuDiff_PDF(nObs1, nObs2 int, ȳ1, ȳ2, σ, μ1Pri, σ1Pri, μ2Pri, σ2Pri float64) func(x float64) float64 13 | 14 | pdf := NormalMuDiff_PDF_NPriKn(20, 23, 299909, 299756.217391304, 100, 100, 300000, 500, 300000, 500) 15 | alpha := []float64{100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200} 16 | known := []float64{0.002975008, 0.004951945, 0.007404859, 0.009947435, 0.0120049, 0.01301546, 0.01267692, 0.01109229, 0.008719312, 0.006157386, 0.003906284} 17 | 18 | // check 19 | n := len(known) 20 | for i := 0; i < n; i++ { 21 | x := pdf(alpha[i]) 22 | y := known[i] 23 | if !check(x, y) { 24 | t.Error() 25 | fmt.Println(i, x, y) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /bayes/_tst/Michelson.csv: -------------------------------------------------------------------------------- 1 | 299850,299900,299930,299950,299980,300000,299930,299760,300000,299960,299740,300070,299850,299980,299880,299980,299650,299810,300000,299960 2 | 299883,299778,299682,299611,300051,299578,299774,299772,299573,299748,299851,299723,299816,299796,299711,299599,299781,299796,299820,299696,299748,299797,299809 3 | 4 | -------------------------------------------------------------------------------- /bayes/_tst/R: -------------------------------------------------------------------------------- 1 | theta <- rnorm(100000) 2 | q <- quantile(theta) 3 | write(theta, file = "t", ncolumns = 1000, append = FALSE, sep = ",") 4 | write(q, file = "q", ncolumns = 5, append = FALSE, sep = ",") 5 | pnorm(0.685864) 6 | 7 | ## generate a sample of 20 observations from a N(-0.5,1) population 8 | x = rnorm(20,-0.5,1) 9 | write(x, file = "x", ncolumns = 20, append = FALSE, sep = ",") 10 | ## find the posterior density with a N(0,1) prior on mu 11 | normnp(x,sigma=1) 12 | ## find the posterior density with N(0.5,3) prior on mu 13 | normnp(x,0.5,3,1) 14 | 15 | 16 | x = rnorm(20,0.634298887,1.75223) 17 | mean(x) 18 | normnp(x,0.512,3.05,1.33) 19 | 20 | awk '{print $2}' < foo | 9 tr '\x0a' ',' > vals 21 | 22 | ## generate a ssingle observation from a N(0.634298887,1.75223) population 23 | y = rnorm(1,0.634298887,1.75223) 24 | mean(y) 25 | normnp(y,0.512,3.05,1.33) 26 | 27 | ## Let mu have the discrete distribution with 5 possible 28 | ## values, 2, 2.5, 3, 3.5 and 4, and associated prior probability of 29 | ## 0.1, 0.2, 0.4, 0.2, 0.1 respectively. Find the posterior 30 | ## distribution after a drawing random sample of n = 5 observations 31 | ## from a N(mu,1) distribution y = [1.52, 0.02, 3.35, 3.49, 1.82] 32 | mu = seq(2,4,by=0.5) 33 | mu.prior = c(0.1,0.2,0.4,0.2,0.1) 34 | y = c(1.52,0.02,3.35,3.49,1.82) 35 | post <- normdp(y,1,mu,mu.prior) 36 | 37 | 38 | 39 | # Bolstad:210 40 | alpha = c(0.005, 0.01, 0.025, 0.05, 0.5, 0.95, 0.975, 0.99, 0.995) 41 | q = qnorm(alpha, 32, 0.5774) 42 | write(q, file = "q", ncolumns = 9, append = FALSE, sep = ",") 43 | 44 | # Michelson data, diff. of means : 242 45 | y1 = c(299850,299900,299930,299950,299980,300000,299930,299760,300000,299960,299740,300070,299850,299980,299880,299980,299650,299810,300000,299960) 46 | y2 = c(299883,299778,299682,299611,300051,299578,299774,299772,299573,299748,299851,299723,299816,299796,299711,299599,299781,299796,299820,299696,299748,299797,299809) 47 | m1 = normnp(y1, m.x = 300000, s.x = 500, sigma.x = 100) 48 | # 299909.1816367, 22.3383526 49 | m2 = normnp(y2, m.x = 300000, s.x = 500, sigma.x = 100) 50 | # 299756.640625, 20.8333333 51 | md = 299909.1816367 - 299756.640625 52 | sd = sqrt(22.3383526^2 + 20.8333333^2) 53 | x = c(100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200) 54 | p = dnorm(x, md, sd) 55 | write(p, file = "p", ncolumns = 11, append = FALSE, sep = ",") 56 | 57 | -------------------------------------------------------------------------------- /bayes/_tst/betabinexch_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | // Test against R:LearningBayes:betabinexch 11 | func TestBetaBinExch(t *testing.T) { 12 | fmt.Println("Testing BetaBinExch()") 13 | theta1 := -1.0 14 | theta2 := 0.0 15 | n := []float64{20, 20, 20, 20, 20} 16 | c := []float64{1, 4, 3, 6, 10} 17 | 18 | x := BetaBinExch(theta1, theta2, c, n) 19 | y := -58.4339 20 | 21 | if abs(x/y-1) > 1e4 { 22 | fmt.Println("means failed: x, y ", x, y) 23 | t.Error() 24 | } 25 | } 26 | 27 | // Test against R:LearningBayes:betabinexch0 28 | func TestBetaBinExch0(t *testing.T) { 29 | fmt.Println("Testing BetaBinExch0()") 30 | theta1 := 0.1 31 | theta2 := 10.0 32 | n := []float64{20, 20, 20, 20, 20} 33 | c := []float64{1, 4, 3, 6, 10} 34 | 35 | x := BetaBinExch(theta1, theta2, c, n) 36 | y := -58.82094 37 | 38 | if abs(x/y-1) > 1e4 { 39 | fmt.Println("means failed: x, y ", x, y) 40 | t.Error() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /bayes/_tst/betaselect_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes 9 | func TestBetaprior1(t *testing.T) { 10 | fmt.Println("betaprior1 ", betaprior1(5, 0.5, 0.45)) 11 | fmt.Println("should be 0.5258179") 12 | } 13 | 14 | func TestBetaSelect(t *testing.T) { 15 | x, y := BetaFromQtls(0.5, 0.25, 0.9, 0.45) 16 | fmt.Println("BetaFromQtls ", x, y) 17 | fmt.Println("should be 2.67 7.37") 18 | } 19 | -------------------------------------------------------------------------------- /bayes/_tst/bfexch_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes:bfexch() 9 | func TestBFExch(t *testing.T) { 10 | y := []float64{1, 3, 2, 4, 6, 4, 3} 11 | n := []float64{10, 10, 10, 10, 10, 10, 10} 12 | theta := 1.0 13 | k := 20.0 14 | 15 | fmt.Println("Testing BFExch #1") 16 | 17 | c1 := BFExch(theta, y, n, k) 18 | c2 := -16.48318 19 | if !check(c1, c2) { 20 | t.Error() 21 | fmt.Println("BFExch: ", c1, "should be ", c2) 22 | } 23 | fmt.Println("BFExch: ", c1, "should be ", c2) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bayes/_tst/check_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | func check(x, y float64) bool { 4 | const acc float64 = 1e-2 // accuracy 5 | var z float64 6 | if x/y > 1.00 { 7 | z = y / x 8 | } else { 9 | z = x / y 10 | } 11 | if 1-z > acc { 12 | return false 13 | } 14 | return true 15 | } 16 | -------------------------------------------------------------------------------- /bayes/_tst/ctable_indep_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "code.google.com/p/probab/dst" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | // Test against R:LearningBayes:bfindep() 10 | func TestFactCTableIndep(t *testing.T) { 11 | y := [][]float64{ 12 | {1, 10}, 13 | {5, 20}, 14 | } 15 | k := 20.0 16 | m := 1000000 17 | fmt.Println("Testing ldirichlet") 18 | 19 | c5 := ldirichlet(y) 20 | fmt.Println("ldirichlet: ", c5) 21 | fmt.Println("should be: -2.302585 -12.266791") 22 | 23 | fmt.Println("Testing meanSd") 24 | 25 | nrm := make([]float64, m) 26 | for i, _ := range nrm { 27 | nrm[i] = dst.NormalNext(5, 0.6) 28 | } 29 | mu, sd := meanSd(nrm) 30 | fmt.Println("mu, sd :", mu, sd) 31 | 32 | fmt.Println("cols2vec") 33 | fmt.Println(cols2vec(y)) 34 | fmt.Println("should be 1 5 10 20") 35 | 36 | fmt.Println("Testing FactCTableIndep #1") 37 | c1, c2 := FactCTableIndep(y, k, m) 38 | c3, c4 := 0.6768298, 0.002508772 39 | if !check(c1, c3) || !check(c2, c4) { 40 | t.Error() 41 | fmt.Println("FactCTableIndep: bf = ", c1, "should be ", c3, "+/- 0.015") 42 | fmt.Println(" nse = ", c2, "should be ", c4, "+/- 0.003") 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /bayes/_tst/ctable_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes:ctable(y,a) 9 | func TestFactCTableUnif(t *testing.T) { 10 | a := [][]float64{ 11 | {1, 1, 1}, 12 | {1, 1, 1}, 13 | } 14 | 15 | y := [][]float64{ 16 | {10, 6, 6}, 17 | {4, 3, 10}, 18 | } 19 | 20 | fmt.Println("Testing FactCTableUnif #1") 21 | 22 | c1 := FactCTableUnif(y, a) 23 | c2 := 2.288513 24 | if !check(c1, c2) { 25 | t.Error() 26 | fmt.Println("FactCTableUnif: ", FactCTableUnif(y, a), "should be ", c2) 27 | } 28 | 29 | fmt.Println("Testing FactCTableUnif #2") 30 | a = [][]float64{ 31 | {1, 1}, 32 | {1, 1}, 33 | } 34 | 35 | y = [][]float64{ 36 | {10, 4}, 37 | {4, 10}, 38 | } 39 | c1 = FactCTableUnif(y, a) 40 | c2 = 7.490698 41 | if !check(c1, c2) { 42 | t.Error() 43 | fmt.Println("FactCTableUnif: ", FactCTableUnif(y, a), "should be ", c2) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /bayes/_tst/discint_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes 9 | func TestDiscHPI(t *testing.T) { 10 | x := []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 11 | p := []float64{0.0282475249, 0.1210608210, 0.2334744405, 0.2668279320, 0.2001209490, 0.1029193452, 0.0367569090, 0.0090016920, 0.0014467005, 0.0001377810, 0.0000059049} 12 | pcontent := 0.8 13 | 14 | probExact, hpiSet := DiscHPI(x, p, pcontent) 15 | fmt.Println("DiscHPI probExact :", probExact) 16 | fmt.Println("should be 0.8214841") 17 | fmt.Println("DiscHPI hpiSet :", hpiSet) 18 | fmt.Println("should be [1 2 3 4]") 19 | fmt.Println() 20 | fmt.Println() 21 | fmt.Println() 22 | fmt.Println() 23 | } 24 | 25 | func TestDiscHPI2(t *testing.T) { 26 | x := []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100} 27 | p := []float64{1.995076e-06, 2.798110e-05, 1.942565e-04, 8.899916e-04, 3.026936e-03, 8.150982e-03, 1.810038e-02, 3.408970e-02, 5.558039e-02, 7.968424e-02, 1.016996e-01, 1.167010e-01, 1.213917e-01, 1.152481e-01, 1.004455e-01, 8.076873e-02, 6.017938e-02, 4.170457e-02, 2.697085e-02, 1.632527e-02, 9.273016e-03, 4.954470e-03, 2.495210e-03, 1.186805e-03, 5.340285e-04, 2.276898e-04, 9.211640e-05, 3.540874e-05, 1.294735e-05, 4.508383e-06, 1.496454e-06, 4.739203e-07, 1.433210e-07, 4.142003e-08, 1.144753e-08, 3.027563e-09, 7.666720e-10, 1.859916e-10, 4.324698e-11, 9.642473e-12, 2.062357e-12, 4.232887e-13, 8.339595e-14, 1.577648e-14, 2.866406e-15, 5.002864e-16, 8.389365e-17, 1.351856e-17, 2.093489e-18, 3.115900e-19, 4.457477e-20, 6.129069e-21, 8.100144e-22, 1.028877e-22, 1.255953e-23, 1.473241e-24, 1.660366e-25, 1.797576e-26, 1.869103e-27, 1.866105e-28, 1.788439e-29, 1.644788e-30, 1.451070e-31, 1.227543e-32, 9.953231e-34, 7.731411e-35, 5.750272e-36, 4.092588e-37, 2.785535e-38, 1.811820e-39, 1.125341e-40, 6.668875e-42, 3.767243e-43, 2.026582e-44, 1.037055e-45, 5.042193e-47, 2.326223e-48, 1.016898e-49, 4.205486e-51, 1.642545e-52, 6.047169e-54, 2.094125e-55, 6.805309e-57, 2.069892e-58, 5.875204e-60, 1.551063e-61, 3.794267e-63, 8.563319e-65, 1.774224e-66, 3.355097e-68, 5.751231e-70, 8.863901e-72, 1.216144e-73, 1.467228e-75, 1.532404e-77, 1.357396e-79, 9.915414e-82, 5.734620e-84, 2.462098e-86, 6.975986e-89, 9.783881e-92} 28 | pcontent := .95 29 | 30 | probExact, hpiSet := DiscHPI(x, p, pcontent) 31 | fmt.Println("DiscHPI probExact :", probExact) 32 | fmt.Println("should be 0.9525642") 33 | fmt.Println("DiscHPI hpiSet :", hpiSet) 34 | fmt.Println("should be [6 7 8 9 10 11 12 13 14 15 16 17 18]") 35 | 36 | } 37 | -------------------------------------------------------------------------------- /bayes/_tst/gibbs_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | func logpost(theta []float64) float64 { 11 | s1, f1, s2, f2 := 6.0, 2.0, 3.0, 10.0 12 | return LogCTablePost(s1, f1, s2, f2, theta[0], theta[1]) 13 | } 14 | 15 | // Test against R:LearningBayes:gibbs 16 | func TestGibbs(t *testing.T) { 17 | m := 10000000 18 | start := []float64{1.0, 1.0} 19 | scale := []float64{2.0, 2.0} 20 | fmt.Println("Testing Gibbs") 21 | _, arate := Gibbs(logpost, start, m, scale) 22 | fmt.Println("arate : ", arate) 23 | } 24 | -------------------------------------------------------------------------------- /bayes/_tst/histprior_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes 9 | func TestHistPrior(t *testing.T) { 10 | p := []float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99} 11 | midpts := []float64{0.1, 0.3, 0.5, 0.7, 0.9} 12 | prob := []float64{0.10, 0.20, 0.30, 0.32, 0.80} 13 | 14 | y := []float64{0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.32, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80, 0.80} 15 | 16 | x := HistPrior(p, midpts, prob) 17 | 18 | for i := range x { 19 | if x[i] != y[i] { 20 | fmt.Println("failed: i, x[i] , y[i] ", i, x[i], y[i]) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /bayes/_tst/howardprior_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "testing" 7 | ) 8 | 9 | // Test against R:LearningBayes 10 | func TestLnHowardPrior(t *testing.T) { 11 | z := LnHowardPrior(0.1, 0.5, 1, 1, 1, 1, 2) 12 | fmt.Println("LnHowardPrior :", z) 13 | fmt.Println("should be -0.6034745") 14 | } 15 | func TestHowardPosteriorProb(t *testing.T) { 16 | rand.Seed(56589856) 17 | sigma := 2.0 18 | z := HowardPosteriorProb(3, 18, 7, 12, 1, 1, 1, 1, sigma) 19 | fmt.Println("HowardPosteriorProb :", z) 20 | fmt.Println("should be 0.0161") 21 | sigma = 1.0 22 | z = HowardPosteriorProb(3, 18, 7, 12, 1, 1, 1, 1, sigma) 23 | fmt.Println("HowardPosteriorProb :", z) 24 | fmt.Println("should be 0.0343") 25 | sigma = 0.5 26 | z = HowardPosteriorProb(3, 18, 7, 12, 1, 1, 1, 1, sigma) 27 | fmt.Println("HowardPosteriorProb :", z) 28 | fmt.Println("should be 0.1037") 29 | sigma = 0.25 30 | z = HowardPosteriorProb(3, 18, 7, 12, 1, 1, 1, 1, sigma) 31 | fmt.Println("HowardPosteriorProb :", z) 32 | fmt.Println("should be 0.2374") 33 | } 34 | -------------------------------------------------------------------------------- /bayes/_tst/logctablepost_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | // Test against R:LearningBayes:logctablepost 11 | func TestLogCTablePost(t *testing.T) { 12 | fmt.Println("Testing LogCTablePost()") 13 | s1, f1, s2, f2, theta1, theta2 := 6.0, 2.0, 3.0, 10.0, 2.0, 4.0 14 | x := LogCTablePost(s1, f1, s2, f2, theta1, theta2) 15 | y := -20.4611 16 | 17 | if abs(x/y-1) > 1e4 { 18 | fmt.Println("means failed: x, y ", x, y) 19 | t.Error() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /bayes/_tst/logisticpost_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | // Test against R:LearningBayes:logisticpost 11 | func TestLogisticPost(t *testing.T) { 12 | fmt.Println("Testing LogisticPost()") 13 | beta0 := 2.0 14 | beta1 := 10.0 15 | 16 | d := []float64{-0.86, -0.3, -0.05, 0.73} 17 | n := []float64{5, 5, 5, 5} 18 | z := []float64{0, 1, 3, 5} 19 | x := LogisticPost(d, n, z, beta0, beta1) 20 | y := -6.580629 21 | 22 | if abs(x/y-1) > 1e4 { 23 | fmt.Println("means failed: x, y ", x, y) 24 | t.Error() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /bayes/_tst/logpoissgamma_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes 9 | func TestLogPoissGamma(t *testing.T) { 10 | fmt.Println("TestLogPoissGamma #1") 11 | theta := []float64{-1, 0, 1, 2} 12 | d := []float64{2, 4, 3, 6, 1, 0, 4, 3, 10, 2} 13 | sh := 1.0 14 | rt := 1.0 15 | y := []float64{-49.289786, -20.243112, -3.144212, -18.522729} 16 | 17 | x := LogPoissGamma(theta, d, sh, rt) 18 | 19 | for i := range x { 20 | if abs(x[i]-y[i]) > 1e4 { 21 | fmt.Println("failed: i, x[i] , y[i] ", i, x[i], y[i]) 22 | t.Error() 23 | } 24 | } 25 | 26 | fmt.Println("TestLogPoissGamma #2") 27 | sh = 1.4 28 | rt = 0.6 29 | y = []float64{-50.138177, -20.438655, -2.252443, -15.362650} 30 | 31 | x = LogPoissGamma(theta, d, sh, rt) 32 | 33 | for i := range x { 34 | if abs(x[i]-y[i]) > 1e4 { 35 | fmt.Println("failed: i, x[i] , y[i] ", i, x[i], y[i]) 36 | t.Error() 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /bayes/_tst/logpoissnormal_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes 9 | func TestLogPoissNormal(t *testing.T) { 10 | theta := []float64{-1, 0, 1, 2} 11 | d := []float64{2, 4, 3, 6, 1, 0, 4, 3, 10, 2} 12 | mean := 0.0 13 | sd := 1.0 14 | 15 | y := []float64{-49.340845, -20.162051, -2.844869, -16.052612} 16 | 17 | x := LogPoissNormal(theta, d, mean, sd) 18 | 19 | for i := range x { 20 | if abs(x[i]-y[i]) > 1e4 { 21 | fmt.Println("failed: i, x[i] , y[i] ", i, x[i], y[i]) 22 | t.Error() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /bayes/_tst/mnormt_onesided_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestNormMeanTestOneSided(t *testing.T) { 9 | fmt.Println("NormMeanTestOneSided: ") 10 | bf, priOdds, postOdds, postH := NormMeanTestOneSided(175, 170, 1000, 176, 10, 3) 11 | fmt.Println("bf, priOdds, postOdds, postH", bf, priOdds, postOdds, postH) 12 | fmt.Println("should be 0.1694947 1.008011 0.1708525 0.1459215") 13 | } 14 | 15 | // Ref.: Albert (2009) 16 | -------------------------------------------------------------------------------- /bayes/_tst/mnormt_twosided_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestNormMeanTestTwoSided(t *testing.T) { 9 | fmt.Println("NormMeanTestTwoSided: ") 10 | m0 := 170.0 11 | prob := 0.5 12 | smpMean := 176.0 13 | smpSize := 10 14 | popSd := 3.0 15 | tau := []float64{0.5, 1, 2, 4, 8} 16 | bf, post := NormMeanTestTwoSided(m0, prob, tau, smpMean, smpSize, popSd) 17 | fmt.Println("bf ", bf, post) 18 | fmt.Println("should be 1.462146e-02 3.897038e-05 1.894326e-07 2.591162e-08 2.309739e-08") 19 | fmt.Println("post ", post) 20 | fmt.Println("should be 1.441076e-02 3.896887e-05 1.894325e-07 2.591162e-08 2.309739e-08") 21 | } 22 | -------------------------------------------------------------------------------- /bayes/_tst/normal_normal_mix_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | // Test against R:LearningBayes:normal.normal.mix 11 | func TestNormalNormalMix(t *testing.T) { 12 | fmt.Println("Testing NormalNormalMix()") 13 | probs := []float64{.5, .5} 14 | priorMean := []float64{0.0, 2.0} 15 | priorVar := []float64{1.0, 0.5} 16 | y := 1.0 17 | sigma2 := .5 18 | 19 | postProbs, postMean, postVar := NormalNormalMix(probs, priorMean, priorVar, y, sigma2) 20 | 21 | fmt.Println("postProbs ", postProbs) 22 | fmt.Println("should be: [0.4909845 0.5090155]") 23 | fmt.Println("postMean ", postMean) 24 | fmt.Println("should be: [0.6666667 1.5000000]") 25 | fmt.Println("postVar ", postVar) 26 | fmt.Println("should be: [0.3333333 0.2500000]") 27 | } 28 | -------------------------------------------------------------------------------- /bayes/_tst/normpostsim_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | // Test against R:LearningBayes 11 | func TestNormPostSimNoPrior(t *testing.T) { 12 | fmt.Println("Testing NormPostSimNoPrior()") 13 | m := 100000 14 | d := []float64{-67, -48, 6, 8, 14, 16, 23, 24, 28, 29, 41, 49, 67, 60, 75} 15 | means, vars := NormPostSimNoPrior(d, m) 16 | 17 | x := mean(means) 18 | y := 21.67034 19 | 20 | if abs(x/y-1) > 1e4 { 21 | fmt.Println("means failed: x, y ", x, y) 22 | t.Error() 23 | } 24 | 25 | x = mean(vars) 26 | y = 1735.703 27 | 28 | if abs(x/y-1) > 1e4 { 29 | fmt.Println("vars failed: x, y ", x, y) 30 | t.Error() 31 | } 32 | } 33 | 34 | func TestNormPostNoPriorNext(t *testing.T) { 35 | fmt.Println("Testing NormPostNoPriorNext()") 36 | d := []float64{-67, -48, 6, 8, 14, 16, 23, 24, 28, 29, 41, 49, 67, 60, 75} 37 | m := 100000 38 | mn := 0.0 39 | vr := 0.0 40 | 41 | for i := 0; i < m; i++ { 42 | mni, vri := NormPostNoPriorNext(d) 43 | mn += mni 44 | vr += vri 45 | } 46 | mn /= float64(m) 47 | vr /= float64(m) 48 | 49 | y := 21.67034 50 | 51 | if abs(mn/y-1) > 1e4 { 52 | fmt.Println("means failed: mn, y ", mn, y) 53 | t.Error() 54 | } 55 | 56 | y = 1735.703 57 | 58 | if abs(vr/y-1) > 1e4 { 59 | fmt.Println("vars failed: vr, y ", vr, y) 60 | t.Error() 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /bayes/_tst/pbetat_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes 9 | func TestProbBetaTest(t *testing.T) { 10 | p0 := .5 11 | prob := .5 12 | a := 10.0 13 | b := 10.0 14 | succ := 5 15 | fail := 15 16 | 17 | bf, post := ProbBetaTest(p0, prob, a, b, succ, fail) 18 | fmt.Println("ProbBetaTest bf, post: ", bf, post) 19 | fmt.Println("should be 0.3893163, 0.2802215") 20 | } 21 | func TestCumSum(t *testing.T) { 22 | y := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 23 | 24 | fmt.Println("TestCumSum: ", cumSum(y)) 25 | fmt.Println("should be 1 3 6 10 15 21 28 36 45 55") 26 | } 27 | -------------------------------------------------------------------------------- /bayes/_tst/pdisc_test.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:LearningBayes 9 | func TestPropDisc(t *testing.T) { 10 | p := []float64{.2, .25, .3, .35} 11 | prior := []float64{.25, .25, .25, .25} 12 | succ := 5 13 | fail := 10 14 | 15 | out := PropDisc(p, prior, succ, fail) 16 | fmt.Println("PropDisc ", out) 17 | fmt.Println("should be 0.1502369 0.2404581 0.3001328 0.3091723") 18 | } 19 | -------------------------------------------------------------------------------- /bayes/_tst/poissgamexch_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | // Test against R:LearningBayes:poissgamexch 11 | func TestPoissGamExch(t *testing.T) { 12 | fmt.Println("Testing PoissGamExch()") 13 | theta1 := -4.0 14 | theta2 := 0.0 15 | z0 := 0.5 16 | 17 | e := []float64{532, 584, 672, 722, 904} 18 | c := []float64{0, 0, 2, 1, 1} 19 | 20 | x := PoissGamExch(theta1, theta2, z0, c, e) 21 | y := -42.03939 22 | 23 | if abs(x/y-1) > 1e4 { 24 | fmt.Println("means failed: x, y ", x, y) 25 | t.Error() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /bayes/beta_hdi_qtl.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Highest density iterval (HDI) limits from quantile function, for Beta distribution. 6 | // Ref: Kruschke 2012: Chapter 23.3.3, p. 629 and further. 7 | 8 | import ( 9 | "code.google.com/p/probab/dst" 10 | ) 11 | 12 | // Interval width 13 | func iw(α, β, credMass, lowTailPr float64) float64 { 14 | return dst.BetaQtlFor(α, β, credMass+lowTailPr) - dst.BetaQtlFor(α, β, lowTailPr) 15 | } 16 | 17 | // Interval width for fixed α, β, credMass 18 | func iwFix(α, β, credMass float64) func(x float64) float64 { 19 | return func(x float64) float64 { return iw(α, β, credMass, x) } 20 | } 21 | 22 | // BetaHDI returns the Highhest Density Interval limits of the Beta Distribution. 23 | func BetaHDI(α, β, credMass, tol float64) (lo, hi float64) { 24 | f := iwFix(α, β, credMass) 25 | // func fmin(f func(float64) float64, ax, bx, tol float64) float64 { 26 | 27 | min := fmin(f, 0, 1-credMass, tol) 28 | lo = dst.BetaQtlFor(α, β, min) 29 | hi = dst.BetaQtlFor(α, β, credMass+min) 30 | return lo, hi 31 | } 32 | -------------------------------------------------------------------------------- /bayes/betabinexch.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Log posterior of logit mean and log precision for Binomial/beta exchangeable model. 6 | // Ref.: Albert (2009) 7 | 8 | func logB(y, n, k, eta float64) float64 { 9 | return lnB(k*eta+y, k*(1-eta)+n-y) - lnB(k*eta, k*(1-eta)) 10 | } 11 | 12 | // BetaBinExch returns the log posterior density of logit mean and log precision for a Binomial/beta exchangeable model. 13 | func BetaBinExch(theta1, theta2 float64, y, n []float64) float64 { 14 | // Arguments: 15 | // theta1, theta2 - parameter values of logit eta and log k 16 | // Data: 17 | // y - counts 18 | // n - sample sizes 19 | // Returns: 20 | // value of the log posterior 21 | 22 | eta := exp(theta1) / (1 + exp(theta1)) 23 | k := exp(theta2) 24 | val := 0.0 25 | for i, _ := range y { 26 | val += logB(y[i], n[i], k, eta) 27 | } 28 | val += theta2 - 2*log(1+exp(theta2)) 29 | return val 30 | } 31 | 32 | // BetaBinExch0 returns the log posterior density of mean and precision for a Binomial/beta exchangeable model. 33 | func BetaBinExch0(theta1, theta2 float64, y, n []float64) float64 { 34 | // Arguments: 35 | // theta1, theta2 - parameter values of logit eta and log k 36 | // Data: 37 | // y - counts 38 | // n - sample sizes 39 | // Returns: 40 | // value of the log posterior 41 | 42 | eta := theta1 43 | k := theta2 44 | val := 0.0 45 | for i, _ := range y { 46 | val += logB(y[i], n[i], k, eta) 47 | } 48 | val += -2*log(1+k) - log(eta) - log(1-eta) 49 | return val 50 | } 51 | -------------------------------------------------------------------------------- /bayes/betaselect.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Selection of Beta Prior Given Knowledge of Two Quantiles. 6 | // Ref.: Albert (2009) 7 | 8 | import ( 9 | dst "code.google.com/p/probab/dst" 10 | ) 11 | 12 | // betaprior1 returns the prior mean m given a beta(k*m, K*(1-m)) prior 13 | // where the pth quantile is given by x. 14 | func betaprior1(k, x, p float64) float64 { 15 | var m0, p0 float64 16 | mLo := 0.0 17 | mHi := 1.0 18 | rep := true 19 | for rep == true { 20 | m0 = (mLo + mHi) / 2.0 21 | p0 = dst.BetaCDFAt(k*m0, k*(1-m0), x) 22 | if p0 < p { 23 | mHi = m0 24 | } else { 25 | mLo = m0 26 | } 27 | if abs(p0-p) < .0001 { 28 | rep = false 29 | } 30 | } 31 | return m0 32 | } 33 | 34 | // BetaFromQtls finds the shape parameters of a beta density that matches knowledge of two quantiles of the distribution. 35 | func BetaFromQtls(p1, x1, p2, x2 float64) (alpha, beta float64) { 36 | // Arguments: 37 | // p1 first probability 38 | // x1 its quantile 39 | // p2 second probability 40 | // x2 its quantile 41 | // Returns: 42 | // alpha, beta params of the corresponding Beta distribution. 43 | 44 | m := make([]float64, 100) 45 | logK := make([]float64, 100) 46 | k := make([]float64, 100) 47 | for i := 0; i < 100; i++ { 48 | v := -3.0 + 0.1111111*float64(i) 49 | logK[i] = v 50 | k[i] = exp(v) 51 | m[i] = betaprior1(exp(v), x1, p1) 52 | } 53 | 54 | prob2 := make([]float64, 100) 55 | for i, _ := range prob2 { 56 | prob2[i] = dst.BetaCDFAt(k[i]*m[i], k[i]*(1-m[i]), x2) 57 | } 58 | 59 | yOut := linInt(prob2, logK, p2) 60 | k0 := exp(yOut) 61 | m0 := betaprior1(k0, x1, p1) 62 | alpha = k0 * m0 63 | beta = k0 * (1 - m0) 64 | return 65 | } 66 | -------------------------------------------------------------------------------- /bayes/bfexch.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Logarithm of the integral of the Bayes factor for testing homogeneity of a set of proportions. 6 | // Ref.: Albert (2009) 7 | 8 | func logF(k, eta float64, y, n []float64) []float64 { 9 | v := make([]float64, len(y)) 10 | for i, _ := range v { 11 | v[i] = lnB(k*eta+y[i], k*(1-eta)+n[i]-y[i]) - lnB(k*eta, k*(1-eta)) 12 | } 13 | return v 14 | } 15 | 16 | // BFExch returns the logarithm of the integral of the Bayes factor for testing homogeneity. 17 | // of a set of proportions. 18 | func BFExch(theta float64, y, n []float64, k float64) float64 { 19 | // Arguments: 20 | // theta - value of the logit of the prior mean hyperparameter 21 | // y - counts 22 | // n - sample sizes 23 | // k - prior precision hyperparameter 24 | // 25 | // Returns: 26 | // value of the logarithm of the integral. 27 | 28 | eta := exp(theta) / (1 + exp(theta)) 29 | sum := 0.0 30 | sumY := 0.0 31 | sumNY := 0.0 32 | w := logF(k, eta, y, n) 33 | for i, _ := range y { 34 | sum += w[i] 35 | sumY += y[i] 36 | sumNY += n[i] - y[i] 37 | } 38 | return sum + log(eta*(1-eta)) - lnB(sumY+1, sumNY+1) 39 | } 40 | -------------------------------------------------------------------------------- /bayes/cri.go: -------------------------------------------------------------------------------- 1 | // Bayesian credible interval. 2 | 3 | package bayes 4 | 5 | /* 6 | import ( 7 | . "code.google.com/p/probab/dst" 8 | "math" 9 | ) 10 | */ 11 | 12 | // Bayesian credible interval for (analytical) quantile function 13 | func CrI(α float64, qtl func(𝛩 float64) float64) (hi, lo float64) { 14 | p := (1 - α) 15 | lo = qtl(p / 2) 16 | hi = qtl(1 - p/2) 17 | return 18 | } 19 | 20 | // Credible interval for a sample from a posterior density 21 | func ECrI(𝛩 []float64, α float64) (lo, hi float64) { 22 | p := (1 - α) 23 | lo = eQtl(𝛩, p/2) 24 | hi = eQtl(𝛩, 1-p/2) 25 | return 26 | } 27 | -------------------------------------------------------------------------------- /bayes/ctable.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Bayes factor against independence in a 6 | // 2-way contingency table using uniform priors. 7 | // Ref.: Albert (2009) 8 | 9 | import ( 10 | fn "code.google.com/p/go-fn/fn" 11 | "math" 12 | ) 13 | 14 | func lDirich(a []float64) float64 { 15 | sumLnΓ := 0.0 16 | sum := 0.0 17 | for _, x := range a { 18 | sumLnΓ += fn.LnΓ(x) 19 | sum += x 20 | } 21 | return sumLnΓ - fn.LnΓ(sum) 22 | } 23 | 24 | func rowSums(a [][]float64) []float64 { 25 | v := make([]float64, len(a)) 26 | for i, row := range a { 27 | for _, x := range row { 28 | v[i] += x 29 | } 30 | } 31 | return v 32 | } 33 | 34 | func colSums(a [][]float64) []float64 { 35 | v := make([]float64, len(a[0])) 36 | for _, row := range a { 37 | for j, x := range row { 38 | v[j] += x 39 | } 40 | } 41 | return v 42 | } 43 | 44 | // FactCTableUnif returns the Bayes factor for testing independence in a contingency table. 45 | func FactCTableUnif(y, a [][]float64) float64 { 46 | // Bayes factor against independence in a 47 | // 2-way contingency table using uniform priors, 48 | // where Y is a matrix containing the 2-way table of counts, 49 | // and A is a matrix of prior hyperparameters. 50 | 51 | nRows := len(y) 52 | nCols := len(y[0]) 53 | fRows := float64(nRows) 54 | fCols := float64(nCols) 55 | ac := colSums(a) 56 | ar := rowSums(a) 57 | yc := colSums(y) 58 | yr := rowSums(y) 59 | 60 | t1 := make([]float64, nRows*nCols) 61 | k := 0 62 | for j := 0; j < nCols; j++ { 63 | for i := 0; i < nRows; i++ { 64 | t1[k] = y[i][j] + a[i][j] 65 | k++ 66 | } 67 | } 68 | 69 | t2 := make([]float64, nRows) 70 | for i := 0; i < nRows; i++ { 71 | t2[i] = ar[i] - fCols + 1 72 | } 73 | 74 | t3 := make([]float64, nCols) 75 | for i := 0; i < nCols; i++ { 76 | t3[i] = ac[i] - fRows + 1 77 | } 78 | 79 | t4 := make([]float64, nRows*nCols) 80 | k = 0 81 | for j := 0; j < nCols; j++ { 82 | for i := 0; i < nRows; i++ { 83 | t4[k] = a[i][j] 84 | k++ 85 | } 86 | } 87 | 88 | t5 := make([]float64, nRows) 89 | for i := 0; i < nRows; i++ { 90 | t5[i] = yr[i] + ar[i] - fCols + 1 91 | } 92 | 93 | t6 := make([]float64, nCols) 94 | for i := 0; i < nCols; i++ { 95 | t6[i] = yc[i] + ac[i] - fRows + 1 96 | } 97 | 98 | lbf := lDirich(t1) + lDirich(t2) + lDirich(t3) - lDirich(t4) - lDirich(t5) - lDirich(t6) 99 | return math.Exp(lbf) 100 | } 101 | -------------------------------------------------------------------------------- /bayes/deviance.go: -------------------------------------------------------------------------------- 1 | // Bayesian deviance 2 | // Aitkin 2010: 41 3 | 4 | package bayes 5 | 6 | import "math" 7 | 8 | // Bayesian deviance 9 | func deviance(likelihood float64) float64 { 10 | return -2 * math.Log(likelihood) 11 | } 12 | 13 | // Bayesian deviance difference 14 | func devdiff(like1, like2 float64) float64 { 15 | lr := like1 / like2 16 | return -2 * math.Log(lr) 17 | } 18 | -------------------------------------------------------------------------------- /bayes/discint.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Highest probability interval for a discrete probability distribution. 6 | // Ref.: Albert (2009): 184 [mnormt.onesided()] 7 | 8 | import ( 9 | "sort" 10 | ) 11 | 12 | // cumSum returns cumulative sums of a slice. 13 | func cumSum(x []float64) []float64 { 14 | v := make([]float64, len(x)) 15 | for i, _ := range x { 16 | if i == 0 { 17 | v[i] = x[i] 18 | } else { 19 | v[i] = v[i-1] + x[i] 20 | } 21 | } 22 | return v 23 | } 24 | 25 | type IndexSorter struct { 26 | Target []float64 27 | Indices []int 28 | } 29 | 30 | func NewSorter(t []float64) IndexSorter { 31 | iv := make([]int, len(t)) 32 | for i := range iv { 33 | iv[i] = i 34 | } 35 | return IndexSorter{Target: t, Indices: iv} 36 | } 37 | func (s IndexSorter) Len() int { return len(s.Target) } 38 | func (s IndexSorter) Less(i, j int) bool { return s.Target[i] < s.Target[j] } 39 | func (s IndexSorter) Swap(i, j int) { 40 | s.Target[i], s.Target[j] = s.Target[j], s.Target[i] 41 | s.Indices[i], s.Indices[j] = s.Indices[j], s.Indices[i] 42 | } 43 | 44 | // DiscHPI computes a highest probability interval for a discrete distribution. 45 | func DiscHPI(x, p []float64, probContent float64) (probExact float64, hpiSet []float64) { 46 | // Arguments: 47 | // x - values where probability is listed 48 | // p - probability at x 49 | // probContent - target probability content of the HPI 50 | // Returns: 51 | // probExact - exact probability content of the HPI 52 | // hpiSet set of values of x within the highest probability interval 53 | s := NewSorter(p) 54 | sort.Sort(s) 55 | ix := s.Indices 56 | ps := s.Target 57 | 58 | // reverse sorted indices 59 | iRev := make([]int, len(ix)) 60 | for i, _ := range ix { 61 | iRev[i] = ix[len(ix)-i-1] 62 | } 63 | 64 | // reverse sorted probabilities 65 | pRev := make([]float64, len(ps)) 66 | for i, _ := range ps { 67 | pRev[i] = ps[len(ps)-i-1] 68 | } 69 | 70 | // sort x 71 | xRev := make([]float64, len(iRev)) 72 | for i, _ := range xRev { 73 | xRev[i] = x[iRev[i]] 74 | } 75 | 76 | cp := cumSum(pRev) 77 | 78 | // find first index where cp>=probContent 79 | j := 0 80 | for i, _ := range cp { 81 | if cp[i] >= probContent { 82 | break 83 | } 84 | j++ 85 | } 86 | probExact = cp[j] 87 | hpiSet = make([]float64, j+1) 88 | for i := 0; i < j+1; i++ { 89 | hpiSet[i] = xRev[i] 90 | } 91 | sort.Float64s(hpiSet) 92 | return probExact, hpiSet 93 | } 94 | -------------------------------------------------------------------------------- /bayes/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | // Bayesian inference. 4 | package bayes 5 | -------------------------------------------------------------------------------- /bayes/e_cdf.go: -------------------------------------------------------------------------------- 1 | // Empirical CDF 2 | 3 | package bayes 4 | 5 | import "sort" 6 | 7 | // Empirical CDF, x is an array of observed values, y is a value where CDF is evaluated 8 | // returns CDF value at y 9 | func eCDF(x []float64, y float64) float64 { 10 | var ( 11 | i int 12 | v float64 13 | ) 14 | 15 | n := len(x) 16 | sort.Float64s(x) 17 | for i = 0; i < n && x[i] < y; i++ { 18 | } 19 | //return (2*float64(i)+1)/(2*float64(n)) // linear interpolation 20 | 21 | if i == n { 22 | v = 1 23 | } else { // linear interpolation 24 | dx := y - x[i] 25 | dp := dx / (x[i+1] - x[i]) 26 | v = (float64(i) + dp) / float64(n) 27 | } 28 | return v 29 | 30 | } 31 | -------------------------------------------------------------------------------- /bayes/e_qtl.go: -------------------------------------------------------------------------------- 1 | // Empirical quantile from a sample from a PDF | PMF. 2 | 3 | package bayes 4 | 5 | import "sort" 6 | 7 | // Empirical quantile from a sample from a PDF | PMF. 8 | // returns α-quantile 9 | func eQtl(x []float64, α float64) float64 { 10 | var ( 11 | i int 12 | v float64 13 | ) 14 | 15 | n := len(x) 16 | sort.Float64s(x) 17 | p := 0.0 18 | for i = 0; i < n && p < α*float64(n); i++ { 19 | p++ 20 | } 21 | if i == n { 22 | v = x[i] 23 | } else { // linear interpolation 24 | dp := α*float64(n) - p 25 | dx := (x[i+1] - x[i]) * dp 26 | v = x[i] + dx 27 | } 28 | return v 29 | } 30 | -------------------------------------------------------------------------------- /bayes/fn.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | fn "code.google.com/p/go-fn/fn" 7 | "math" 8 | ) 9 | 10 | const π = float64(math.Pi) 11 | const ln2 = math.Ln2 12 | const lnSqrt2π = 0.918938533204672741780329736406 // log(sqrt(2*pi)) 13 | const min64 = math.SmallestNonzeroFloat64 // DBL_MIN 14 | const eps64 = 1.1102230246251565e-16 // DBL_EPSILON 15 | const maxExp = 1024.0 // DBL_MAX_EXP 16 | const sqrt2 = math.Sqrt2 17 | 18 | var nan = math.NaN() 19 | 20 | var fZero float64 = float64(0.0) 21 | var fOne float64 = float64(1.0) 22 | var iZero int64 = int64(0) 23 | var iOne int64 = int64(1) 24 | 25 | var negInf float64 = math.Inf(-1) 26 | var posInf float64 = math.Inf(+1) 27 | 28 | // Functions imported from "math" 29 | var abs func(float64) float64 = math.Abs 30 | var floor func(float64) float64 = math.Floor 31 | var ceil func(float64) float64 = math.Ceil 32 | var log func(float64) float64 = math.Log 33 | var log1p func(float64) float64 = math.Log1p 34 | var exp func(float64) float64 = math.Exp 35 | var sqrt func(float64) float64 = math.Sqrt 36 | var pow func(float64, float64) float64 = math.Pow 37 | var atan func(float64) float64 = math.Atan 38 | var tan func(float64) float64 = math.Tan 39 | var trunc func(float64) float64 = math.Trunc 40 | var erf func(float64) float64 = math.Erf 41 | var erfc func(float64) float64 = math.Erfc 42 | var isNaN func(float64) bool = math.IsNaN 43 | var isInf func(float64, int) bool = math.IsInf 44 | 45 | // Functions imported from "code.google.com/p/go-fn/fn" 46 | var lnB func(float64, float64) float64 = fn.LnB 47 | var lnΓ func(float64) float64 = fn.LnΓ 48 | 49 | // sum returns the sum of the data vector. 50 | func sum(x []float64) float64 { 51 | s := 0.0 52 | for _, val := range x { 53 | s += val 54 | } 55 | return s 56 | } 57 | 58 | // mean returns the mean of the data vector. 59 | func mean(x []float64) float64 { 60 | μ := sum(x) 61 | μ /= float64(len(x)) 62 | return μ 63 | } 64 | -------------------------------------------------------------------------------- /bayes/gibbs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | import ( 6 | "code.google.com/p/probab/dst" 7 | "math/rand" 8 | ) 9 | 10 | /* 11 | 12 | gibbs=function(logpost,start,m,scale,...) 13 | { 14 | p=length(start) 15 | vth=array(0,dim=c(m,p)) 16 | f0=logpost(start,...) 17 | arate=array(0,dim=c(1,p)) 18 | 19 | th0=start 20 | for (i in 1:m) 21 | { 22 | for (j in 1:p) 23 | { 24 | th1=th0 25 | th1[j]=th0[j]+rnorm(1)*scale[j] 26 | f1=logpost(th1,...) 27 | u=runif(1)>>>>>> 20 | // Interval width for fixed α, β, credMass 21 | func iwFix(α, β, credMass float64) func(x float64) float64 { 22 | return func(x float64) float64 { return iw(α, β, credMass, x) } 23 | } 24 | 25 | // BetaHDI returns the Highhest Density Interval limits of the Beta Distribution. 26 | func BetaHDI(α, β, credMass, tol float64) (lo, hi float64) { 27 | f := iwFix(α, β, credMass) 28 | // func fmin(f func(float64) float64, ax, bx, tol float64) float64 { 29 | 30 | min := fmin(f, 0, 1-credMass, tol) 31 | lo = dst.BetaQtlFor(α, β, min) 32 | hi = dst.BetaQtlFor(α, β, credMass+min) 33 | return lo, hi 34 | } 35 | */ 36 | -------------------------------------------------------------------------------- /bayes/histprior.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Density function of a histogram distribution. 6 | // Ref.: Albert (2009) 7 | 8 | // HistPrior returns the density of a probability distribution defined on a set of equal-width intervals. 9 | func HistPrior(p, midpts, prob []float64) []float64 { 10 | // Arguments: 11 | // p - vector of values for which density is to be computed 12 | // midpts - vector of midpoints of the intervals 13 | // prob - vector of probabilities of the intervals 14 | // Returns: 15 | // vector of values of the probability density 16 | 17 | maxDiff := 1e4 18 | if len(midpts) != len(prob) { 19 | panic(" len(midpts) != len(prob)") 20 | } 21 | 22 | for i, _ := range midpts { 23 | d := midpts[1] - midpts[0] 24 | if i > 0 { 25 | if abs(midpts[i]-midpts[i-1]-d) > maxDiff { 26 | panic("midpts not equidistant") 27 | } 28 | } 29 | 30 | } 31 | 32 | lo := make([]float64, len(midpts)) 33 | val := make([]float64, len(p)) 34 | binwidth := midpts[1] - midpts[0] 35 | for i, _ := range midpts { 36 | lo[i] = midpts[i] - binwidth/2 37 | } 38 | 39 | for i, _ := range p { 40 | for j := 0; j < len(lo); j++ { 41 | if p[i] >= lo[j] { 42 | val[i] = prob[j] 43 | } 44 | } 45 | } 46 | return val 47 | } 48 | -------------------------------------------------------------------------------- /bayes/howardprior.go: -------------------------------------------------------------------------------- 1 | package bayes 2 | 3 | // Logarithm of Howard’s dependent prior for two proportions 4 | // Ref.: Albert (2009) 5 | 6 | import ( 7 | "math/rand" 8 | ) 9 | 10 | // LnHowardPrior returns the logarithm of a dependent prior on two proportions proposed by 11 | // Howard in a Statistical Science paper in 1998. 12 | func LnHowardPrior(p1, p2, alpha, beta, gamma, delta, sigma float64) float64 { 13 | // Arguments: 14 | // p1 , p2 - proportions to be tested 15 | // par vector containing parameter values alpha, beta, gamma, delta, sigma 16 | // Returns: 17 | // z - logarithm of a dependent prior 18 | 19 | u := log(p1/(1-p1)*(1-p2)/p2) / sigma 20 | z := -0.5*u*u + (alpha-1)*log(p1) + (beta-1)*log(1-p1) + (gamma-1)*log(p2) + (delta-1)*log(1-p2) 21 | return z 22 | } 23 | 24 | // HowardPosteriorProb returns the posterior probability that p1 > p2. 25 | func HowardPosteriorProb(y1, n1, y2, n2, alpha, beta, gamma, delta, sigma float64) float64 { 26 | nIter := 10000000 27 | // updated params for posterior that has the same functional form as prior 28 | alpha += y1 29 | beta += n1 - y1 30 | gamma += y2 31 | delta += n2 - y2 32 | sum1 := 0.0 33 | sum2 := 0.0 34 | // brute force sampling from posterior, should be improved 35 | for i := 0; i < nIter; i++ { 36 | p1 := rand.Float64() 37 | if p1 < 0.0001 { 38 | p1 = 0.0001 39 | } 40 | if p1 > 0.9999 { 41 | p1 = 0.9999 42 | } 43 | 44 | p2 := rand.Float64() 45 | if p2 < 0.0001 { 46 | p2 = 0.0001 47 | } 48 | if p2 > 0.9999 { 49 | p2 = 0.9999 50 | } 51 | // posterior 52 | pr := exp(LnHowardPrior(p1, p2, alpha, beta, gamma, delta, sigma)) 53 | if p1 > p2 { 54 | sum1 += pr 55 | } else { 56 | sum2 += pr 57 | } 58 | } 59 | return sum1 / (sum1 + sum2) 60 | } 61 | -------------------------------------------------------------------------------- /bayes/logctablepost.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Log posterior of difference and sum of logits in a 2x2 table. 6 | 7 | // LogCTablePost returns the log posterior density for the difference and sum of logits in a 2x2 contingency table 8 | // for independent binomial samples and uniform prior placed on the logits. 9 | func LogCTablePost(s1, f1, s2, f2, theta1, theta2 float64) float64 { 10 | // Arguments 11 | // theta1 - difference of logits 12 | // theta2 - sum of logits 13 | // s1,f1,s2,f2 - number of successes and failures for first sample, and then the second sample 14 | // Returns: 15 | // value of the log posterior 16 | 17 | logitp1 := (theta1 + theta2) / 2 18 | logitp2 := (theta2 - theta1) / 2 19 | term1 := s1*logitp1 - (s1+f1)*log(1+exp(logitp1)) 20 | term2 := s2*logitp2 - (s2+f2)*log(1+exp(logitp2)) 21 | return term1 + term2 22 | } 23 | 24 | /*& 25 | logctablepost=function (theta, data) 26 | { 27 | theta1 = theta[1] 28 | theta2 = theta[2] 29 | s1 = data[1] 30 | f1 = data[2] 31 | s2 = data[3] 32 | f2 = data[4] 33 | logitp1 = (theta1 + theta2)/2 34 | logitp2 = (theta2 - theta1)/2 35 | term1 = s1 * logitp1 - (s1 + f1) * log(1 + exp(logitp1)) 36 | term2 = s2 * logitp2 - (s2 + f2) * log(1 + exp(logitp2)) 37 | return(term1 + term2) 38 | } 39 | */ 40 | -------------------------------------------------------------------------------- /bayes/logisticpost.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Log posterior for a binary response model with a logistic link and a uniform prior. 6 | // Ref.: Albert (2009) 7 | 8 | func logFn(x, n, y, beta0, beta1 float64) float64 { 9 | lp := beta0 + beta1*x 10 | p := exp(lp) / (1 + exp(lp)) 11 | return y*log(p) + (n-y)*log(1-p) 12 | } 13 | 14 | // LogisticPost returns the log posterior density of (beta0, beta1) when yi are independent binomial(ni, pi) 15 | // and logit(pi)=beta0+beta1*xi and a uniform prior is placed on (beta0, beta1). 16 | func LogisticPost(x, n, y []float64, beta0, beta1 float64) float64 { 17 | 18 | val := 0.0 19 | for i, _ := range y { 20 | val += logFn(x[i], n[i], y[i], beta0, beta1) 21 | } 22 | return val 23 | } 24 | -------------------------------------------------------------------------------- /bayes/logisticpost.go.orig: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Log posterior of difference and sum of logits in a 2x2 table. 6 | 7 | // LogCTablePost returns the log posterior density for the difference and sum of logits in a 2x2 contingency table 8 | // for independent binomial samples and uniform prior placed on the logits. 9 | func LogCTablePost(s1, f1, s2, f2, theta1, theta2 float64) float64 { 10 | // Arguments 11 | // theta1 - difference of logits 12 | // theta2 - sum of logits 13 | // s1,f1,s2,f2 - number of successes and failures for first sample, and then the second sample 14 | // Returns: 15 | // value of the log posterior 16 | 17 | logitp1 := (theta1 + theta2) / 2 18 | logitp2 := (theta2 - theta1) / 2 19 | term1 := s1*logitp1 - (s1+f1)*log(1+exp(logitp1)) 20 | term2 := s2*logitp2 - (s2+f2)*log(1+exp(logitp2)) 21 | return term1 + term2 22 | } 23 | 24 | /*& 25 | logctablepost=function (theta, data) 26 | { 27 | theta1 = theta[1] 28 | theta2 = theta[2] 29 | s1 = data[1] 30 | f1 = data[2] 31 | s2 = data[3] 32 | f2 = data[4] 33 | logitp1 = (theta1 + theta2)/2 34 | logitp2 = (theta2 - theta1)/2 35 | term1 = s1 * logitp1 - (s1 + f1) * log(1 + exp(logitp1)) 36 | term2 = s2 * logitp2 - (s2 + f2) * log(1 + exp(logitp2)) 37 | return(term1 + term2) 38 | } 39 | */ 40 | -------------------------------------------------------------------------------- /bayes/logpoissgamma.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Log posterior with Poisson sampling and gamma prior. 6 | // Ref.: Albert (2009) 7 | 8 | import ( 9 | "code.google.com/p/probab/dst" 10 | ) 11 | 12 | // LogPoissGamma returns the logarithm of the posterior density of a Poisson log mean with a gamma prior. 13 | func LogPoissGamma(theta, y []float64, sh, rt float64) []float64 { 14 | // Arguments: 15 | // theta - vector of values of the log mean parameter 16 | // y - vector of observations, and 17 | // sh, rt - shape and rate=1/scale parameters of the gamma prior 18 | 19 | // Returns: 20 | // logPosterior - vector of values of the log posterior for all values in theta 21 | 22 | lambda := make([]float64, len(theta)) 23 | for i, _ := range lambda { 24 | lambda[i] = exp(theta[i]) 25 | } 26 | 27 | // shape=sum(y)+1 28 | shape := 1.0 29 | for _, val := range y { 30 | shape += val 31 | } 32 | 33 | scale := 1 / float64(len(y)) 34 | 35 | logLike := make([]float64, len(lambda)) 36 | for i, _ := range logLike { 37 | logLike[i] = dst.GammaLnPDFAt(shape, scale, lambda[i]) 38 | } 39 | 40 | logPrior := make([]float64, len(theta)) 41 | for i, _ := range logPrior { 42 | logPrior[i] = dst.GammaLnPDFAt(sh, 1/(rt*lambda[i]), lambda[i]) 43 | } 44 | 45 | logPosterior := make([]float64, len(logPrior)) 46 | for i, _ := range logPrior { 47 | logPosterior[i] = logLike[i] + logPrior[i] 48 | } 49 | return logPosterior 50 | } 51 | -------------------------------------------------------------------------------- /bayes/logpoissnormal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Log posterior with Poisson sampling and normal prior. 6 | // Ref.: Albert (2009) 7 | 8 | import ( 9 | "code.google.com/p/probab/dst" 10 | ) 11 | 12 | // LogPoissNormal returns the logarithm of the posterior density of a Poisson log mean with a normal prior. 13 | func LogPoissNormal(theta, y []float64, mean, sd float64) []float64 { 14 | // Arguments: 15 | // theta - vector of values of the log mean parameter 16 | // y - vector of observations, and 17 | // mean, sd - parameters of the normal prior 18 | // Returns: 19 | // logPosterior - vector of values of the log posterior for all values in theta 20 | 21 | lambda := make([]float64, len(theta)) 22 | for i, _ := range lambda { 23 | lambda[i] = exp(theta[i]) 24 | } 25 | 26 | // shape=sum(y)+1 27 | shape := 1.0 28 | for _, val := range y { 29 | shape += val 30 | } 31 | 32 | scale := 1 / float64(len(y)) 33 | 34 | logLike := make([]float64, len(lambda)) 35 | for i, _ := range logLike { 36 | logLike[i] = log(dst.GammaPDFAt(shape, scale, lambda[i])) 37 | } 38 | 39 | logPrior := make([]float64, len(theta)) 40 | lnPdf := dst.NormalLnPDF(mean, sd) 41 | for i, _ := range logPrior { 42 | logPrior[i] = lnPdf(theta[i]) 43 | } 44 | 45 | logPosterior := make([]float64, len(logPrior)) 46 | for i, _ := range logPrior { 47 | logPosterior[i] = logLike[i] + logPrior[i] 48 | } 49 | return logPosterior 50 | } 51 | -------------------------------------------------------------------------------- /bayes/mnormt_onesided.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | //Bayesian test of one-sided hypothesis about a normal mean 6 | // Ref.: Albert (2009): 184 [mnormt.onesided()] 7 | 8 | import ( 9 | "code.google.com/p/probab/dst" 10 | ) 11 | 12 | // NormMeanTestOneSided does a Bayesian test of the hypothesis that a normal mean is less than or equal to a specified value. 13 | func NormMeanTestOneSided(m0, priMean, priSD, smpMean float64, smpSize int, popSd float64) (bf, priOdds, postOdds, postH float64) { 14 | // 15 | // Arguments 16 | // m0 - value of the normal mean to be tested 17 | // priMean - mean of the normal prior distribution 18 | // priSD - standard deviation of the normal prior distribution 19 | // smpMean - sample mean 20 | // smpSize - sample size 21 | // popSd - known value of the population standard deviation 22 | // 23 | // Returns 24 | // bf Bayes factor in support of the null hypothesis 25 | // priOdds prior odds of the null hypothesis 26 | // postOdds posterior odds of the null hypothesis 27 | // postH posterior probability of the null hypothesis 28 | // 29 | // 30 | n := float64(smpSize) 31 | priVar := priSD * priSD 32 | priH := dst.NormalCDFAt(priMean, priSD, m0) 33 | priA := 1 - priH 34 | priOdds = priH / priA 35 | 36 | popVar := popSd * popSd 37 | postPrecision := 1/priVar + n/popVar 38 | postVar := 1 / postPrecision 39 | postSd := sqrt(postVar) 40 | postMean := (smpMean*n/popVar + priMean/priVar) / postPrecision 41 | postH = dst.NormalCDFAt(postMean, postSd, m0) 42 | postA := 1 - postH 43 | postOdds = postH / postA 44 | bf = postOdds / priOdds 45 | return 46 | } 47 | -------------------------------------------------------------------------------- /bayes/mnormt_twosided.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | //Bayesian test of a two-sided hypothesis about a normal mean 6 | // Ref.: Albert (2009): 184 [mnormt.onesided()] 7 | 8 | // NormMeanTestTwoSided does a Bayesian test that a normal mean is equal to a specified value using a normal prior. 9 | func NormMeanTestTwoSided(m0, prob float64, t []float64, smpMean float64, smpSize int, popSd float64) (bf, post []float64) { 10 | // 11 | // Arguments: 12 | // m0 - value of the normal mean to be tested 13 | // prob - prior probability of the hypothesis 14 | // t - vector of values of the prior standard deviation under the alternative hypothesis 15 | // smpMean - sample mean 16 | // n - sample size 17 | // popSd - known value of the population standard deviation 18 | // 19 | // Returns: 20 | // bf vector of values of the Bayes factor in support of the null hypothesis 21 | // post vector of posterior probabilities of the null hypothesis 22 | // 23 | n := float64(smpSize) 24 | popVar := popSd * popSd 25 | diffMean2 := (smpMean - m0) * (smpMean - m0) 26 | num := 0.5*log(n) - log(popSd) - 0.5*n/popVar*diffMean2 27 | for i, val := range t { 28 | t[i] *= val 29 | } 30 | den := make([]float64, len(t)) 31 | for i, _ := range den { 32 | den[i] = -0.5*log(popVar/n+t[i]) - 0.5/(popVar/n+t[i])*diffMean2 33 | } 34 | bf = make([]float64, len(t)) 35 | for i, _ := range bf { 36 | bf[i] = exp(num - den[i]) 37 | } 38 | post = make([]float64, len(t)) 39 | for i, _ := range post { 40 | post[i] = prob * bf[i] / (prob*bf[i] + 1 - prob) 41 | } 42 | return 43 | } 44 | -------------------------------------------------------------------------------- /bayes/multinom_p.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Bayesian inference about the parameter vector p of multinomial distribution. 6 | // Conjugate prior is Dirichlet(|α|), conjugate posterior is Dirichlet(|α+x|). 7 | // http://en.wikipedia.org/wiki/Dirichletdistribution#Conjugatetomultinomial 8 | 9 | import ( 10 | . "code.google.com/p/probab/dst" 11 | "fmt" 12 | ) 13 | 14 | // Posterior PDF, Dirichlet prior 15 | // for Haldane improper prior, use α[i] = 0 16 | // Ericson 1969 recommends prior with sum(α[i]) small, of the order of 1, e.g., 1/len(α) 17 | // Aitkin 2010: 96-107 18 | func MultinomPiPDFDirPri(α, x []float64) float64 { 19 | // if α == nil, use Haldane 20 | if α == nil { 21 | for i := 0; i < len(x); i++ { 22 | α[i] = 0 23 | } 24 | } 25 | 26 | if len(α) != len(x) { 27 | panic(fmt.Sprintf("len(α) != len(x)")) 28 | } 29 | 30 | for i := 0; i < len(x); i++ { 31 | α[i] += x[i] // posterior params 32 | } 33 | return DirichletPDFAt(α, x) 34 | } 35 | 36 | // Sampling from posterior, Dirichlet prior 37 | // Returns an array of sampled Multinomial Pi's 38 | func MultinomPiNext(α, x []float64) []float64 { 39 | for i := 0; i < len(x); i++ { 40 | α[i] += x[i] // posterior params 41 | } 42 | return DirichletNext(α) 43 | } 44 | -------------------------------------------------------------------------------- /bayes/normal_normal_mix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Posterior for normal sampling and a mixture of normals prior 6 | 7 | import ( 8 | "code.google.com/p/probab/dst" 9 | ) 10 | 11 | // NormalNormalMix returns the parameters and mixing probabilities for a normal sampling problem, variance known, 12 | // where the prior is a discrete mixture of normal densities. 13 | func NormalNormalMix(probs, priorMean, priorVar []float64, y, sigma2 float64) (postProbs, postMean, postVar []float64) { 14 | // Arguments: 15 | // probs vector of probabilities of the normal components of the prior 16 | // priorMean vector of the prior means for a normal component of the prior 17 | // priorVar vector of the prior variances for a normal component of the prior 18 | // y - observation 19 | // sigma2 - sampling variance 20 | // Returns: 21 | // postProbs - vector of probabilities of the normal components of the posterior 22 | // postMean - vector of means for a normal component of the posterior 23 | // postMean - vector of variances for a normal component of the posterior 24 | 25 | postPrecision := make([]float64, len(probs)) 26 | for i, _ := range probs { 27 | postPrecision[i] = 1/priorVar[i] + 1/sigma2 28 | } 29 | 30 | postVar = make([]float64, len(probs)) 31 | for i, _ := range probs { 32 | postVar[i] = 1 / postPrecision[i] 33 | } 34 | 35 | postMean = make([]float64, len(probs)) 36 | for i, _ := range probs { 37 | postMean[i] = (y/sigma2 + priorMean[i]/priorVar[i]) / postPrecision[i] 38 | } 39 | 40 | mProb := make([]float64, len(probs)) 41 | for i, _ := range probs { 42 | mProb[i] = dst.NormalPDFAt(priorMean[i], sqrt(sigma2+priorVar[i]), y) 43 | } 44 | 45 | prod := make([]float64, len(probs)) 46 | for i, _ := range probs { 47 | prod[i] = probs[i] * mProb[i] 48 | } 49 | 50 | postProbs = make([]float64, len(probs)) 51 | for i, _ := range probs { 52 | postProbs[i] = probs[i] * mProb[i] / sum(prod) 53 | } 54 | 55 | return postProbs, postMean, postVar 56 | } 57 | -------------------------------------------------------------------------------- /bayes/p_null_smp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Probability of a one sided null hypothesis from a sample from a posterior density. 6 | 7 | // PNullSmpLowT returns the lower tail probability of a one sided null hypothesis from a sample from a posterior density. 8 | func PNullSmpLowT(θ []float64, θ0 float64) float64 { 9 | return eCDF(θ, θ0) 10 | } 11 | 12 | // PNullSmpUppT returns the upper tail probability of a one sided null hypothesis from a sample from a posterior density. 13 | func PNullSmpUppT(θ []float64, θ0 float64) float64 { 14 | return 1 - eCDF(θ, θ0) 15 | } 16 | -------------------------------------------------------------------------------- /bayes/pbetat.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // ProbBetaTest does a Bayesian test that a proportion is equal to a specified value using a beta prior. 6 | func ProbBetaTest(p0, prob, a, b float64, succ, fail int) (bf, post float64) { 7 | // Arguments 8 | // p0 value of the proportion to be tested 9 | // prob prior probability of the hypothesis 10 | // a alpha parameter of the beta prior under the alternative hypothesis 11 | // b beta parameter of the beta prior under the alternative hypothesis 12 | // succ number of successes 13 | // fail number of failures 14 | // Value 15 | // bf the Bayes factor in support of the null hypothesis 16 | // post the posterior probability of the null hypothesis 17 | // Ref.: Albert (2009): 54. 18 | 19 | s := float64(succ) 20 | f := float64(fail) 21 | lbf := s*log(p0) + f*log(1-p0) + lnB(a, b) - lnB(a+s, b+f) 22 | bf = exp(lbf) 23 | post = prob * bf / (prob*bf + 1 - prob) 24 | return 25 | } 26 | -------------------------------------------------------------------------------- /bayes/pdisc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // PropDisc returns the posterior distribution for a proportion for a discrete prior distribution. 6 | func PropDisc(p, prior []float64, succ, fail int) []float64 { 7 | //Arguments: 8 | // p vector of proportion values 9 | // prior vector of prior probabilities 10 | // succ number of successes 11 | // fail number of failures 12 | // Value: 13 | // vector of posterior probabilities. 14 | // Ref.: Albert (2009): Chapter 2.3: 19-22. 15 | 16 | s := float64(succ) 17 | f := float64(fail) 18 | mx := -1e99 19 | 20 | p1 := make([]float64, len(p)) 21 | for i, _ := range p { 22 | if p[i] == 0 || p[i] == 1 { 23 | p1[i] = 0.5 24 | } else { 25 | p1[i] = p[i] 26 | } 27 | } 28 | 29 | like := make([]float64, len(p)) 30 | for i, _ := range like { 31 | like[i] = s*log(p1[i]) + f*log(1-p1[i]) 32 | } 33 | 34 | for i, _ := range like { 35 | if !(p[i] > 0 && p[i] < 1) { 36 | if (p[i] == 0 && s > 0) || (p[i] == 1 && f > 0) { 37 | like[i] = nan 38 | } 39 | } 40 | } 41 | 42 | for i, _ := range like { 43 | if like[i] > mx { 44 | mx = like[i] 45 | } 46 | } 47 | 48 | for i, val := range like { 49 | like[i] = exp(val - mx) 50 | } 51 | 52 | //product=like*prior 53 | product := make([]float64, len(p)) 54 | for i, _ := range product { 55 | product[i] = like[i] * prior[i] 56 | } 57 | 58 | //post=product/sum(product) 59 | sum := 0.0 60 | for i, _ := range product { 61 | sum += product[i] 62 | } 63 | 64 | post := make([]float64, len(product)) 65 | for i, _ := range product { 66 | post[i] = product[i] / sum 67 | } 68 | return post 69 | } 70 | -------------------------------------------------------------------------------- /bayes/poissgamexch.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Log posterior of Poisson/gamma exchangeable model. 6 | // Ref.: Albert (2009) 7 | 8 | func logG(y, e, alpha, beta float64) float64 { 9 | return lnΓ(alpha+y) - (y+alpha)*log(e+beta) + alpha*log(beta) - lnΓ(alpha) 10 | } 11 | 12 | // PoissGamExch returns the log posterior density of log alpha and log mu for a Poisson/gamma exchangeable model. 13 | func PoissGamExch(theta1, theta2, z0 float64, y, e []float64) float64 { 14 | // Arguments: 15 | // theta1, theta2 - parameter values of log alpha and log mu 16 | // z0, prior hyperparameter 17 | // data: y and e 18 | // Returns: 19 | // value of the log posterior 20 | 21 | alpha := exp(theta1) 22 | mu := exp(theta2) 23 | beta := alpha / mu 24 | val := 0.0 25 | for i, _ := range y { 26 | val += logG(y[i], e[i], alpha, beta) 27 | } 28 | val += log(alpha) - 2*log(alpha+z0) 29 | return val 30 | } 31 | -------------------------------------------------------------------------------- /bayes/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package bayes 4 | 5 | // Some utility functions. 6 | 7 | // meanSd returns mean and standard deviation of a vector. 8 | func meanSd(data []float64) (mean, sd float64) { 9 | n := 0.0 10 | mean = 0.0 11 | m2 := 0.0 12 | for _, x := range data { 13 | n++ 14 | delta := x - mean 15 | mean += delta / n 16 | if n > 1 { 17 | m2 += delta * (x - mean) 18 | } 19 | } 20 | sd = sqrt(m2 / (n - 1)) 21 | return 22 | } 23 | 24 | // cols2vec unloads complete matrix y columnwise to vector v. 25 | func cols2vec(y [][]float64) []float64 { 26 | v := make([]float64, len(y)*len(y[0])) 27 | col := 0 28 | for j, _ := range y[0] { 29 | for i, _ := range y { 30 | v[col] = y[i][j] 31 | col++ 32 | } 33 | } 34 | return v 35 | } 36 | 37 | // linInt is a linear interpolation function. 38 | func linInt(x, y []float64, xVal float64) float64 { 39 | // x vector must be nondecreasing 40 | 41 | if xVal < x[0] || xVal > x[len(x)-1] { 42 | return nan 43 | } 44 | 45 | // find out which segment we are in 46 | n := 0 47 | for i, _ := range x { 48 | if xVal > x[i] { 49 | n = i 50 | } else { 51 | break 52 | } 53 | } 54 | if n > len(y) { 55 | return nan 56 | } 57 | 58 | // interpolate 59 | x0, y0 := x[n], y[n] 60 | x1, y1 := x[n+1], y[n+1] 61 | a := x1 - x0 62 | b := y1 - y0 63 | yVal := b*(xVal-x0)/a + y0 64 | return yVal 65 | } 66 | -------------------------------------------------------------------------------- /cmd/binomProportionBayes/binomProportionBayes.go: -------------------------------------------------------------------------------- 1 | // Summary of the posterior distribution of the binomial parameter. 2 | package main 3 | 4 | import ( 5 | "code.google.com/p/probab/bayes" 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | // Summary of the posterior distribution of the binomial parameter. 11 | func main() { 12 | var ( 13 | k, n int64 14 | a, b float64 15 | ) 16 | fmt.Scanf("%d %d %f %f", k, n, a, b) 17 | pr := []float64{0.005, 0.01, 0.025, 0.05, 0.5, 0.95, 0.975, 0.99, 0.995} 18 | 19 | /* 20 | k = 10 21 | n = 20 22 | a := 0.5 23 | b := 0.5 24 | */ 25 | /* 26 | prior = dbeta(pi,a,b) 27 | likelihood = dbinom(k,n,prob=pi) 28 | posterior = dbeta(pi,a+k,b+n-k) 29 | */ 30 | 31 | //* posterior summary 32 | m1 := (a + float64(k)) / (a + b + float64(n)) 33 | v1 := m1 * (1 - m1) / (a + b + float64(n) + 1) 34 | s1 := math.Sqrt(v1) 35 | fmt.Println("Posterior Mean : ", m1) 36 | fmt.Println("Posterior Variance : ", v1) 37 | fmt.Println("Posterior Std. Deviation : ", s1) 38 | 39 | fmt.Println("Posterior Mean : ", bayes.BinomPiPostMean(a, b, n, k)) 40 | fmt.Println("Posterior Variance : ", bayes.BinomPiPostVar(a, b, n, k)) 41 | 42 | fmt.Println("\nProb.\t\tQuantile \n") 43 | for i := 0; i < 9; i++ { 44 | qf := bayes.BinomPiQtlBPri(k, n, a, b) 45 | qtl := qf(pr[i]) 46 | fmt.Println(pr[i], "\t\t", qtl) 47 | } 48 | fmt.Println("\n") 49 | } 50 | -------------------------------------------------------------------------------- /cmd/poissonRateBayes/poissonRateBayes.go: -------------------------------------------------------------------------------- 1 | // Summary of the posterior distribution of the Poisson parameter. 2 | 3 | package main 4 | 5 | import ( 6 | "code.google.com/p/probab/bayes" 7 | "fmt" 8 | ) 9 | 10 | // Summary of the posterior distribution of the Poisson parameter. 11 | func main() { 12 | var ( 13 | x, n int64 14 | r, v float64 15 | ) 16 | 17 | fmt.Scanf("%d %d %f %f", &x, &n, &r, &v) 18 | // fmt.Println("%d %d %f %f", x, n, r, v) 19 | 20 | pr := []float64{0.005, 0.01, 0.025, 0.05, 0.5, 0.95, 0.975, 0.99, 0.995} 21 | 22 | if r < 0 || v < 0 { 23 | panic("Shape parameter r and rate parameter v must be greater than or equal to zero") 24 | } 25 | fmt.Println("\nProb.\t\tQuantile \n") 26 | for i := 0; i < 9; i++ { 27 | qtl := bayes.PoissonLambdaQtlGPri(x, n, r, v) 28 | fmt.Println(pr[i], "\t\t", qtl(pr[i])) 29 | } 30 | fmt.Println("\n") 31 | } 32 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | // Probability distributions and statistics. 4 | package probab 5 | -------------------------------------------------------------------------------- /dst/BUGS: -------------------------------------------------------------------------------- 1 | Polya PDF, CDF did not pass test for k=25, 40 2 | 3 | test of GammaLn CDF 4 | 4 1.210826572900094 -0.8978305 5 | test of Gamma Qtl #2 6 | 0.2 1.0823704633003444 0.9607058 7 | 0.25 -2.737874865150927 1.109665 8 | -------------------------------------------------------------------------------- /dst/REFERENCES: -------------------------------------------------------------------------------- 1 | Ahrens, J.H. and Dieter, U. (1982). Computer generation of Poisson deviates from modified normal distributions. ACM Trans. Math. Software 8, 163-179. 2 | Decker, R. D. and Fitzgibbon, D.J. (1991). The normal and Poisson approximations to the Binomial: a closer look, Department of Mathematics Technical Report No. 82.3, Hartford, CT: University of Hartford. 3 | Hayya, J., Armstrong, D., & Gressis, N. (1975). A note on the ratio of two normally distributed variables. Management Science, 21(11), 1338-1341. 4 | Hinkley, D. V. (1969). On the ratio of two correlated normal random variables. Biometrika, 56(3), 635-639. 5 | Peizer D.B. and Pratt J.W. 1968 A Normal Approximation for Binomial, F, Beta, and Other Common, Related Tail Probabilities, I. Journal of the American Statistical Association, 63 (324): 1416-1456. 6 | -------------------------------------------------------------------------------- /dst/ToDo: -------------------------------------------------------------------------------- 1 | f.go df1, df2 should be int64 2 | rename all to k, θ (for consistency) 3 | 4 | implement Normal approx. for Poisson, Binomial throughout 5 | 6 | -------------------------------------------------------------------------------- /dst/_tst/09_test.go: -------------------------------------------------------------------------------- 1 | // test of Student's t distribution 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | "math/rand" 7 | "testing" 8 | ) 9 | 10 | // test against known values 11 | func TestStudentsT_PDF(t *testing.T) { 12 | fmt.Println("test of Student's t distribution: PDF") 13 | fn := StudentsT_PDF(3) 14 | x := fn(3) 15 | y := 0.02297204 16 | if !check(x, y) { 17 | t.Error() 18 | fmt.Println(x, y) 19 | } 20 | } 21 | 22 | func TestStudentsT_CDF(t *testing.T) { 23 | fmt.Println("test of Student's t distribution: CDF") 24 | fn := StudentsT_CDF(3) 25 | x := fn(3) 26 | y := 0.9711656 27 | if !check(x, y) { 28 | t.Error() 29 | fmt.Println(x, y) 30 | } 31 | } 32 | 33 | func TestStudentsT_CDF2(t *testing.T) { 34 | fmt.Println("test of Student's t distribution: CDF #2") 35 | fn := StudentsT_CDF(99) 36 | x := fn(3) 37 | y := 0.9982922 38 | if !check(x, y) { 39 | t.Error() 40 | fmt.Println(x, y) 41 | } 42 | } 43 | 44 | func TestStudentsT_CDF3(t *testing.T) { 45 | fmt.Println("test of Student's t distribution: CDF #3") 46 | fn := StudentsT_CDF(1) 47 | x := fn(2e100) 48 | y := 1.0 49 | if !check(x, y) { 50 | t.Error() 51 | fmt.Println(x, y) 52 | } 53 | } 54 | 55 | func TestStudentsT_Qtl(t *testing.T) { 56 | fmt.Println("test of Student's t distribution: Quantile") 57 | fn := StudentsT_Qtl(1e25) 58 | x := fn(0.9982922) 59 | y := 2.927627 60 | if !check(x, y) { 61 | t.Error() 62 | fmt.Println(x, y) 63 | } 64 | } 65 | 66 | func TestStudentsT_Qtl2(t *testing.T) { 67 | fmt.Println("test of Student's t distribution: Quantile #2") 68 | fn := StudentsT_Qtl(99) 69 | x := fn(0.9982922) 70 | y := 2.999991 71 | if !check(x, y) { 72 | t.Error() 73 | fmt.Println(x, y) 74 | } 75 | } 76 | 77 | func TestStudentsT_Qtl3(t *testing.T) { 78 | fmt.Println("test of Student's t distribution: Quantile #3") 79 | fn := StudentsT_Qtl(3) 80 | x := fn(0.5) 81 | y := 0.0 82 | if !check(x, y) { 83 | t.Error() 84 | fmt.Println(x, y) 85 | } 86 | } 87 | 88 | func TestStudentsT_Qtl4(t *testing.T) { 89 | fmt.Println("test of Student's t distribution: Quantile against CDF, 100000 iterations") 90 | 91 | for i := 0; i < 100000; i++ { 92 | //func (r *Rand) Intn(n int) int { 93 | df := float64(rand.Intn(10000) + 1) 94 | p := rand.Float64() 95 | fn := StudentsT_Qtl(df) 96 | x := fn(p) 97 | cdf := StudentsT_CDF(df) 98 | y := cdf(x) 99 | if !check(y, p) { 100 | t.Error() 101 | fmt.Println(y, p) 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /dst/_tst/10_test.go: -------------------------------------------------------------------------------- 1 | // test of Zipf-Mandelbrot distribution 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | // "math/rand" 7 | "testing" 8 | ) 9 | 10 | // test against known values 11 | func TestZipfMandelbrot_PDF(t *testing.T) { 12 | fmt.Println("test of Zipf-Mandelbrot distribution: PDF") 13 | fn := ZipfMandelbrotPMF(100, 3, 2) 14 | // fn := ZipfMandelbrotPMF(N, b, s) 15 | 16 | x := fn(5) 17 | y := 0.05699202 18 | if !check(x, y) { 19 | t.Error() 20 | fmt.Println(x, y) 21 | } 22 | } 23 | 24 | // test against known values 25 | func TestZipfMandelbrot_CDF(t *testing.T) { 26 | fmt.Println("test of Zipf-Mandelbrot distribution: CDF") 27 | fn := ZipfMandelbrotCDF(100, 3, 2) 28 | x := fn(5) 29 | y := 0.6066174 30 | if !check(x, y) { 31 | t.Error() 32 | fmt.Println(x, y) 33 | } 34 | } 35 | 36 | // test against known values 37 | func TestZipfMandelbrotQtl(t *testing.T) { 38 | fmt.Println("test of Zipf-Mandelbrot distribution: Qtl") 39 | fn := ZipfMandelbrotQtl(100, 3, 2) 40 | x := float64(fn(0.6)) 41 | y := float64(5) 42 | if !check(x, y) { 43 | t.Error() 44 | fmt.Println(x, y) 45 | } 46 | } 47 | 48 | // test against known values 49 | func TestZipfMandelbrotQtl2(t *testing.T) { 50 | fmt.Println("test of Zipf-Mandelbrot distribution: Qtl") 51 | fn := ZipfMandelbrotQtl(100, 3, 2) 52 | x := float64(fn(0.01)) 53 | y := float64(1) 54 | if !check(x, y) { 55 | t.Error() 56 | fmt.Println(x, y) 57 | } 58 | } 59 | 60 | // test against known values 61 | func TestNextZipfMandelbrot(t *testing.T) { 62 | fmt.Println("test of Zipf-Mandelbrot distribution: Random number") 63 | const nIter = 1e7 64 | x := 0.0 65 | for i := 0; i < nIter; i++ { 66 | x += float64(NextZipfMandelbrot(100, 3, 2)) 67 | } 68 | x /= nIter 69 | y := float64(9.341125927812211) 70 | if !check(x, y) { 71 | t.Error() 72 | fmt.Println(x, y) 73 | } 74 | } 75 | 76 | func TestZipfMandelbrotMean(t *testing.T) { 77 | fmt.Println("test of Zipf-Mandelbrot distribution: Mean") 78 | x := ZipfMandelbrotMean(100, 3, 2) 79 | y := float64(9.341125927812211) 80 | if !check(x, y) { 81 | t.Error() 82 | fmt.Println(x, y) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /dst/_tst/11_test.go: -------------------------------------------------------------------------------- 1 | // test of Zeta distribution 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | // "math/rand" 7 | "testing" 8 | ) 9 | 10 | // test of Zeta distribution 11 | 12 | func TestNextZeta(t *testing.T) { 13 | fmt.Println("test NextZeta") 14 | const nIter = 1e7 15 | x := 0.0 16 | y := ZetaMean(2.152) 17 | for i := 0; i < nIter; i++ { 18 | x += float64(NextZeta(2.152)) 19 | } 20 | x /= nIter 21 | if !check(x, y) { 22 | t.Error() 23 | fmt.Println(x, y) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dst/_tst/12_test.go: -------------------------------------------------------------------------------- 1 | // test of Pareto-II distribution 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | "math" 7 | "testing" 8 | ) 9 | 10 | // test against known values: PDF 11 | func TestParetoII_PDF(t *testing.T) { 12 | θ := 4.0 13 | α := 3.0 14 | v := 2.0 15 | fmt.Println("test of Pareto-II distribution: PDF") 16 | fn := ParetoII_PDF(θ, α) 17 | x := fn(v) 18 | y := 0.1481481 19 | if !check(x, y) { 20 | t.Error() 21 | fmt.Println(x, y) 22 | } 23 | 24 | θ = 1.0567 25 | α = 2.1865 26 | v = 8.7896 27 | fn = ParetoII_PDF(θ, α) 28 | x = fn(v) 29 | y = 0.001686768 30 | if !check(x, y) { 31 | t.Error() 32 | fmt.Println(x, y) 33 | } 34 | } 35 | 36 | // test against known values: CDF 37 | func TestParetoII_CDF(t *testing.T) { 38 | fmt.Println("test of Pareto-II distribution: CDF") 39 | θ := 1.0567 40 | α := 2.1865 41 | v := 8.7896 42 | fn := ParetoII_CDF(θ, α) 43 | x := fn(v) 44 | y := 0.9924041 45 | if !check(x, y) { 46 | t.Error() 47 | fmt.Println(x, y) 48 | } 49 | } 50 | 51 | // test against known values: Qtl 52 | func TestParetoII_Qtl(t *testing.T) { 53 | fmt.Println("test of Pareto-II distribution: Qtl") 54 | θ := 1.0567 55 | α := 2.1865 56 | v := 0.6543 57 | fn := ParetoII_Qtl(θ, α) 58 | x := fn(v) 59 | y := 0.6609253 60 | if !check(x, y) { 61 | t.Error() 62 | fmt.Println(x, y) 63 | } 64 | } 65 | 66 | func TestParetoIIMean(t *testing.T) { 67 | fmt.Println("test of Pareto-II distribution: Mean") 68 | θ := 1.0567 69 | α := 2.1865 70 | x := ParetoII_Mean(θ, α) 71 | y := 0.8906026 72 | if !check(x, y) { 73 | t.Error() 74 | fmt.Println(x, y) 75 | } 76 | } 77 | 78 | func TestParetoIIVar(t *testing.T) { 79 | fmt.Println("test of Pareto-II distribution: Variance") 80 | θ := 1.0567 81 | α := 2.1865 82 | x := ParetoII_Var(θ, α) 83 | y := 10.09222 84 | if !check(x, y) { 85 | t.Error() 86 | fmt.Println(x, y) 87 | } 88 | } 89 | 90 | func TestParetoIISkew(t *testing.T) { 91 | fmt.Println("test of Pareto-II distribution: Skewness") 92 | θ := 7.0 93 | α := 8.0 94 | x := ParetoII_Skew(θ, α) 95 | y := 9.8 96 | if !check(x, y) { 97 | t.Error() 98 | fmt.Println(x, y) 99 | } 100 | } 101 | 102 | func TestNextParetoII(t *testing.T) { 103 | fmt.Println("test of Pareto-II distribution: Random number") 104 | const nIter = 1e7 105 | const eps = 1e-3 106 | θ := 1.0567 107 | α := 2.1865 108 | x := 0.0 109 | for i := 0; i < nIter; i++ { 110 | x += NextParetoII(θ, α) 111 | } 112 | x /= nIter // mean 113 | y := 0.8906026 114 | if math.Abs(x/y-1) > eps { 115 | t.Error() 116 | fmt.Println(x, y) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /dst/_tst/13_test.go: -------------------------------------------------------------------------------- 1 | // test of Planck distribution 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | // "math/rand" 7 | "testing" 8 | ) 9 | 10 | func TestNextPlanck(t *testing.T) { 11 | fmt.Println("test NextPlanck") 12 | const nIter = 1e5 13 | x := 0.0 14 | y := PlanckMean(2, 3) 15 | for i := 0; i < nIter; i++ { 16 | x += float64(NextPlanck(2, 3)) 17 | } 18 | x /= nIter 19 | if !check(x, y) { 20 | t.Error() 21 | fmt.Println(x, y) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dst/_tst/beta_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // test against known values 9 | func TestBeta_PDF_CDF(t *testing.T) { 10 | var ( 11 | α, β, prob float64 12 | i int64 13 | ) 14 | 15 | // edit the following values: >>> 16 | α = 0.5 17 | β = 2.0 18 | 19 | x := []float64{0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1} 20 | pdf := []float64{3.1863968679, 2.1345374206, 1.6460179221, 1.3416407865, 1.125, 0.9585144756, 0.8240253984, 0.7115124735, 0.6149186938, 0.5303300859, 0.4550849072, 0.3872983346, 0.3255911783, 0.2689264371, 0.2165063509, 0.1677050983, 0.1220233825, 0.0790569415, 0.0384741882, 0} 21 | cdf := []float64{0.3298200267, 0.4585302607, 0.5519001268, 0.6260990337, 0.6875, 0.7394254526, 0.7838805713, 0.8221921916, 0.8552960014, 0.8838834765, 0.9084843147, 0.9295160031, 0.9473152854, 0.9621590305, 0.9742785793, 0.9838699101, 0.9911010292, 0.996117463, 0.9990464203, 1} 22 | 23 | // <<< 24 | 25 | fmt.Println("test of Beta PDF") 26 | for i = 0; i < int64(len(x)); i++ { 27 | prob = Beta_PDF_At(α, β, x[i]) 28 | if !check(prob, pdf[i]) { 29 | t.Error() 30 | fmt.Println(x[i], prob, pdf[i]) 31 | 32 | } 33 | } 34 | 35 | fmt.Println("test of Beta CDF") 36 | for i = 0; i < int64(len(x)); i++ { 37 | prob = Beta_CDF_At(α, β, x[i]) 38 | if !check(prob, cdf[i]) { 39 | t.Error() 40 | fmt.Println(x[i], prob, cdf[i]) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dst/_tst/betaqtl_test.go: -------------------------------------------------------------------------------- 1 | // test of Beta_Qtl_For(α, β, p) 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | "math" 7 | "math/rand" 8 | "testing" 9 | ) 10 | 11 | // test against known values 12 | func TestBeta_Qtl_For(t *testing.T) { 13 | fmt.Println("test of Beta_Qtl_For") 14 | var x, y, err, α, β, p float64 15 | var count, tests int64 16 | 17 | α = 10.001 18 | β = 5.0001 19 | p = 0.01 20 | x = Beta_Qtl_For(α, β, p) 21 | y = 0.3726 22 | if !check(x, y) { 23 | t.Error() 24 | } 25 | 26 | p = 0.5 27 | x = Beta_Qtl_For(α, β, p) 28 | y = 0.6742 29 | if !check(x, y) { 30 | t.Error() 31 | } 32 | 33 | p = 0.99 34 | x = Beta_Qtl_For(α, β, p) 35 | y = 0.8981 36 | if !check(x, y) { 37 | t.Error() 38 | } 39 | 40 | for count = 0; count < tests; { 41 | α = 6*rand.Float64() + 0.3 42 | β = 6*rand.Float64() + 0.3 43 | x = rand.Float64() 44 | p = Beta_CDF_At(α, β, x) 45 | inv_cdf := Beta_Qtl_For(α, β, p) 46 | err = math.Abs(inv_cdf - x) 47 | if math.Abs(inv_cdf) < 2.0 && p < 1.00 { 48 | count++ 49 | if !check(inv_cdf, x) { 50 | t.Error() 51 | fmt.Println("α =", α, " β =", β, " p =", p, " x =", x, " err=", err, " inv_cdf=", inv_cdf) 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dst/_tst/binom_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // test against known values 9 | func TestBinomial_PMF_CDF(t *testing.T) { 10 | var ( 11 | α, prob float64 12 | i, n int64 13 | ) 14 | 15 | // edit the following values: >>> 16 | α = 0.5 17 | n = 20 18 | 19 | k := []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} 20 | pmf := []float64{9.5367431640625E-007, 1.9073486328125E-005, 0.0001811981, 0.0010871887, 0.0046205521, 0.0147857666, 0.0369644165, 0.073928833, 0.1201343536, 0.1601791382, 0.176197052, 0.1601791382, 0.1201343536, 0.073928833, 0.0369644165, 0.0147857666, 0.0046205521, 0.0010871887, 0.0001811981, 1.9073486328125E-005, 9.5367431640625E-007} 21 | cdf := []float64{9.5367431640625E-007, 2.00271606445312E-005, 0.0002012253, 0.001288414, 0.0059089661, 0.0206947327, 0.0576591492, 0.1315879822, 0.2517223358, 0.411901474, 0.588098526, 0.7482776642, 0.8684120178, 0.9423408508, 0.9793052673, 0.9940910339, 0.998711586, 0.9997987747, 0.9999799728, 0.9999990463, 1} 22 | 23 | // <<< 24 | 25 | fmt.Println("test of Binomial PMF") 26 | for i = 0; i < int64(len(k)); i++ { 27 | prob = BinomialPMFAt(n, α, k[i]) 28 | if !check(prob, pmf[i]) { 29 | t.Error() 30 | fmt.Println(k[i], prob, pmf[i]) 31 | 32 | } 33 | } 34 | fmt.Println("test of Binomial CDF") 35 | for i = 0; i < int64(len(k)); i++ { 36 | prob = BinomialCDFAt(n, α, k[i]) 37 | if !check(prob, cdf[i]) { 38 | t.Error() 39 | fmt.Println(k[i], prob, cdf[i]) 40 | } 41 | } 42 | } 43 | 44 | func TestBinomial_Qtl(t *testing.T) { 45 | var ( 46 | ρ float64 47 | i, n int64 48 | ) 49 | ρ = 0.5 50 | n = 20 51 | p := []float64{0.1, 0.3, 0.5, 0.7, 0.9} 52 | qtl := []int64{7, 9, 10, 11, 13} 53 | fmt.Println("test of Binomial Qtl") 54 | for i = 0; i < int64(len(p)); i++ { 55 | q := BinomialQtlFor(n, ρ, p[i]) 56 | if q != qtl[i] { 57 | t.Error() 58 | fmt.Println(p[i], q, qtl[i]) 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /dst/_tst/cauchy_test.go: -------------------------------------------------------------------------------- 1 | // test of Cauchy distribution against R:actuar:dinvgamma() 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | // test against known values 10 | func TestCauchy(t *testing.T) { 11 | fmt.Println("test of Cauchy distribution: PDF") 12 | fn := CauchyPDF(2.2, 1.33) 13 | x := fn(3.35) 14 | y := 0.1369451 15 | if !check(x, y) { 16 | t.Error() 17 | fmt.Println(x, y) 18 | } 19 | 20 | fmt.Println("test of Cauchy distribution: CDF") 21 | fn = CauchyCDF(2.2, 1.33) 22 | x = fn(3.35) 23 | y = 0.7269373 24 | if !check(x, y) { 25 | t.Error() 26 | fmt.Println(x, y) 27 | } 28 | 29 | fmt.Println("test of Cauchy distribution: Qtl") 30 | qtl := CauchyQtl(2.2, 1.33) 31 | x = qtl(0.7269373) 32 | y = 3.35 33 | if !check(x, y) { 34 | t.Error() 35 | fmt.Println(x, y) 36 | } 37 | 38 | fmt.Println("test of Cauchy distribution: LnPDF") 39 | fn = CauchyLnPDF(2.2, 1.33) 40 | x = fn(3.35) 41 | y = -1.988175 42 | if !check(x, y) { 43 | t.Error() 44 | fmt.Println(x, y) 45 | } 46 | 47 | fmt.Println("test of Cauchy distribution: LnCDF") 48 | fn = CauchyLnCDF(2.2, 1.33) 49 | x = fn(3.35) 50 | y = -0.318915 51 | if !check(x, y) { 52 | t.Error() 53 | fmt.Println(x, y) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dst/_tst/fqtl_test.go: -------------------------------------------------------------------------------- 1 | // test of F_Qtl_For 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | // test against known values 10 | func TestF_Qtl_For(t *testing.T) { 11 | fmt.Println("test of F_Qtl_For") 12 | var df1, df2, x, y, p float64 13 | df1 = 3 14 | df2 = 3 15 | x = 0.46 16 | cdf := F_CDF(df1, df2) 17 | p = cdf(x) 18 | y = F_Qtl_For(df1, df2, p) 19 | 20 | if !check(x, y) { 21 | t.Error() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dst/_tst/hyper_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestHypergeomQtl(t *testing.T) { 9 | var nN, m, nn int64 10 | nN = 20 11 | m = 11 12 | nn = 5 13 | p := []float64{0.1, 0.3, 0.5, 0.7, 0.9} 14 | qtl := []float64{2, 2, 3, 3, 4} 15 | fmt.Println("TestHypergeomQtl") 16 | for i := 0; i < int(len(p)); i++ { 17 | q := HypergeometricQtlFor(nN, m, nn, p[i]) 18 | if q != qtl[i] { 19 | t.Error() 20 | fmt.Println(p[i], q, qtl[i]) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dst/_tst/hypergeom_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // test against known values 9 | func TestHypergeometric_CDF(t *testing.T) { 10 | var ( 11 | size, m, n, k int64 12 | ) 13 | 14 | // edit the following values: >>> 15 | size = 200 16 | m = 60 17 | n = 50 18 | k = 14 19 | known := 0.4339792084682835697 20 | 21 | prob := Hypergeometric_CDF_At(size, m, n, k) 22 | fmt.Println("test of Hypergeometric CDF") 23 | if !check(prob, known) { 24 | t.Error() 25 | fmt.Println(prob, known) 26 | } 27 | 28 | size = 10 29 | m = 5 30 | n = 6 31 | k = 2 32 | known = 0.238095238095238095238 33 | 34 | prob = Hypergeometric_PMF_At(size, m, n, k) 35 | fmt.Println("test of Hypergeometric PMF") 36 | if !check(prob, known) { 37 | t.Error() 38 | fmt.Println(prob, known) 39 | } 40 | 41 | known = 0.26190476190476190476 42 | 43 | prob = Hypergeometric_CDF_At(size, m, n, k) 44 | fmt.Println("2nd test of Hypergeometric CDF") 45 | if !check(prob, known) { 46 | t.Error() 47 | fmt.Println(prob, known) 48 | } 49 | 50 | size = 100 51 | m = 49 52 | n = 55 53 | k = 27 54 | known = 0.15916742856360957427 55 | 56 | prob = Hypergeometric_PMF_At(size, m, n, k) 57 | fmt.Println("test of Hypergeometric PMF") 58 | if !check(prob, known) { 59 | t.Error() 60 | fmt.Println(prob, known) 61 | } 62 | 63 | known = 0.5873860392113934918 64 | 65 | prob = Hypergeometric_CDF_At(size, m, n, k) 66 | fmt.Println("2nd test of Hypergeometric CDF") 67 | if !check(prob, known) { 68 | t.Error() 69 | fmt.Println(prob, known) 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /dst/_tst/igamma_test.go: -------------------------------------------------------------------------------- 1 | // test of InvGamma distribution against R:actuar:dinvgamma() 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | // "math/rand" 7 | "testing" 8 | ) 9 | 10 | // test against known values 11 | func TestInvGamma(t *testing.T) { 12 | fmt.Println("test of InvGamma distribution: PDF") 13 | fn := InvGammaPDF(2.2, 1.33) 14 | x := fn(3.35) 15 | y := 0.0238674 16 | if !check(x, y) { 17 | t.Error() 18 | fmt.Println(x, y) 19 | } 20 | 21 | fmt.Println("test of InvGamma distribution: CDF") 22 | fn = InvGammaCDF(2.2, 1.33) 23 | x = fn(3.35) 24 | y = 0.9586864 25 | if !check(x, y) { 26 | t.Error() 27 | fmt.Println(x, y) 28 | } 29 | 30 | fmt.Println("test of InvGamma distribution: Qtl") 31 | qtl := InvGammaQtl(2.2, 1.33) 32 | x = qtl(0.9586864) 33 | y = 3.35 34 | 35 | if !check(x, y) { 36 | t.Error() 37 | fmt.Println(x, y) 38 | } 39 | 40 | fmt.Println("test of InvGamma distribution: LnPDF") 41 | fn = InvGammaLnPDF(2.2, 1.33) 42 | x = fn(3.35) 43 | y = -3.735242 44 | if !check(x, y) { 45 | t.Error() 46 | fmt.Println(x, y) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /dst/_tst/levy_test.go: -------------------------------------------------------------------------------- 1 | // test of Levy distribution against R:rmutil:dlevy() 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | // "math/rand" 7 | "testing" 8 | ) 9 | 10 | // test against known values 11 | func TestLevy(t *testing.T) { 12 | fmt.Println("test of Levy distribution: PDF") 13 | fn := LevyPDF(2.2, 1.33) 14 | x := fn(3.35) 15 | y := 0.2092443 16 | if !check(x, y) { 17 | t.Error() 18 | fmt.Println(x, y) 19 | } 20 | 21 | fmt.Println("test of Levy distribution: CDF") 22 | fn = LevyCDF(2.2, 1.33) 23 | x = fn(3.35) 24 | y = 0.2821881 25 | if !check(x, y) { 26 | t.Error() 27 | fmt.Println(x, y) 28 | } 29 | 30 | fmt.Println("test of Levy distribution: Qtl") 31 | qtl := LevyQtl(2.2, 1.33) 32 | x = qtl(0.2821881) 33 | y = 3.35 34 | if !check(x, y) { 35 | t.Error() 36 | fmt.Println(x, y) 37 | } 38 | 39 | fmt.Println("test of Levy distribution: LnPDF") 40 | fn = LevyLnPDF(2.2, 1.33) 41 | x = fn(3.35) 42 | y = -1.564253 43 | if !check(x, y) { 44 | t.Error() 45 | fmt.Println(x, y) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /dst/_tst/logistic_test.go: -------------------------------------------------------------------------------- 1 | // test of Logistic distribution 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | // "math/rand" 7 | "testing" 8 | ) 9 | 10 | // test against known values 11 | func TestLogistic(t *testing.T) { 12 | fmt.Println("test of Logistic distribution: PDF") 13 | fn := LogisticPDF(4.2, 1.33) 14 | x := fn(3.35) 15 | y := 0.1700109 16 | if !check(x, y) { 17 | t.Error() 18 | fmt.Println(x, y) 19 | } 20 | 21 | fmt.Println("test of Logistic distribution: CDF") 22 | fn = LogisticCDF(4.2, 1.33) 23 | x = fn(3.35) 24 | y = 0.3454505 25 | if !check(x, y) { 26 | t.Error() 27 | fmt.Println(x, y) 28 | } 29 | 30 | fmt.Println("test of Logistic distribution: Qtl") 31 | qtl := LogisticQtl(4.2, 1.33) 32 | x = qtl(0.3454505) 33 | y = 3.35 34 | if !check(x, y) { 35 | t.Error() 36 | fmt.Println(x, y) 37 | } 38 | 39 | fmt.Println("test of Logistic distribution: LnPDF") 40 | fn = LogisticLnPDF(4.2, 1.33) 41 | x = fn(3.35) 42 | y = -1.771893 43 | if !check(x, y) { 44 | t.Error() 45 | fmt.Println(x, y) 46 | } 47 | 48 | fmt.Println("test of Logistic distribution: LnCDF") 49 | fn = LogisticLnCDF(4.2, 1.33) 50 | x = fn(3.35) 51 | y = -1.062906 52 | if !check(x, y) { 53 | t.Error() 54 | fmt.Println(x, y) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /dst/_tst/lognorm_test.go: -------------------------------------------------------------------------------- 1 | // test of LogNormal distribution 2 | package dst 3 | 4 | import ( 5 | "fmt" 6 | // "math/rand" 7 | "testing" 8 | ) 9 | 10 | // test against known values 11 | func TestLogNormal(t *testing.T) { 12 | fmt.Println("test of LogNormal distribution: PDF") 13 | fn := LogNormalPDF(4.2, 1.33) 14 | x := fn(3.35) 15 | y := 0.007141318 16 | if !check(x, y) { 17 | t.Error() 18 | fmt.Println(x, y) 19 | } 20 | 21 | fmt.Println("test of LogNormal distribution: CDF") 22 | fn = LogNormalCDF(4.2, 1.33) 23 | x = fn(3.35) 24 | y = 0.01225937 25 | if !check(x, y) { 26 | t.Error() 27 | fmt.Println(x, y) 28 | } 29 | 30 | fmt.Println("test of LogNormal distribution: Qtl") 31 | qtl := LogNormalQtl(4.2, 1.33) 32 | x = qtl(0.01225937) 33 | y = 3.350001 34 | if !check(x, y) { 35 | t.Error() 36 | fmt.Println(x, y) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dst/_tst/negbinom_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // test against known values 9 | func TestNegativeBinomial_PMF_CDF(t *testing.T) { 10 | var ( 11 | ρ float64 12 | i, n int64 13 | ) 14 | 15 | // edit the following values: >>> 16 | ρ = 0.5 17 | n = 20 18 | 19 | k := []int64{10, 11, 12, 16, 25, 40} 20 | pmf := []float64{0.0186544004827737808228, 0.025437818840146064758, 0.0328571826685220003128, 0.05907974191359244287, 0.04004139896255765052, 0.00121194851197753156874} 21 | cdf := []float64{0.0493685733526945114136, 0.074806392192840576172, 0.1076635748613625764847, 0.30885965851484797895, 0.81435098276449480181, 0.9968911986703366647292} 22 | 23 | // <<< 24 | 25 | fmt.Println("test of NegativeBinomial PMF") 26 | for i = 0; i < int64(len(k)); i++ { 27 | prob := NegBinomialPMFAt(ρ, n, k[i]) 28 | if !check(prob, pmf[i]) { 29 | t.Error() 30 | fmt.Println(k[i], prob, pmf[i]) 31 | 32 | } 33 | } 34 | 35 | fmt.Println("test of NegativeBinomial CDF") 36 | for i = 0; i < int64(len(k)); i++ { 37 | prob := NegBinomialCDFAt(ρ, n, k[i]) 38 | if !check(prob, cdf[i]) { 39 | t.Error() 40 | fmt.Println(k[i], prob, cdf[i]) 41 | } 42 | } 43 | } 44 | 45 | func TestNegativeBinomial_Qtl(t *testing.T) { 46 | var ( 47 | ρ float64 48 | i, n int64 49 | ) 50 | ρ = 0.5 51 | n = 20 52 | p := []float64{0.1, 0.3, 0.5, 0.7, 0.9} 53 | qtl := []int64{12, 16, 19, 23, 28} 54 | fmt.Println("test of NegativeBinomial Qtl") 55 | for i = 0; i < int64(len(p)); i++ { 56 | q := NegBinomialQtlFor(ρ, n, p[i]) 57 | if q != qtl[i] { 58 | t.Error() 59 | fmt.Println(p[i], q, qtl[i]) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /dst/_tst/next_test.go: -------------------------------------------------------------------------------- 1 | // test of Next functions 2 | // uses mean and variance of a big sample against computed values 3 | 4 | package dst 5 | 6 | import ( 7 | "fmt" 8 | "math" 9 | "math/rand" 10 | "testing" 11 | ) 12 | 13 | // test of Normal distribution 14 | func Test_Next_Normal(t *testing.T) { 15 | const nRuns int = 1 16 | const iter int = 100000 // need to be at least 1e5 17 | var n int 18 | var x, μ, σ, μ2, σ2, m, m2, delta float64 19 | fmt.Println("tests of Next functions:") 20 | fmt.Println("\tNormal distribution") 21 | 22 | for i := 0; i < nRuns; i++ { 23 | μ = 6 * rand.Float64() 24 | σ = 6*rand.Float64() + 1e-15 25 | μ2 = 0.0 // sample mean 26 | σ2 = 0.0 // sample variance unbiased 27 | m = 0.0 28 | m2 = 0.0 29 | 30 | for j := 0; j < iter; j++ { 31 | n += 1 32 | x = NextNormal(μ, σ) 33 | μ2 += x 34 | delta = x - m 35 | m += delta / float64(n) 36 | m2 += delta * (x - m) 37 | } 38 | σ2 = math.Sqrt(m2 / float64(n-1)) 39 | μ2 /= float64(iter) 40 | 41 | if !check(μ, μ2) { 42 | t.Error() 43 | fmt.Println(μ, μ2) 44 | } 45 | if !check(σ, σ2) { 46 | t.Error() 47 | fmt.Println(σ, σ2) 48 | } 49 | } 50 | } 51 | 52 | // test of Gamma distribution 53 | func Test_Next_Gamma(t *testing.T) { 54 | const nRuns int = 3 55 | const iter int = 10000 // need to be at least 1e5 56 | var n int 57 | var x, k, θ, μ, var1, μ2, var2, m, m2, delta float64 58 | fmt.Println("\tGamma distribution") 59 | 60 | for i := 0; i < nRuns; i++ { 61 | k = math.Ceil(6 * rand.Float64()) 62 | θ = 6*rand.Float64() + 1e-15 63 | μ = GammaMean(k, θ) 64 | var1 = GammaVar(k, θ) 65 | μ2 = 0.0 // sample mean 66 | var2 = 0.0 // sample variance unbiased 67 | m = 0.0 68 | m2 = 0.0 69 | 70 | for j := 0; j < iter; j++ { 71 | n += 1 72 | x = NextGamma(k, θ) 73 | μ2 += x 74 | delta = x - m 75 | m += delta / float64(n) 76 | m2 += delta * (x - m) 77 | } 78 | var2 = math.Sqrt(m2 / float64(n-1)) 79 | μ2 /= float64(iter) 80 | 81 | if !check(μ, μ2) { 82 | t.Error() 83 | fmt.Println(k, θ, μ, μ2) 84 | } 85 | if !check(var1, var2) { 86 | t.Error() 87 | fmt.Println(k, θ, var1, var2) 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /dst/_tst/poisson_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | /* 9 | // test against known values 10 | func TestPoisson_PMF_CDF(t *testing.T) { 11 | var ( 12 | α, prob float64 13 | i int64 14 | ) 15 | 16 | 17 | // edit the following values: >>> 18 | α=6 19 | k:=[]int64{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20} 20 | pmf:=[]float64{0.0024787522,0.0148725131,0.0446175392,0.0892350784,0.1338526175,0.160623141,0.160623141,0.137676978,0.1032577335,0.068838489,0.0413030934,0.02252896,0.01126448,0.0051989908,0.0022281389,0.0008912556,0.0003342208,0.0001179603,3.93200983298978E-005,1.24168731568098E-005,3.72506194704295E-006} 21 | cdf:=[]float64{0.0024787522,0.0173512652,0.0619688044,0.1512038828,0.2850565003,0.4456796414,0.6063027824,0.7439797605,0.847237494,0.916075983,0.9573790764,0.9799080365,0.9911725165,0.9963715073,0.9985996462,0.9994909017,0.9998251226,0.9999430829,0.999982403,0.9999948198,0.9999985449} 22 | // <<< 23 | 24 | fmt.Println("test of Poisson PMF") 25 | for i = 0; i < int64(len(k)); i++ { 26 | prob=Poisson_PMF_At(α, k[i]) 27 | if !check(prob, pmf[i]){ 28 | t.Error() 29 | fmt.Println(k[i], prob, pmf[i]) 30 | 31 | } 32 | } 33 | fmt.Println("test of Poisson CDF") 34 | for i = 0; i < int64(len(k)); i++ { 35 | prob=Poisson_CDF_At(α, k[i]) 36 | if !check(prob, cdf[i]){ 37 | t.Error() 38 | fmt.Println(k[i], prob, cdf[i]) 39 | } 40 | 41 | cf:=Poisson_CDF_a(α) 42 | if !check(cf(k[i]), cdf[i]){ 43 | t.Error() 44 | fmt.Println(k[i], prob, cdf[i]) 45 | } 46 | 47 | } 48 | } 49 | */ 50 | func TestPoissonNext(t *testing.T) { 51 | var λ float64 52 | λ = 1000 53 | n := 0.0 54 | mean := 0.0 55 | m2 := 0.0 56 | for j := 0; j < 100000000; j++ { 57 | n++ 58 | x := float64(PoissonNext(λ)) 59 | delta := x - mean 60 | mean += delta / n 61 | if n > 1 { 62 | m2 += delta * (x - mean) 63 | } 64 | } 65 | v := m2 / n 66 | fmt.Println("mean, var: ", mean, v) 67 | } 68 | -------------------------------------------------------------------------------- /dst/_tst/polya_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | /* 9 | // test against known values 10 | func TestPolyaPMFCDF(t *testing.T) { 11 | var ( 12 | ρ, n float64 13 | i int64 14 | ) 15 | 16 | // edit the following values: >>> 17 | ρ=0.5 18 | n=20 19 | 20 | k:=[]int64{10, 11, 12, 16, 25, 40} 21 | pmf:=[]float64{0.0186544004827737808228, 0.025437818840146064758, 0.0328571826685220003128, 0.05907974191359244287, 0.04004139896255765052, 0.00121194851197753156874} 22 | cdf:=[]float64{0.0493685733526945114136, 0.074806392192840576172, 0.1076635748613625764847, 0.30885965851484797895, 0.81435098276449480181, 0.9968911986703366647292} 23 | 24 | // <<< 25 | 26 | fmt.Println("test of Polya PMF") 27 | for i = 0; i < int64(len(k)); i++ { 28 | prob:=PolyaPMFAt(ρ, n, k[i]) 29 | if !check(prob, pmf[i]){ 30 | t.Error() 31 | fmt.Println(k[i], prob, pmf[i]) 32 | 33 | } 34 | } 35 | 36 | fmt.Println("test of Polya CDF") 37 | for i = 0; i < int64(len(k)); i++ { 38 | prob:=PolyaCDFAt(ρ, n, k[i]) 39 | if !check(prob, cdf[i]){ 40 | t.Error() 41 | fmt.Println(k[i], prob, cdf[i]) 42 | } 43 | } 44 | } 45 | */ 46 | func TestPolyaQtl(t *testing.T) { 47 | var ( 48 | ρ, n float64 49 | i int64 50 | ) 51 | ρ = 0.5 52 | n = 20 53 | p := []float64{0.1, 0.3, 0.5, 0.7, 0.9} 54 | qtl := []int64{12, 16, 19, 23, 28} 55 | fmt.Println("test of Polya Qtl") 56 | for i = 0; i < int64(len(p)); i++ { 57 | q := PolyaQtlFor(ρ, n, p[i]) 58 | if q != qtl[i] { 59 | t.Error() 60 | fmt.Println(p[i], q, qtl[i]) 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /dst/_tst/qtl_test.go: -------------------------------------------------------------------------------- 1 | // test of Quantile functions 2 | // uses CDF and back using Qtl 3 | 4 | package dst 5 | 6 | import ( 7 | "fmt" 8 | "math" 9 | "math/rand" 10 | "testing" 11 | ) 12 | 13 | // test of Beta distribution 14 | func Test_Quantiles_Beta(t *testing.T) { 15 | const nRuns int64 = 10 16 | var i int64 17 | fmt.Println("test of Quantile functions:") 18 | fmt.Println("\tBeta distribution") 19 | for i = 0; i < nRuns; i++ { 20 | α := 6*rand.Float64() + 0.05 21 | β := 6*rand.Float64() + 0.05 22 | x := 0.9*rand.Float64() + 0.05 23 | p := Beta_CDF_At(α, β, x) 24 | if p > 1e-15 { 25 | 26 | y := Beta_Qtl_For(α, β, p) 27 | if !check(x, y) { 28 | t.Error() 29 | fmt.Println(α, β, p, x, y) 30 | } 31 | } 32 | } 33 | } 34 | 35 | // test of F distribution 36 | func Test_Quantiles_F(t *testing.T) { 37 | const nRuns int64 = 10 38 | var i int64 39 | fmt.Println("\tF-distribution") 40 | for i = 0; i < nRuns; i++ { 41 | df1 := 100*rand.Float64() + 1.05 42 | df2 := 100*rand.Float64() + 1.05 43 | x := 5 * rand.Float64() 44 | p := F_CDF_At(math.Ceil(df1), math.Ceil(df2), x) 45 | if p > 1e-15 { 46 | y := F_Qtl_For(math.Ceil(df1), math.Ceil(df2), p) 47 | if !check(x, y) { 48 | t.Error() 49 | fmt.Println(math.Ceil(df1), math.Ceil(df2), p, x, y) 50 | } 51 | } 52 | } 53 | } 54 | 55 | // test of Gamma distribution 56 | func Test_Quantiles_Gamma(t *testing.T) { 57 | const nRuns int64 = 100 58 | var i int64 59 | fmt.Println("\tGamma distribution") 60 | for i = 0; i < nRuns; i++ { 61 | k := 10*rand.Float64() + 1.05 62 | θ := 3*rand.Float64() + 0.05 63 | x := 25 * rand.Float64() 64 | p := Gamma_CDF_At(math.Ceil(k), θ, x) 65 | if p > 1e-15 && p < 1-1e-15 { 66 | y := Gamma_Qtl_For(math.Ceil(k), θ, p) 67 | if !check(x, y) { 68 | t.Error() 69 | fmt.Println(math.Ceil(k), θ, p, x, y) 70 | } 71 | } 72 | } 73 | } 74 | 75 | // test of Standard Normal distribution 76 | func Test_Quantiles_Z(t *testing.T) { 77 | const nRuns int64 = 100 78 | var i int64 79 | fmt.Println("\tStandard Normal distribution") 80 | for i = 0; i < nRuns; i++ { 81 | x := 6 * rand.Float64() 82 | p := Z_CDF_At(x) 83 | if p > 1e-15 && p < 1-1e-15 { 84 | y := Z_Qtl_For(p) 85 | if !check(x, y) { 86 | t.Error() 87 | fmt.Println(p, x, y) 88 | } 89 | } 90 | } 91 | } 92 | 93 | // test of Normal distribution 94 | func Test_Quantiles_Normal(t *testing.T) { 95 | const nRuns int = 100 96 | fmt.Println("\tNormal distribution") 97 | for i := 0; i < nRuns; i++ { 98 | μ := 6 * rand.Float64() 99 | σ := 6*rand.Float64() + 1e-15 100 | x := 6 * rand.Float64() 101 | p := Normal_CDF_At(μ, σ, x) 102 | if p > 1e-15 && p < 1-1e-15 { 103 | y := Normal_Qtl_For(μ, σ, p) 104 | if !check(x, y) { 105 | t.Error() 106 | fmt.Println(p, x, y) 107 | } 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /dst/_tst/rpoisson_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestPoissonNext2(t *testing.T) { 9 | var λ float64 10 | λ = 1000 11 | n := 0.0 12 | mean := 0.0 13 | m2 := 0.0 14 | // for j := 0; j < 100000000; j++ { 15 | for j := 0; j < 1000; j++ { 16 | n++ 17 | x := float64(PoissonNext(λ)) 18 | delta := x - mean 19 | mean += delta / n 20 | if n > 1 { 21 | m2 += delta * (x - mean) 22 | } 23 | } 24 | v := m2 / n 25 | fmt.Println("mean, var: ", mean, v) 26 | } 27 | -------------------------------------------------------------------------------- /dst/_tst/stat_test.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | . "code.google.com/p/go-fn/fn" 5 | "fmt" 6 | "math" 7 | "math/rand" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | var Seed func(int64) = rand.Seed 13 | 14 | func XTestDir(t *testing.T) { 15 | α := []float64{4, 5, 6} 16 | dgen := Dirichlet(α) 17 | counts := [3]int{0, 0, 0} 18 | const total = 150000 19 | for i := 0; i < total; i++ { 20 | θ := dgen() 21 | v := NextChoice(θ) 22 | counts[v]++ 23 | } 24 | fmt.Printf("%v\n", counts) 25 | } 26 | 27 | func TestNullWeights(t *testing.T) { 28 | n := int64(10) 29 | weights := make([]float64, n) 30 | m := NextChoice(weights) 31 | if n != m { 32 | t.Error() 33 | } 34 | } 35 | 36 | func TestLnGamma(t *testing.T) { 37 | acc := 0.0000001 38 | check := func(x, y float64) bool { 39 | if false { 40 | return x == y 41 | } 42 | return math.Abs(x-y) < acc 43 | } 44 | for i := 0; i < 100; i++ { 45 | x := NextGamma(10, 10) 46 | g1 := LnΓ(x) 47 | g2, _ := math.Lgamma(x) 48 | if !check(g1, g2) { 49 | t.Error(fmt.Sprintf("For %v: %v vs %v", x, g1, g2)) 50 | } 51 | } 52 | //var start int64 53 | Seed(10) 54 | start := time.Now() 55 | for i := 0; i < 1e6; i++ { 56 | x := NextGamma(10, 10) 57 | math.Lgamma(x) 58 | } 59 | now := time.Now() 60 | duration2 := float64(now.Sub(start)) / 1e9 61 | 62 | //duration2 := float64(time.Now()-start) / 1e9 63 | Seed(10) 64 | start = time.Now() 65 | for i := 0; i < 1e6; i++ { 66 | x := NextGamma(10, 10) 67 | LnΓ(x) 68 | } 69 | now = time.Now() 70 | duration1 := float64(now.Sub(start)) / 1e9 71 | fmt.Printf("Mine was %f\nTheirs was %f\n", duration1, duration2) 72 | } 73 | 74 | func XTestGen(t *testing.T) { 75 | fmt.Printf("NextUniform => %f\n", NextUniform()) 76 | fmt.Printf("NextExp => %f\n", NextExp(1.5)) 77 | fmt.Printf("NextGamma => %f\n", NextGamma(.3, 1)) 78 | fmt.Printf("NextNormal => %f\n", NextNormal(0, 1)) 79 | fmt.Printf("NextRange => %d\n", NextRange(10)) 80 | fmt.Printf("NextChoice => %d\n", NextChoice([]float64{.3, .3, .4})) 81 | fmt.Printf("NextMultinomial => %v\n", 82 | NextMultinomial([]float64{.3, .3, .4}, 100)) 83 | fmt.Printf("NextDirichlet => %v\n", NextDirichlet([]float64{.3, .3, .4})) 84 | fmt.Printf("NextBernoulli => %d\n", NextBernoulli(.5)) 85 | fmt.Printf("NextGeometric => %d\n", NextGeometric(.5)) 86 | fmt.Printf("NextBinomial => %d\n", NextBinomial(.5, 10)) 87 | fmt.Printf("NextPoisson => %d\n", NextPoisson(1.5)) 88 | fmt.Printf("NextXsquare => %f\n", NextXsquare(3)) 89 | fmt.Printf("NextNegativeBinomial => %d\n", NextNegativeBinomial(.5, 10)) 90 | fmt.Printf("NextStudentsT => %f\n", NextStudentsT(7)) 91 | fmt.Printf("NextF => %f\n", NextF(7, 3)) 92 | /* fmt.Printf("NextWishart => %v\n", 93 | 94 | NextWishart(100, matrix.MakeDenseMatrixStacked([][]float64{[]float64{1, 0}, []float64{0, 1}}))) 95 | fmt.Printf("NextInverseWishart => %v\n", 96 | NextInverseWishart(100, matrix.MakeDenseMatrixStacked([][]float64{[]float64{1, 0}, []float64{0, 1}}))) 97 | */ 98 | } 99 | 100 | /* 101 | // test of Binomial p confidence interval // failed due to some unknown bug 102 | func TestBinomP_CI(t *testing.T) { 103 | fmt.Println("test of Binomial p confidence interval") 104 | var n int64 105 | var k, nn, p, alpha, low, high, low2, high2 float64 106 | n=30 107 | nn=float64(n) 108 | p=0.1 109 | k=nn*p 110 | 111 | alpha=0.1 112 | low2=0.04 113 | high2=0.21 114 | low, high = Binom_p_ConfI(n, p, alpha) 115 | fmt.Println(low, " = ", low2, "\t", high, " = ", high2) 116 | } 117 | */ 118 | -------------------------------------------------------------------------------- /dst/_tst/template_test.txt: -------------------------------------------------------------------------------- 1 | // Template for testing functions 2 | // 's/DISTRIBUTION/MyDistribution/g' 3 | 4 | package stat 5 | 6 | import ( 7 | "math" 8 | "testing" 9 | "fmt" 10 | ) 11 | 12 | func check (x, y float64) bool { 13 | const acc float64 = 1e-4 // accuracy 14 | var z float64 15 | if x/y > 1.00 { 16 | z = y/x 17 | } else { 18 | z = x/y 19 | } 20 | if 1-z > acc { 21 | return false 22 | } 23 | return true 24 | } 25 | 26 | // test against known values 27 | func TestDISTRIBUTION_PDF_CDF(t *testing.T) { 28 | var ( 29 | x, p []float64 30 | i int64 31 | ) 32 | 33 | fmt.Println("") 34 | fmt.Println("test for DISTRIBUTION PDF and CDF") 35 | fmt.Println("") 36 | 37 | // edit the following values: >>> 38 | α=6 39 | β=6 40 | x=[]{0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5] 41 | p=[]{0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5] 42 | <<< // 43 | 44 | for i = 0; i < len(x); i++ { 45 | prob=DISTRIBUTION_PDF_At(α, β, x[i]) 46 | if !check(prob, p[i]){ 47 | t.Error() 48 | } 49 | prob=DISTRIBUTION_CDF_At(α, β, x[i]) 50 | if !check(prob, p[i]){ 51 | t.Error() 52 | } 53 | } 54 | } 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | // test for inverse CDF 63 | func TestDISTRIBUTIONInv_CDF_For(t *testing.T) { 64 | fmt.Println("") 65 | fmt.Println("test for DISTRIBUTIONInv_CDF_For(α, β, p)") 66 | fmt.Println("") 67 | var x, y, z, err, α, β, p float64 68 | var count, tests int64 69 | 70 | for count = 0; count < tests; { 71 | α=6*rand.Float64()+0.3 72 | β=6*rand.Float64()+0.3 73 | x=rand.Float64() 74 | p=DISTRIBUTION_CDF_At(α, β, x) 75 | y:=DISTRIBUTIONInv_CDF_For(α, β, p) 76 | err=math.Abs(y - x) 77 | if math.Abs(y) < 2.0 && p < 1.00 { 78 | count++ 79 | if !check(y, x){ 80 | t.Error() 81 | fmt.Println("α =",α , " β =", β, " p =", p, " x =", x, " err=", err, " inv_cdf=", y) 82 | } 83 | } 84 | } 85 | } 86 | 87 | 88 | // test ONLY for discrete CDF 89 | // sums PMF up to k 90 | 91 | func TestDISTRIBUTION_CDF_For(t *testing.T) { 92 | fmt.Println("") 93 | fmt.Println("test for DISTRIBUTION_CDF_For") 94 | fmt.Println("") 95 | var acc, param1, param2, x, y, z, p float64 96 | k, n, count, tests int64 97 | 98 | acc = 1e-4 99 | 100 | check := func(x, y, acc float64) bool { 101 | if x/y > 1.00 { 102 | z = y/x 103 | } else { 104 | z = x/y 105 | } 106 | if 1-z > acc { 107 | return false 108 | } 109 | return true 110 | } 111 | 112 | for count = 0; count < tests; { 113 | param1=6*rand.Float64()+0.3 // adjust param limits 114 | param2=6*rand.Float64()+0.3 // adjust param limits 115 | k=rand.Int63n(n) // adjust upper limit of k 116 | cdf:=DISTRIBUTION_CDF(param1, param2) 117 | y=cdf(k) 118 | x = 0 119 | for i = 0; i < k; i++; { 120 | pmf:=DISTRIBUTION_PMF(param1, param2) 121 | x += pmf(i) 122 | } 123 | if !check(x, y, acc){ 124 | t.Error() 125 | } 126 | } 127 | 128 | 129 | -------------------------------------------------------------------------------- /dst/bd0.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // bd0 the "deviance part". 6 | func bd0(x, np float64) float64 { 7 | // Evaluates the "deviance part" 8 | // bd0(x,M) := M // D0(x/M) = M//[ x/M // log(x/M) + 1 - (x/M) ] = 9 | // = x // log(x/M) + M - x 10 | // where M = E[X] = n//p (or = lambda), for x, M > 0 11 | // 12 | // in a manner that should be stable (with small relative error) 13 | // for all x and M=np. In particular for x/np close to 1, direct 14 | // evaluation fails, and evaluation is based on the Taylor series 15 | // of log((1+v)/(1-v)) with v = (x-np)/(x+np). 16 | // Rewritten from the C code by Catherine Loader, catherine@research.bell-labs.com. October 23, 2000. 17 | if isInf(x, 0) || isInf(np, 0) || np == 0 { 18 | return NaN 19 | } 20 | if abs(x-np) < 0.1*(x+np) { 21 | v := (x - np) / (x + np) 22 | s := (x - np) * v 23 | ej := 2 * x * v 24 | v = v * v 25 | for j := 1; ; j++ { // Taylor series 26 | ej *= v 27 | s1 := s + ej/(float64(j<<1)+1) 28 | if s1 == s { // last term was effectively 0 29 | return s1 30 | } 31 | s = s1 32 | } 33 | } 34 | // else: | x - np | is not too small 35 | return x*log(x/np) + np - x 36 | } 37 | -------------------------------------------------------------------------------- /dst/bernoulli.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Bernoulli distribution. 6 | 7 | // BernoulliPMF returns the PMF of the Bernoulli distribution. 8 | func BernoulliPMF(ρ float64) func(k int64) float64 { 9 | return func(k int64) float64 { 10 | if k < 0 || k > 1 { 11 | return NaN 12 | } 13 | if k == 1 { 14 | return ρ 15 | } 16 | return 1 - ρ 17 | } 18 | } 19 | 20 | // BernoulliLnPMF returns the natural logarithm of the PMF of the Bernoulli distribution. 21 | func BernoulliLnPMF(ρ float64) func(k int64) float64 { 22 | return func(k int64) float64 { 23 | if k == 1 { 24 | return log(ρ) 25 | } 26 | return log(1 - ρ) 27 | } 28 | } 29 | 30 | // BernoulliPMFAt returns the value of PMF of Bernoulli distribution at x. 31 | func BernoulliPMFAt(ρ float64, k int64) float64 { 32 | pmf := BernoulliPMF(ρ) 33 | return pmf(k) 34 | } 35 | 36 | // BernoulliCDF returns the value of CDF of the Bernoulli distribution, at x. 37 | func BernoulliCDF(ρ float64) func(k int64) float64 { 38 | return func(k int64) float64 { 39 | if k < 0 || k > 1 { 40 | return NaN 41 | } 42 | if k == 1 { 43 | return 1 44 | } 45 | return 1 - ρ 46 | } 47 | } 48 | 49 | // BernoulliCDFAt returns the value of CDF of the Bernoulli distribution, at x. 50 | func BernoulliCDFAt(ρ float64, k int64) float64 { 51 | cdf := BernoulliCDF(ρ) 52 | return cdf(k) 53 | } 54 | 55 | // BernoulliNext returns random number drawn from the Bernoulli distribution. 56 | func BernoulliNext(ρ float64) int64 { 57 | if UniformNext(0, 1) < ρ { 58 | return 1 59 | } 60 | return 0 61 | } 62 | 63 | // Bernoulli returns the random number generator with Bernoulli distribution. 64 | func Bernoulli(ρ float64) func() int64 { return func() int64 { return BernoulliNext(ρ) } } 65 | -------------------------------------------------------------------------------- /dst/beta-mu-nu.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Beta distribution reparametrized using mean (μ) and sample size (ν). 6 | // Kruschke, J. K. (2011). Doing Bayesian data analysis: A tutorial with R and BUGS. p. 83: Academic Press / Elsevier. ISBN 978-0123814852. 7 | 8 | // BetaμνPDF returns the PDF of the Beta distribution reparametrized using mean and sample size. 9 | func BetaμνPDF(μ, ν float64) func(x float64) float64 { 10 | α := μ * ν 11 | β := (1 - μ) * ν 12 | return BetaPDF(α, β) 13 | } 14 | 15 | // BetaμνLnPDF returns the natural logarithm of the PDF of the Beta distribution reparametrized using mean and sample size. 16 | func BetaμνLnPDF(μ, ν float64) func(x float64) float64 { 17 | α := μ * ν 18 | β := (1 - μ) * ν 19 | return BetaLnPDF(α, β) 20 | } 21 | 22 | // BetaμνNext returns random number drawn from the Beta distribution reparametrized using mean and sample size. 23 | func BetaμνNext(μ, ν float64) float64 { 24 | α := μ * ν 25 | β := (1 - μ) * ν 26 | if ν <= 0 { 27 | return NaN 28 | } 29 | return BetaNext(α, β) 30 | } 31 | 32 | // Betaμν returns the random number generator with Beta distribution reparametrized using mean and sample size. 33 | func Betaμν(μ, ν float64) func() float64 { 34 | α := μ * ν 35 | β := (1 - μ) * ν 36 | return func() float64 { return BetaNext(α, β) } 37 | } 38 | 39 | // BetaμνPDFAt returns the value of PDF of Beta distribution at x. 40 | func BetaμνPDFAt(μ, ν, x float64) float64 { 41 | pdf := BetaμνPDF(μ, ν) 42 | return pdf(x) 43 | } 44 | 45 | // BetaμνCDF returns the CDF of the Beta distribution reparametrized using mean and sample size. 46 | func BetaμνCDF(μ, ν float64) func(x float64) float64 { 47 | α := μ * ν 48 | β := (1 - μ) * ν 49 | return BetaCDF(α, β) 50 | } 51 | 52 | // BetaμνCDFAt returns the value of CDF of the Beta distribution reparametrized using mean and sample size, at x. 53 | func BetaμνCDFAt(μ, ν, x float64) float64 { 54 | cdf := BetaCDF(μ, ν) 55 | return cdf(x) 56 | } 57 | 58 | // BetaμνQtl returns the inverse of the CDF (quantile) of the Beta distribution reparametrized using mean and sample size. 59 | func BetaμνQtl(μ, ν float64) func(p float64) float64 { 60 | // p: probability for which the quantile is evaluated 61 | α := μ * ν 62 | β := (1 - μ) * ν 63 | return BetaQtl(α, β) 64 | } 65 | 66 | // BetaμνQtlFor returns the inverse of the CDF (quantile) of the Beta distribution reparametrized using mean and sample size, for a given probability. 67 | func BetaμνQtlFor(μ, ν, p float64) float64 { 68 | cdf := BetaμνQtl(μ, ν) 69 | return cdf(p) 70 | } 71 | -------------------------------------------------------------------------------- /dst/beta-mu-sigma.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Beta distribution reparametrized using mean and standard deviation. 6 | 7 | // BetaμσPDF returns the PDF of the Beta distribution reparametrized using mean and standard deviation. 8 | func BetaμσPDF(μ, σ float64) func(x float64) float64 { 9 | α := μ * (μ*(1-μ)/(σ*σ) - 1) 10 | β := (1 - μ) * (μ*(1-μ)/(σ*σ) - 1) 11 | return BetaPDF(α, β) 12 | } 13 | 14 | // BetaμσLnPDF returns the natural logarithm of the PDF of the Beta distribution reparametrized using mean and standard deviation. 15 | func BetaμσLnPDF(μ, σ float64) func(x float64) float64 { 16 | α := μ * (μ*(1-μ)/(σ*σ) - 1) 17 | β := (1 - μ) * (μ*(1-μ)/(σ*σ) - 1) 18 | return BetaLnPDF(α, β) 19 | } 20 | 21 | // BetaμσNext returns random number drawn from the Beta distribution reparametrized using mean and standard deviation. 22 | func BetaμσNext(μ, σ float64) float64 { 23 | α := μ * (μ*(1-μ)/(σ*σ) - 1) 24 | β := (1 - μ) * (μ*(1-μ)/(σ*σ) - 1) 25 | return BetaNext(α, β) 26 | } 27 | 28 | // Betaμσ returns the random number generator with Beta distribution reparametrized using mean and standard deviation. 29 | func Betaμσ(μ, σ float64) func() float64 { 30 | α := μ * (μ*(1-μ)/(σ*σ) - 1) 31 | β := (1 - μ) * (μ*(1-μ)/(σ*σ) - 1) 32 | return func() float64 { return BetaNext(α, β) } 33 | } 34 | 35 | // BetaμσPDFAt returns the value of PDF of Beta distribution at x. 36 | func BetaμσPDFAt(μ, σ, x float64) float64 { 37 | pdf := BetaμσPDF(μ, σ) 38 | return pdf(x) 39 | } 40 | 41 | // BetaμσCDF returns the CDF of the Beta distribution reparametrized using mean and standard deviation. 42 | func BetaμσCDF(μ, σ float64) func(x float64) float64 { 43 | α := μ * (μ*(1-μ)/(σ*σ) - 1) 44 | β := (1 - μ) * (μ*(1-μ)/(σ*σ) - 1) 45 | return BetaCDF(α, β) 46 | } 47 | 48 | // BetaμσCDFAt returns the value of CDF of the Beta distribution reparametrized using mean and standard deviation, at x. 49 | func BetaμσCDFAt(μ, σ, x float64) float64 { 50 | cdf := BetaCDF(μ, σ) 51 | return cdf(x) 52 | } 53 | 54 | // BetaμσQtl returns the inverse of the CDF (quantile) of the Beta distribution reparametrized using mean and standard deviation. 55 | func BetaμσQtl(μ, σ float64) func(p float64) float64 { 56 | // p: probability for which the quantile is evaluated 57 | α := μ * (μ*(1-μ)/(σ*σ) - 1) 58 | β := (1 - μ) * (μ*(1-μ)/(σ*σ) - 1) 59 | return BetaQtl(α, β) 60 | } 61 | 62 | // BetaμσQtlFor returns the inverse of the CDF (quantile) of the Beta distribution reparametrized using mean and standard deviation, for a given probability. 63 | func BetaμσQtlFor(μ, σ, p float64) float64 { 64 | cdf := BetaμσQtl(μ, σ) 65 | return cdf(p) 66 | } 67 | -------------------------------------------------------------------------------- /dst/chisq.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Chi-Squared distribution. 6 | // Parameters: 7 | // n ∈ ℕ (degrees of freedom) 8 | // Support: 9 | // x ∈ [0, +∞] 10 | 11 | // ChiSquarePDF returns the PDF of the ChiSquare distribution. 12 | func ChiSquarePDF(n int64) func(x float64) float64 { 13 | k := float64(n) / 2 14 | normalization := pow(0.5, k) / Γ(k) 15 | return func(x float64) float64 { 16 | return normalization * pow(x, k-1) * ExponentialNext(-x/2) 17 | } 18 | } 19 | 20 | // ChiSquareLnPDF returns the natural logarithm of the PDF of the ChiSquare distribution. 21 | func ChiSquareLnPDF(n int64) func(x float64) float64 { 22 | k := float64(n) / 2 23 | normalization := log(0.5)*k - LnΓ(k) 24 | return func(x float64) float64 { 25 | return normalization + log(x)*(k-1) - x/2 26 | } 27 | } 28 | 29 | // ChiSquarePDFAt returns the value of PDF of ChiSquare distribution at x. 30 | // UniformPDFAt returns the value of PDF of Uniform distribution at x. 31 | func ChiSquarePDFAt(n int64, x float64) float64 { 32 | pdf := ChiSquarePDF(n) 33 | return pdf(x) 34 | } 35 | 36 | // ChiSquareCDF returns the CDF of the ChiSquare distribution. 37 | func ChiSquareCDF(n int64) func(x float64) float64 { 38 | return func(x float64) float64 { 39 | return Γr(float64(n)/2, x/2) 40 | } 41 | } 42 | 43 | // ChiSquareCDFAt returns the value of CDF of the ChiSquare distribution, at x. 44 | func ChiSquareCDFAt(n int64, x float64) float64 { 45 | cdf := ChiSquareCDF(n) 46 | return cdf(x) 47 | } 48 | 49 | // ChiSquareQtl returns the inverse of the CDF (quantile) of the ChiSquare distribution. 50 | func ChiSquareQtl(n int64) func(p float64) float64 { 51 | return func(p float64) float64 { 52 | return GammaQtlFor(float64(n)/2, 2, p) 53 | } 54 | } 55 | 56 | // ChiSquareNext returns random number drawn from the ChiSquare distribution. 57 | func ChiSquareNext(n int64) (x float64) { 58 | //ChiSquare(n) => sum of n N(0,1)^2 59 | for i := iZero; i < n; i++ { 60 | n := NormalNext(0, 1) 61 | x += n * n 62 | } 63 | return 64 | } 65 | 66 | // ChiSquare returns the random number generator with ChiSquare distribution. 67 | func ChiSquare(n int64) func() float64 { 68 | return func() float64 { 69 | return ChiSquareNext(n) 70 | } 71 | } 72 | 73 | // ChiSquareMean returns the mean of the ChiSquare distribution. 74 | func ChiSquareMean(n int64) float64 { 75 | return float64(n) 76 | } 77 | 78 | // ChiSquareMedian returns the approximate median of the ChiSquare distribution. 79 | func ChiSquareMedian(n int64) float64 { 80 | c := 1 - (2.0 / (9.0 * n)) 81 | c = c * c * c 82 | return float64(n * c) 83 | } 84 | 85 | // ChiSquareMode returns the mode of the ChiSquare distribution. 86 | func ChiSquareMode(n int64) float64 { 87 | return max(float64(n-2), 0) 88 | } 89 | 90 | // ChiSquareVar returns the variance of the ChiSquare distribution. 91 | func ChiSquareVar(n int64) float64 { 92 | return float64(2 * n) 93 | } 94 | 95 | // ChiSquareStd returns the standard deviation of the ChiSquare distribution. 96 | func ChiSquareStd(n int64) float64 { 97 | return sqrt(float64(2 * n)) 98 | } 99 | 100 | // ChiSquareSkew returns the skewness of the ChiSquare distribution. 101 | func ChiSquareSkew(n int64) float64 { 102 | return sqrt(float64(8 / n)) 103 | } 104 | 105 | // ChiSquareExKurt returns the excess kurtosis of the ChiSquare distribution. 106 | func ChiSquareExKurt(n int64) float64 { 107 | return float64(12 / n) 108 | } 109 | -------------------------------------------------------------------------------- /dst/choice.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import () 4 | 5 | func ChoicePMF(θ []float64) func(i int64) float64 { 6 | return func(i int64) float64 { 7 | return θ[i] 8 | } 9 | } 10 | 11 | func ChoiceLnPMF(θ []float64) func(i int64) float64 { 12 | return func(i int64) float64 { 13 | return log(θ[i]) 14 | } 15 | } 16 | 17 | func ChoiceNext(θ []float64) int64 { 18 | u := UniformNext(0, 1) 19 | i := 0 20 | sum := θ[0] 21 | for ; sum < u && i < len(θ)-1; i++ { 22 | sum += θ[i+1] 23 | } 24 | if u >= sum { 25 | return int64(len(θ)) 26 | } 27 | return int64(i) 28 | } 29 | 30 | func Choice(θ []float64) func() int64 { 31 | return func() int64 { 32 | return ChoiceNext(θ) 33 | } 34 | } 35 | 36 | func LogChoiceNext(lws []float64) int64 { 37 | return LogChoice(lws)() 38 | } 39 | 40 | func LogChoice(lws []float64) func() int64 { 41 | max := lws[0] 42 | for _, lw := range lws[1:len(lws)] { 43 | if lw > max { 44 | max = lw 45 | } 46 | } 47 | ws := make([]float64, len(lws)) 48 | var sum float64 49 | for i, lw := range lws { 50 | ws[i] = exp(lw - max) 51 | sum += ws[i] 52 | } 53 | norm := 1 / sum 54 | for i := range ws { 55 | ws[i] *= norm 56 | } 57 | return Choice(ws) 58 | } 59 | -------------------------------------------------------------------------------- /dst/crp.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | func CRPPMF(α float64) func(x []int64) float64 { 4 | return func(x []int64) float64 { 5 | n := int64(len(x)) 6 | counts := make([]int64, int(α*log(float64(len(x))))) 7 | sum := fZero 8 | 9 | p := fOne 10 | 11 | for i := iZero; i < n; i++ { 12 | if x[i] >= int64(len(counts)) { 13 | counts = copyInt64(counts, 2*int64(len(counts))) 14 | } 15 | 16 | if counts[x[i]] == 0 { 17 | p *= α / (sum + α) 18 | } else { 19 | p *= float64(x[i]) / (sum + α) 20 | } 21 | 22 | counts[x[i]] += 1 23 | sum += 1 24 | } 25 | return p 26 | } 27 | } 28 | 29 | func CRPLnPMF(α float64) func(x []int64) float64 { 30 | return func(x []int64) float64 { 31 | counts := make([]float64, len(x)) 32 | total := fZero 33 | r := fZero 34 | for _, c := range x { 35 | if counts[c] == 0 { 36 | r++ 37 | } 38 | counts[c]++ 39 | total++ 40 | } 41 | ll := r * log(α) 42 | ll += LnΓ(α) - LnΓ(α+total) 43 | for _, count := range counts { 44 | if count != 0 { 45 | ll += LnΓ(count) 46 | } 47 | } 48 | return ll 49 | } 50 | } 51 | 52 | /* 53 | func CRPLnPMF2(α float64) func(x []int64) float64 { 54 | return func(x []int64) float64 { 55 | n := int64(len(x)); 56 | counts := make([]int64, int(α*log(float64(len(x))))); 57 | sum := fZero; 58 | 59 | p := fZero; 60 | 61 | for i:=iZero; i= int64(len(counts)) { 63 | counts = copyInt64(counts, 2*int64(len(counts))) 64 | } 65 | 66 | if counts[x[i]] == 0 { 67 | p += log(α)-log(sum+α); 68 | } else { 69 | p += log(float64(x[i]))-log(sum+α); 70 | } 71 | 72 | counts[x[i]] += 1; 73 | sum += 1; 74 | } 75 | return p; 76 | } 77 | } 78 | */ 79 | -------------------------------------------------------------------------------- /dst/dirichlet.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Dirichlet distribution. It is the multivariate generalization of the beta distribution. 6 | // Parameters: 7 | // αi > 0 concentration parameters 8 | // Support: 9 | // θi ∈ [0, 1] and Σθi = 1 10 | 11 | // DirichletPDF returns the PDF of the Dirichlet distribution. 12 | func DirichletPDF(α []float64) func(θ []float64) float64 { 13 | return func(θ []float64) float64 { 14 | k := len(α) 15 | if len(θ) != k { 16 | return 0 17 | } 18 | l := float64(1.0) 19 | totalα := float64(0) 20 | for i := 0; i < k; i++ { 21 | if θ[i] < 0 || θ[i] > 1 { 22 | return 0 23 | } 24 | l *= pow(θ[i], α[i]-1) 25 | l /= Γ(α[i]) 26 | totalα += α[i] 27 | } 28 | l *= Γ(totalα) 29 | return l 30 | } 31 | } 32 | 33 | // DirichletLnPDF returns the natural logarithm of the PDF of the Dirichlet distribution. 34 | func DirichletLnPDF(α []float64) func(x []float64) float64 { 35 | return func(x []float64) float64 { 36 | k := len(α) 37 | if len(x) != k { 38 | return negInf 39 | } 40 | l := fZero 41 | totalα := float64(0) 42 | for i := 0; i < k; i++ { 43 | if x[i] < 0 || x[i] > 1 { 44 | return negInf 45 | } 46 | l += (α[i] - 1) * log(x[i]) 47 | l -= LnΓ(α[i]) 48 | totalα += α[i] 49 | } 50 | l += LnΓ(totalα) 51 | return l 52 | } 53 | } 54 | 55 | // DirichletPDFAt returns the value of PDF of Dirichlet distribution at x. 56 | func DirichletPDFAt(α, θ []float64) float64 { 57 | pdf := DirichletPDF(α) 58 | return pdf(θ) 59 | } 60 | 61 | // DirichletNext returns random number drawn from the Dirichlet distribution. 62 | func DirichletNext(α []float64) []float64 { 63 | k := len(α) 64 | x := make([]float64, k) 65 | sum := fZero 66 | for i := 0; i < len(α); i++ { 67 | x[i] = GammaNext(α[i], 1.0) 68 | sum += x[i] 69 | } 70 | for i := 0; i < len(α); i++ { 71 | x[i] /= sum 72 | } 73 | return x 74 | } 75 | 76 | // Dirichlet returns the random number generator with Dirichlet distribution. 77 | func Dirichlet(α []float64) func() []float64 { 78 | return func() []float64 { return DirichletNext(α) } 79 | } 80 | 81 | // DirichletMean returns the mean of the Dirichlet distribution. 82 | func DirichletMean(α []float64) []float64 { 83 | k := len(α) 84 | x := make([]float64, k) 85 | sum := fZero 86 | for i := 0; i < k; i++ { 87 | sum += α[i] 88 | } 89 | 90 | for i := 0; i < k; i++ { 91 | x[i] = α[i] / sum 92 | } 93 | return x 94 | } 95 | 96 | // DirichletMode returns the mode of the Dirichlet distribution. 97 | func DirichletMode(α []float64) []float64 { 98 | k := len(α) 99 | x := make([]float64, k) 100 | sum := fZero 101 | for i := 0; i < k; i++ { 102 | if α[i] <= 1 { // REVISION and citation NEEDED! 103 | panic("mode not defined") 104 | } 105 | sum += α[i] 106 | } 107 | 108 | for i := 0; i < k; i++ { 109 | x[i] = (α[i] - 1) / (sum - float64(k)) 110 | } 111 | return x 112 | } 113 | 114 | // DirichletVar returns the variance of the Dirichlet distribution. 115 | func DirichletVar(α []float64) []float64 { 116 | k := len(α) 117 | x := make([]float64, k) 118 | sum := fZero 119 | for i := 0; i < k; i++ { 120 | sum += α[i] 121 | } 122 | 123 | for i := 0; i < k; i++ { 124 | x[i] = (α[i] * (sum - α[i])) / (sum * sum * (sum + 1)) 125 | 126 | } 127 | return x 128 | } 129 | -------------------------------------------------------------------------------- /dst/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | // Probability distributions. 4 | package dst 5 | -------------------------------------------------------------------------------- /dst/exp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Exponential distribution (a.k.a. negative exponential distribution). 6 | // Parameters: 7 | // λ > 0: rate, or inverse scale 8 | // Support: x ∈ [0; ∞). 9 | 10 | import ( 11 | "math/rand" 12 | ) 13 | 14 | // ExponentialPDF returns the PDF of the Exponential distribution. 15 | func ExponentialPDF(λ float64) func(x float64) float64 { 16 | return func(x float64) float64 { 17 | if x < 0 { 18 | return 0 19 | } 20 | return λ * exp(-λ*x) 21 | } 22 | } 23 | 24 | // ExponentialLnPDF returns the natural logarithm of the PDF of the Exponential distribution. 25 | func ExponentialLnPDF(λ float64) func(x float64) float64 { 26 | return func(x float64) float64 { 27 | if x < 0 { 28 | return negInf 29 | } 30 | return log(λ) - λ*x 31 | } 32 | } 33 | 34 | // ExponentialPDFAt returns the value of PDF of Exponential distribution at x. 35 | func ExponentialPDFAt(λ, x float64) float64 { 36 | pdf := ExponentialPDF(λ) 37 | return pdf(x) 38 | } 39 | 40 | // ExponentialCDF returns the CDF of the Exponential distribution. 41 | func ExponentialCDF(λ float64) func(x float64) float64 { 42 | return func(x float64) float64 { 43 | if x < 0 { 44 | return 0 45 | } 46 | return 1 - exp(-λ*x) 47 | } 48 | } 49 | 50 | // ExponentialCDFAt returns the value of CDF of the Exponential distribution, at x. 51 | func ExponentialCDFAt(λ, x float64) float64 { 52 | cdf := ExponentialCDF(λ) 53 | return cdf(x) 54 | } 55 | 56 | // ExponentialQtl returns the inverse of the CDF (quantile) of the Exponential distribution. 57 | func ExponentialQtl(λ float64) func(p float64) float64 { 58 | // p: probability for which the quantile is evaluated 59 | return func(p float64) float64 { 60 | return -log(1-p) / λ 61 | } 62 | } 63 | 64 | // ExponentialQtlFor returns the inverse of the CDF (quantile) of the Exponential distribution, for given probability. 65 | func ExponentialQtlFor(λ, p float64) float64 { 66 | cdf := ExponentialQtl(λ) 67 | return cdf(p) 68 | } 69 | 70 | // ExponentialNext returns random number drawn from the Exponential distribution. 71 | func ExponentialNext(λ float64) float64 { return rand.ExpFloat64() / λ } 72 | 73 | // Exponential returns the random number generator with Exponential distribution. 74 | func Exponential(λ float64) func() float64 { return func() float64 { return ExponentialNext(λ) } } 75 | 76 | // ExponentialMean returns the mean of the Exponential distribution. 77 | func ExponentialMean(λ float64) float64 { 78 | return 1 / λ 79 | } 80 | 81 | // Exponential returns the median of the Exponential distribution. 82 | func ExponentialMedian(λ float64) (med float64) { 83 | return (1 / λ) * log(2) 84 | } 85 | 86 | // ExponentialMode returns the mode of the Exponential distribution. 87 | func ExponentialMode(λ float64) float64 { 88 | return 0 89 | } 90 | 91 | // ExponentialVar returns the variance of the Exponential distribution. 92 | func ExponentialVar(λ float64) float64 { 93 | return 1 / (λ * λ) 94 | } 95 | 96 | // ExponentialStd returns the standard deviation of the Exponential distribution. 97 | func ExponentialStd(λ float64) float64 { 98 | return 1 / λ 99 | } 100 | 101 | // ExponentialSkew returns the skewness of the Exponential distribution. 102 | func ExponentialSkew(λ float64) (s float64) { 103 | return 2 104 | } 105 | 106 | // ExponentialExKurt returns the excess kurtosis of the Exponential distribution. 107 | func ExponentialExKurt(λ float64) float64 { 108 | return 6 109 | } 110 | 111 | // ExponentialMGF returns the moment-generating function of the Exponential distribution. 112 | func ExponentialMGF(λ, p, t float64) float64 { 113 | return 1 / (1 - t/λ) 114 | } 115 | -------------------------------------------------------------------------------- /dst/gamma_aux_ln.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Gamma distribution, helper functions, log versions. 6 | 7 | func pgamma_raw_ln(x, shape float64) float64 { 8 | // Here, assume that (x, shape) are not NA & shape > 0 . 9 | var res, sum float64 10 | 11 | if x <= 0 { 12 | return negInf 13 | } 14 | 15 | if x >= posInf { 16 | return 0 17 | } 18 | 19 | if x < 1 { 20 | res = pgamma_smallx_ln(x, shape) 21 | } else if x <= shape-1 && x < 0.8*(shape+50) { 22 | // incl. large shape compared to x 23 | sum = log(pd_upper_series(x, shape)) // = x/shape + o(x/shape) 24 | d := dpois_wrap_ln(shape, x) 25 | 26 | // res = log_p ? sum + d : sum * d 27 | res = sum + d 28 | 29 | } else if shape-1 < x && shape < 0.8*(x+50) { 30 | // incl. large x compared to shape 31 | 32 | d := dpois_wrap_ln(shape, x) 33 | if shape < 1 { 34 | if x*eps64 > 1-shape { 35 | // sum = R_D__1 36 | sum = 0 37 | } else { 38 | f := pd_lower_cf(shape, x-(shape-1)) * x / shape 39 | // = [shape/(x - shape+1) + o(shape/(x-shape+1))] * x/shape = 1 + o(1) 40 | // sum = log_p ? log (f) : f 41 | 42 | sum = log(f) 43 | } 44 | } else { 45 | sum = pd_lower_series(x, shape-1) // = (shape-1)/x + o((shape-1)/x) 46 | 47 | // sum = log_p ? log1p (sum) : 1 + sum 48 | sum = log1p(sum) 49 | 50 | } 51 | // res = log_p ? R_Log1_Exp (d + sum) : 1 - d * sum 52 | res = log1Exp(d + sum) 53 | 54 | } else { /* x >= 1 and x fairly near shape. */ 55 | res = ppois_asymp(shape-1, x, true) 56 | } 57 | return res 58 | } 59 | 60 | // Abramowitz and Stegun 6.5.29 [right] 61 | func pgamma_smallx_ln(x, shape float64) float64 { 62 | var term, f2 float64 63 | sum := 0.0 64 | c := shape 65 | n := 0.0 66 | 67 | // Relative to 6.5.29 all terms have been multiplied by shape 68 | // and the first, thus being 1, is omitted. 69 | term = 1e32 // just to enter the while loop 70 | for abs(term) > eps64*abs(sum) { 71 | n++ 72 | c *= -x / n 73 | term = c / (shape + n) 74 | sum += term 75 | } 76 | 77 | f1 := log1p(sum) 78 | 79 | if shape > 1 { 80 | f2 = dpois_raw_ln(shape, x) 81 | f2 = f2 + x 82 | } else { 83 | f2 = shape*log(x) - lgamma1p(shape) 84 | } 85 | return f1 + f2 86 | } 87 | 88 | func dpois_wrap_ln(x_plus_1, lambda float64) float64 { 89 | if isInf(lambda, 0) { 90 | return negInf 91 | } 92 | 93 | if x_plus_1 > 1 { 94 | return dpois_raw_ln(x_plus_1-1, lambda) 95 | 96 | } 97 | 98 | if lambda > abs(x_plus_1-1)*M_cutoff { 99 | return -lambda - lgammafn(x_plus_1) 100 | } 101 | 102 | d := dpois_raw_ln(x_plus_1, lambda) 103 | return d + log(x_plus_1/lambda) 104 | } 105 | 106 | func dpois_raw_ln(x, lambda float64) float64 { 107 | // x >= 0 ; integer for dpois(), but not e.g. for pgamma()! 108 | // lambda >= 0 109 | 110 | if lambda == 0 { 111 | if x == 0 { 112 | return 0 113 | } else { 114 | return negInf 115 | } 116 | } 117 | 118 | if isInf(lambda, 0) { 119 | return negInf 120 | } 121 | 122 | if x < 0 { 123 | return negInf 124 | } 125 | 126 | if x <= lambda*min64 { 127 | return -lambda 128 | } 129 | 130 | if lambda < x*min64 { 131 | return -lambda + x*log(lambda) - lgammafn(x+1) 132 | } 133 | 134 | return -0.5*log((π+π)*x) + (-stirlerr(x) - bd0(x, lambda)) 135 | } 136 | -------------------------------------------------------------------------------- /dst/geom0.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Geometric distribution (type 0). 6 | // The probability distribution of the number Y = X − 1 of failures before the first success, supported on the set { 0, 1, 2, 3, ... } 7 | // Parameters: 8 | // ρ ∈ (0, 1] probability of success in each trial 9 | // Support: 10 | // k ∈ {0, ... , n} 11 | 12 | // GeometricPMF returns the PMF of the Geometric distribution. 13 | func GeometricPMF(ρ float64) func(k int64) float64 { 14 | return func(k int64) float64 { return ρ * pow(1-ρ, float64(k)) } 15 | } 16 | 17 | // GeometricLnPMF returns the natural logarithm of the PMF of the Geometric distribution. 18 | func GeometricLnPMF(ρ float64) func(k int64) float64 { 19 | return func(k int64) float64 { return log(1-ρ) + float64(k)*log(ρ) } 20 | } 21 | 22 | // GeometricPMFAt returns the value of PMF of Geometric distribution at k. 23 | func GeometricPMFAt(ρ float64, k int64) float64 { 24 | pmf := GeometricPMF(ρ) 25 | return pmf(k) 26 | } 27 | 28 | // GeometricCDF returns the value of CDF of the Geometric distribution, at k. 29 | func GeometricCDF(ρ float64) func(k int64) float64 { 30 | return func(k int64) float64 { 31 | if k < 0 { 32 | return NaN 33 | } 34 | return 1 - pow(1-ρ, float64(k+1)) 35 | } 36 | } 37 | 38 | // GeometricCDFAt returns the value of CDF of the Geometric distribution, at x. 39 | func GeometricCDFAt(ρ float64, k int64) float64 { 40 | cdf := GeometricCDF(ρ) 41 | return cdf(k) 42 | } 43 | 44 | /* Not tested, looking strange, commented out, waiting for revision 45 | // GeometricNext returns random number drawn from the Geometric distribution. 46 | //GeometricNext(ρ) => # of GeometricNext(ρ) failures before one success 47 | func GeometricNext(ρ float64) int64 { 48 | if GeometricNext(ρ) == 1 { 49 | return 1 + GeometricNext(ρ) 50 | } 51 | return 0 52 | } 53 | 54 | // Geometric returns the random number generator with Geometric distribution. 55 | func Geometric(ρ float64) func() int64 { return func() int64 { return GeometricNext(ρ) } } 56 | */ 57 | 58 | // GeometricMean returns the mean of the Geometric distribution. 59 | func GeometricMean(ρ float64) float64 { 60 | return (1 - ρ) / ρ 61 | } 62 | 63 | /* to be implemented 64 | // GeometricMedian returns the median of the Geometric distribution. 65 | func GeometricMedian(ρ float64) float64 { 66 | return floor(float64(n)*p) 67 | } 68 | */ 69 | 70 | // GeometricMode returns the mode of the Geometric distribution. 71 | func GeometricMode(ρ float64) float64 { 72 | return 0 73 | } 74 | 75 | // GeometricVar returns the variance of the Geometric distribution. 76 | func GeometricVar(ρ float64) float64 { 77 | return (1 - ρ) / (ρ * ρ) 78 | } 79 | 80 | // GeometricStd returns the standard deviation of the Geometric distribution. 81 | func GeometricStd(ρ float64) float64 { 82 | return sqrt(1-ρ) / ρ 83 | } 84 | 85 | // GeometricSkew returns the skewness of the Geometric distribution. 86 | func GeometricSkew(ρ float64) float64 { 87 | return (2 - ρ) / sqrt(1-ρ) 88 | } 89 | 90 | // GeometricExKurt returns the excess kurtosis of the Geometric distribution. 91 | func GeometricExKurt(ρ float64) float64 { 92 | return 6 + (ρ*ρ)/(1-ρ) 93 | } 94 | 95 | // GeometricMGF returns the moment-generating function of the Geometric distribution. 96 | func GeometricMGF(ρ, t float64) float64 { 97 | return ρ / (1 - (1-ρ)*exp(t)) 98 | } 99 | -------------------------------------------------------------------------------- /dst/geom1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Geometric distribution (type 1). 6 | // The probability distribution of the number Y = X − 1 of failures before the first success, supported on the set {1, 2, 3, ... } 7 | // Parameters: 8 | // ρ ∈ (0, 1] probability of success in each trial 9 | // Support: 10 | // k ∈ {1, ... , n} 11 | 12 | // Geometric1PMF returns the PMF of the Geometric1 distribution. 13 | func Geometric1PMF(ρ float64) func(k int64) float64 { 14 | return func(k int64) float64 { return ρ * pow(1-ρ, float64(k-1)) } 15 | } 16 | 17 | // Geometric1LnPMF returns the natural logarithm of the PMF of the Geometric distribution (type 1). 18 | func Geometric1LnPMF(ρ float64) func(k int64) float64 { 19 | return func(k int64) float64 { return log(1-ρ) + float64(k-1)*log(ρ) } 20 | } 21 | 22 | // Geometric1PMFAt returns the value of PMF of Geometric distribution (type 1) at k. 23 | func Geometric1PMFAt(ρ float64, k int64) float64 { 24 | pmf := Geometric1PMF(ρ) 25 | return pmf(k) 26 | } 27 | 28 | // Geometric1CDF returns the value of CDF of the Geometric distribution (type 1). 29 | func Geometric1CDF(ρ float64) func(k int64) float64 { 30 | return func(k int64) float64 { 31 | if k < 0 { 32 | return NaN 33 | } 34 | return 1 - pow(1-ρ, float64(k)) 35 | } 36 | } 37 | 38 | // Geometric1CDFAt returns the value of CDF of the Geometric distribution (type 1) at k. 39 | func Geometric1CDFAt(ρ float64, k int64) float64 { 40 | cdf := Geometric1CDF(ρ) 41 | return cdf(k) 42 | } 43 | 44 | /* Not tested, looking strange, commented out, waiting for revision 45 | // Geometric1Next returns random number drawn from the Geometric distribution (type 1). 46 | //Geometric1Next(ρ) => # of Geometric1Next(ρ) failures before one success 47 | func Geometric1Next(ρ float64) int64 { 48 | if Geometric1Next(ρ) == 1 { 49 | return 1 + Geometric1Next(ρ) 50 | } 51 | return 0 52 | } 53 | 54 | // Geometric1 returns the random number generator with Geometric distribution (type 1). 55 | func Geometric1(ρ float64) func() int64 { return func() int64 { return Geometric1Next(ρ) } } 56 | */ 57 | 58 | // Geometric1Mean returns the mean of the Geometric distribution (type 1). 59 | func Geometric1Mean(ρ float64) float64 { 60 | return 1 / ρ 61 | } 62 | 63 | /* to be implemented 64 | // Geometric1Median returns the median of the Geometric distribution (type 1). 65 | func Geometric1Median(ρ float64) float64 { 66 | return floor(float64(n)*p) 67 | } 68 | */ 69 | 70 | // Geometric1Mode returns the mode of the Geometric distribution (type 1). 71 | func Geometric1Mode(ρ float64) float64 { 72 | return 1 73 | } 74 | 75 | // Geometric1Var returns the variance of the Geometric distribution (type 1). 76 | func Geometric1Var(ρ float64) float64 { 77 | return (1 - ρ) / (ρ * ρ) 78 | } 79 | 80 | // Geometric1Std returns the standard deviation of the Geometric distribution (type 1). 81 | func Geometric1Std(ρ float64) float64 { 82 | return sqrt(1-ρ) / ρ 83 | } 84 | 85 | // Geometric1Skew returns the skewness of the Geometric distribution (type 1). 86 | func Geometric1Skew(ρ float64) float64 { 87 | return (2 - ρ) / sqrt(1-ρ) 88 | } 89 | 90 | // Geometric1ExKurt returns the excess kurtosis of the Geometric distribution (type 1). 91 | func Geometric1ExKurt(ρ float64) float64 { 92 | return 6 + (ρ*ρ)/(1-ρ) 93 | } 94 | 95 | // Geometric1MGF returns the moment-generating function of the Geometric distribution (type 1). 96 | func Geometric1MGF(ρ, t float64) float64 { 97 | if t >= -log(1-ρ) { 98 | return NaN 99 | } 100 | return ρ * exp(t) / (1 - (1-ρ)*exp(t)) 101 | } 102 | -------------------------------------------------------------------------------- /dst/iwishart.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Inverse-Wishart distribution (not to be confused with Inverse CDF of Wishart distribution). 6 | // The inverse Wishart distribution, also called the inverted Wishart distribution, is a probability distribution defined on real-valued positive-definite matrices. In Bayesian statistics it is used as the conjugate prior for the covariance matrix of a multivariate normal distribution. 7 | // 8 | // Parameters: 9 | // n > p-1 degrees of freedom (real) 10 | // Ψ >0 inverse scale matrix (positive definite) 11 | // 12 | // Support: 13 | // X is positive definite 14 | 15 | import ( 16 | m "github.com/skelterjohn/go.matrix" 17 | ) 18 | 19 | // InverseWishartPDF returns the PDF of the Inverse-Wishart distribution. 20 | func InverseWishartPDF(n int, Ψ *m.DenseMatrix) func(B *m.DenseMatrix) float64 { 21 | p := Ψ.Rows() 22 | Ψdet := Ψ.Det() 23 | normalization := pow(Ψdet, -0.5*float64(n)) * 24 | pow(2, -0.5*float64(n*p)) / 25 | Γ(float64(n)/2) 26 | return func(B *m.DenseMatrix) float64 { 27 | Bdet := B.Det() 28 | Binv, _ := B.Inverse() 29 | ΨBinv, _ := Ψ.Times(Binv) 30 | return normalization * 31 | pow(Bdet, -.5*float64(n+p+1)) * 32 | exp(-0.5*ΨBinv.Trace()) 33 | } 34 | } 35 | 36 | // InverseWishartLnPDF returns the natural logarithm of the PDF of the Inverse-Wishart distribution. 37 | func InverseWishartLnPDF(n int, Ψ *m.DenseMatrix) func(W *m.DenseMatrix) float64 { 38 | p := Ψ.Rows() 39 | Ψdet := Ψ.Det() 40 | normalization := log(Ψdet)*-0.5*float64(n) + 41 | log(2)*-0.5*float64(n*p) - 42 | LnΓ(float64(n)/2) 43 | return func(B *m.DenseMatrix) float64 { 44 | Bdet := B.Det() 45 | Binv, _ := B.Inverse() 46 | ΨBinv, _ := Ψ.Times(Binv) 47 | return normalization + 48 | log(Bdet)*-.5*float64(n+p+1) + 49 | -0.5*ΨBinv.Trace() 50 | } 51 | } 52 | 53 | // InverseWishartNext returns random number drawn from the Inverse-Wishart distribution. 54 | func InverseWishartNext(n int, V *m.DenseMatrix) *m.DenseMatrix { 55 | return InverseWishart(n, V)() 56 | } 57 | 58 | // InverseWishart returns the random number generator with Inverse-Wishart distribution. 59 | func InverseWishart(n int, V *m.DenseMatrix) func() *m.DenseMatrix { 60 | p := V.Rows() 61 | zeros := m.Zeros(p, 1) 62 | rowGen := MVNormal(zeros, V) 63 | return func() *m.DenseMatrix { 64 | x := make([][]float64, n) 65 | for i := 0; i < n; i++ { 66 | x[i] = rowGen().Array() 67 | } 68 | X := m.MakeDenseMatrixStacked(x) 69 | S, _ := X.Transpose().TimesDense(X) 70 | Sinv, _ := S.Inverse() 71 | return Sinv 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /dst/lognormal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Log-normal () distribution is a continuous probability distribution of a random variable whose logarithm is normally distributed. If X is a random variable with a normal distribution, then Y = exp(X) has a log-normal distribution; likewise, if Y is log-normally distributed, then X = log(Y) has a normal distribution. 6 | // 7 | // Parameters: 8 | // μ ∈ R (location) 9 | // σ > 0 standard deviation (scale) 10 | // 11 | // Support: 12 | // x ∈ R 13 | 14 | import ( 15 | 16 | // "math/rand" 17 | ) 18 | 19 | // LogNormalPDF returns the PDF of the LogNormal distribution. 20 | func LogNormalPDF(μ, σ float64) func(x float64) float64 { 21 | normalogormalizer := 0.3989422804014327 / σ 22 | return func(x float64) float64 { return normalogormalizer * exp(-1*(log(x)-μ)*(log(x)-μ)/(2*σ*σ)) / x } 23 | } 24 | 25 | // LogNormalPDFAt returns the value of PDF of LogNormal distribution at x. 26 | func LogNormalPDFAt(μ, σ, x float64) float64 { 27 | pdf := LogNormalPDF(μ, σ) 28 | return pdf(x) 29 | } 30 | 31 | // LogNormalCDF returns the CDF of the LogNormal distribution. 32 | func LogNormalCDF(μ, σ float64) func(x float64) float64 { 33 | return func(x float64) float64 { return ((1.0 / 2.0) * (1 + erf((log(x)-μ)/(σ*sqrt2)))) } 34 | } 35 | 36 | // LogNormalCDFAt returns the value of CDF of the LogNormal distribution, at x. 37 | func LogNormalCDFAt(μ, σ, x float64) float64 { 38 | cdf := LogNormalCDF(μ, σ) 39 | return cdf(x) 40 | } 41 | 42 | // LogNormalQtl returns the inverse of the CDF (quantile) of the LogNormal distribution. 43 | func LogNormalQtl(μ, σ float64) func(p float64) float64 { 44 | return func(p float64) float64 { 45 | return exp(σ*ZQtlFor(p) + μ) 46 | } 47 | } 48 | 49 | // LogNormalQtlFor returns the inverse of the CDF (quantile) of the LogNormal distribution, for given probability. 50 | func LogNormalQtlFor(μ, σ, p float64) float64 { 51 | qtl := LogNormalQtl(μ, σ) 52 | return qtl(p) 53 | } 54 | 55 | // LogNormalNext returns random number drawn from the LogNormal distribution. 56 | func LogNormalNext(μ, σ float64) float64 { return exp(NormalNext(μ, σ)) } 57 | 58 | // LogNormal returns the random number generator with LogNormal distribution. 59 | func LogNormal(μ, σ float64) func() float64 { 60 | return func() float64 { return LogNormalNext(μ, σ) } 61 | } 62 | 63 | // LogNormalMean returns the mean of the LogNormal distribution. 64 | func LogNormalMean(μ, σ float64) float64 { 65 | return exp(μ + σ*σ/2) 66 | } 67 | 68 | // LogNormalMode returns the mode of the LogNormal distribution. 69 | func LogNormalMode(μ, σ float64) float64 { 70 | return exp(μ - σ*σ) 71 | } 72 | 73 | // LogNormalMedian returns the median of the LogNormal distribution. 74 | func LogNormalMedian(μ, σ float64) float64 { 75 | return exp(μ) 76 | } 77 | 78 | // LogNormalVar returns the variance of the LogNormal distribution. 79 | func LogNormalVar(μ, σ float64) float64 { 80 | return exp(σ*σ) - 1*exp(2*μ+σ*σ) 81 | } 82 | 83 | // LogNormalStd returns the standard deviation of the LogNormal distribution. 84 | func LogNormalStd(μ, σ float64) float64 { 85 | return sqrt(LogNormalVar(μ, σ)) 86 | } 87 | 88 | // LogNormalSkew returns the skewness of the LogNormal distribution. 89 | func LogNormalSkew(μ, σ float64) float64 { 90 | return exp(σ*σ) + 2*sqrt(exp(σ*σ)-1) 91 | } 92 | 93 | // LogNormalExKurt returns the excess kurtosis of the LogNormal distribution. 94 | func LogNormalExKurt(μ, σ float64) float64 { 95 | return exp(4*σ*σ) + 2*exp(3*σ*σ) + 3*exp(2*σ*σ) - 6 96 | } 97 | -------------------------------------------------------------------------------- /dst/matrix_normal.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "fmt" 5 | mx "github.com/skelterjohn/go.matrix" 6 | ) 7 | 8 | func checkMatrixNormal(M, Omega, Sigma *mx.DenseMatrix) { 9 | p := M.Rows() 10 | m := M.Cols() 11 | if Omega.Rows() != p { 12 | panic(fmt.Sprintf("Omega.Rows != M.Rows, %d != %d", Omega.Rows(), p)) 13 | } 14 | if Omega.Cols() != Omega.Rows() { 15 | panic("Omega is not square") 16 | } 17 | if Sigma.Rows() != m { 18 | panic(fmt.Sprintf("Sigma.Cols != M.Cols, %d != %d", Sigma.Cols(), m)) 19 | } 20 | if Sigma.Cols() != Sigma.Rows() { 21 | panic("Sigma is not square") 22 | } 23 | } 24 | 25 | /* 26 | M is the mean, Omega is the row covariance, Sigma is the column covariance. 27 | */ 28 | func MatrixNormalPDF(M, Omega, Sigma *mx.DenseMatrix) func(A *mx.DenseMatrix) float64 { 29 | checkMatrixNormal(M, Omega, Sigma) 30 | pf := float64(M.Rows()) 31 | mf := float64(M.Cols()) 32 | 33 | norm := pow(2*π, -0.5*mf*pf) 34 | norm *= pow(Omega.Det(), -0.5*mf) 35 | norm *= pow(Sigma.Det(), -0.5*pf) 36 | 37 | return func(X *mx.DenseMatrix) (p float64) { 38 | p = norm 39 | 40 | sinv, err := Sigma.Inverse() 41 | if err != nil { 42 | panic(err) 43 | } 44 | oinv, err := Omega.Inverse() 45 | if err != nil { 46 | panic(err) 47 | } 48 | diff, err := X.MinusDense(M) 49 | if err != nil { 50 | panic(err) 51 | } 52 | inner := oinv 53 | 54 | inner, err = inner.TimesDense(diff.Transpose()) 55 | if err != nil { 56 | panic(err) 57 | } 58 | 59 | inner, err = inner.TimesDense(sinv) 60 | if err != nil { 61 | panic(err) 62 | } 63 | 64 | inner, err = inner.TimesDense(diff) 65 | if err != nil { 66 | panic(err) 67 | } 68 | 69 | innerTrace := inner.Trace() 70 | 71 | p *= exp(-0.5 * innerTrace) 72 | 73 | return 74 | } 75 | } 76 | func MatrixNormalLnPDF(M, Omega, Sigma *mx.DenseMatrix) func(A *mx.DenseMatrix) float64 { 77 | checkMatrixNormal(M, Omega, Sigma) 78 | 79 | pf := float64(M.Rows()) 80 | mf := float64(M.Cols()) 81 | 82 | sinv, err := Sigma.Inverse() 83 | if err != nil { 84 | panic(err) 85 | } 86 | oinv, err := Omega.Inverse() 87 | if err != nil { 88 | panic(err) 89 | } 90 | 91 | norm := (2 * π) * (-0.5 * mf * pf) 92 | norm += Omega.Det() * (-0.5 * mf) 93 | norm += Sigma.Det() * (-0.5 * pf) 94 | 95 | return func(X *mx.DenseMatrix) (lp float64) { 96 | lp = norm 97 | diff, err := X.MinusDense(M) 98 | if err != nil { 99 | panic(err) 100 | } 101 | inner := oinv 102 | 103 | inner, err = inner.TimesDense(diff.Transpose()) 104 | if err != nil { 105 | panic(err) 106 | } 107 | 108 | inner, err = inner.TimesDense(sinv) 109 | if err != nil { 110 | panic(err) 111 | } 112 | 113 | inner, err = inner.TimesDense(diff) 114 | if err != nil { 115 | panic(err) 116 | } 117 | 118 | innerTrace := inner.Trace() 119 | 120 | lp += -0.5 * innerTrace 121 | 122 | return 123 | } 124 | } 125 | func MatrixNormal(M, Omega, Sigma *mx.DenseMatrix) func() (X *mx.DenseMatrix) { 126 | checkMatrixNormal(M, Omega, Sigma) 127 | 128 | Mv := mx.Vectorize(M) 129 | Cov := mx.Kronecker(Omega, Sigma) 130 | normal := MVNormal(Mv, Cov) 131 | return func() (X *mx.DenseMatrix) { 132 | Xv := normal() 133 | X = mx.Unvectorize(Xv, M.Rows(), M.Cols()) 134 | return 135 | } 136 | } 137 | func MatrixNormalNext(M, Omega, Sigma *mx.DenseMatrix) (X *mx.DenseMatrix) { 138 | return MatrixNormal(M, Omega, Sigma)() 139 | } 140 | -------------------------------------------------------------------------------- /dst/mv_normal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Multivariate normal distribution. 6 | // The multivariate normal distribution or multivariate Gaussian distribution, is a generalization of the one-dimensional (univariate) normal distribution to higher dimensions. One possible definition is that a random vector is said to be k-variate normally distributed if every linear combination of its k components has a univariate normal distribution. However, its importance derives mainly from the multivariate central limit theorem. The multivariate normal distribution is often used to describe, at least approximately, any set of (possibly) correlated real-valued random variables each of which clusters around a mean value. 7 | // 8 | // Parameters: 9 | // μ ∈ ℝk (Rk) location 10 | // Σ ∈ ℝk✕k (Rkxk) covariance (nonnegative-definite matrix) 11 | // 12 | // Support: 13 | // x ∈ μ+span(Σ) ⊆ ℝk 14 | 15 | import ( 16 | . "github.com/skelterjohn/go.matrix" 17 | ) 18 | 19 | // MVNormalPDF returns the PDF of the Multivariate normal distribution. 20 | func MVNormalPDF(μ *DenseMatrix, Σ *DenseMatrix) func(x *DenseMatrix) float64 { 21 | p := μ.Rows() 22 | backμ := μ.DenseMatrix() 23 | backμ.Scale(-1) 24 | 25 | Σdet := Σ.Det() 26 | ΣdetRt := sqrt(Σdet) 27 | Σinv, _ := Σ.Inverse() 28 | 29 | normalization := pow(2*π, -float64(p)/2) / ΣdetRt 30 | 31 | return func(x *DenseMatrix) float64 { 32 | δ, _ := x.PlusDense(backμ) 33 | tmp := δ.Transpose() 34 | tmp, _ = tmp.TimesDense(Σinv) 35 | tmp, _ = tmp.TimesDense(δ) 36 | f := tmp.Get(0, 0) 37 | return normalization * exp(-f/2) 38 | } 39 | } 40 | 41 | // MVNormalNext returns random number drawn from the Multivariate normal distribution. 42 | func MVNormalNext(μ *DenseMatrix, Σ *DenseMatrix) *DenseMatrix { 43 | n := μ.Rows() 44 | x := Zeros(n, 1) 45 | for i := 0; i < n; i++ { 46 | x.Set(i, 0, NormalNext(0, 1)) 47 | } 48 | C, err := Σ.Cholesky() 49 | Cx, err := C.TimesDense(x) 50 | μCx, err := μ.PlusDense(Cx) 51 | if err != nil { 52 | panic(err) 53 | } 54 | return μCx 55 | } 56 | 57 | // MVNormal returns the random number generator with Multivariate normal distribution. 58 | func MVNormal(μ *DenseMatrix, Σ *DenseMatrix) func() *DenseMatrix { 59 | C, _ := Σ.Cholesky() 60 | n := μ.Rows() 61 | return func() *DenseMatrix { 62 | x := Zeros(n, 1) 63 | for i := 0; i < n; i++ { 64 | x.Set(i, 0, NormalNext(0, 1)) 65 | } 66 | Cx, _ := C.TimesDense(x) 67 | MCx, _ := μ.PlusDense(Cx) 68 | return MCx 69 | } 70 | } 71 | 72 | // MVNormalMean returns the mean of the Multivariate normal distribution. 73 | func MVNormalMean(μ *DenseMatrix, Σ *DenseMatrix) *DenseMatrix { 74 | return μ 75 | } 76 | 77 | // MVNormalMode returns the mode of the Multivariate normal distribution. 78 | func MVNormalMode(μ *DenseMatrix, Σ *DenseMatrix) *DenseMatrix { 79 | return μ 80 | } 81 | 82 | // MVNormalVar returns the variance of the Multivariate normal distribution. 83 | func MVNormalVar(μ *DenseMatrix, Σ *DenseMatrix) *DenseMatrix { 84 | return Σ 85 | } 86 | -------------------------------------------------------------------------------- /dst/pareto_tap.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Tapered Pareto distribution. 6 | // 7 | // Parameters: 8 | // θ > 0.0 (scale) "a" 9 | // α > 0.0 (shape) "lambda" 10 | // taper > 0.0 (tapering) 11 | // 12 | // Support: 13 | // x >= θ 14 | // inspired by R:PtProcess 15 | 16 | import ( 17 | "math/rand" 18 | ) 19 | 20 | // ParetoTapChkParams checks parameters of the Tapered Pareto distribution. 21 | func ParetoTapChkParams(θ, α, taper float64) bool { 22 | ok := true 23 | if α <= 0 || θ <= 0 || taper <= 0 { 24 | ok = false 25 | } 26 | return ok 27 | } 28 | 29 | // ParetoTapChkSupport checks support of the Tapered Pareto distribution. 30 | func ParetoTapChkSupport(x float64) bool { 31 | ok := true 32 | if x < 0 { 33 | ok = false 34 | } 35 | return ok 36 | } 37 | 38 | // ParetoTapPDF returns the PDF of the Tapered Pareto distribution. 39 | func ParetoTapPDF(θ, α, taper float64) func(x float64) float64 { 40 | return func(x float64) float64 { 41 | return (α/x + 1/taper) * pow((θ/x), α) * exp((θ-x)/taper) 42 | } 43 | } 44 | 45 | // ParetoTapPDFAt returns the value of PDF of Tapered Pareto distribution at x. 46 | func ParetoTapPDFAt(θ, α, taper, x float64) float64 { 47 | pdf := ParetoTapPDF(θ, α, taper) 48 | return pdf(x) 49 | } 50 | 51 | // ParetoTapCDF returns the CDF of the Tapered Pareto distribution. 52 | func ParetoTapCDF(θ, α, taper float64) func(x float64) float64 { 53 | return func(x float64) float64 { 54 | return 1 - pow(θ/x, α)*exp((θ-x)/taper) 55 | } 56 | } 57 | 58 | // ParetoTapCDFAt returns the value of CDF of the Tapered Pareto distribution, at x. 59 | func ParetoTapCDFAt(θ, α, taper, x float64) float64 { 60 | cdf := ParetoTapCDF(θ, α, taper) 61 | return cdf(x) 62 | } 63 | 64 | // ParetoTapQtl returns the inverse of the CDF (quantile) of the Tapered Pareto distribution. 65 | func ParetoTapQtl(θ, α, taper float64) func(p float64) float64 { 66 | return func(p float64) float64 { 67 | tol := 1e-8 68 | x := θ + 1 69 | 70 | // solve using Newton-Raphson method 71 | for { 72 | delta := (ParetoTapCDFAt(θ, α, taper, x) - p) / ParetoTapPDFAt(θ, α, taper, x) 73 | x -= delta 74 | if abs(delta) < tol { 75 | break 76 | } 77 | } 78 | return x 79 | } 80 | } 81 | 82 | // ParetoTapQtlFor returns the inverse of the CDF (quantile) of the Tapered Pareto distribution, for given probability. 83 | func ParetoTapQtlFor(θ, α, taper, p float64) float64 { 84 | cdf := ParetoTapQtl(θ, α, taper) 85 | return cdf(p) 86 | } 87 | 88 | // ParetoTapNext returns random number drawn from the Tapered Pareto distribution. 89 | func ParetoTapNext(θ, α, taper float64) float64 { 90 | qtl := ParetoTapQtl(θ, α, taper) 91 | p := rand.Float64() 92 | return qtl(p) 93 | } 94 | 95 | // ParetoTap returns the random number generator with Tapered Pareto distribution. 96 | func ParetoTap(θ, α, taper float64) func() float64 { 97 | return func() float64 { return ParetoTapNext(θ, α, taper) } 98 | } 99 | 100 | /* 101 | 102 | func ParetoTapMean(θ, α, taper float64) float64 { 103 | } 104 | 105 | func ParetoTapMedian(θ, α, taper float64) float64 { 106 | } 107 | 108 | func ParetoTapMode(θ, α, taper float64) float64 { 109 | } 110 | 111 | func ParetoTapVar(θ, α, taper float64) float64 { 112 | } 113 | 114 | */ 115 | -------------------------------------------------------------------------------- /dst/planck.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Planck distribution. 6 | // Johnson and Kotz, 1970 7 | // 8 | // Parameters: 9 | // a > 0.0 10 | // b > 0.0 11 | // 12 | // Support: 13 | // x > 0.0 14 | 15 | // PlanckPDF returns the PDF of the Planck distribution. 16 | func PlanckPDF(a, b float64) func(x float64) float64 { 17 | // ζ() waiting for better implementation 18 | ζ := ζ 19 | return func(x float64) float64 { 20 | t1 := pow(b, a+1) 21 | t2 := pow(x, a) 22 | t3 := Γ(a+1) * ζ(a+1) 23 | t4 := exp(b*x) - 1 24 | p := (t1 * t2) / (t3 * t4) 25 | return p 26 | } 27 | } 28 | 29 | // PlanckNext returns random number drawn from the Planck distribution. 30 | // Devroye 1986: 552. 31 | // Devroye, L. 1986: Non-Uniform Random Variate Generation. Springer-Verlag, New York. ISBN 0-387-96305-7. 32 | func PlanckNext(a, b float64) (x float64) { 33 | g := GammaNext(a+1, 1) // OK, consulted with Luc Devroye 34 | z := float64(ZetaNext(a + 1)) 35 | return g / (b * z) 36 | } 37 | 38 | // Planck returns the random number generator with Planck distribution. 39 | func Planck(a, b float64) func() float64 { 40 | return func() float64 { return PlanckNext(a, b) } 41 | } 42 | -------------------------------------------------------------------------------- /dst/range.go: -------------------------------------------------------------------------------- 1 | package dst 2 | 3 | import ( 4 | "math/rand" 5 | ) 6 | 7 | func RangePMF(n int64) func(i int64) float64 { 8 | return func(i int64) float64 { 9 | return fOne / float64(n) 10 | } 11 | } 12 | func LnRangePMF(n int64) func(i int64) float64 { 13 | return func(i int64) float64 { 14 | return -log(float64(n)) 15 | } 16 | } 17 | func RangeNext(n int64) int64 { 18 | return rand.Int63n(n) 19 | } 20 | func Range(n int64) func() int64 { 21 | return func() int64 { 22 | return RangeNext(n) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dst/ratio_gaussian.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Gaussian ratio distribution. 6 | 7 | import ( 8 | "math" 9 | ) 10 | 11 | //GearyHinkleyTransformation transforms the ratio of two normally distributed variables to the transformed variable T would approximately have a standard Gaussian distribution. See Hinkley(1969). 12 | func GearyHinkleyTransformation(z, μX, σX, μY, σY, ρ float64) float64 { 13 | //A Geary–Hinkley transformation, under certain assumptions, returns the transformed variable T that would approximately have a standard Gaussian distribution. The approximation is good if Y is unlikely to assume negative values. 14 | // X = N(μX, σ2X) and Y = N(μY, σ2Y) 15 | // Z = X/Y 16 | // http://en.wikipedia.org/wiki/Ratio_distribution#A_transformation_to_Gaussianity 17 | σ2X := σX * σX 18 | σ2Y := σY * σY 19 | 20 | t1 := μY*z - μX 21 | t2 := math.Sqrt(σ2Y*z*z - 2*ρ*σX*σY*z + σ2X) 22 | return t1 / t2 23 | } 24 | 25 | func phi(x float64) float64 { 26 | return ((1.0 / 2.0) * (1 + erf((x)/(sqrt2)))) 27 | } 28 | 29 | // GaussianRatioNoCorrPDFAt returns the value of PDF of Gaussian Ratio distribution of uncorrelated variables. 30 | func GaussianRatioNoCorrPDF(μX, σX, μY, σY float64) func(z float64) float64 { 31 | return func(z float64) float64 { 32 | σ2X := σX * σX 33 | σ2Y := σY * σY 34 | μ2X := μX * μX 35 | μ2Y := μY * μY 36 | a := math.Sqrt(z*z/σ2X + 1/σ2Y) 37 | b := μX*z/σ2X + μY/σ2Y 38 | c := math.Exp(b*b/(2*a*a) - (μ2X/σ2X+μ2Y/σ2Y)/2) 39 | return b*c/((a*a*a)*math.Sqrt(2*π)*σX*σY)*(2*phi(b/a)-1) + math.Exp(-(μ2X/σ2X+μ2Y/σ2Y)/2)/(a*a*π*σX*σY) 40 | } 41 | } 42 | 43 | // GaussianRatioNoCorrPDFAt returns the value of PDF of Gaussian Ratio distribution of uncorrelated variables, at x. 44 | func GaussianRatioNoCorrPDFAt(μX, σX, μY, σY, x float64) float64 { 45 | pdf := GaussianRatioNoCorrPDF(μX, σX, μY, σY) 46 | return pdf(x) 47 | } 48 | 49 | // GaussianRatioPDF returns the value of PDF of Gaussian Ratio distribution of correlated variables, at x. 50 | func GaussianRatioPDF(μX, σX, μY, σY, ρ float64) func(z float64) float64 { 51 | return func(z float64) float64 { 52 | α := ρ * σX / σY 53 | β := (σX / σY) * math.Sqrt(1-ρ*ρ) 54 | return β / (π*(z-α)*(z-α) + β*β) 55 | 56 | } 57 | } 58 | 59 | // GaussianRatioPDFAt returns the value of PDF of Gaussian Ratio distribution of correlated variables, at x. 60 | func GaussianRatioPDFAt(μX, σX, μY, σY, ρ, x float64) float64 { 61 | pdf := GaussianRatioPDF(μX, σX, μY, σY, ρ) 62 | return pdf(x) 63 | } 64 | 65 | // GaussianRatioApproxCDF returns the approximation of CDF of Gaussian Ratio distribution of correlated variables. 66 | func GaussianRatioApproxCDF(μX, σX, μY, σY, ρ float64) func(z float64) float64 { 67 | // Hinkley 1969:636, Eq. 5 68 | return func(w float64) float64 { 69 | σ2X := σX * σX 70 | σ2Y := σY * σY 71 | 72 | a := math.Sqrt(w*w*σ2X - 2*ρ*w/(σX*σY) + (1 / σ2Y)) 73 | // Hinkley 1969:636, Eq. 2 74 | 75 | t1 := μY*w - μX 76 | t2 := σX * σY * a 77 | return phi(t1 / t2) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /dst/stirlerr.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Computes the log of the error term in Stirling's formula. 6 | func stirlerr(n float64) float64 { 7 | // stirlerr(n) = log(n!) - log( sqrt(2//pi//n)//(n/e)^n ) 8 | // = log Gamma(n+1) - 1/2 // [log(2//pi) + log(n)] - n//[log(n) - 1] 9 | // = log Gamma(n+1) - (n + 1/2) // log(n) + n - log(2//pi)/2 10 | // see also lgammacor() in ./lgammacor.c which computes almost the same! 11 | // 12 | // For n > 15, uses the series 1/12n - 1/360n^3 + ... 13 | // For n <=15, integers or half-integers, uses stored values. 14 | // For other n < 15, uses lgamma directly (don't use this to 15 | // write lgamma!) 16 | // Rewritten from the C code by Catherine Loader, catherine@research.bell-labs.com. 17 | 18 | const ( 19 | S0 = 0.083333333333333333333 // 1/12 20 | S1 = 0.00277777777777777777778 // 1/360 21 | S2 = 0.00079365079365079365079365 // 1/1260 22 | S3 = 0.000595238095238095238095238 // 1/1680 23 | S4 = 0.0008417508417508417508417508 // 1/1188 24 | ) 25 | 26 | // error for 0, 0.5, 1.0, 1.5, ..., 14.5, 15.0. 27 | sferr_halves := [31]float64{ 28 | 0.0, // n=0 - wrong, placeholder only 29 | 0.1534264097200273452913848, // 0.5 30 | 0.0810614667953272582196702, // 1.0 31 | 0.0548141210519176538961390, // 1.5 32 | 0.0413406959554092940938221, // 2.0 33 | 0.03316287351993628748511048, // 2.5 34 | 0.02767792568499833914878929, // 3.0 35 | 0.02374616365629749597132920, // 3.5 36 | 0.02079067210376509311152277, // 4.0 37 | 0.01848845053267318523077934, // 4.5 38 | 0.01664469118982119216319487, // 5.0 39 | 0.01513497322191737887351255, // 5.5 40 | 0.01387612882307074799874573, // 6.0 41 | 0.01281046524292022692424986, // 6.5 42 | 0.01189670994589177009505572, // 7.0 43 | 0.01110455975820691732662991, // 7.5 44 | 0.010411265261972096497478567, // 8.0 45 | 0.009799416126158803298389475, // 8.5 46 | 0.009255462182712732917728637, // 9.0 47 | 0.008768700134139385462952823, // 9.5 48 | 0.008330563433362871256469318, // 10.0 49 | 0.007934114564314020547248100, // 10.5 50 | 0.007573675487951840794972024, // 11.0 51 | 0.007244554301320383179543912, // 11.5 52 | 0.006942840107209529865664152, // 12.0 53 | 0.006665247032707682442354394, // 12.5 54 | 0.006408994188004207068439631, // 13.0 55 | 0.006171712263039457647532867, // 13.5 56 | 0.005951370112758847735624416, // 14.0 57 | 0.005746216513010115682023589, // 14.5 58 | 0.005554733551962801371038690} // 15.0 59 | 60 | var nn float64 61 | 62 | if n <= 15.0 { 63 | nn = n + n 64 | if nn == trunc(nn) { 65 | return (sferr_halves[int(nn)]) 66 | } 67 | return (lgammafn(n+1.) - (n+0.5)*log(n) + n - M_LN_SQRT_2PI) 68 | } 69 | 70 | nn = n * n 71 | if n > 500 { 72 | return (S0 - S1/nn) / n 73 | } 74 | if n > 80 { 75 | return (S0 - (S1-S2/nn)/nn) / n 76 | } 77 | if n > 35 { 78 | return (S0 - (S1-(S2-S3/nn)/nn)/nn) / n 79 | } 80 | // 15 < n <= 35 81 | return (S0 - (S1-(S2-(S3-S4/nn)/nn)/nn)/nn) / n 82 | } 83 | -------------------------------------------------------------------------------- /dst/wishart.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Wishart distribution. 6 | // A generalization to multiple dimensions of the chi-squared distribution, or, in the case of non-integer degrees of freedom, of the gamma distribution. 7 | // Wishart, J. (1928). "The generalised product moment distribution in samples from a normal multivariate population". Biometrika 20A (1-2): 32–52. doi:10.1093/biomet/20A.1-2.32. 8 | // Parameters: 9 | // n > p-1 degrees of freedom (real) 10 | // V > 0 pxp scale matrix (positive definite, real) 11 | // 12 | // Support: 13 | // X pxp positive definite, real 14 | 15 | import ( 16 | m "github.com/skelterjohn/go.matrix" 17 | ) 18 | 19 | // WishartPDF returns the PDF of the Wishart distribution. 20 | func WishartPDF(n int, V *m.DenseMatrix) func(W *m.DenseMatrix) float64 { 21 | p := V.Rows() 22 | Vdet := V.Det() 23 | Vinv, _ := V.Inverse() 24 | normalization := pow(2, -0.5*float64(n*p)) * 25 | pow(Vdet, -0.5*float64(n)) / 26 | Γ(0.5*float64(n)) 27 | return func(W *m.DenseMatrix) float64 { 28 | VinvW, _ := Vinv.Times(W) 29 | return normalization * pow(W.Det(), 0.5*float64(n-p-1)) * 30 | exp(-0.5*VinvW.Trace()) 31 | } 32 | } 33 | 34 | // WishartLnPDF returns the natural logarithm of the PDF of the Wishart distribution. 35 | func WishartLnPDF(n int, V *m.DenseMatrix) func(W *m.DenseMatrix) float64 { 36 | 37 | p := V.Rows() 38 | Vdet := V.Det() 39 | Vinv, _ := V.Inverse() 40 | normalization := log(2)*(-0.5*float64(n*p)) + 41 | log(Vdet)*(-0.5*float64(n)) - 42 | LnΓ(0.5*float64(n)) 43 | return func(W *m.DenseMatrix) float64 { 44 | VinvW, _ := Vinv.Times(W) 45 | return normalization + 46 | log(W.Det())*0.5*float64(n-p-1) - 47 | 0.5*VinvW.Trace() 48 | } 49 | } 50 | 51 | // WishartNext returns random number drawn from the Wishart distribution. 52 | func WishartNext(n int, V *m.DenseMatrix) *m.DenseMatrix { 53 | return Wishart(n, V)() 54 | } 55 | 56 | // Wishart returns the random number generator with Wishart distribution. 57 | func Wishart(n int, V *m.DenseMatrix) func() *m.DenseMatrix { 58 | p := V.Rows() 59 | zeros := m.Zeros(p, 1) 60 | rowGen := MVNormal(zeros, V) 61 | return func() *m.DenseMatrix { 62 | x := make([][]float64, n) 63 | for i := 0; i < n; i++ { 64 | x[i] = rowGen().Array() 65 | } 66 | X := m.MakeDenseMatrixStacked(x) 67 | S, _ := X.Transpose().TimesDense(X) 68 | return S 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /dst/yule.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Yule–Simon distribution. 6 | // Yule, G. U. (1925). "A Mathematical Theory of Evolution, based on the Conclusions of Dr. J. C. Willis, F.R.S". Philosophical Transactions of the Royal Society of London, Ser. B 213 (402–410): 21–87. doi:10.1098/rstb.1925.0002 7 | // Simon, H. A. (1955). "On a class of skew distribution functions". Biometrika 42 (3–4): 425–440. doi:10.1093/biomet/42.3-4.425 8 | // 9 | // Parameters: 10 | // a > 0 shape (real) 11 | // 12 | // Support: 13 | // k ∈ {1, 2, ... } 14 | 15 | // YulePMF returns the PMF of the Yule–Simon distribution. 16 | func YulePMF(a float64) func(k int64) float64 { 17 | return func(k int64) float64 { 18 | p := a * B(a+1, float64(k)) 19 | return p 20 | } 21 | } 22 | 23 | // YulePMFAt returns the value of PMF of Yule–Simon distribution at k. 24 | func YulePMFAt(a float64, k int64) float64 { 25 | pmf := YulePMF(a) 26 | return pmf(k) 27 | } 28 | 29 | // YuleCDF returns the CDF of the Yule–Simon distribution. 30 | func YuleCDF(a float64) func(k int64) float64 { 31 | return func(k int64) float64 { 32 | kk := float64(k) 33 | p := 1 - kk*B(kk, a+1) 34 | return p 35 | } 36 | } 37 | 38 | // YuleCDFAt returns the value of CDF of the Yule–Simon distribution, at x. 39 | func YuleCDFAt(a float64, k int64) float64 { 40 | cdf := YuleCDF(a) 41 | return cdf(k) 42 | } 43 | 44 | // YuleNext returns random number drawn from the Yule–Simon distribution. 45 | func YuleNext(a float64) (k int64) { 46 | // Devroye 1986: 553. 47 | // Devroye, L. 1986: Non-Uniform Random Variate Generation. Springer-Verlag, New York. ISBN 0-387-96305-7. 48 | e1 := ExponentialNext(2) 49 | e2 := ExponentialNext(2) 50 | k = int64(ceil(-e1 / (log(1 - exp(-e2/(a-1)))))) 51 | return 52 | } 53 | 54 | // Yule returns the random number generator with Yule–Simon distribution. 55 | func Yule(a float64) func() int64 { 56 | return func() int64 { return YuleNext(a) } 57 | } 58 | 59 | // YuleMean returns the mean of the Yule–Simon distribution. 60 | func YuleMean(a float64) float64 { 61 | if a <= 1 { 62 | return NaN 63 | } 64 | return a / (a - 1) 65 | } 66 | 67 | // YuleMode returns the mode of the Yule–Simon distribution. 68 | func YuleMode(a float64) float64 { 69 | return 1.00 70 | } 71 | 72 | // YuleVar returns the variance of the Yule–Simon distribution. 73 | func YuleVar(a float64) float64 { 74 | if a <= 2 { 75 | return NaN 76 | } 77 | return a * a / ((a - 1) * (a - 1) * (a - 2)) 78 | } 79 | 80 | // YuleStd returns the standard deviation of the Yule–Simon distribution. 81 | func YuleStd(a float64) float64 { 82 | if a <= 2 { 83 | return NaN 84 | } 85 | return a / ((a - 1) * sqrt(a-2)) 86 | } 87 | 88 | // YuleSkew returns the skewness of the Yule–Simon distribution. 89 | func YuleSkew(a float64) float64 { 90 | if a <= 3 { 91 | return NaN 92 | } 93 | return ((a + 1) * (a + 1) * sqrt(a-2)) / ((a - 3) * a) 94 | } 95 | 96 | // YuleExKurt returns the excess kurtosis of the Yule–Simon distribution. 97 | func YuleExKurt(a float64) float64 { 98 | if a <= 4 { 99 | return NaN 100 | } 101 | return a + 3 + (11*a*a*a-49*a-22)/((a-4)*(a-3)*a) 102 | } 103 | -------------------------------------------------------------------------------- /dst/z.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Standard Normal (or Gaussian, or Gauss-Laplace) distribution. 6 | // A continuous probability distribution, defined on the entire real line, that has a bell-shaped probability density function, known as the Gaussian function. 7 | // 8 | // Parameters: none 9 | // 10 | // Support: 11 | // x ∈ R 12 | 13 | import ( 14 | 15 | // "math/rand" 16 | ) 17 | 18 | // ZPDF returns the PDF of the Standard Normal distribution. 19 | func ZPDF() func(float64) float64 { 20 | return NormalPDF(0, 1) 21 | } 22 | 23 | // ZPDFAt returns the value of PDF of Standard Normal distribution at x. 24 | func ZPDFAt(x float64) float64 { 25 | pdf := NormalPDF(0, 1) 26 | return pdf(x) 27 | } 28 | 29 | // ZCDF returns the CDF of the Standard Normal distribution. 30 | func ZCDF() func(float64) float64 { 31 | return NormalCDF(0, 1) 32 | } 33 | 34 | // ZCDFAt returns the value of CDF of the Standard Normal distribution, at x. 35 | func ZCDFAt(x float64) float64 { 36 | cdf := NormalCDF(0, 1) 37 | return cdf(x) 38 | } 39 | 40 | // ZQtl returns the inverse of the CDF (quantile) of the Standard Normal distribution. 41 | func ZQtl() func(p float64) float64 { 42 | return func(p float64) float64 { 43 | 44 | var r, x, pp, dp float64 45 | 46 | dp = p - 0.5 47 | switch { 48 | case p == 1.0: 49 | return posInf 50 | case p == 0.0: 51 | return negInf 52 | } 53 | if abs(dp) <= 0.425 { 54 | x = small(dp) 55 | return x 56 | } 57 | if p < 0.5 { 58 | pp = p 59 | } else { 60 | pp = 1.0 - p 61 | } 62 | r = sqrt(-log(pp)) 63 | if r <= 5.0 { 64 | x = intermediate(r) 65 | } else { 66 | x = tail(r) 67 | } 68 | if p < 0.5 { 69 | return -x 70 | } 71 | return x 72 | } 73 | } 74 | 75 | // ZQtlFor returns the inverse of the CDF (quantile) of the Standard Normal distribution, for given probability. 76 | func ZQtlFor(p float64) float64 { 77 | qtl := ZQtl() 78 | return qtl(p) 79 | } 80 | -------------------------------------------------------------------------------- /dst/zeta.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Zeta distribution. 6 | // The zeta distribution is equivalent to the Zipf distribution for infinite N. 7 | // 8 | // Parameters: 9 | // s > 1.0 (real) 10 | // 11 | // Support: 12 | // k > 0 (integer) 13 | 14 | import ( 15 | "math/rand" 16 | ) 17 | 18 | // ZetaPMF returns the PMF of the Zeta distribution. 19 | func ZetaPMF(s float64) func(k int64) float64 { 20 | return func(k int64) float64 { 21 | t1 := 1 / pow(float64(k), s) 22 | t2 := ζ(s) 23 | p := t1 / t2 24 | return p 25 | } 26 | } 27 | 28 | // ZetaPMFAt returns the value of PMF of Zeta distribution at k. 29 | func ZetaPMFAt(s float64, k int64) float64 { 30 | pmf := ZetaPMF(s) 31 | return pmf(k) 32 | } 33 | 34 | // ZetaCDF returns the CDF of the Zeta distribution. 35 | func ZetaCDF(s float64) func(k int64) float64 { 36 | return func(k int64) float64 { 37 | t1 := hNum(k, s) 38 | t2 := ζ(s) 39 | p := t1 / t2 40 | return p 41 | } 42 | } 43 | 44 | // ZetaCDFAt returns the value of CDF of the Zeta distribution, at x. 45 | func ZetaCDFAt(s float64, k int64) float64 { 46 | pmf := ZetaCDF(s) 47 | return pmf(k) 48 | } 49 | 50 | // ZetaNext returns random number drawn from the Zeta distribution. 51 | func ZetaNext(s float64) (k int64) { 52 | // Devroye 1986: 550. Called "Zipf distribution" there. 53 | // Devroye, L. 1986: Non-Uniform Random Variate Generation. Springer-Verlag, New York. ISBN 0-387-96305-7. 54 | var x float64 55 | b := pow(2.0, s-1.0) 56 | for { 57 | u := rand.Float64() 58 | v := rand.Float64() 59 | x = floor(pow(u, -1/(s-1))) 60 | t := pow(1+1.0/x, s-1) 61 | delta := v * x * (t - 1.0) / (b - 1.0) 62 | if delta <= (t / b) { 63 | break 64 | } 65 | } 66 | k = int64(x) 67 | return 68 | } 69 | 70 | // Zeta returns the random number generator with Zeta distribution. 71 | func Zeta(s float64) func() int64 { 72 | return func() int64 { return ZetaNext(s) } 73 | } 74 | 75 | // ZetaMean returns the mean of the Zeta distribution. 76 | func ZetaMean(s float64) float64 { 77 | if s <= 2 { 78 | return NaN 79 | } 80 | t1 := ζ(s - 1) 81 | t2 := ζ(s) 82 | return t1 / t2 83 | } 84 | 85 | // ZetaMode returns the mode of the Zeta distribution. 86 | func ZetaMode() float64 { 87 | return 1 88 | } 89 | 90 | // ZetaVar returns the variance of the Zeta distribution. 91 | func ZetaVar(s float64) float64 { 92 | if s <= 3 { 93 | return NaN 94 | } 95 | t1 := ζ(s) 96 | t2 := ζ(s - 2) 97 | t3 := ζ((s - 1) * (s - 1)) 98 | t4 := ζ(s * s) 99 | return (t1*t2 - t3) / t4 100 | } 101 | -------------------------------------------------------------------------------- /dst/zipf-mandelbrot.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package dst 4 | 5 | // Zipf-Mandelbrot distribution. 6 | // For finite n and q == 0 it reduces to Zipf distribution. 7 | // 8 | // Parameters: 9 | // n ∈ {1, 2, 3,, ...} (integer) 10 | // q ∈ [0, ∞) (real) 11 | // s ∈ (0, ∞) (real) 12 | // 13 | // Support: 14 | // k ∈ {1, 2, ... , n} 15 | 16 | // Zipf-Mandelbrot distribution 17 | 18 | import ( 19 | "math/rand" 20 | ) 21 | 22 | // ZipfMandelbrotChkParams checks parameters of the Zipf-Mandelbrot distribution. 23 | func ZipfMandelbrotChkParams(n int64, q, s float64) bool { 24 | v := false 25 | if n > 0 && q >= 0 && s > 0 { 26 | v = true 27 | } 28 | return v 29 | } 30 | 31 | // ZipfMandelbrotPMF returns the PMF of the Zipf-Mandelbrot distribution. 32 | func ZipfMandelbrotPMF(n int64, q, s float64) func(k int64) float64 { 33 | return func(k int64) float64 { 34 | p := 1 / (pow((float64(k)+q), s) * hNumG(n, q, s)) 35 | return p 36 | } 37 | } 38 | 39 | // ZipfMandelbrotPMFAt returns the value of PMF of Zipf-Mandelbrot distribution at k. 40 | func ZipfMandelbrotPMFAt(n int64, q, s float64, k int64) float64 { 41 | pmf := ZipfMandelbrotPMF(n, q, s) 42 | return pmf(k) 43 | } 44 | 45 | // ZipfMandelbrotCDF returns the CDF of the Zipf-Mandelbrot distribution. 46 | func ZipfMandelbrotCDF(n int64, q, s float64) func(k int64) float64 { 47 | return func(k int64) float64 { 48 | p := hNumG(k, q, s) / hNumG(n, q, s) 49 | return p 50 | } 51 | } 52 | 53 | // ZipfMandelbrotCDFAt returns the value of CDF of the Zipf-Mandelbrot distribution, at x. 54 | func ZipfMandelbrotCDFAt(n int64, q, s float64, k int64) float64 { 55 | cdf := ZipfMandelbrotCDF(n, q, s) 56 | return cdf(k) 57 | } 58 | 59 | // Quantile Function for the Zipf-Mandelbrot distribution 60 | func ZipfMandelbrotQtl(n int64, q, s float64) func(p float64) int64 { 61 | return func(p float64) int64 { 62 | var k int64 63 | const kMax = 1e16 64 | cdf := ZipfMandelbrotCDF(n, q, s) 65 | if cdf(1) >= p { 66 | k = 1 67 | } else { 68 | for k = 1; cdf(k) < p; k++ { 69 | if k > kMax { 70 | panic("not found") 71 | } 72 | } 73 | } 74 | return k 75 | } 76 | } 77 | 78 | // ZipfMandelbrotNext returns random number drawn from the Zipf-Mandelbrot distribution. 79 | func ZipfMandelbrotNext(n int64, q, s float64) (k int64) { 80 | qtl := ZipfMandelbrotQtl(n, q, s) 81 | p := rand.Float64() 82 | return qtl(p) 83 | } 84 | 85 | // ZipfMandelbrot returns the random number generator with Zipf-Mandelbrot distribution. 86 | func ZipfMandelbrot(n int64, q, s float64) func() int64 { 87 | return func() int64 { return ZipfMandelbrotNext(n, q, s) } 88 | } 89 | 90 | // ZipfMandelbrotMean returns the mean of the Zipf-Mandelbrot distribution. 91 | func ZipfMandelbrotMean(n int64, q, s float64) float64 { 92 | return hNumG(n, q, s-1)/hNumG(n, q, s) - q 93 | } 94 | -------------------------------------------------------------------------------- /stat/REFERENCES: -------------------------------------------------------------------------------- 1 | Anscombe, F.J., Glynn, W.J. (1983) Distribution of kurtosis statistic for normal statistics. Biometrika, 70 (1): 227-234. 2 | Bonett, D.G., Seier, E. (2002) A test of normality with high uniform power. Computational Statistics and Data Analysis, 40: 435-445. 3 | D’Agostino, R.B. (1970). Transformation to Normality of the Null Distribution of G1. Biometrika,57, 3: 679-681.Geary, R.C. (1936). Moments of the ratio of the mean deviation to the standard deviation for normal samples. Biometrika, 28, 295-307. 4 | Hahn, G. J., Meeker, W. Q. (1991) Statistical Intervals: A Guide for Practitioners. J. Wiley & Sons, New York. 5 | Jarque, C. M., Bera, A. K. (1980) Efficient test for normality, homoscedasticity and serial independence of residuals, Economic Letters, 6 (3): 255-259. 6 | Komsta, L., Novomestky, F. (2013). R Package ‘moments’ http://cran.r-project.org/web/packages/moments/index.html 7 | -------------------------------------------------------------------------------- /stat/_tst/agostino_test.go: -------------------------------------------------------------------------------- 1 | package stat 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:moments:agostino 9 | 10 | func TestSampleAgostino(t *testing.T) { 11 | const delta = 1e-4 12 | 13 | d := []float64{-0.670789480, -0.150969186, -0.551925020, -0.482406038, -1.173156862, 0.367903204, 1.059533774, 1.794411979, -1.895192051, -0.571951213, -0.726043212, 0.627210778, -1.272177905, -0.144797609, -0.968422674, 0.283461379, 0.988415637, 2.475978661, -0.536749821, -0.025513855, -1.534900705, -0.230832466, 0.620245249, 1.495396229, -2.111838253, 0.228080184, 0.251295357, 0.181974246, -0.001878552, -2.085836898, 0.834083317, -1.321850451, 1.192865393, -0.195088801, 1.748176403, 1.780233827, -1.212874246, -0.275506872, -0.474797265, -0.496230943, 1.872632489, 0.165565088, -1.143077239, -0.683540167, -2.029626407, 0.027388799, 0.263192684, -0.637438762, -0.460420680, 0.316033043, -0.166534773, -0.270718891, 0.634184308, -0.302168613, 0.928756911, 0.737386257, -0.546999206, 0.107967686, -0.082850172, -1.895955213, 1.576817423, -0.079801919, 0.382725131, 0.758249530, -2.054212936, -1.285879785, -0.009835473, 0.636242575, 0.169251475, -0.465556922, -0.387162464, -0.172489252, -1.910986672, 2.291340848, 1.499807228, -0.707866084, -0.430782756, -0.943412247, 1.663281221, 0.392045957, -0.006054918, -0.330406096, 0.519286029, 0.700169631, -0.521821484, -0.412689406, 0.814297193, -0.709301954, -0.861132419, -1.471550480, -0.686849429, 0.174766897, -0.333436632, 1.291139538, 0.040605740, -0.399557291, 2.169674201, -1.712460224, 0.377688521, -1.831853999} 14 | fmt.Println("Agostino test two-sided") 15 | alt := 0 16 | a, b, c := Agostino(d, alt) 17 | x, y, z := 0.2013, 0.5719, 0.5674 18 | if abs(x-a) > delta { 19 | fmt.Println("failed skewness: ", a, x) 20 | t.Error() 21 | } 22 | if abs(y-b) > delta { 23 | fmt.Println("failed z: ", b, y) 24 | t.Error() 25 | } 26 | if abs(y-b) > delta { 27 | fmt.Println("failed p-value: ", c, z) 28 | t.Error() 29 | } 30 | 31 | fmt.Println("Agostino test less") 32 | alt = 1 33 | a, b, c = Agostino(d, alt) 34 | x, y, z = 0.2013, 0.5719, 0.2837 35 | if abs(x-a) > delta { 36 | fmt.Println("failed skewness: ", a, x) 37 | t.Error() 38 | } 39 | if abs(y-b) > delta { 40 | fmt.Println("failed z: ", b, y) 41 | t.Error() 42 | } 43 | if abs(y-b) > delta { 44 | fmt.Println("failed p-value: ", c, z) 45 | t.Error() 46 | } 47 | 48 | fmt.Println("Agostino test greater") 49 | alt = 2 50 | a, b, c = Agostino(d, alt) 51 | x, y, z = 0.2013, 0.5719, 0.2837 52 | if abs(x-a) > delta { 53 | fmt.Println("failed skewness: ", a, x) 54 | t.Error() 55 | } 56 | if abs(y-b) > delta { 57 | fmt.Println("failed z: ", b, y) 58 | t.Error() 59 | } 60 | if abs(y-b) > delta { 61 | fmt.Println("failed p-value: ", c, z) 62 | t.Error() 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /stat/_tst/anscombe_test.go: -------------------------------------------------------------------------------- 1 | package stat 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:moments:anscombe 9 | 10 | func TestSampleAnscombe(t *testing.T) { 11 | const delta = 1e-4 12 | 13 | d := []float64{-0.670789480, -0.150969186, -0.551925020, -0.482406038, -1.173156862, 0.367903204, 1.059533774, 1.794411979, -1.895192051, -0.571951213, -0.726043212, 0.627210778, -1.272177905, -0.144797609, -0.968422674, 0.283461379, 0.988415637, 2.475978661, -0.536749821, -0.025513855, -1.534900705, -0.230832466, 0.620245249, 1.495396229, -2.111838253, 0.228080184, 0.251295357, 0.181974246, -0.001878552, -2.085836898, 0.834083317, -1.321850451, 1.192865393, -0.195088801, 1.748176403, 1.780233827, -1.212874246, -0.275506872, -0.474797265, -0.496230943, 1.872632489, 0.165565088, -1.143077239, -0.683540167, -2.029626407, 0.027388799, 0.263192684, -0.637438762, -0.460420680, 0.316033043, -0.166534773, -0.270718891, 0.634184308, -0.302168613, 0.928756911, 0.737386257, -0.546999206, 0.107967686, -0.082850172, -1.895955213, 1.576817423, -0.079801919, 0.382725131, 0.758249530, -2.054212936, -1.285879785, -0.009835473, 0.636242575, 0.169251475, -0.465556922, -0.387162464, -0.172489252, -1.910986672, 2.291340848, 1.499807228, -0.707866084, -0.430782756, -0.943412247, 1.663281221, 0.392045957, -0.006054918, -0.330406096, 0.519286029, 0.700169631, -0.521821484, -0.412689406, 0.814297193, -0.709301954, -0.861132419, -1.471550480, -0.686849429, 0.174766897, -0.333436632, 1.291139538, 0.040605740, -0.399557291, 2.169674201, -1.712460224, 0.377688521, -1.831853999} 14 | fmt.Println("Anscombe test two-sided") 15 | alt := 0 16 | a, b, c := Anscombe(d, alt) 17 | x, y, z := 2.8244, -0.0971, 0.9226 18 | if abs(x-a) > delta { 19 | fmt.Println("failed skewness: ", a, x) 20 | t.Error() 21 | } 22 | if abs(y-b) > delta { 23 | fmt.Println("failed z: ", b, y) 24 | t.Error() 25 | } 26 | if abs(y-b) > delta { 27 | fmt.Println("failed p-value: ", c, z) 28 | t.Error() 29 | } 30 | 31 | fmt.Println("Anscombe test less") 32 | alt = 1 33 | a, b, c = Anscombe(d, alt) 34 | x, y, z = 2.8244, -0.0971, 0.5387 35 | if abs(x-a) > delta { 36 | fmt.Println("failed skewness: ", a, x) 37 | t.Error() 38 | } 39 | if abs(y-b) > delta { 40 | fmt.Println("failed z: ", b, y) 41 | t.Error() 42 | } 43 | if abs(y-b) > delta { 44 | fmt.Println("failed p-value: ", c, z) 45 | t.Error() 46 | } 47 | 48 | fmt.Println("Anscombe test greater") 49 | alt = 2 50 | a, b, c = Anscombe(d, alt) 51 | x, y, z = 2.8244, -0.0971, 0.4613 52 | if abs(x-a) > delta { 53 | fmt.Println("failed skewness: ", a, x) 54 | t.Error() 55 | } 56 | if abs(y-b) > delta { 57 | fmt.Println("failed z: ", b, y) 58 | t.Error() 59 | } 60 | if abs(y-b) > delta { 61 | fmt.Println("failed p-value: ", c, z) 62 | t.Error() 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /stat/_tst/bonett_test.go: -------------------------------------------------------------------------------- 1 | package stat 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:moments:bonett.test 9 | 10 | func TestSampleBonett(t *testing.T) { 11 | const delta = 1e-4 12 | 13 | d := []float64{-0.670789480, -0.150969186, -0.551925020, -0.482406038, -1.173156862, 0.367903204, 1.059533774, 1.794411979, -1.895192051, -0.571951213, -0.726043212, 0.627210778, -1.272177905, -0.144797609, -0.968422674, 0.283461379, 0.988415637, 2.475978661, -0.536749821, -0.025513855, -1.534900705, -0.230832466, 0.620245249, 1.495396229, -2.111838253, 0.228080184, 0.251295357, 0.181974246, -0.001878552, -2.085836898, 0.834083317, -1.321850451, 1.192865393, -0.195088801, 1.748176403, 1.780233827, -1.212874246, -0.275506872, -0.474797265, -0.496230943, 1.872632489, 0.165565088, -1.143077239, -0.683540167, -2.029626407, 0.027388799, 0.263192684, -0.637438762, -0.460420680, 0.316033043, -0.166534773, -0.270718891, 0.634184308, -0.302168613, 0.928756911, 0.737386257, -0.546999206, 0.107967686, -0.082850172, -1.895955213, 1.576817423, -0.079801919, 0.382725131, 0.758249530, -2.054212936, -1.285879785, -0.009835473, 0.636242575, 0.169251475, -0.465556922, -0.387162464, -0.172489252, -1.910986672, 2.291340848, 1.499807228, -0.707866084, -0.430782756, -0.943412247, 1.663281221, 0.392045957, -0.006054918, -0.330406096, 0.519286029, 0.700169631, -0.521821484, -0.412689406, 0.814297193, -0.709301954, -0.861132419, -1.471550480, -0.686849429, 0.174766897, -0.333436632, 1.291139538, 0.040605740, -0.399557291, 2.169674201, -1.712460224, 0.377688521, -1.831853999} 14 | 15 | fmt.Println("Bonett test two-sided") 16 | alt := 0 17 | a, b, c := Bonett(d, alt) 18 | x, y, z := 0.8074, 0.9789, 0.3276 19 | 20 | if abs(x-a) > delta { 21 | fmt.Println("failed skewness: ", a, x) 22 | t.Error() 23 | } 24 | if abs(y-b) > delta { 25 | fmt.Println("failed z: ", b, y) 26 | t.Error() 27 | } 28 | if abs(y-b) > delta { 29 | fmt.Println("failed p-value: ", c, z) 30 | t.Error() 31 | } 32 | 33 | fmt.Println("Bonett test less") 34 | alt = 1 35 | a, b, c = Bonett(d, alt) 36 | x, y, z = 0.8074, 0.9789, 0.1638 37 | 38 | if abs(x-a) > delta { 39 | fmt.Println("failed skewness: ", a, x) 40 | t.Error() 41 | } 42 | if abs(y-b) > delta { 43 | fmt.Println("failed z: ", b, y) 44 | t.Error() 45 | } 46 | if abs(y-b) > delta { 47 | fmt.Println("failed p-value: ", c, z) 48 | t.Error() 49 | } 50 | 51 | fmt.Println("Bonett test greater") 52 | alt = 2 53 | a, b, c = Bonett(d, alt) 54 | x, y, z = 0.8074, 0.9789, 0.8362 55 | if abs(x-a) > delta { 56 | fmt.Println("failed skewness: ", a, x) 57 | t.Error() 58 | } 59 | if abs(y-b) > delta { 60 | fmt.Println("failed z: ", b, y) 61 | t.Error() 62 | } 63 | if abs(y-b) > delta { 64 | fmt.Println("failed p-value: ", c, z) 65 | t.Error() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /stat/_tst/cov_test.go: -------------------------------------------------------------------------------- 1 | package stat 2 | 3 | import ( 4 | "fmt" 5 | mtx "github.com/skelterjohn/go.matrix" 6 | "testing" 7 | ) 8 | 9 | // Covariance test against R 10 | func TestCovariance(t *testing.T) { 11 | fmt.Println("Covariance test against R") 12 | data := GetData() 13 | out := SCov(data) 14 | 15 | //known values 16 | dist := [...]float64{1.773643, -0.3381504, 0.4803343, -0.8050336, 0.3154475, 0.2026154, 0.5576372, -0.3982494, 0.2083944, 0.1306447, 17 | -0.3381504, 0.8108673, 0.1696915, 0.5268912, -0.1279332, -0.0810701, 0.4332097, -0.01344127, 0.3683854, -0.1976432, 18 | 0.4803343, 0.1696915, 0.4986279, 0.02131043, 0.2643708, -0.3654575, 0.6973307, -0.3021538, -0.221391, -0.07286902, 19 | -0.8050336, 0.5268912, 0.02131043, 0.7320278, 0.01051328, -0.4524992, 0.0321159, -0.1932133, 0.1346962, 0.003491767, 20 | 0.3154475, -0.1279332, 0.2643708, 0.01051328, 0.4088249, -0.3923959, 0.2455576, -0.3880454, -0.2810396, 0.1249063, 21 | 0.2026154, -0.0810701, -0.3654575, -0.4524992, -0.3923959, 0.8562731, -0.3241916, 0.5470234, 0.3595004, -0.1266668, 22 | 0.5576372, 0.4332097, 0.6973307, 0.0321159, 0.2455576, -0.3241916, 1.149185, -0.1579107, -0.3901415, -0.3014224, 23 | -0.3982494, -0.01344127, -0.3021538, -0.1932133, -0.3880454, 0.5470234, -0.1579107, 0.7091816, -0.2188541, -0.3055508, 24 | 0.2083944, 0.3683854, -0.221391, 0.1346962, -0.2810396, 0.3595004, -0.3901415, -0.2188541, 1.283379, 0.2383891, 25 | 0.1306447, -0.1976432, -0.07286902, 0.003491767, 0.1249063, -0.1266668, -0.3014224, -0.3055508, 0.2383891, 0.2644874} 26 | 27 | cols := data.Cols() 28 | known := mtx.Zeros(cols, cols) 29 | for i := 0; i < cols; i++ { 30 | for j := i + 1; j < cols; j++ { 31 | known.Set(i, j, dist[i*cols+j]) 32 | } 33 | } 34 | 35 | // check 36 | for i := 0; i < cols; i++ { 37 | for j := i + 1; j < cols; j++ { 38 | if !check(out.Get(i, j), known.Get(i, j)) { 39 | t.Error() 40 | fmt.Println(i, j, out.Get(i, j), known.Get(i, j)) 41 | } 42 | } 43 | } 44 | } 45 | 46 | // Variance test against R 47 | func TestVariance(t *testing.T) { 48 | fmt.Println("Variance test against R") 49 | data := GetData() 50 | out := SVar(data) 51 | 52 | //known values 53 | dist := [...]float64{1.7736433, 0.8108673, 0.4986279, 0.7320278, 0.4088249, 0.8562731, 1.1491851, 0.7091816, 1.2833793, 0.2644874} 54 | 55 | cols := data.Cols() 56 | fmt.Println("cols: ", cols) 57 | 58 | known := NewVector(cols) 59 | for i := 0; i < cols; i++ { 60 | known.Set(i, dist[i]) 61 | } 62 | 63 | // check 64 | for i := 0; i < cols; i++ { 65 | if !check(out.Get(i), known.Get(i)) { 66 | t.Error() 67 | } 68 | fmt.Println(i, out.Get(i), known.Get(i)) 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /stat/_tst/jarque_test.go: -------------------------------------------------------------------------------- 1 | package stat 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Test against R:moments:anscombe 9 | 10 | func TestSampleJarque(t *testing.T) { 11 | const delta = 1e-4 12 | 13 | d := []float64{-0.670789480, -0.150969186, -0.551925020, -0.482406038, -1.173156862, 0.367903204, 1.059533774, 1.794411979, -1.895192051, -0.571951213, -0.726043212, 0.627210778, -1.272177905, -0.144797609, -0.968422674, 0.283461379, 0.988415637, 2.475978661, -0.536749821, -0.025513855, -1.534900705, -0.230832466, 0.620245249, 1.495396229, -2.111838253, 0.228080184, 0.251295357, 0.181974246, -0.001878552, -2.085836898, 0.834083317, -1.321850451, 1.192865393, -0.195088801, 1.748176403, 1.780233827, -1.212874246, -0.275506872, -0.474797265, -0.496230943, 1.872632489, 0.165565088, -1.143077239, -0.683540167, -2.029626407, 0.027388799, 0.263192684, -0.637438762, -0.460420680, 0.316033043, -0.166534773, -0.270718891, 0.634184308, -0.302168613, 0.928756911, 0.737386257, -0.546999206, 0.107967686, -0.082850172, -1.895955213, 1.576817423, -0.079801919, 0.382725131, 0.758249530, -2.054212936, -1.285879785, -0.009835473, 0.636242575, 0.169251475, -0.465556922, -0.387162464, -0.172489252, -1.910986672, 2.291340848, 1.499807228, -0.707866084, -0.430782756, -0.943412247, 1.663281221, 0.392045957, -0.006054918, -0.330406096, 0.519286029, 0.700169631, -0.521821484, -0.412689406, 0.814297193, -0.709301954, -0.861132419, -1.471550480, -0.686849429, 0.174766897, -0.333436632, 1.291139538, 0.040605740, -0.399557291, 2.169674201, -1.712460224, 0.377688521, -1.831853999} 14 | 15 | fmt.Println("Jarque test two-sided") 16 | a, b := Jarque(d) 17 | x, y := 0.8041, 0.669 18 | if abs(x-a) > delta { 19 | fmt.Println("failed Jarque-Bera statistic: ", a, x) 20 | t.Error() 21 | } 22 | if abs(y-b) > delta { 23 | fmt.Println("failed p-value: ", b, y) 24 | t.Error() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /stat/_tst/moments_test.go: -------------------------------------------------------------------------------- 1 | package stat 2 | 3 | import ( 4 | "code.google.com/p/probab/dst" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | // Test against R:moments 10 | func TestSampleSkewness(t *testing.T) { 11 | fmt.Println("Testing Skewness") 12 | m := 10000000 13 | mu := 0.0 14 | sd := 1.0 15 | d := make([]float64, m) 16 | for i, _ := range d { 17 | d[i] = dst.NormalNext(mu, sd) 18 | } 19 | 20 | x := Skew(d) 21 | y := 0.0 22 | if abs(x-y) > 1e-3 { 23 | fmt.Println("failed: x, y ", x, y) 24 | t.Error() 25 | } 26 | } 27 | 28 | func TestSampleKurtosis(t *testing.T) { 29 | fmt.Println("Testing Kurtosis") 30 | m := 10000000 31 | mu := 0.0 32 | sd := 1.0 33 | d := make([]float64, m) 34 | for i, _ := range d { 35 | d[i] = dst.NormalNext(mu, sd) 36 | } 37 | 38 | x := Kurt(d) 39 | y := 3.0 40 | if abs(x-y) > 1e-3 { 41 | fmt.Println("failed: x, y ", x, y) 42 | t.Error() 43 | } 44 | } 45 | 46 | func TestSampleMoments(t *testing.T) { 47 | fmt.Println("Testing Moments") 48 | m := 10000000 49 | mu := 0.0 50 | sd := 1.0 51 | d := make([]float64, m) 52 | for i, _ := range d { 53 | d[i] = dst.NormalNext(mu, sd) 54 | } 55 | 56 | order := 4 57 | central := false 58 | absolute := false 59 | x := moment(d, order, central, absolute) 60 | y := 3.0 61 | if abs(x-y) > 1e-2 { 62 | fmt.Println("failed: x, y ", x, y) 63 | t.Error() 64 | } 65 | } 66 | 67 | func TestSampleGeary(t *testing.T) { 68 | fmt.Println("Testing Geary kurtosis") 69 | m := 1000000 70 | mu := 0.0 71 | sd := 1.0 72 | d := make([]float64, m) 73 | for i, _ := range d { 74 | d[i] = dst.NormalNext(mu, sd) 75 | } 76 | 77 | x := Geary(d) 78 | y := 0.7979113 79 | if abs(x-y) > 1e-2 { 80 | fmt.Println("failed: x, y ", x, y) 81 | t.Error() 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /stat/agostino.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package stat 4 | 5 | // D’Agostino test for skewness in normally distributed data. 6 | // Ref.: D’Agostino (1970). 7 | 8 | import ( 9 | "code.google.com/p/probab/dst" 10 | "sort" 11 | ) 12 | 13 | // Agostino performs D’Agostino test for skewness in normally distributed data vector. 14 | func Agostino(x []float64, alternative int) (skew, z, pVal float64) { 15 | // Arguments: 16 | // x - vector of observations 17 | // alternative - 0 = "twoSided", 1 = "less", 2 = "greater" 18 | // 19 | // Details: 20 | // Under the hypothesis of normality, data should be symmetrical (i.e. skewness should be equal to 21 | // zero). This test has such null hypothesis and is useful to detect a significant skewness in normally 22 | // distributed data. 23 | // 24 | // Returns: 25 | // skew - skewness estimator 26 | // z - its transformation 27 | // pVal - the p-value for the test. 28 | 29 | const ( 30 | twoSided = iota 31 | less 32 | greater 33 | ) 34 | 35 | sort.Float64s(x) 36 | n := float64(len(x)) 37 | dm := diffMean(x) 38 | d3 := make([]float64, len(dm)) 39 | for i, val := range dm { 40 | d3[i] = val * val * val 41 | } 42 | 43 | d2 := make([]float64, len(dm)) 44 | for i, val := range dm { 45 | d2[i] = val * val 46 | } 47 | 48 | //skew <- (sum((x-mean(x))^3)/n)/(sum((x-mean(x))^2)/n)^(3/2) 49 | 50 | skew = (sum(d3) / n) / pow((sum(d2)/n), 1.5) 51 | y := skew * sqrt((n+1)*(n+3)/(6*(n-2))) 52 | b2 := 3 * (n*n + 27*n - 70) * (n + 1) * (n + 3) / ((n - 2) * (n + 5) * (n + 7) * (n + 9)) 53 | w := sqrt(-1 + sqrt(2*(b2-1))) 54 | d := 1 / sqrt(log10(w)) 55 | a := sqrt(2 / (w*w - 1)) 56 | z = d * log10(y/a+sqrt((y/a)*(y/a)+1)) 57 | pVal = 1 - dst.NormalCDFAt(0, 1, z) 58 | 59 | switch alternative { 60 | case twoSided: 61 | pVal = 2 * pVal 62 | if pVal > 1 { 63 | pVal = 2 - pVal 64 | } 65 | case less: // do nothing 66 | case greater: 67 | pVal = 1 - pVal 68 | } 69 | return skew, z, pVal 70 | } 71 | -------------------------------------------------------------------------------- /stat/anscombe.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package stat 4 | 5 | // Anscombe-Glynn test of kurtosis for normally distributed data. 6 | // Ref.: Anscombe & Glynn (1983). 7 | 8 | import ( 9 | "code.google.com/p/probab/dst" 10 | "sort" 11 | ) 12 | 13 | // Anscombe performs Anscombe-Glynn test of kurtosis for normally distributed data vector. 14 | func Anscombe(x []float64, alternative int) (kurt, z, pVal float64) { 15 | // Arguments: 16 | // x - vector of observations 17 | // alternative - 0 = "twoSided", 1 = "less", 2 = "greater" 18 | // 19 | // Details: 20 | // Under the hypothesis of normality, data should have kurtosis equal to 3. This test has such null 21 | // hypothesis and is useful to detect a significant difference of kurtosis in normally distributed data. 22 | // 23 | // Returns: 24 | // kurt - kurtosis estimator 25 | // z - its transformation 26 | // pVal - the p-value for the test. 27 | 28 | const ( 29 | twoSided = iota 30 | less 31 | greater 32 | ) 33 | 34 | sort.Float64s(x) 35 | n := float64(len(x)) 36 | dm := diffMean(x) 37 | d4 := make([]float64, len(dm)) 38 | for i, val := range dm { 39 | d4[i] = val * val * val * val 40 | } 41 | 42 | d2 := make([]float64, len(dm)) 43 | for i, val := range dm { 44 | d2[i] = val * val 45 | } 46 | 47 | //b <- n*sum( (x-mean(x))^4 )/(sum( (x-mean(x))^2 )^2); 48 | sum2 := sum(d2) 49 | kurt = n * sum(d4) / (sum2 * sum2) 50 | 51 | eb2 := 3 * (n - 1) / (n + 1) 52 | vb2 := 24 * n * (n - 2) * (n - 3) / ((n + 1) * (n + 1) * (n + 3) * (n + 5)) 53 | m3 := (6 * (n*n - 5*n + 2) / ((n + 7) * (n + 9))) * sqrt((6*(n+3)*(n+5))/(n*(n-2)*(n-3))) 54 | a := 6 + (8/m3)*(2/m3+sqrt(1+4/(m3*m3))) 55 | xx := (kurt - eb2) / sqrt(vb2) 56 | z0 := (1 - 2/a) / (1 + xx*sqrt(2/(a-4))) 57 | z = (1 - 2/(9*a) - pow(z0, 1.0/3.0)) / sqrt(2/(9*a)) 58 | pVal = 1 - dst.NormalCDFAt(0, 1, z) 59 | 60 | switch alternative { 61 | case twoSided: 62 | pVal = 2 * pVal 63 | if pVal > 1 { 64 | pVal = 2 - pVal 65 | } 66 | case less: // do nothing 67 | case greater: 68 | pVal = 1 - pVal 69 | } 70 | 71 | return kurt, z, pVal 72 | } 73 | -------------------------------------------------------------------------------- /stat/binom_ci.go: -------------------------------------------------------------------------------- 1 | package stat 2 | 3 | //Frequentist Confidence Interval for binomial parameter 4 | 5 | import "code.google.com/p/probab/dst" 6 | 7 | // BinomPConfInt returns a one-sided frequentist Confidence Interval for binomial parameter estimated from a random sample. 8 | // Ref.: Hahn & Meeker (1991). 9 | func BinomPConfInt(n, k int64, alpha float64) (lo, hi float64) { 10 | // Arguments: 11 | // n - sample size 12 | // k - observed number of successes (p=n/k) 13 | // alpha - lervel of confidence 14 | // 15 | // Returns: 16 | // lo lower confidence limit 17 | // hi upper confidence limit 18 | 19 | if k <= 0 { 20 | lo = 0.0 21 | } else { 22 | lo = 1.0 / (1.0 + float64((n-k+1))*dst.FQtlFor(2*n-2*k+2, 2*k, alpha)/float64(k)) 23 | } 24 | 25 | if k >= n { 26 | hi = 1.0 27 | } else { 28 | hi = 1.0 / (1.0 + float64((n-k))/(float64((k+1))*dst.FQtlFor(2*k+2, 2*n-2*k, alpha))) 29 | } 30 | return 31 | } 32 | -------------------------------------------------------------------------------- /stat/bonett.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package stat 4 | 5 | // Bonett-Seier test of Geary’s kurtosis. 6 | // Ref.: 7 | 8 | import ( 9 | "code.google.com/p/probab/dst" 10 | "sort" 11 | ) 12 | 13 | // Bonett performs Bonett-Seier test of Geary’s measure of kurtosis for normally distributed data vector. 14 | func Bonett(x []float64, alternative int) (kurt, z, pVal float64) { 15 | // Arguments: 16 | // x - vector of observations 17 | // alternative - 0 = "twoSided", 1 = "less", 2 = "greater" 18 | // 19 | // Details: 20 | // Under the hypothesis of normality, data should have Geary’s kurtosis equal to sqrt(2/pi) (0.7979). 21 | // This test has such null hypothesis and is useful to detect a significant difference of Geary’s kurtosis 22 | // in normally distributed data. 23 | // 24 | // Returns: 25 | // kurt - kurtosis estimator 26 | // z - its transformation 27 | // pVal - the p-value for the test. 28 | 29 | const ( 30 | twoSided = iota 31 | less 32 | greater 33 | ) 34 | 35 | sort.Float64s(x) 36 | n := float64(len(x)) 37 | dm := diffMean(x) 38 | 39 | d2 := make([]float64, len(dm)) 40 | for i, val := range dm { 41 | d2[i] = val * val 42 | } 43 | 44 | adm := make([]float64, len(dm)) 45 | for i, val := range dm { 46 | adm[i] = abs(val) 47 | } 48 | 49 | rho := sqrt(sum(d2) / n) 50 | kurt = sum(adm) / n 51 | omega := 13.29 * (log(rho) - log(kurt)) 52 | z = sqrt(n+2) * (omega - 3) / 3.54 53 | pVal = 1 - dst.NormalCDFAt(0, 1, z) 54 | 55 | switch alternative { 56 | case twoSided: 57 | pVal = 2 * pVal 58 | if pVal > 1 { 59 | pVal = 2 - pVal 60 | } 61 | case less: // do nothing 62 | case greater: 63 | pVal = 1 - pVal 64 | } 65 | 66 | return kurt, z, pVal 67 | } 68 | -------------------------------------------------------------------------------- /stat/cov.go: -------------------------------------------------------------------------------- 1 | // Covariance matrix 2 | 3 | package stat 4 | 5 | import ( 6 | . "github.com/skelterjohn/go.matrix" 7 | ) 8 | 9 | // Covariance matrix between columns of data matrix, two-pass algorithm 10 | // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Covariance 11 | func Cov(data *DenseMatrix) *DenseMatrix { 12 | rows := data.Rows() 13 | cols := data.Cols() 14 | out := Zeros(cols, cols) 15 | 16 | for i := 0; i < cols; i++ { 17 | for j := i; j < cols; j++ { 18 | meanX := 0.0 19 | meanY := 0.0 20 | // calculate column means 21 | for k := 0; k < rows; k++ { 22 | meanX += data.Get(k, i) 23 | meanY += data.Get(k, j) 24 | } 25 | meanX /= float64(rows) 26 | meanY /= float64(rows) 27 | // calculate covariance 28 | cov := 0.0 29 | for k := 0; k < rows; k++ { 30 | x := data.Get(k, i) 31 | y := data.Get(k, j) 32 | cov += (x - meanX) * (y - meanY) 33 | } 34 | cov /= float64(rows) 35 | out.Set(i, j, cov) 36 | out.Set(j, i, cov) 37 | } 38 | } 39 | return out 40 | } 41 | 42 | // Sample covariance matrix between columns of data matrix, for samples 43 | // This is R:cov() 44 | func SCov(data *DenseMatrix) *DenseMatrix { 45 | rows := data.Rows() 46 | cols := data.Cols() 47 | out := Cov(data) 48 | 49 | for i := 0; i < cols; i++ { 50 | for j := i; j < cols; j++ { 51 | v := out.Get(i, j) * float64(rows) / (float64(rows) - 1) 52 | out.Set(i, j, v) 53 | out.Set(j, i, v) 54 | } 55 | } 56 | return out 57 | } 58 | -------------------------------------------------------------------------------- /stat/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | // Statistics package. 4 | package stat 5 | -------------------------------------------------------------------------------- /stat/fn.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package stat 4 | 5 | import ( 6 | fn "code.google.com/p/go-fn/fn" 7 | "math" 8 | ) 9 | 10 | const π = float64(math.Pi) 11 | const ln2 = math.Ln2 12 | const lnSqrt2π = 0.918938533204672741780329736406 // log(sqrt(2*pi)) 13 | const min64 = math.SmallestNonzeroFloat64 // DBL_MIN 14 | const eps64 = 1.1102230246251565e-16 // DBL_EPSILON 15 | const maxExp = 1024.0 // DBL_MAX_EXP 16 | const sqrt2 = math.Sqrt2 17 | 18 | var nan = math.NaN() 19 | 20 | var fZero float64 = float64(0.0) 21 | var fOne float64 = float64(1.0) 22 | var iZero int64 = int64(0) 23 | var iOne int64 = int64(1) 24 | 25 | var negInf float64 = math.Inf(-1) 26 | var posInf float64 = math.Inf(+1) 27 | 28 | // Functions imported from "math" 29 | var abs func(float64) float64 = math.Abs 30 | var floor func(float64) float64 = math.Floor 31 | var ceil func(float64) float64 = math.Ceil 32 | var log func(float64) float64 = math.Log 33 | var log1p func(float64) float64 = math.Log1p 34 | var log10 func(float64) float64 = math.Log10 35 | var exp func(float64) float64 = math.Exp 36 | var sqrt func(float64) float64 = math.Sqrt 37 | var pow func(float64, float64) float64 = math.Pow 38 | var atan func(float64) float64 = math.Atan 39 | var tan func(float64) float64 = math.Tan 40 | var trunc func(float64) float64 = math.Trunc 41 | var erf func(float64) float64 = math.Erf 42 | var erfc func(float64) float64 = math.Erfc 43 | var isNaN func(float64) bool = math.IsNaN 44 | var isInf func(float64, int) bool = math.IsInf 45 | 46 | // Functions imported from "code.google.com/p/go-fn/fn" 47 | var lnB func(float64, float64) float64 = fn.LnB 48 | var lnΓ func(float64) float64 = fn.LnΓ 49 | 50 | // vAbs recalculates the data vector to absolute values. 51 | func vAbs(x []float64) { 52 | for i, val := range x { 53 | x[i] = abs(val) 54 | } 55 | } 56 | 57 | // vCent recalculates the data vector to centralized values. 58 | func vCent(x []float64) { 59 | mu := Mean(x) 60 | for i, val := range x { 61 | x[i] = val - mu 62 | } 63 | } 64 | 65 | // vPow recalculates the data vector to absolute values. 66 | func vPow(x []float64, power float64) { 67 | for i, val := range x { 68 | x[i] = pow(val, power) 69 | } 70 | } 71 | 72 | // sum returns the sum of the data vector. 73 | func sum(x []float64) float64 { 74 | s := 0.0 75 | for _, val := range x { 76 | s += val 77 | } 78 | return s 79 | } 80 | 81 | // mean returns the mean of the data vector. 82 | func mean(x []float64) float64 { 83 | μ := sum(x) 84 | μ /= float64(len(x)) 85 | return μ 86 | } 87 | 88 | // diffMean returns the vector of centralized values. 89 | func diffMean(x []float64) []float64 { 90 | d := make([]float64, len(x)) 91 | mu := Mean(x) 92 | for i, val := range x { 93 | d[i] = val - mu 94 | } 95 | return d 96 | } 97 | -------------------------------------------------------------------------------- /stat/jarque.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package stat 4 | 5 | // Jarque-Bera test for normality. 6 | // Ref.: Jarque & Bera (1980). 7 | 8 | import ( 9 | "code.google.com/p/probab/dst" 10 | ) 11 | 12 | // Jarque performs performs the Jarque-Bera test on the given data sample to determine if the data are 13 | // sample drawn from a normal population. 14 | func Jarque(x []float64) (jb, pVal float64) { 15 | // Arguments: 16 | // x - vector of observations 17 | // 18 | // Details: 19 | // Under the hypothesis of normality, data should be symmetrical (i.e. skewness should be equal to zero) 20 | // and have skewness chose to three. The Jarque-Bera statistic is chi-square distributed with two degrees of freedom. 21 | // Alternative hypothesis is "greater". 22 | // 23 | // Returns: 24 | // jb - the Jarque-Bera statistic 25 | // pVal - the p-value for the test. 26 | 27 | n := float64(len(x)) 28 | k := Kurt(x) 29 | s := Skew(x) 30 | jb = (n / 6) * (s*s + 0.25*((k-3)*(k-3))) 31 | pVal = 1 - dst.ChiSquareCDFAt(2, jb) 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /stat/moments.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | // Moments for the data vector. 4 | 5 | package stat 6 | 7 | // Mean returns the mean of the data vector. 8 | func Mean(x []float64) float64 { 9 | μ := sum(x) 10 | μ /= float64(len(x)) 11 | return μ 12 | } 13 | 14 | // Skew returns skewness of the data vector. 15 | func Skew(x []float64) float64 { 16 | n := float64(len(x)) 17 | d3 := diffMean(x) 18 | for i, val := range d3 { 19 | d3[i] = val * val * val 20 | } 21 | d2 := diffMean(x) 22 | for i, val := range d2 { 23 | d2[i] = val * val 24 | } 25 | return (sum(d3) / n) / pow((sum(d2)/n), 1.5) 26 | } 27 | 28 | // Kurt returns the estimator of Pearson’s measure of kurtosis of the data vector. This is NOT the Excess Kustosis! 29 | func Kurt(x []float64) float64 { 30 | n := float64(len(x)) 31 | d4 := diffMean(x) 32 | for i, val := range d4 { 33 | d4[i] = val * val * val * val 34 | } 35 | d2 := diffMean(x) 36 | for i, val := range d2 { 37 | d2[i] = val * val 38 | } 39 | sum2 := sum(d2) 40 | return n * sum(d4) / (sum2 * sum2) 41 | } 42 | 43 | // Moment returns moment of specified order of the data vector. 44 | func moment(x []float64, order int, central, absolute bool) float64 { 45 | n := float64(len(x)) 46 | if order < 1 { 47 | panic(" order < 1") 48 | } 49 | if central { 50 | vCent(x) 51 | } 52 | if absolute { 53 | vAbs(x) 54 | } 55 | vPow(x, float64(order)) 56 | return sum(x) / n 57 | } 58 | 59 | // Geary returns an estimator of Geary’s measure of kurtosis. 60 | func Geary(x []float64) float64 { 61 | // The Geary’s kurtosis is computed by dividing average difference between observation 62 | // and the mean by standard deviation of the sample. 63 | n := float64(len(x)) 64 | d2 := diffMean(x) 65 | for i, val := range d2 { 66 | d2[i] = val * val 67 | } 68 | rho := sqrt(sum(d2) / n) 69 | vCent(x) 70 | vAbs(x) 71 | tau := sum(x) / n 72 | return tau / rho 73 | } 74 | -------------------------------------------------------------------------------- /stat/raw2central.go.new: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package stat 4 | 5 | /* 6 | 7 | np1 <- length( mu.raw ) 8 | n <- np1 - 1 9 | mu.central <- rep( 0, np1 ) 10 | mu.central[1] <- 1 11 | eta <- mu.raw[2] 12 | j <- 2 13 | for ( k in 1:n ) { 14 | total <- 0 15 | for ( i in 0:k ) { 16 | total <- total + choose(k,i) * ( (- eta )^(k-i) ) * mu.raw[i+1] 17 | } 18 | mu.central[j] <- total 19 | j <- j + 1 20 | } 21 | return( mu.central ) 22 | */ 23 | 24 | // RawToCentral returns 25 | func RawToCentral(x []float64) []float64 { 26 | 27 | 28 | np1 := float64(len( mu.raw )) 29 | n := len( mu.raw ) - 1 30 | mu.central := make ([float64, len (mu.raw )) 31 | mu.central[0] = 1 32 | eta := mu.raw[1] 33 | j :=1 34 | for k :=0, k < n; k++ { 35 | total :=0 36 | for i :=0, i < k; i++ { 37 | total += choose(k,i) * ( (- eta )^(k-i) ) * mu.raw[i+1] // ToDo 38 | } 39 | 40 | ETC.... 41 | 42 | } 43 | -------------------------------------------------------------------------------- /stat/sample_mean_var.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | package stat 4 | 5 | // Sample mean and variance (unbiased estimator) 6 | 7 | // Sample mean and unbiased (Bessel correction) variance estimates for a data vector. 8 | func SampleMeanVar(x []float64) (μ, σ2 float64) { 9 | // Arguments: 10 | // x - vector of observations 11 | // 12 | // Returns: 13 | // μ - mean estimator 14 | // σ2 - variance estimator 15 | 16 | var n int 17 | var m, m2 float64 18 | μ = 0.0 // sample mean 19 | σ2 = 0.0 // sample variance unbiased 20 | m = 0.0 21 | m2 = 0.0 22 | 23 | for _, val := range x { 24 | n += 1 25 | μ += val 26 | delta := val - m 27 | m += delta / float64(n) 28 | m2 += delta * (val - m) 29 | } 30 | 31 | σ2 = m2 / float64(n-1) 32 | μ /= float64(len(x)) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /stat/var.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 - 2013 The Probab Authors. All rights reserved. See the LICENSE file. 2 | 3 | // Variance vector for data matrix. 4 | 5 | package stat 6 | 7 | import ( 8 | . "github.com/skelterjohn/go.matrix" 9 | ) 10 | 11 | // Population variance vector of columns of data matrix, one-pass algorithm 12 | // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm 13 | func Var(data *DenseMatrix) *Vector { 14 | rows := data.Rows() 15 | cols := data.Cols() 16 | out := NewVector(cols) 17 | 18 | for i := 0; i < cols; i++ { 19 | n := 0.0 20 | mean := 0.0 21 | m2 := 0.0 22 | for j := 0; j < rows; j++ { 23 | n++ 24 | x := data.Get(j, i) 25 | delta := x - mean 26 | mean += delta / n 27 | if n > 1 { 28 | m2 += delta * (x - mean) 29 | } 30 | } 31 | v := m2 / n 32 | out.Set(i, v) 33 | } 34 | return out 35 | } 36 | 37 | // Sample variance vector of columns of data matrix, one-pass algorithm 38 | // This is R:var() 39 | func SVar(data *DenseMatrix) *Vector { 40 | rows := data.Rows() 41 | cols := data.Cols() 42 | n := float64(rows) 43 | out := Var(data) 44 | 45 | for i := 0; i < cols; i++ { 46 | v := out.Get(i) * n / (n - 1) 47 | out.Set(i, v) 48 | } 49 | return out 50 | } 51 | -------------------------------------------------------------------------------- /stat/vector.go: -------------------------------------------------------------------------------- 1 | package stat 2 | 3 | type Vector struct { 4 | X []float64 // data 5 | L int // length 6 | } 7 | 8 | func NewVector(length int) (v *Vector) { 9 | v = new(Vector) 10 | v.L = length 11 | v.X = make([]float64, length) 12 | return v 13 | } 14 | 15 | func (v Vector) Set(i int, x float64) { 16 | v.X[i] = x 17 | } 18 | 19 | func (v Vector) Get(i int) float64 { 20 | return v.X[i] 21 | } 22 | 23 | func (v Vector) Swap(i int, j int) { 24 | x := v.X[i] 25 | v.X[i] = v.X[j] 26 | v.X[j] = x 27 | } 28 | 29 | func (v Vector) Len() int { 30 | return v.L 31 | } 32 | --------------------------------------------------------------------------------