func Example() { fmt.Println("Evaluate the expected value of x^2 + 3 under a Weibull distribution") f := func(x float64) float64 { d := distuv.Weibull{Lambda: 1, K: 1.5} return (x*x + 3) * d.Prob(x) } ev := quad.Fixed(f, 0, math.Inf(1), 10, nil, 0) fmt.Printf("EV with 10 points = %0.6v\n", ev) ev = quad.Fixed(f, 0, math.Inf(1), 30, nil, 0) fmt.Printf("EV with 30 points = %0.6v\n", ev) ev = quad.Fixed(f, 0, math.Inf(1), 100, nil, 0) fmt.Printf("EV with 100 points = %0.6v\n", ev) ev = quad.Fixed(f, 0, math.Inf(1), 10000, nil, 0) fmt.Printf("EV with 10000 points = %0.6v\n\n", ev) fmt.Println("Estimate using parallel evaluations of f.") concurrent := runtime.GOMAXPROCS(0) ev = quad.Fixed(f, 0, math.Inf(1), 100, nil, concurrent) fmt.Printf("EV = %0.6v\n", ev) // Output: // Evaluate the expected value of x^2 + 3 under a Weibull distribution // EV with 10 points = 4.20175 // EV with 30 points = 4.19066 // EV with 100 points = 4.19064 // EV with 10000 points = 4.19064 // // Estimate using parallel evaluations of f. // EV = 4.19064 }
func checkProbContinuous(t *testing.T, i int, x []float64, p probLogprober) { // Check that the PDF is consistent (integrates to 1). q := quad.Fixed(p.Prob, math.Inf(-1), math.Inf(1), 100000, nil, 0) if math.Abs(q-1) > 1e-10 { t.Errorf("Probability distribution doesn't integrate to 1. Got %v", q) } // Check that PDF and LogPDF are consistent. for i, v := range x { if math.Abs(math.Log(p.Prob(v))-p.LogProb(v)) > 1e-14 { t.Errorf("Prob and LogProb mismatch case %v at %v: want %v, got %v", i, v, math.Log(v), p.LogProb(v)) break } } }
// checkProbQuantContinuous checks that the Prob, Rand, and Quantile are all consistent. // checkProbContinuous only checks that Prob is a valid distribution (integrates // to 1 and greater than 0). However, this is also true if the PDF of a different // distribution is used. This checks that PDF is also consistent with the // CDF implementation and the random samples. func checkProbQuantContinuous(t *testing.T, i int, xs []float64, c cumulantProber, tol float64) { ps := make([]float64, 101) floats.Span(ps, 0, 1) var xp, x float64 for i, p := range ps { x = c.Quantile(p) if p == 0 { xp = x if floats.Min(xs) < x { t.Errorf("Sample of x less than Quantile(0). Case %v.", i) break } continue } if p == 1 { if floats.Max(xs) > x { t.Errorf("Sample of x greater than Quantile(1). Case %v.", i) break } } // The integral of the PDF between xp and x should be the difference in // the quantiles. q := quad.Fixed(c.Prob, xp, x, 1000, nil, 0) if math.Abs(q-(p-ps[i-1])) > 1e-10 { t.Errorf("Integral of PDF doesn't match quantile. Case %v. Want %v, got %v.", i, p-ps[i-1], q) break } pEst := stat.CDF(x, stat.Empirical, xs, nil) if math.Abs(pEst-p) > tol { t.Errorf("Empirical CDF doesn't match quantile. Case %v.", i) } xp = x } }