mirror of
https://github.com/gonum/gonum.git
synced 2025-10-08 00:20:11 +08:00
121 lines
3.6 KiB
Go
121 lines
3.6 KiB
Go
// Copyright ©2014 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 distuv
|
|
|
|
import (
|
|
"golang.org/x/exp/rand"
|
|
"gonum.org/v1/gonum/floats"
|
|
"math"
|
|
"testing"
|
|
)
|
|
|
|
func TestLaplaceProb(t *testing.T) {
|
|
pts := []univariateProbPoint{
|
|
{
|
|
loc: 0,
|
|
prob: 0.5,
|
|
cumProb: 0.5,
|
|
logProb: math.Log(0.5),
|
|
},
|
|
{
|
|
loc: -1,
|
|
prob: 1 / (2 * math.E),
|
|
cumProb: 0.1839397205857211607977618850807304337229055655158839172539184008487307478724499016785736371729598219,
|
|
logProb: math.Log(1 / (2 * math.E)),
|
|
},
|
|
{
|
|
loc: 1,
|
|
prob: 1 / (2 * math.E),
|
|
cumProb: 0.8160602794142788392022381149192695662770944344841160827460815991512692521275500983214263628270401781,
|
|
logProb: math.Log(1 / (2 * math.E)),
|
|
},
|
|
{
|
|
loc: -7,
|
|
prob: 1 / (2 * math.Pow(math.E, 7)),
|
|
cumProb: 0.0004559409827772581040015680422046413132368622637180269204080667109447399446551532646631395032324502210,
|
|
logProb: math.Log(1 / (2 * math.Pow(math.E, 7))),
|
|
},
|
|
{
|
|
loc: 7,
|
|
prob: 1 / (2 * math.Pow(math.E, 7)),
|
|
cumProb: 0.9995440590172227418959984319577953586867631377362819730795919332890552600553448467353368604967675498,
|
|
logProb: math.Log(1 / (2 * math.Pow(math.E, 7))),
|
|
},
|
|
{
|
|
loc: -20,
|
|
prob: math.Exp(-20.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641869),
|
|
cumProb: 1.030576811219278913982970190077910488187903637799551846486122330814582011892279676639955463952790684 * 1e-9,
|
|
logProb: -20.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641869,
|
|
},
|
|
{
|
|
loc: 20,
|
|
prob: math.Exp(-20.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641869),
|
|
cumProb: 0.999999998969423188780721086017029809922089511812096362200448153513877669185417988107720323360044536,
|
|
logProb: -20.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641869,
|
|
},
|
|
}
|
|
testDistributionProbs(t, Laplace{Mu: 0, Scale: 1}, "Laplace", pts)
|
|
}
|
|
func TestLaplaceFit(t *testing.T) {
|
|
cases := []struct {
|
|
samples []float64
|
|
weights []float64
|
|
wantMu float64
|
|
wantScale float64
|
|
}{
|
|
{
|
|
samples: []float64{10, 1, 1},
|
|
weights: nil,
|
|
wantMu: 1,
|
|
wantScale: 3,
|
|
},
|
|
{
|
|
samples: []float64{10, 1, 1},
|
|
weights: []float64{10, 10, 10},
|
|
wantMu: 1,
|
|
wantScale: 3,
|
|
},
|
|
{
|
|
samples: []float64{10, 1, 1},
|
|
weights: []float64{0, 1, 1},
|
|
wantMu: 1,
|
|
wantScale: 0,
|
|
},
|
|
}
|
|
for i, test := range cases {
|
|
d := Laplace{}
|
|
d.Fit(test.samples, test.weights)
|
|
if !floats.EqualWithinAbsOrRel(d.Mu, test.wantMu, 1e-10, 1e-10) {
|
|
t.Errorf("unexpected location result for test %d: got:%f, want:%f", i, d.Mu, test.wantMu)
|
|
}
|
|
if !floats.EqualWithinAbsOrRel(d.Scale, test.wantScale, 1e-10, 1e-10) {
|
|
t.Errorf("unexpected scale result for test %d: got:%f, want:%f", i, d.Scale, test.wantScale)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLaplaceFitRandomSamples(t *testing.T) {
|
|
|
|
nSamples := 100000
|
|
src := rand.New(rand.NewSource(1))
|
|
l := Laplace{
|
|
Mu: 3,
|
|
Scale: 5,
|
|
Src: src,
|
|
}
|
|
samples := make([]float64, nSamples)
|
|
for i := range samples {
|
|
samples[i] = l.Rand()
|
|
}
|
|
le := Laplace{}
|
|
le.Fit(samples, nil)
|
|
if !floats.EqualWithinAbsOrRel(le.Mu, l.Mu, 1e-2, 1e-2) {
|
|
t.Errorf("unexpected location result for random test got:%f, want:%f", le.Mu, l.Mu)
|
|
}
|
|
if !floats.EqualWithinAbsOrRel(le.Scale, l.Scale, 1e-2, 1e-2) {
|
|
t.Errorf("unexpected scale result for random test got:%f, want:%f", le.Scale, l.Scale)
|
|
}
|
|
}
|