gonum.org/v1/gonum@v0.14.0/stat/distuv/pareto_test.go (about)

     1  // Copyright ©2017 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package distuv
     6  
     7  import (
     8  	"math"
     9  	"sort"
    10  	"testing"
    11  
    12  	"golang.org/x/exp/rand"
    13  
    14  	"gonum.org/v1/gonum/floats/scalar"
    15  )
    16  
    17  func TestParetoProb(t *testing.T) {
    18  	t.Parallel()
    19  	for _, test := range []struct {
    20  		x, xm, alpha, want float64
    21  	}{
    22  		{0, 1, 1, 0},
    23  		{0.5, 1, 1, 0},
    24  		{1, 1, 1, 1.0},
    25  		{1.5, 1, 1, 0.444444444444444},
    26  		{2, 1, 1, 0.25},
    27  		{2.5, 1, 1, 0.16},
    28  		{3, 1, 1, 0.1111111111111111},
    29  		{3.5, 1, 1, 0.081632653061224},
    30  		{4, 1, 1, 0.0625},
    31  		{4.5, 1, 1, 0.049382716049383},
    32  		{5, 1, 1, 0.04},
    33  
    34  		{0, 1, 2, 0},
    35  		{0.5, 1, 2, 0},
    36  		{1, 1, 2, 2},
    37  		{1.5, 1, 2, 0.592592592592593},
    38  		{2, 1, 2, 0.25},
    39  		{2.5, 1, 2, 0.128},
    40  		{3, 1, 2, 0.074074074074074},
    41  		{3.5, 1, 2, 0.046647230320700},
    42  		{4, 1, 2, 0.03125},
    43  		{4.5, 1, 2, 0.021947873799726},
    44  		{5, 1, 2, 0.016},
    45  
    46  		{0, 1, 3, 0},
    47  		{0.5, 1, 3, 0},
    48  		{1, 1, 3, 3.0},
    49  		{1.5, 1, 3, 0.592592592592593},
    50  		{2, 1, 3, 0.1875},
    51  		{2.5, 1, 3, 0.0768},
    52  		{3, 1, 3, 0.037037037037037},
    53  		{3.5, 1, 3, 0.019991670137443},
    54  		{4, 1, 3, 0.011718750000000},
    55  		{4.5, 1, 3, 0.007315957933242},
    56  		{5, 1, 3, 0.0048},
    57  	} {
    58  		pdf := Pareto{test.xm, test.alpha, nil}.Prob(test.x)
    59  		if !scalar.EqualWithinAbsOrRel(pdf, test.want, 1e-10, 1e-10) {
    60  			t.Errorf("Pdf mismatch, x = %v, xm = %v, alpha = %v. Got %v, want %v", test.x, test.xm, test.alpha, pdf, test.want)
    61  		}
    62  	}
    63  }
    64  
    65  func TestParetoCDF(t *testing.T) {
    66  	t.Parallel()
    67  	for _, test := range []struct {
    68  		x, xm, alpha, want float64
    69  	}{
    70  		{0, 1, 1, 0},
    71  		{0.5, 1, 1, 0},
    72  		{1, 1, 1, 0},
    73  		{1.5, 1, 1, 0.333333333333333},
    74  		{2, 1, 1, 0.5},
    75  		{2.5, 1, 1, 0.6},
    76  		{3, 1, 1, 0.666666666666667},
    77  		{3.5, 1, 1, 0.714285714285714},
    78  		{4, 1, 1, 0.75},
    79  		{4.5, 1, 1, 0.777777777777778},
    80  		{5, 1, 1, 0.80},
    81  		{5.5, 1, 1, 0.818181818181818},
    82  		{6, 1, 1, 0.833333333333333},
    83  		{6.5, 1, 1, 0.846153846153846},
    84  		{7, 1, 1, 0.857142857142857},
    85  		{7.5, 1, 1, 0.866666666666667},
    86  		{8, 1, 1, 0.875},
    87  		{8.5, 1, 1, 0.882352941176471},
    88  		{9, 1, 1, 0.888888888888889},
    89  		{9.5, 1, 1, 0.894736842105263},
    90  		{10, 1, 1, 0.90},
    91  
    92  		{0, 1, 2, 0},
    93  		{0.5, 1, 2, 0},
    94  		{1, 1, 2, 0},
    95  		{1.5, 1, 2, 0.555555555555556},
    96  		{2, 1, 2, 0.75},
    97  		{2.5, 1, 2, 0.84},
    98  		{3, 1, 2, 0.888888888888889},
    99  		{3.5, 1, 2, 0.918367346938776},
   100  		{4, 1, 2, 0.9375},
   101  		{4.5, 1, 2, 0.950617283950617},
   102  		{5, 1, 2, 0.96},
   103  		{5.5, 1, 2, 0.966942148760331},
   104  		{6, 1, 2, 0.972222222222222},
   105  		{6.5, 1, 2, 0.976331360946746},
   106  		{7, 1, 2, 0.979591836734694},
   107  		{7.5, 1, 2, 0.982222222222222},
   108  		{8, 1, 2, 0.984375000000000},
   109  		{8.5, 1, 2, 0.986159169550173},
   110  		{9, 1, 2, 0.987654320987654},
   111  		{9.5, 1, 2, 0.988919667590028},
   112  		{10, 1, 2, 0.99},
   113  
   114  		{0, 1, 3, 0},
   115  		{0.5, 1, 3, 0},
   116  		{1, 1, 3, 0},
   117  		{1.5, 1, 3, 0.703703703703704},
   118  		{2, 1, 3, 0.875},
   119  		{2.5, 1, 3, 0.936},
   120  		{3, 1, 3, 0.962962962962963},
   121  		{3.5, 1, 3, 0.976676384839650},
   122  		{4, 1, 3, 0.984375000000000},
   123  		{4.5, 1, 3, 0.989026063100137},
   124  		{5, 1, 3, 0.992},
   125  		{5.5, 1, 3, 0.993989481592787},
   126  		{6, 1, 3, 0.995370370370370},
   127  		{6.5, 1, 3, 0.996358670914884},
   128  		{7, 1, 3, 0.997084548104956},
   129  		{7.5, 1, 3, 0.997629629629630},
   130  		{8, 1, 3, 0.998046875000000},
   131  		{8.5, 1, 3, 0.998371667005903},
   132  		{9, 1, 3, 0.998628257887517},
   133  		{9.5, 1, 3, 0.998833649220003},
   134  		{10, 1, 3, 0.999},
   135  	} {
   136  		cdf := Pareto{test.xm, test.alpha, nil}.CDF(test.x)
   137  		if !scalar.EqualWithinAbsOrRel(cdf, test.want, 1e-10, 1e-10) {
   138  			t.Errorf("CDF mismatch, x = %v, xm = %v, alpha = %v. Got %v, want %v", test.x, test.xm, test.alpha, cdf, test.want)
   139  		}
   140  	}
   141  }
   142  
   143  func TestPareto(t *testing.T) {
   144  	t.Parallel()
   145  	src := rand.New(rand.NewSource(1))
   146  	for i, p := range []Pareto{
   147  		{1, 10, src},
   148  		{1, 20, src},
   149  	} {
   150  		testPareto(t, p, i)
   151  	}
   152  }
   153  
   154  func testPareto(t *testing.T, p Pareto, i int) {
   155  	const (
   156  		tol  = 1e-2
   157  		n    = 1e6
   158  		bins = 50
   159  	)
   160  	x := make([]float64, n)
   161  	generateSamples(x, p)
   162  	sort.Float64s(x)
   163  
   164  	checkQuantileCDFSurvival(t, i, x, p, 1e-3)
   165  	testRandLogProbContinuous(t, i, 0, x, p, tol, bins)
   166  	checkMean(t, i, x, p, tol)
   167  	checkVarAndStd(t, i, x, p, tol)
   168  	checkExKurtosis(t, i, x, p, 7e-2)
   169  	checkProbContinuous(t, i, x, p.Xm, math.Inf(1), p, 1e-10)
   170  	checkEntropy(t, i, x, p, 1e-2)
   171  	checkMedian(t, i, x, p, 1e-3)
   172  
   173  	if p.Xm != p.Mode() {
   174  		t.Errorf("Mismatch in mode value: got %v, want %g", p.Mode(), p.Xm)
   175  	}
   176  	if p.NumParameters() != 2 {
   177  		t.Errorf("Mismatch in NumParameters: got %v, want 2", p.NumParameters())
   178  	}
   179  	surv := p.Survival(p.Xm - 0.0001)
   180  	if surv != 1 {
   181  		t.Errorf("Mismatch in Survival below Xm: got %v, want 1", surv)
   182  	}
   183  }
   184  
   185  func TestParetoNotExists(t *testing.T) {
   186  	t.Parallel()
   187  	p := Pareto{0, 4, nil}
   188  	exKurt := p.ExKurtosis()
   189  	if !math.IsNaN(exKurt) {
   190  		t.Errorf("Expected NaN excess kurtosis for Alpha == 4, got %v", exKurt)
   191  	}
   192  	p = Pareto{0, 1, nil}
   193  	mean := p.Mean()
   194  	if !math.IsInf(mean, 1) {
   195  		t.Errorf("Expected mean == +Inf for Alpha == 1, got %v", mean)
   196  	}
   197  	p = Pareto{0, 2, nil}
   198  	variance := p.Variance()
   199  	if !math.IsInf(variance, 1) {
   200  		t.Errorf("Expected variance == +Inf for Alpha == 1, got %v", variance)
   201  	}
   202  	stdDev := p.StdDev()
   203  	if !math.IsInf(stdDev, 1) {
   204  		t.Errorf("Expected standard deviation == +Inf for Alpha == 1, got %v", stdDev)
   205  	}
   206  }
   207  
   208  func BenchmarkParetoRand(b *testing.B) {
   209  	src := rand.New(rand.NewSource(1))
   210  	p := Pareto{1, 1, src}
   211  	for i := 0; i < b.N; i++ {
   212  		p.Rand()
   213  	}
   214  }