Files
gonum/stat/sampleuv/sample_test.go
Brendan Tracey e5448cb39f stat/all: reduce random size and test tolerance to decrease testing t… (#181)
* stat/all: reduce random size and test tolerance to decrease testing time.

We were generating a lot of random numbers, which is slow. Decrease the size of those random numbers, and in some cases increase the tolerance to compensate. In a couple cases, pull out code from testFullDist to allow for more fine-grained testing. This decrases:
distmat from 4.5s to 0.5s
distmv from 24.8s to 9s
distuv from 65.2s to 13s
samplemv from 2.8s to 1.2s
sampleuv from 3.5s to 2.1s
2017-08-07 18:09:24 -06:00

100 lines
2.5 KiB
Go

// Copyright ©2015 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sampleuv
import (
"math"
"sort"
"testing"
"gonum.org/v1/gonum/stat"
"gonum.org/v1/gonum/stat/distuv"
)
type lhDist interface {
Quantile(float64) float64
CDF(float64) float64
}
func TestLatinHypercube(t *testing.T) {
for _, nSamples := range []int{1, 2, 5, 10, 20} {
samples := make([]float64, nSamples)
for _, dist := range []lhDist{
distuv.Uniform{Min: 0, Max: 1},
distuv.Uniform{Min: 0, Max: 10},
distuv.Normal{Mu: 5, Sigma: 3},
} {
LatinHypercube(samples, dist, nil)
sort.Float64s(samples)
for i, v := range samples {
p := dist.CDF(v)
if p < float64(i)/float64(nSamples) || p > float64(i+1)/float64(nSamples) {
t.Errorf("probability out of bounds")
}
}
}
}
}
func TestImportance(t *testing.T) {
// Test by finding the expected value of a Normal.
trueMean := 3.0
target := distuv.Normal{Mu: trueMean, Sigma: 2}
proposal := distuv.Normal{Mu: 0, Sigma: 5}
nSamples := 100000
x := make([]float64, nSamples)
weights := make([]float64, nSamples)
Importance(x, weights, target, proposal)
ev := stat.Mean(x, weights)
if math.Abs(ev-trueMean) > 1e-2 {
t.Errorf("Mean mismatch: Want %v, got %v", trueMean, ev)
}
}
func TestRejection(t *testing.T) {
// Test by finding the expected value of a Normal.
trueMean := 3.0
target := distuv.Normal{Mu: trueMean, Sigma: 2}
proposal := distuv.Normal{Mu: 0, Sigma: 5}
nSamples := 20000
x := make([]float64, nSamples)
Rejection(x, target, proposal, 100, nil)
ev := stat.Mean(x, nil)
if math.Abs(ev-trueMean) > 2e-2 {
t.Errorf("Mean mismatch: Want %v, got %v", trueMean, ev)
}
}
type condNorm struct {
Sigma float64
}
func (c condNorm) ConditionalRand(y float64) float64 {
return distuv.Normal{Mu: y, Sigma: c.Sigma}.Rand()
}
func (c condNorm) ConditionalLogProb(x, y float64) float64 {
return distuv.Normal{Mu: y, Sigma: c.Sigma}.LogProb(x)
}
func TestMetropolisHastings(t *testing.T) {
// Test by finding the expected value of a Normal.
trueMean := 3.0
target := distuv.Normal{Mu: trueMean, Sigma: 2}
proposal := condNorm{Sigma: 5}
burnin := 500
nSamples := 100000 + burnin
x := make([]float64, nSamples)
MetropolisHastings(x, 100, target, proposal, nil)
// Remove burnin
x = x[burnin:]
ev := stat.Mean(x, nil)
if math.Abs(ev-trueMean) > 1e-2 {
t.Errorf("Mean mismatch: Want %v, got %v", trueMean, ev)
}
}