func TestImportance(t *testing.T) { // Test by finding the expected value of a multi-variate normal. dim := 3 target, ok := randomNormal(dim) if !ok { t.Fatal("bad test, sigma not pos def") } muImp := make([]float64, dim) sigmaImp := mat64.NewSymDense(dim, nil) for i := 0; i < dim; i++ { sigmaImp.SetSym(i, i, 3) } proposal, ok := distmv.NewNormal(muImp, sigmaImp, nil) if !ok { t.Fatal("bad test, sigma not pos def") } nSamples := 100000 batch := mat64.NewDense(nSamples, dim, nil) weights := make([]float64, nSamples) Importance(batch, weights, target, proposal) compareNormal(t, target, batch, weights) }
// NewProposalNormal constructs a new ProposalNormal for use as a proposal // distribution for Metropolis-Hastings. ProposalNormal is a multivariate normal // distribution (implemented by distmv.Normal) where the covariance matrix is fixed // and the mean of the distribution changes. // // NewProposalNormal returns {nil, false} if the covariance matrix is not positive-definite. func NewProposalNormal(sigma *mat64.SymDense, src *rand.Rand) (*ProposalNormal, bool) { mu := make([]float64, sigma.Symmetric()) normal, ok := distmv.NewNormal(mu, sigma, src) if !ok { return nil, false } p := &ProposalNormal{ normal: normal, } return p, true }
// randomNormal constructs a random Normal distribution. func randomNormal(dim int) (*distmv.Normal, bool) { data := make([]float64, dim*dim) for i := range data { data[i] = rand.Float64() } a := mat64.NewDense(dim, dim, data) var sigma mat64.SymDense sigma.SymOuterK(1, a) mu := make([]float64, dim) for i := range mu { mu[i] = rand.NormFloat64() } return distmv.NewNormal(mu, &sigma, nil) }
func TestRejection(t *testing.T) { // Test by finding the expected value of a uniform. dim := 3 bounds := make([]distmv.Bound, dim) for i := 0; i < dim; i++ { min := rand.NormFloat64() max := rand.NormFloat64() if min > max { min, max = max, min } bounds[i].Min = min bounds[i].Max = max } target := distmv.NewUniform(bounds, nil) mu := target.Mean(nil) muImp := make([]float64, dim) sigmaImp := mat64.NewSymDense(dim, nil) for i := 0; i < dim; i++ { sigmaImp.SetSym(i, i, 6) } proposal, ok := distmv.NewNormal(muImp, sigmaImp, nil) if !ok { t.Fatal("bad test, sigma not pos def") } nSamples := 1000 batch := mat64.NewDense(nSamples, dim, nil) weights := make([]float64, nSamples) _, ok = Rejection(batch, target, proposal, 1000, nil) if !ok { t.Error("Bad test, nan samples") } for i := 0; i < dim; i++ { col := mat64.Col(nil, i, batch) ev := stat.Mean(col, weights) if math.Abs(ev-mu[i]) > 1e-2 { t.Errorf("Mean mismatch: Want %v, got %v", mu[i], ev) } } }