diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/CHANGELOG.md golang-github-montanaflynn-stats-0.6.4/CHANGELOG.md --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/CHANGELOG.md 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/CHANGELOG.md 2021-01-13 11:52:47.000000000 +0000 @@ -1,64 +1,14 @@ -# Change Log -## [0.2.0](https://github.com/montanaflynn/stats/tree/0.2.0) + +## [v0.6.4](https://github.com/montanaflynn/stats/compare/v0.6.3...v0.6.4) (2021-01-13) -### Merged pull requests: +### Fix -- Fixed typographical error, changed accomdate to accommodate in README. [\#5](https://github.com/montanaflynn/stats/pull/5) ([saromanov](https://github.com/orthographic-pedant)) +* Fix failing tests due to precision errors on arm64 ([#58](https://github.com/montanaflynn/stats/issues/58)) + +### Update + +* Update examples directory to include a README.md used for synopsis +* Update go.mod to include go version where modules are enabled by default +* Update changelog with v0.6.3 changes -### Package changes: - -- Add `Correlation` function -- Add `Covariance` function -- Add `StandardDeviation` function to be the same as `StandardDeviationPopulation` -- Change `Variance` function to be the same as `PopulationVariation` -- Add helper methods to `Float64Data` -- Add `Float64Data` type to use instead of `[]float64` -- Add `Series` type which references to `[]Coordinate` - -## [0.1.0](https://github.com/montanaflynn/stats/tree/0.1.0) - -Several functions were renamed in this release. They will still function but may be deprecated in the future. - -### Package changes: - -- Rename `VarP` to `PopulationVariance` -- Rename `VarS` to `SampleVariance` -- Rename `LinReg` to `LinearRegression` -- Rename `ExpReg` to `ExponentialRegression` -- Rename `LogReg` to `LogarithmicRegression` -- Rename `StdDevP` to `StandardDeviationPopulation` -- Rename `StdDevS` to `StandardDeviationSample` - -## [0.0.9](https://github.com/montanaflynn/stats/tree/0.0.9) - -### Closed issues: - -- Functions have unexpected side effects [\#3](https://github.com/montanaflynn/stats/issues/3) -- Percentile is not calculated correctly [\#2](https://github.com/montanaflynn/stats/issues/2) - -### Merged pull requests: - -- Sample [\#4](https://github.com/montanaflynn/stats/pull/4) ([saromanov](https://github.com/saromanov)) - -### Package changes: - -- Add HarmonicMean func -- Add GeometricMean func -- Add Outliers stuct and QuantileOutliers func -- Add Interquartile Range, Midhinge and Trimean examples -- Add Trimean -- Add Midhinge -- Add Inter Quartile Range -- Add Quantiles struct and Quantile func -- Add Nearest Rank method of calculating percentiles -- Add errors for all functions -- Add sample -- Add Linear, Exponential and Logarithmic Regression -- Add sample and population variance and deviation -- Add Percentile and Float64ToInt -- Add Round -- Add Standard deviation -- Add Sum -- Add Min and Ma- x -- Add Mean, Median and Mode diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/correlation.go golang-github-montanaflynn-stats-0.6.4/correlation.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/correlation.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/correlation.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,6 +1,8 @@ package stats -import "math" +import ( + "math" +) // Correlation describes the degree of relationship between two sets of data func Correlation(data1, data2 Float64Data) (float64, error) { @@ -9,7 +11,7 @@ l2 := data2.Len() if l1 == 0 || l2 == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } if l1 != l2 { @@ -27,7 +29,32 @@ return covp / (sdev1 * sdev2), nil } -// Pearson calculates the Pearson product-moment correlation coefficient between two variables. +// Pearson calculates the Pearson product-moment correlation coefficient between two variables func Pearson(data1, data2 Float64Data) (float64, error) { return Correlation(data1, data2) } + +// AutoCorrelation is the correlation of a signal with a delayed copy of itself as a function of delay +func AutoCorrelation(data Float64Data, lags int) (float64, error) { + if len(data) < 1 { + return 0, EmptyInputErr + } + + mean, _ := Mean(data) + + var result, q float64 + + for i := 0; i < lags; i++ { + v := (data[0] - mean) * (data[0] - mean) + for i := 1; i < len(data); i++ { + delta0 := data[i-1] - mean + delta1 := data[i] - mean + q += (delta0*delta1 - q) / float64(i+1) + v += (delta1*delta1 - v) / float64(i+1) + } + + result = q / v + } + + return result, nil +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/correlation_test.go golang-github-montanaflynn-stats-0.6.4/correlation_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/correlation_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/correlation_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,50 +1,82 @@ -package stats +package stats_test import ( + "fmt" + "math" "testing" + + "github.com/montanaflynn/stats" ) +func ExampleCorrelation() { + s1 := []float64{1, 2, 3, 4, 5} + s2 := []float64{1, 2, 3, 5, 6} + a, _ := stats.Correlation(s1, s2) + rounded, _ := stats.Round(a, 5) + fmt.Println(rounded) + // Output: 0.99124 +} + func TestCorrelation(t *testing.T) { s1 := []float64{1, 2, 3, 4, 5} s2 := []float64{10, -51.2, 8} s3 := []float64{1, 2, 3, 5, 6} s4 := []float64{} s5 := []float64{0, 0, 0} - - a, err := Correlation(s5, s5) - if err != nil { - t.Errorf("Should not have returned an error") - } - if a != 0 { - t.Errorf("Should have returned 0") - } - - _, err = Correlation(s1, s2) - if err == nil { - t.Errorf("Mismatched slice lengths should have returned an error") - } - - a, err = Correlation(s1, s3) - if err != nil { - t.Errorf("Should not have returned an error") + testCases := []struct { + name string + input [][]float64 + output float64 + err error + }{ + {"Empty Slice Error", [][]float64{s4, s4}, math.NaN(), stats.EmptyInputErr}, + {"Different Length Error", [][]float64{s1, s2}, math.NaN(), stats.SizeErr}, + {"Correlation Value", [][]float64{s1, s3}, 0.9912407071619302, nil}, + {"Same Input Value", [][]float64{s5, s5}, 0.00, nil}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + a, err := stats.Correlation(tc.input[0], tc.input[1]) + if err != nil { + if err != tc.err { + t.Errorf("Should have returned error %s", tc.err) + } + } else if !veryclose(a, tc.output) { + t.Errorf("Result %.08f should be %.08f", a, tc.output) + } + a2, err2 := stats.Pearson(tc.input[0], tc.input[1]) + if err2 != nil { + if err2 != tc.err { + t.Errorf("Should have returned error %s", tc.err) + } + } else if !veryclose(a2, tc.output) { + t.Errorf("Result %.08f should be %.08f", a2, tc.output) + } + }) } +} - if a != 0.9912407071619302 { - t.Errorf("Correlation %v != %v", a, 0.9912407071619302) - } +func ExampleAutoCorrelation() { + s1 := []float64{1, 2, 3, 4, 5} + a, _ := stats.AutoCorrelation(s1, 1) + fmt.Println(a) + // Output: 0.4 +} - _, err = Correlation(s1, s4) - if err == nil { - t.Errorf("Empty slice should have returned an error") - } +func TestAutoCorrelation(t *testing.T) { + s1 := []float64{1, 2, 3, 4, 5} + s2 := []float64{} - a, err = Pearson(s1, s3) + a, err := stats.AutoCorrelation(s1, 1) if err != nil { t.Errorf("Should not have returned an error") } - - if a != 0.9912407071619302 { - t.Errorf("Correlation %v != %v", a, 0.9912407071619302) + if a != 0.4 { + t.Errorf("Should have returned 0.4") } + _, err = stats.AutoCorrelation(s2, 1) + if err != stats.EmptyInputErr { + t.Errorf("Should have returned empty input error") + } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/cumulative_sum.go golang-github-montanaflynn-stats-0.6.4/cumulative_sum.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/cumulative_sum.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/cumulative_sum.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,21 @@ +package stats + +// CumulativeSum calculates the cumulative sum of the input slice +func CumulativeSum(input Float64Data) ([]float64, error) { + + if input.Len() == 0 { + return Float64Data{}, EmptyInput + } + + cumSum := make([]float64, input.Len()) + + for i, val := range input { + if i == 0 { + cumSum[i] = val + } else { + cumSum[i] = cumSum[i-1] + val + } + } + + return cumSum, nil +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/cumulative_sum_test.go golang-github-montanaflynn-stats-0.6.4/cumulative_sum_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/cumulative_sum_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/cumulative_sum_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,53 @@ +package stats_test + +import ( + "fmt" + "reflect" + "testing" + + "github.com/montanaflynn/stats" +) + +func ExampleCumulativeSum() { + data := []float64{1.0, 2.1, 3.2, 4.823, 4.1, 5.8} + csum, _ := stats.CumulativeSum(data) + fmt.Println(csum) + // Output: [1 3.1 6.300000000000001 11.123000000000001 15.223 21.023] +} + +func TestCumulativeSum(t *testing.T) { + for _, c := range []struct { + in []float64 + out []float64 + }{ + {[]float64{1, 2, 3}, []float64{1, 3, 6}}, + {[]float64{1.0, 1.1, 1.2, 2.2}, []float64{1.0, 2.1, 3.3, 5.5}}, + {[]float64{-1, -1, 2, -3}, []float64{-1, -2, 0, -3}}, + } { + got, err := stats.CumulativeSum(c.in) + if err != nil { + t.Errorf("Returned an error") + } + if !reflect.DeepEqual(c.out, got) { + t.Errorf("CumulativeSum(%.1f) => %.1f != %.1f", c.in, got, c.out) + } + } + _, err := stats.CumulativeSum([]float64{}) + if err == nil { + t.Errorf("Empty slice should have returned an error") + } +} + +func BenchmarkCumulativeSumSmallFloatSlice(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = stats.CumulativeSum(makeFloatSlice(5)) + } +} + +func BenchmarkCumulativeSumLargeFloatSlice(b *testing.B) { + lf := makeFloatSlice(100000) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = stats.CumulativeSum(lf) + } +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/data.go golang-github-montanaflynn-stats-0.6.4/data.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/data.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/data.go 2021-01-13 11:52:47.000000000 +0000 @@ -24,6 +24,9 @@ // Sum returns the total of all the numbers in the data func (f Float64Data) Sum() (float64, error) { return Sum(f) } +// CumulativeSum returns the cumulative sum of the data +func (f Float64Data) CumulativeSum() ([]float64, error) { return CumulativeSum(f) } + // Mean returns the mean of the data func (f Float64Data) Mean() (float64, error) { return Mean(f) } @@ -84,6 +87,11 @@ return Correlation(f, d) } +// AutoCorrelation is the correlation of a signal with a delayed copy of itself as a function of delay +func (f Float64Data) AutoCorrelation(lags int) (float64, error) { + return AutoCorrelation(f, lags) +} + // Pearson calculates the Pearson product-moment correlation coefficient between two variables. func (f Float64Data) Pearson(d Float64Data) (float64, error) { return Pearson(f, d) @@ -134,7 +142,23 @@ return Covariance(f, d) } -// CovariancePopulation computes covariance for entire population between two variables. +// CovariancePopulation computes covariance for entire population between two variables func (f Float64Data) CovariancePopulation(d Float64Data) (float64, error) { return CovariancePopulation(f, d) } + +// Sigmoid returns the input values along the sigmoid or s-shaped curve +func (f Float64Data) Sigmoid() ([]float64, error) { + return Sigmoid(f) +} + +// SoftMax returns the input values in the range of 0 to 1 +// with sum of all the probabilities being equal to one. +func (f Float64Data) SoftMax() ([]float64, error) { + return SoftMax(f) +} + +// Entropy provides calculation of the entropy +func (f Float64Data) Entropy() (float64, error) { + return Entropy(f) +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/data_test.go golang-github-montanaflynn-stats-0.6.4/data_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/data_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/data_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,14 +1,18 @@ -package stats +package stats_test import ( "math" + "math/rand" "reflect" "runtime" "testing" + "time" + + "github.com/montanaflynn/stats" ) -var data1 = Float64Data{-10, -10.001, 5, 1.1, 2, 3, 4.20, 5} -var data2 = Float64Data{-9, -9.001, 4, .1, 1, 2, 3.20, 5} +var data1 = stats.Float64Data{-10, -10.001, 5, 1.1, 2, 3, 4.20, 5} +var data2 = stats.Float64Data{-9, -9.001, 4, .1, 1, 2, 3.20, 5} func getFunctionName(i interface{}) string { return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() @@ -18,11 +22,31 @@ if err != nil { t.Errorf("%s returned an error", name) } - if result != f { + if !veryclose(result, f) { t.Errorf("%s() => %v != %v", name, result, f) } } +// makeFloatSlice makes a slice of float64s +func makeFloatSlice(c int) []float64 { + lf := make([]float64, 0, c) + for i := 0; i < c; i++ { + f := float64(i * 100) + lf = append(lf, f) + } + return lf +} + +func makeRandFloatSlice(c int) []float64 { + lf := make([]float64, 0, c) + rand.Seed(time.Now().UTC().UnixNano()) + for i := 0; i < c; i++ { + f := float64(i * 100) + lf = append(lf, f) + } + return lf +} + func TestInterfaceMethods(t *testing.T) { // Test Get a := data1.Get(1) @@ -38,7 +62,7 @@ // Test Less b := data1.Less(0, 5) - if b != true { + if !b { t.Errorf("Less() => %v != %v", b, true) } @@ -69,6 +93,13 @@ t.Errorf("Sum() => %v != %v", m, 0.2990000000000004) } + // Test CumulativeSum + cs, _ := data1.CumulativeSum() + want := []float64{5, -5.0009999999999994, -15.001, -13.901, -11.901, -8.901, -4.701, 0.2990000000000004} + if !reflect.DeepEqual(cs, want) { + t.Errorf("CumulativeSum() => %v != %v", cs, want) + } + // Test Mean m, _ = data1.Mean() if m != 0.03737500000000005 { @@ -140,7 +171,7 @@ } -func assertOtherDataMethods(fn func(d Float64Data) (float64, error), d Float64Data, f float64, t *testing.T) { +func assertOtherDataMethods(fn func(d stats.Float64Data) (float64, error), d stats.Float64Data, f float64, t *testing.T) { res, err := fn(d) checkResult(res, err, getFunctionName(fn), f, t) } @@ -154,6 +185,13 @@ assertOtherDataMethods(data1.CovariancePopulation, data2, 6.458743859374998, t) } +func TestAutoCorrelationMethod(t *testing.T) { + _, err := data1.AutoCorrelation(1) + if err != nil { + t.Error("stats.Float64Data.AutoCorrelation returned an error") + } +} + func TestSampleMethod(t *testing.T) { // Test Sample method _, err := data1.Sample(5, true) @@ -176,31 +214,58 @@ } } +func TestSigmoidMethod(t *testing.T) { + d := stats.LoadRawData([]float64{3.0, 1.0, 2.1}) + a := []float64{0.9525741268224334, 0.7310585786300049, 0.8909031788043871} + s, _ := d.Sigmoid() + if !reflect.DeepEqual(s, a) { + t.Errorf("Sigmoid() => %g != %g", s, a) + } +} + +func TestSoftMaxMethod(t *testing.T) { + d := stats.LoadRawData([]float64{3.0, 1.0, 0.2}) + a := []float64{0.8360188027814407, 0.11314284146556013, 0.05083835575299916} + s, _ := d.SoftMax() + if !reflect.DeepEqual(s, a) { + t.Errorf("SoftMax() => %g != %g", s, a) + } +} + +func TestEntropyMethod(t *testing.T) { + d := stats.LoadRawData([]float64{3.0, 1.0, 0.2}) + a := 0.7270013625470586 + e, _ := d.Entropy() + if e != a { + t.Errorf("Entropy() => %v != %v", e, a) + } +} + // Here we show the regular way of doing it // with a plain old slice of float64s func BenchmarkRegularAPI(b *testing.B) { for i := 0; i < b.N; i++ { data := []float64{-10, -7, -3.11, 5, 1.1, 2, 3, 4.20, 5, 18} - Min(data) - Max(data) - Sum(data) - Mean(data) - Median(data) - Mode(data) + _, _ = stats.Min(data) + _, _ = stats.Max(data) + _, _ = stats.Sum(data) + _, _ = stats.Mean(data) + _, _ = stats.Median(data) + _, _ = stats.Mode(data) } } // Here's where things get interesting // and we start to use the included -// Float64Data type and methods +// stats.Float64Data type and methods func BenchmarkMethodsAPI(b *testing.B) { for i := 0; i < b.N; i++ { - data := Float64Data{-10, -7, -3.11, 5, 1.1, 2, 3, 4.20, 5, 18} - data.Min() - data.Max() - data.Sum() - data.Mean() - data.Median() - data.Mode() + data := stats.Float64Data{-10, -7, -3.11, 5, 1.1, 2, 3, 4.20, 5, 18} + _, _ = data.Min() + _, _ = data.Max() + _, _ = data.Sum() + _, _ = data.Mean() + _, _ = data.Median() + _, _ = data.Mode() } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/changelog golang-github-montanaflynn-stats-0.6.4/debian/changelog --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/changelog 2017-08-08 07:05:09.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/debian/changelog 2021-01-14 08:03:43.000000000 +0000 @@ -1,3 +1,54 @@ +golang-github-montanaflynn-stats (0.6.4-2) unstable; urgency=medium + + * debian/control: Change Section from devel to golang + + -- Anthony Fok Thu, 14 Jan 2021 01:03:43 -0700 + +golang-github-montanaflynn-stats (0.6.4-1) unstable; urgency=medium + + * New upstream version 0.6.4 + * Remove 0001-Fix-failing-tests-due-to-precision-errors-on-arm64.patch as + it is applied upstream, see https://github.com/montanaflynn/stats/pull/58 + Thanks to Guinness and Nicolas Braud-Santoni (nicoo) for the fix! + + -- Anthony Fok Wed, 13 Jan 2021 19:36:15 -0700 + +golang-github-montanaflynn-stats (0.6.3-3) unstable; urgency=low + + * Team upload. + * Fix tests on non-amd64 architectures (Closes: #976562) + + -- Guinness Tue, 15 Dec 2020 18:53:05 +0100 + +golang-github-montanaflynn-stats (0.6.3-2) unstable; urgency=medium + + * debian/rules: Fix FTBFS by skipping test on non-amd64 architectures until + test failures due to FMA (fused multiply-add) differences are resolved. + See https://github.com/montanaflynn/stats/issues/33 (Closes: #976562) + * debian/control: Bump Standards-Version to 4.5.1 (no change) + + -- Anthony Fok Tue, 15 Dec 2020 05:36:45 -0700 + +golang-github-montanaflynn-stats (0.6.3-1) unstable; urgency=medium + + [ Alexandre Viau ] + * Point Vcs-* urls to salsa.debian.org. + + [ Anthony Fok ] + * New upstream version 0.6.3 + * debian/watch: Update to version=4 + * debian/gbp.conf: Set debian-branch to debian/sid for DEP-14 conformance + * Apply "cme fix dpkg" fixes: + - Organize debian/control fields + - Change Priority from "extra" to "optional" + - Update debhelper dependency to "Build-Depends: debhelper-compat (= 13)" + - Bump Standards-Version to 4.5.0 (no change) + * Add "Rules-Requires-Root: no" to debian/control + * Update Maintainer email address to team+pkg-go@tracker.debian.org + * Add debian/upstream/metadata + + -- Anthony Fok Fri, 23 Oct 2020 01:36:30 -0600 + golang-github-montanaflynn-stats (0.2.0+git20170729.66.4a16327-1) unstable; urgency=medium * Initial release (Closes: #871464) diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/compat golang-github-montanaflynn-stats-0.6.4/debian/compat --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/compat 2017-08-08 06:39:09.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -10 diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/control golang-github-montanaflynn-stats-0.6.4/debian/control --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/control 2017-08-08 06:59:01.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/debian/control 2021-01-14 08:03:18.000000000 +0000 @@ -1,17 +1,18 @@ Source: golang-github-montanaflynn-stats -Section: devel -Priority: extra -Maintainer: Debian Go Packaging Team +Maintainer: Debian Go Packaging Team Uploaders: Anthony Fok -Build-Depends: debhelper (>= 10), +Section: golang +Testsuite: autopkgtest-pkg-go +Priority: optional +Build-Depends: debhelper-compat (= 13), dh-golang, golang-any -Standards-Version: 4.0.0 +Standards-Version: 4.5.1 +Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-github-montanaflynn-stats +Vcs-Git: https://salsa.debian.org/go-team/packages/golang-github-montanaflynn-stats.git Homepage: https://github.com/montanaflynn/stats -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-go/packages/golang-github-montanaflynn-stats.git -Vcs-Git: https://anonscm.debian.org/git/pkg-go/packages/golang-github-montanaflynn-stats.git +Rules-Requires-Root: no XS-Go-Import-Path: github.com/montanaflynn/stats -Testsuite: autopkgtest-pkg-go Package: golang-github-montanaflynn-stats-dev Architecture: all diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/gbp.conf golang-github-montanaflynn-stats-0.6.4/debian/gbp.conf --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/gbp.conf 2017-08-08 06:39:10.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/debian/gbp.conf 2020-10-23 07:25:43.000000000 +0000 @@ -1,2 +1,4 @@ [DEFAULT] +debian-branch = debian/sid +dist = DEP14 pristine-tar = True diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/gitlab-ci.yml golang-github-montanaflynn-stats-0.6.4/debian/gitlab-ci.yml --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/gitlab-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/debian/gitlab-ci.yml 2020-10-23 07:20:45.000000000 +0000 @@ -0,0 +1,28 @@ + +# auto-generated, DO NOT MODIFY. +# The authoritative copy of this file lives at: +# https://salsa.debian.org/go-team/ci/blob/master/cmd/ci/gitlabciyml.go + +# TODO: publish under debian-go-team/ci +image: stapelberg/ci2 + +test_the_archive: + artifacts: + paths: + - before-applying-commit.json + - after-applying-commit.json + script: + # Create an overlay to discard writes to /srv/gopath/src after the build: + - "rm -rf /cache/overlay/{upper,work}" + - "mkdir -p /cache/overlay/{upper,work}" + - "mount -t overlay overlay -o lowerdir=/srv/gopath/src,upperdir=/cache/overlay/upper,workdir=/cache/overlay/work /srv/gopath/src" + - "export GOPATH=/srv/gopath" + - "export GOCACHE=/cache/go" + # Build the world as-is: + - "ci-build -exemptions=/var/lib/ci-build/exemptions.json > before-applying-commit.json" + # Copy this package into the overlay: + - "GBP_CONF_FILES=:debian/gbp.conf gbp buildpackage --git-no-pristine-tar --git-ignore-branch --git-ignore-new --git-export-dir=/tmp/export --git-no-overlay --git-tarball-dir=/nonexistant --git-cleaner=/bin/true --git-builder='dpkg-buildpackage -S -d --no-sign'" + - "pgt-gopath -dsc /tmp/export/*.dsc" + # Rebuild the world: + - "ci-build -exemptions=/var/lib/ci-build/exemptions.json > after-applying-commit.json" + - "ci-diff before-applying-commit.json after-applying-commit.json" diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/upstream/metadata golang-github-montanaflynn-stats-0.6.4/debian/upstream/metadata --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/debian/upstream/metadata 2020-10-23 07:34:45.000000000 +0000 @@ -0,0 +1,5 @@ +--- +Bug-Database: https://github.com/montanaflynn/stats/issues +Bug-Submit: https://github.com/montanaflynn/stats/issues/new +Repository: https://github.com/montanaflynn/stats.git +Repository-Browse: https://github.com/montanaflynn/stats diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/watch golang-github-montanaflynn-stats-0.6.4/debian/watch --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/debian/watch 2017-08-08 06:39:10.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/debian/watch 2020-12-15 12:35:48.000000000 +0000 @@ -1,4 +1,4 @@ -version=3 -opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/golang-github-montanaflynn-stats-\$1\.tar\.gz/,\ -uversionmangle=s/(\d)[_\.\-\+]?(RC|rc|pre|dev|beta|alpha)[.]?(\d*)$/\$1~\$2\$3/ \ - https://github.com/montanaflynn/stats/tags .*/v?(\d\S*)\.tar\.gz +version=4 +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%golang-github-montanaflynn-stats-$1.tar.gz%" \ + https://github.com/montanaflynn/stats/tags \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/deviation.go golang-github-montanaflynn-stats-0.6.4/deviation.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/deviation.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/deviation.go 2021-01-13 11:52:47.000000000 +0000 @@ -10,7 +10,7 @@ // MedianAbsoluteDeviationPopulation finds the median of the absolute deviations from the population median func MedianAbsoluteDeviationPopulation(input Float64Data) (mad float64, err error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } i := copyslice(input) @@ -32,7 +32,7 @@ func StandardDeviationPopulation(input Float64Data) (sdev float64, err error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Get the population variance @@ -46,7 +46,7 @@ func StandardDeviationSample(input Float64Data) (sdev float64, err error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Get the sample variance diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/deviation_test.go golang-github-montanaflynn-stats-0.6.4/deviation_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/deviation_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/deviation_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,20 +1,22 @@ -package stats +package stats_test import ( "math" "testing" + + "github.com/montanaflynn/stats" ) func TestMedianAbsoluteDeviation(t *testing.T) { - _, err := MedianAbsoluteDeviation([]float64{1, 2, 3}) + _, err := stats.MedianAbsoluteDeviation([]float64{1, 2, 3}) if err != nil { t.Errorf("Returned an error") } } func TestMedianAbsoluteDeviationPopulation(t *testing.T) { - s, _ := MedianAbsoluteDeviation([]float64{1, 2, 3}) - m, err := Round(s, 2) + s, _ := stats.MedianAbsoluteDeviation([]float64{1, 2, 3}) + m, err := stats.Round(s, 2) if err != nil { t.Errorf("Returned an error") } @@ -22,8 +24,8 @@ t.Errorf("%.10f != %.10f", m, 1.00) } - s, _ = MedianAbsoluteDeviation([]float64{-2, 0, 4, 5, 7}) - m, err = Round(s, 2) + s, _ = stats.MedianAbsoluteDeviation([]float64{-2, 0, 4, 5, 7}) + m, err = stats.Round(s, 2) if err != nil { t.Errorf("Returned an error") } @@ -31,30 +33,30 @@ t.Errorf("%.10f != %.10f", m, 3.00) } - m, _ = MedianAbsoluteDeviation([]float64{}) + m, _ = stats.MedianAbsoluteDeviation([]float64{}) if !math.IsNaN(m) { t.Errorf("%.1f != %.1f", m, math.NaN()) } } func TestStandardDeviation(t *testing.T) { - _, err := StandardDeviation([]float64{1, 2, 3}) + _, err := stats.StandardDeviation([]float64{1, 2, 3}) if err != nil { t.Errorf("Returned an error") } } func TestStandardDeviationPopulation(t *testing.T) { - s, _ := StandardDeviationPopulation([]float64{1, 2, 3}) - m, err := Round(s, 2) + s, _ := stats.StandardDeviationPopulation([]float64{1, 2, 3}) + m, err := stats.Round(s, 2) if err != nil { t.Errorf("Returned an error") } if m != 0.82 { t.Errorf("%.10f != %.10f", m, 0.82) } - s, _ = StandardDeviationPopulation([]float64{-1, -2, -3.3}) - m, err = Round(s, 2) + s, _ = stats.StandardDeviationPopulation([]float64{-1, -2, -3.3}) + m, err = stats.Round(s, 2) if err != nil { t.Errorf("Returned an error") } @@ -62,23 +64,23 @@ t.Errorf("%.10f != %.10f", m, 0.94) } - m, _ = StandardDeviationPopulation([]float64{}) + m, _ = stats.StandardDeviationPopulation([]float64{}) if !math.IsNaN(m) { t.Errorf("%.1f != %.1f", m, math.NaN()) } } func TestStandardDeviationSample(t *testing.T) { - s, _ := StandardDeviationSample([]float64{1, 2, 3}) - m, err := Round(s, 2) + s, _ := stats.StandardDeviationSample([]float64{1, 2, 3}) + m, err := stats.Round(s, 2) if err != nil { t.Errorf("Returned an error") } if m != 1.0 { t.Errorf("%.10f != %.10f", m, 1.0) } - s, _ = StandardDeviationSample([]float64{-1, -2, -3.3}) - m, err = Round(s, 2) + s, _ = stats.StandardDeviationSample([]float64{-1, -2, -3.3}) + m, err = stats.Round(s, 2) if err != nil { t.Errorf("Returned an error") } @@ -86,7 +88,7 @@ t.Errorf("%.10f != %.10f", m, 1.15) } - m, _ = StandardDeviationSample([]float64{}) + m, _ = stats.StandardDeviationSample([]float64{}) if !math.IsNaN(m) { t.Errorf("%.1f != %.1f", m, math.NaN()) } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/distances.go golang-github-montanaflynn-stats-0.6.4/distances.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/distances.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/distances.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,88 @@ +package stats + +import ( + "math" +) + +// Validate data for distance calculation +func validateData(dataPointX, dataPointY Float64Data) error { + if len(dataPointX) == 0 || len(dataPointY) == 0 { + return EmptyInputErr + } + + if len(dataPointX) != len(dataPointY) { + return SizeErr + } + return nil +} + +// ChebyshevDistance computes the Chebyshev distance between two data sets +func ChebyshevDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) { + err = validateData(dataPointX, dataPointY) + if err != nil { + return math.NaN(), err + } + var tempDistance float64 + for i := 0; i < len(dataPointY); i++ { + tempDistance = math.Abs(dataPointX[i] - dataPointY[i]) + if distance < tempDistance { + distance = tempDistance + } + } + return distance, nil +} + +// EuclideanDistance computes the Euclidean distance between two data sets +func EuclideanDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) { + + err = validateData(dataPointX, dataPointY) + if err != nil { + return math.NaN(), err + } + distance = 0 + for i := 0; i < len(dataPointX); i++ { + distance = distance + ((dataPointX[i] - dataPointY[i]) * (dataPointX[i] - dataPointY[i])) + } + return math.Sqrt(distance), nil +} + +// ManhattanDistance computes the Manhattan distance between two data sets +func ManhattanDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) { + err = validateData(dataPointX, dataPointY) + if err != nil { + return math.NaN(), err + } + distance = 0 + for i := 0; i < len(dataPointX); i++ { + distance = distance + math.Abs(dataPointX[i]-dataPointY[i]) + } + return distance, nil +} + +// MinkowskiDistance computes the Minkowski distance between two data sets +// +// Arguments: +// dataPointX: First set of data points +// dataPointY: Second set of data points. Length of both data +// sets must be equal. +// lambda: aka p or city blocks; With lambda = 1 +// returned distance is manhattan distance and +// lambda = 2; it is euclidean distance. Lambda +// reaching to infinite - distance would be chebysev +// distance. +// Return: +// Distance or error +func MinkowskiDistance(dataPointX, dataPointY Float64Data, lambda float64) (distance float64, err error) { + err = validateData(dataPointX, dataPointY) + if err != nil { + return math.NaN(), err + } + for i := 0; i < len(dataPointY); i++ { + distance = distance + math.Pow(math.Abs(dataPointX[i]-dataPointY[i]), lambda) + } + distance = math.Pow(distance, 1/lambda) + if math.IsInf(distance, 1) { + return math.NaN(), InfValue + } + return distance, nil +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/distances_test.go golang-github-montanaflynn-stats-0.6.4/distances_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/distances_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/distances_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,79 @@ +package stats_test + +import ( + "fmt" + "testing" + + "github.com/montanaflynn/stats" +) + +type distanceFunctionType func(stats.Float64Data, stats.Float64Data) (float64, error) + +var minkowskiDistanceTestMatrix = []struct { + dataPointX []float64 + dataPointY []float64 + lambda float64 + distance float64 +}{ + {[]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, 1, 24}, + {[]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, 2, 10.583005244258363}, + {[]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, 99, 6}, +} + +var distanceTestMatrix = []struct { + dataPointX []float64 + dataPointY []float64 + distance float64 + distanceFunction distanceFunctionType +}{ + {[]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, 6, stats.ChebyshevDistance}, + {[]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, 24, stats.ManhattanDistance}, + {[]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, 10.583005244258363, stats.EuclideanDistance}, +} + +func TestDataSetDistances(t *testing.T) { + + // Test Minkowski Distance with different lambda values. + for _, testData := range minkowskiDistanceTestMatrix { + distance, err := stats.MinkowskiDistance(testData.dataPointX, testData.dataPointY, testData.lambda) + if err != nil && distance != testData.distance { + t.Errorf("Failed to compute Minkowski distance.") + } + + _, err = stats.MinkowskiDistance([]float64{}, []float64{}, 3) + if err == nil { + t.Errorf("Empty slices should have resulted in an error") + } + + _, err = stats.MinkowskiDistance([]float64{1, 2, 3}, []float64{1, 4}, 3) + if err == nil { + t.Errorf("Different length slices should have resulted in an error") + } + + _, err = stats.MinkowskiDistance([]float64{999, 999, 999}, []float64{1, 1, 1}, 1000) + if err == nil { + t.Errorf("Infinite distance should have resulted in an error") + } + } + + // Compute distance with the help of all algorithms. + for _, testSet := range distanceTestMatrix { + distance, err := testSet.distanceFunction(testSet.dataPointX, testSet.dataPointY) + if err != nil && testSet.distance != distance { + t.Errorf("Failed to compute distance.") + } + + _, err = testSet.distanceFunction([]float64{}, []float64{}) + if err == nil { + t.Errorf("Empty slices should have resulted in an error") + } + } +} + +func ExampleChebyshevDistance() { + d1 := []float64{2, 3, 4, 5, 6, 7, 8} + d2 := []float64{8, 7, 6, 5, 4, 3, 2} + cd, _ := stats.ChebyshevDistance(d1, d2) + fmt.Println(cd) + // Output: 6 +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/doc.go golang-github-montanaflynn-stats-0.6.4/doc.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/doc.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/doc.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,23 @@ +/* +Package stats is a well tested and comprehensive +statistics library package with no dependencies. + +Example Usage: + + // start with some source data to use + data := []float64{1.0, 2.1, 3.2, 4.823, 4.1, 5.8} + + // you could also use different types like this + // data := stats.LoadRawData([]int{1, 2, 3, 4, 5}) + // data := stats.LoadRawData([]interface{}{1.1, "2", 3}) + // etc... + + median, _ := stats.Median(data) + fmt.Println(median) // 3.65 + + roundedMedian, _ := stats.Round(median, 0) + fmt.Println(roundedMedian) // 4 + +MIT License Copyright (c) 2014-2020 Montana Flynn (https://montanaflynn.com) +*/ +package stats diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/DOCUMENTATION.md golang-github-montanaflynn-stats-0.6.4/DOCUMENTATION.md --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/DOCUMENTATION.md 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/DOCUMENTATION.md 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,1227 @@ + + +# stats +`import "github.com/montanaflynn/stats"` + +* [Overview](#pkg-overview) +* [Index](#pkg-index) +* [Examples](#pkg-examples) +* [Subdirectories](#pkg-subdirectories) + +## Overview +Package stats is a well tested and comprehensive +statistics library package with no dependencies. + +Example Usage: + + + // start with some source data to use + data := []float64{1.0, 2.1, 3.2, 4.823, 4.1, 5.8} + + // you could also use different types like this + // data := stats.LoadRawData([]int{1, 2, 3, 4, 5}) + // data := stats.LoadRawData([]interface{}{1.1, "2", 3}) + // etc... + + median, _ := stats.Median(data) + fmt.Println(median) // 3.65 + + roundedMedian, _ := stats.Round(median, 0) + fmt.Println(roundedMedian) // 4 + +MIT License Copyright (c) 2014-2020 Montana Flynn (https://montanaflynn.com) + + + + +## Index +* [Variables](#pkg-variables) +* [func AutoCorrelation(data Float64Data, lags int) (float64, error)](#AutoCorrelation) +* [func ChebyshevDistance(dataPointX, dataPointY Float64Data) (distance float64, err error)](#ChebyshevDistance) +* [func Correlation(data1, data2 Float64Data) (float64, error)](#Correlation) +* [func Covariance(data1, data2 Float64Data) (float64, error)](#Covariance) +* [func CovariancePopulation(data1, data2 Float64Data) (float64, error)](#CovariancePopulation) +* [func CumulativeSum(input Float64Data) ([]float64, error)](#CumulativeSum) +* [func Entropy(input Float64Data) (float64, error)](#Entropy) +* [func EuclideanDistance(dataPointX, dataPointY Float64Data) (distance float64, err error)](#EuclideanDistance) +* [func GeometricMean(input Float64Data) (float64, error)](#GeometricMean) +* [func HarmonicMean(input Float64Data) (float64, error)](#HarmonicMean) +* [func InterQuartileRange(input Float64Data) (float64, error)](#InterQuartileRange) +* [func ManhattanDistance(dataPointX, dataPointY Float64Data) (distance float64, err error)](#ManhattanDistance) +* [func Max(input Float64Data) (max float64, err error)](#Max) +* [func Mean(input Float64Data) (float64, error)](#Mean) +* [func Median(input Float64Data) (median float64, err error)](#Median) +* [func MedianAbsoluteDeviation(input Float64Data) (mad float64, err error)](#MedianAbsoluteDeviation) +* [func MedianAbsoluteDeviationPopulation(input Float64Data) (mad float64, err error)](#MedianAbsoluteDeviationPopulation) +* [func Midhinge(input Float64Data) (float64, error)](#Midhinge) +* [func Min(input Float64Data) (min float64, err error)](#Min) +* [func MinkowskiDistance(dataPointX, dataPointY Float64Data, lambda float64) (distance float64, err error)](#MinkowskiDistance) +* [func Mode(input Float64Data) (mode []float64, err error)](#Mode) +* [func Ncr(n, r int) int](#Ncr) +* [func NormBoxMullerRvs(loc float64, scale float64, size int) []float64](#NormBoxMullerRvs) +* [func NormCdf(x float64, loc float64, scale float64) float64](#NormCdf) +* [func NormEntropy(loc float64, scale float64) float64](#NormEntropy) +* [func NormFit(data []float64) [2]float64](#NormFit) +* [func NormInterval(alpha float64, loc float64, scale float64) [2]float64](#NormInterval) +* [func NormIsf(p float64, loc float64, scale float64) (x float64)](#NormIsf) +* [func NormLogCdf(x float64, loc float64, scale float64) float64](#NormLogCdf) +* [func NormLogPdf(x float64, loc float64, scale float64) float64](#NormLogPdf) +* [func NormLogSf(x float64, loc float64, scale float64) float64](#NormLogSf) +* [func NormMean(loc float64, scale float64) float64](#NormMean) +* [func NormMedian(loc float64, scale float64) float64](#NormMedian) +* [func NormMoment(n int, loc float64, scale float64) float64](#NormMoment) +* [func NormPdf(x float64, loc float64, scale float64) float64](#NormPdf) +* [func NormPpf(p float64, loc float64, scale float64) (x float64)](#NormPpf) +* [func NormPpfRvs(loc float64, scale float64, size int) []float64](#NormPpfRvs) +* [func NormSf(x float64, loc float64, scale float64) float64](#NormSf) +* [func NormStats(loc float64, scale float64, moments string) []float64](#NormStats) +* [func NormStd(loc float64, scale float64) float64](#NormStd) +* [func NormVar(loc float64, scale float64) float64](#NormVar) +* [func Pearson(data1, data2 Float64Data) (float64, error)](#Pearson) +* [func Percentile(input Float64Data, percent float64) (percentile float64, err error)](#Percentile) +* [func PercentileNearestRank(input Float64Data, percent float64) (percentile float64, err error)](#PercentileNearestRank) +* [func PopulationVariance(input Float64Data) (pvar float64, err error)](#PopulationVariance) +* [func Round(input float64, places int) (rounded float64, err error)](#Round) +* [func Sample(input Float64Data, takenum int, replacement bool) ([]float64, error)](#Sample) +* [func SampleVariance(input Float64Data) (svar float64, err error)](#SampleVariance) +* [func Sigmoid(input Float64Data) ([]float64, error)](#Sigmoid) +* [func SoftMax(input Float64Data) ([]float64, error)](#SoftMax) +* [func StableSample(input Float64Data, takenum int) ([]float64, error)](#StableSample) +* [func StandardDeviation(input Float64Data) (sdev float64, err error)](#StandardDeviation) +* [func StandardDeviationPopulation(input Float64Data) (sdev float64, err error)](#StandardDeviationPopulation) +* [func StandardDeviationSample(input Float64Data) (sdev float64, err error)](#StandardDeviationSample) +* [func StdDevP(input Float64Data) (sdev float64, err error)](#StdDevP) +* [func StdDevS(input Float64Data) (sdev float64, err error)](#StdDevS) +* [func Sum(input Float64Data) (sum float64, err error)](#Sum) +* [func Trimean(input Float64Data) (float64, error)](#Trimean) +* [func VarP(input Float64Data) (sdev float64, err error)](#VarP) +* [func VarS(input Float64Data) (sdev float64, err error)](#VarS) +* [func Variance(input Float64Data) (sdev float64, err error)](#Variance) +* [type Coordinate](#Coordinate) + * [func ExpReg(s []Coordinate) (regressions []Coordinate, err error)](#ExpReg) + * [func LinReg(s []Coordinate) (regressions []Coordinate, err error)](#LinReg) + * [func LogReg(s []Coordinate) (regressions []Coordinate, err error)](#LogReg) +* [type Float64Data](#Float64Data) + * [func LoadRawData(raw interface{}) (f Float64Data)](#LoadRawData) + * [func (f Float64Data) AutoCorrelation(lags int) (float64, error)](#Float64Data.AutoCorrelation) + * [func (f Float64Data) Correlation(d Float64Data) (float64, error)](#Float64Data.Correlation) + * [func (f Float64Data) Covariance(d Float64Data) (float64, error)](#Float64Data.Covariance) + * [func (f Float64Data) CovariancePopulation(d Float64Data) (float64, error)](#Float64Data.CovariancePopulation) + * [func (f Float64Data) CumulativeSum() ([]float64, error)](#Float64Data.CumulativeSum) + * [func (f Float64Data) Entropy() (float64, error)](#Float64Data.Entropy) + * [func (f Float64Data) GeometricMean() (float64, error)](#Float64Data.GeometricMean) + * [func (f Float64Data) Get(i int) float64](#Float64Data.Get) + * [func (f Float64Data) HarmonicMean() (float64, error)](#Float64Data.HarmonicMean) + * [func (f Float64Data) InterQuartileRange() (float64, error)](#Float64Data.InterQuartileRange) + * [func (f Float64Data) Len() int](#Float64Data.Len) + * [func (f Float64Data) Less(i, j int) bool](#Float64Data.Less) + * [func (f Float64Data) Max() (float64, error)](#Float64Data.Max) + * [func (f Float64Data) Mean() (float64, error)](#Float64Data.Mean) + * [func (f Float64Data) Median() (float64, error)](#Float64Data.Median) + * [func (f Float64Data) MedianAbsoluteDeviation() (float64, error)](#Float64Data.MedianAbsoluteDeviation) + * [func (f Float64Data) MedianAbsoluteDeviationPopulation() (float64, error)](#Float64Data.MedianAbsoluteDeviationPopulation) + * [func (f Float64Data) Midhinge(d Float64Data) (float64, error)](#Float64Data.Midhinge) + * [func (f Float64Data) Min() (float64, error)](#Float64Data.Min) + * [func (f Float64Data) Mode() ([]float64, error)](#Float64Data.Mode) + * [func (f Float64Data) Pearson(d Float64Data) (float64, error)](#Float64Data.Pearson) + * [func (f Float64Data) Percentile(p float64) (float64, error)](#Float64Data.Percentile) + * [func (f Float64Data) PercentileNearestRank(p float64) (float64, error)](#Float64Data.PercentileNearestRank) + * [func (f Float64Data) PopulationVariance() (float64, error)](#Float64Data.PopulationVariance) + * [func (f Float64Data) Quartile(d Float64Data) (Quartiles, error)](#Float64Data.Quartile) + * [func (f Float64Data) QuartileOutliers() (Outliers, error)](#Float64Data.QuartileOutliers) + * [func (f Float64Data) Sample(n int, r bool) ([]float64, error)](#Float64Data.Sample) + * [func (f Float64Data) SampleVariance() (float64, error)](#Float64Data.SampleVariance) + * [func (f Float64Data) Sigmoid() ([]float64, error)](#Float64Data.Sigmoid) + * [func (f Float64Data) SoftMax() ([]float64, error)](#Float64Data.SoftMax) + * [func (f Float64Data) StandardDeviation() (float64, error)](#Float64Data.StandardDeviation) + * [func (f Float64Data) StandardDeviationPopulation() (float64, error)](#Float64Data.StandardDeviationPopulation) + * [func (f Float64Data) StandardDeviationSample() (float64, error)](#Float64Data.StandardDeviationSample) + * [func (f Float64Data) Sum() (float64, error)](#Float64Data.Sum) + * [func (f Float64Data) Swap(i, j int)](#Float64Data.Swap) + * [func (f Float64Data) Trimean(d Float64Data) (float64, error)](#Float64Data.Trimean) + * [func (f Float64Data) Variance() (float64, error)](#Float64Data.Variance) +* [type Outliers](#Outliers) + * [func QuartileOutliers(input Float64Data) (Outliers, error)](#QuartileOutliers) +* [type Quartiles](#Quartiles) + * [func Quartile(input Float64Data) (Quartiles, error)](#Quartile) +* [type Series](#Series) + * [func ExponentialRegression(s Series) (regressions Series, err error)](#ExponentialRegression) + * [func LinearRegression(s Series) (regressions Series, err error)](#LinearRegression) + * [func LogarithmicRegression(s Series) (regressions Series, err error)](#LogarithmicRegression) + +#### Examples +* [AutoCorrelation](#example_AutoCorrelation) +* [ChebyshevDistance](#example_ChebyshevDistance) +* [Correlation](#example_Correlation) +* [CumulativeSum](#example_CumulativeSum) +* [Entropy](#example_Entropy) +* [LinearRegression](#example_LinearRegression) +* [LoadRawData](#example_LoadRawData) +* [Max](#example_Max) +* [Median](#example_Median) +* [Min](#example_Min) +* [Round](#example_Round) +* [Sigmoid](#example_Sigmoid) +* [SoftMax](#example_SoftMax) +* [Sum](#example_Sum) + +#### Package files +[correlation.go](/src/github.com/montanaflynn/stats/correlation.go) [cumulative_sum.go](/src/github.com/montanaflynn/stats/cumulative_sum.go) [data.go](/src/github.com/montanaflynn/stats/data.go) [deviation.go](/src/github.com/montanaflynn/stats/deviation.go) [distances.go](/src/github.com/montanaflynn/stats/distances.go) [doc.go](/src/github.com/montanaflynn/stats/doc.go) [entropy.go](/src/github.com/montanaflynn/stats/entropy.go) [errors.go](/src/github.com/montanaflynn/stats/errors.go) [legacy.go](/src/github.com/montanaflynn/stats/legacy.go) [load.go](/src/github.com/montanaflynn/stats/load.go) [max.go](/src/github.com/montanaflynn/stats/max.go) [mean.go](/src/github.com/montanaflynn/stats/mean.go) [median.go](/src/github.com/montanaflynn/stats/median.go) [min.go](/src/github.com/montanaflynn/stats/min.go) [mode.go](/src/github.com/montanaflynn/stats/mode.go) [norm.go](/src/github.com/montanaflynn/stats/norm.go) [outlier.go](/src/github.com/montanaflynn/stats/outlier.go) [percentile.go](/src/github.com/montanaflynn/stats/percentile.go) [quartile.go](/src/github.com/montanaflynn/stats/quartile.go) [ranksum.go](/src/github.com/montanaflynn/stats/ranksum.go) [regression.go](/src/github.com/montanaflynn/stats/regression.go) [round.go](/src/github.com/montanaflynn/stats/round.go) [sample.go](/src/github.com/montanaflynn/stats/sample.go) [sigmoid.go](/src/github.com/montanaflynn/stats/sigmoid.go) [softmax.go](/src/github.com/montanaflynn/stats/softmax.go) [sum.go](/src/github.com/montanaflynn/stats/sum.go) [util.go](/src/github.com/montanaflynn/stats/util.go) [variance.go](/src/github.com/montanaflynn/stats/variance.go) + + + +## Variables +``` go +var ( + // ErrEmptyInput Input must not be empty + ErrEmptyInput = statsError{"Input must not be empty."} + // ErrNaN Not a number + ErrNaN = statsError{"Not a number."} + // ErrNegative Must not contain negative values + ErrNegative = statsError{"Must not contain negative values."} + // ErrZero Must not contain zero values + ErrZero = statsError{"Must not contain zero values."} + // ErrBounds Input is outside of range + ErrBounds = statsError{"Input is outside of range."} + // ErrSize Must be the same length + ErrSize = statsError{"Must be the same length."} + // ErrInfValue Value is infinite + ErrInfValue = statsError{"Value is infinite."} + // ErrYCoord Y Value must be greater than zero + ErrYCoord = statsError{"Y Value must be greater than zero."} +) +``` +These are the package-wide error values. +All error identification should use these values. +https://github.com/golang/go/wiki/Errors#naming + +``` go +var ( + EmptyInputErr = ErrEmptyInput + NaNErr = ErrNaN + NegativeErr = ErrNegative + ZeroErr = ErrZero + BoundsErr = ErrBounds + SizeErr = ErrSize + InfValue = ErrInfValue + YCoordErr = ErrYCoord + EmptyInput = ErrEmptyInput +) +``` +Legacy error names that didn't start with Err + + + +## func [AutoCorrelation](/correlation.go?s=853:918#L38) +``` go +func AutoCorrelation(data Float64Data, lags int) (float64, error) +``` +AutoCorrelation is the correlation of a signal with a delayed copy of itself as a function of delay + + + +## func [ChebyshevDistance](/distances.go?s=368:456#L20) +``` go +func ChebyshevDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) +``` +ChebyshevDistance computes the Chebyshev distance between two data sets + + + +## func [Correlation](/correlation.go?s=112:171#L8) +``` go +func Correlation(data1, data2 Float64Data) (float64, error) +``` +Correlation describes the degree of relationship between two sets of data + + + +## func [Covariance](/variance.go?s=1284:1342#L53) +``` go +func Covariance(data1, data2 Float64Data) (float64, error) +``` +Covariance is a measure of how much two sets of data change + + + +## func [CovariancePopulation](/variance.go?s=1864:1932#L81) +``` go +func CovariancePopulation(data1, data2 Float64Data) (float64, error) +``` +CovariancePopulation computes covariance for entire population between two variables. + + + +## func [CumulativeSum](/cumulative_sum.go?s=81:137#L4) +``` go +func CumulativeSum(input Float64Data) ([]float64, error) +``` +CumulativeSum calculates the cumulative sum of the input slice + + + +## func [Entropy](/entropy.go?s=77:125#L6) +``` go +func Entropy(input Float64Data) (float64, error) +``` +Entropy provides calculation of the entropy + + + +## func [EuclideanDistance](/distances.go?s=836:924#L36) +``` go +func EuclideanDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) +``` +EuclideanDistance computes the Euclidean distance between two data sets + + + +## func [GeometricMean](/mean.go?s=319:373#L18) +``` go +func GeometricMean(input Float64Data) (float64, error) +``` +GeometricMean gets the geometric mean for a slice of numbers + + + +## func [HarmonicMean](/mean.go?s=717:770#L40) +``` go +func HarmonicMean(input Float64Data) (float64, error) +``` +HarmonicMean gets the harmonic mean for a slice of numbers + + + +## func [InterQuartileRange](/quartile.go?s=821:880#L45) +``` go +func InterQuartileRange(input Float64Data) (float64, error) +``` +InterQuartileRange finds the range between Q1 and Q3 + + + +## func [ManhattanDistance](/distances.go?s=1277:1365#L50) +``` go +func ManhattanDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) +``` +ManhattanDistance computes the Manhattan distance between two data sets + + + +## func [Max](/max.go?s=78:130#L8) +``` go +func Max(input Float64Data) (max float64, err error) +``` +Max finds the highest number in a slice + + + +## func [Mean](/mean.go?s=77:122#L6) +``` go +func Mean(input Float64Data) (float64, error) +``` +Mean gets the average of a slice of numbers + + + +## func [Median](/median.go?s=85:143#L6) +``` go +func Median(input Float64Data) (median float64, err error) +``` +Median gets the median number in a slice of numbers + + + +## func [MedianAbsoluteDeviation](/deviation.go?s=125:197#L6) +``` go +func MedianAbsoluteDeviation(input Float64Data) (mad float64, err error) +``` +MedianAbsoluteDeviation finds the median of the absolute deviations from the dataset median + + + +## func [MedianAbsoluteDeviationPopulation](/deviation.go?s=360:442#L11) +``` go +func MedianAbsoluteDeviationPopulation(input Float64Data) (mad float64, err error) +``` +MedianAbsoluteDeviationPopulation finds the median of the absolute deviations from the population median + + + +## func [Midhinge](/quartile.go?s=1075:1124#L55) +``` go +func Midhinge(input Float64Data) (float64, error) +``` +Midhinge finds the average of the first and third quartiles + + + +## func [Min](/min.go?s=78:130#L6) +``` go +func Min(input Float64Data) (min float64, err error) +``` +Min finds the lowest number in a set of data + + + +## func [MinkowskiDistance](/distances.go?s=2152:2256#L75) +``` go +func MinkowskiDistance(dataPointX, dataPointY Float64Data, lambda float64) (distance float64, err error) +``` +MinkowskiDistance computes the Minkowski distance between two data sets + +Arguments: + + + dataPointX: First set of data points + dataPointY: Second set of data points. Length of both data + sets must be equal. + lambda: aka p or city blocks; With lambda = 1 + returned distance is manhattan distance and + lambda = 2; it is euclidean distance. Lambda + reaching to infinite - distance would be chebysev + distance. + +Return: + + + Distance or error + + + +## func [Mode](/mode.go?s=85:141#L4) +``` go +func Mode(input Float64Data) (mode []float64, err error) +``` +Mode gets the mode [most frequent value(s)] of a slice of float64s + + + +## func [Ncr](/norm.go?s=7384:7406#L239) +``` go +func Ncr(n, r int) int +``` +Ncr is an N choose R algorithm. +Aaron Cannon's algorithm. + + + +## func [NormBoxMullerRvs](/norm.go?s=667:736#L23) +``` go +func NormBoxMullerRvs(loc float64, scale float64, size int) []float64 +``` +NormBoxMullerRvs generates random variates using the Box–Muller transform. +For more information please visit: http://mathworld.wolfram.com/Box-MullerTransformation.html + + + +## func [NormCdf](/norm.go?s=1826:1885#L52) +``` go +func NormCdf(x float64, loc float64, scale float64) float64 +``` +NormCdf is the cumulative distribution function. + + + +## func [NormEntropy](/norm.go?s=5773:5825#L180) +``` go +func NormEntropy(loc float64, scale float64) float64 +``` +NormEntropy is the differential entropy of the RV. + + + +## func [NormFit](/norm.go?s=6058:6097#L187) +``` go +func NormFit(data []float64) [2]float64 +``` +NormFit returns the maximum likelihood estimators for the Normal Distribution. +Takes array of float64 values. +Returns array of Mean followed by Standard Deviation. + + + +## func [NormInterval](/norm.go?s=6976:7047#L221) +``` go +func NormInterval(alpha float64, loc float64, scale float64) [2]float64 +``` +NormInterval finds endpoints of the range that contains alpha percent of the distribution. + + + +## func [NormIsf](/norm.go?s=4330:4393#L137) +``` go +func NormIsf(p float64, loc float64, scale float64) (x float64) +``` +NormIsf is the inverse survival function (inverse of sf). + + + +## func [NormLogCdf](/norm.go?s=2016:2078#L57) +``` go +func NormLogCdf(x float64, loc float64, scale float64) float64 +``` +NormLogCdf is the log of the cumulative distribution function. + + + +## func [NormLogPdf](/norm.go?s=1590:1652#L47) +``` go +func NormLogPdf(x float64, loc float64, scale float64) float64 +``` +NormLogPdf is the log of the probability density function. + + + +## func [NormLogSf](/norm.go?s=2423:2484#L67) +``` go +func NormLogSf(x float64, loc float64, scale float64) float64 +``` +NormLogSf is the log of the survival function. + + + +## func [NormMean](/norm.go?s=6560:6609#L206) +``` go +func NormMean(loc float64, scale float64) float64 +``` +NormMean is the mean/expected value of the distribution. + + + +## func [NormMedian](/norm.go?s=6431:6482#L201) +``` go +func NormMedian(loc float64, scale float64) float64 +``` +NormMedian is the median of the distribution. + + + +## func [NormMoment](/norm.go?s=4694:4752#L146) +``` go +func NormMoment(n int, loc float64, scale float64) float64 +``` +NormMoment approximates the non-central (raw) moment of order n. +For more information please visit: https://math.stackexchange.com/questions/1945448/methods-for-finding-raw-moments-of-the-normal-distribution + + + +## func [NormPdf](/norm.go?s=1357:1416#L42) +``` go +func NormPdf(x float64, loc float64, scale float64) float64 +``` +NormPdf is the probability density function. + + + +## func [NormPpf](/norm.go?s=2854:2917#L75) +``` go +func NormPpf(p float64, loc float64, scale float64) (x float64) +``` +NormPpf is the point percentile function. +This is based on Peter John Acklam's inverse normal CDF. +algorithm: http://home.online.no/~pjacklam/notes/invnorm/ (no longer visible). +For more information please visit: https://stackedboxes.org/2017/05/01/acklams-normal-quantile-function/ + + + +## func [NormPpfRvs](/norm.go?s=247:310#L12) +``` go +func NormPpfRvs(loc float64, scale float64, size int) []float64 +``` +NormPpfRvs generates random variates using the Point Percentile Function. +For more information please visit: https://demonstrations.wolfram.com/TheMethodOfInverseTransforms/ + + + +## func [NormSf](/norm.go?s=2250:2308#L62) +``` go +func NormSf(x float64, loc float64, scale float64) float64 +``` +NormSf is the survival function (also defined as 1 - cdf, but sf is sometimes more accurate). + + + +## func [NormStats](/norm.go?s=5277:5345#L162) +``` go +func NormStats(loc float64, scale float64, moments string) []float64 +``` +NormStats returns the mean, variance, skew, and/or kurtosis. +Mean(‘m’), variance(‘v’), skew(‘s’), and/or kurtosis(‘k’). +Takes string containing any of 'mvsk'. +Returns array of m v s k in that order. + + + +## func [NormStd](/norm.go?s=6814:6862#L216) +``` go +func NormStd(loc float64, scale float64) float64 +``` +NormStd is the standard deviation of the distribution. + + + +## func [NormVar](/norm.go?s=6675:6723#L211) +``` go +func NormVar(loc float64, scale float64) float64 +``` +NormVar is the variance of the distribution. + + + +## func [Pearson](/correlation.go?s=655:710#L33) +``` go +func Pearson(data1, data2 Float64Data) (float64, error) +``` +Pearson calculates the Pearson product-moment correlation coefficient between two variables + + + +## func [Percentile](/percentile.go?s=98:181#L8) +``` go +func Percentile(input Float64Data, percent float64) (percentile float64, err error) +``` +Percentile finds the relative standing in a slice of floats + + + +## func [PercentileNearestRank](/percentile.go?s=1079:1173#L54) +``` go +func PercentileNearestRank(input Float64Data, percent float64) (percentile float64, err error) +``` +PercentileNearestRank finds the relative standing in a slice of floats using the Nearest Rank method + + + +## func [PopulationVariance](/variance.go?s=828:896#L31) +``` go +func PopulationVariance(input Float64Data) (pvar float64, err error) +``` +PopulationVariance finds the amount of variance within a population + + + +## func [Round](/round.go?s=88:154#L6) +``` go +func Round(input float64, places int) (rounded float64, err error) +``` +Round a float to a specific decimal place or precision + + + +## func [Sample](/sample.go?s=112:192#L9) +``` go +func Sample(input Float64Data, takenum int, replacement bool) ([]float64, error) +``` +Sample returns sample from input with replacement or without + + + +## func [SampleVariance](/variance.go?s=1058:1122#L42) +``` go +func SampleVariance(input Float64Data) (svar float64, err error) +``` +SampleVariance finds the amount of variance within a sample + + + +## func [Sigmoid](/sigmoid.go?s=228:278#L9) +``` go +func Sigmoid(input Float64Data) ([]float64, error) +``` +Sigmoid returns the input values in the range of -1 to 1 +along the sigmoid or s-shaped curve, commonly used in +machine learning while training neural networks as an +activation function. + + + +## func [SoftMax](/softmax.go?s=206:256#L8) +``` go +func SoftMax(input Float64Data) ([]float64, error) +``` +SoftMax returns the input values in the range of 0 to 1 +with sum of all the probabilities being equal to one. It +is commonly used in machine learning neural networks. + + + +## func [StableSample](/sample.go?s=974:1042#L50) +``` go +func StableSample(input Float64Data, takenum int) ([]float64, error) +``` +StableSample like stable sort, it returns samples from input while keeps the order of original data. + + + +## func [StandardDeviation](/deviation.go?s=695:762#L27) +``` go +func StandardDeviation(input Float64Data) (sdev float64, err error) +``` +StandardDeviation the amount of variation in the dataset + + + +## func [StandardDeviationPopulation](/deviation.go?s=892:969#L32) +``` go +func StandardDeviationPopulation(input Float64Data) (sdev float64, err error) +``` +StandardDeviationPopulation finds the amount of variation from the population + + + +## func [StandardDeviationSample](/deviation.go?s=1254:1327#L46) +``` go +func StandardDeviationSample(input Float64Data) (sdev float64, err error) +``` +StandardDeviationSample finds the amount of variation from a sample + + + +## func [StdDevP](/legacy.go?s=339:396#L14) +``` go +func StdDevP(input Float64Data) (sdev float64, err error) +``` +StdDevP is a shortcut to StandardDeviationPopulation + + + +## func [StdDevS](/legacy.go?s=497:554#L19) +``` go +func StdDevS(input Float64Data) (sdev float64, err error) +``` +StdDevS is a shortcut to StandardDeviationSample + + + +## func [Sum](/sum.go?s=78:130#L6) +``` go +func Sum(input Float64Data) (sum float64, err error) +``` +Sum adds all the numbers of a slice together + + + +## func [Trimean](/quartile.go?s=1320:1368#L65) +``` go +func Trimean(input Float64Data) (float64, error) +``` +Trimean finds the average of the median and the midhinge + + + +## func [VarP](/legacy.go?s=59:113#L4) +``` go +func VarP(input Float64Data) (sdev float64, err error) +``` +VarP is a shortcut to PopulationVariance + + + +## func [VarS](/legacy.go?s=193:247#L9) +``` go +func VarS(input Float64Data) (sdev float64, err error) +``` +VarS is a shortcut to SampleVariance + + + +## func [Variance](/variance.go?s=659:717#L26) +``` go +func Variance(input Float64Data) (sdev float64, err error) +``` +Variance the amount of variation in the dataset + + + + +## type [Coordinate](/regression.go?s=143:183#L9) +``` go +type Coordinate struct { + X, Y float64 +} + +``` +Coordinate holds the data in a series + + + + + + + +### func [ExpReg](/legacy.go?s=791:856#L29) +``` go +func ExpReg(s []Coordinate) (regressions []Coordinate, err error) +``` +ExpReg is a shortcut to ExponentialRegression + + +### func [LinReg](/legacy.go?s=643:708#L24) +``` go +func LinReg(s []Coordinate) (regressions []Coordinate, err error) +``` +LinReg is a shortcut to LinearRegression + + +### func [LogReg](/legacy.go?s=944:1009#L34) +``` go +func LogReg(s []Coordinate) (regressions []Coordinate, err error) +``` +LogReg is a shortcut to LogarithmicRegression + + + + + +## type [Float64Data](/data.go?s=80:106#L4) +``` go +type Float64Data []float64 +``` +Float64Data is a named type for []float64 with helper methods + + + + + + + +### func [LoadRawData](/load.go?s=119:168#L9) +``` go +func LoadRawData(raw interface{}) (f Float64Data) +``` +LoadRawData parses and converts a slice of mixed data types to floats + + + + + +### func (Float64Data) [AutoCorrelation](/data.go?s=3257:3320#L91) +``` go +func (f Float64Data) AutoCorrelation(lags int) (float64, error) +``` +AutoCorrelation is the correlation of a signal with a delayed copy of itself as a function of delay + + + + +### func (Float64Data) [Correlation](/data.go?s=3058:3122#L86) +``` go +func (f Float64Data) Correlation(d Float64Data) (float64, error) +``` +Correlation describes the degree of relationship between two sets of data + + + + +### func (Float64Data) [Covariance](/data.go?s=4801:4864#L141) +``` go +func (f Float64Data) Covariance(d Float64Data) (float64, error) +``` +Covariance is a measure of how much two sets of data change + + + + +### func (Float64Data) [CovariancePopulation](/data.go?s=4983:5056#L146) +``` go +func (f Float64Data) CovariancePopulation(d Float64Data) (float64, error) +``` +CovariancePopulation computes covariance for entire population between two variables + + + + +### func (Float64Data) [CumulativeSum](/data.go?s=883:938#L28) +``` go +func (f Float64Data) CumulativeSum() ([]float64, error) +``` +CumulativeSum returns the cumulative sum of the data + + + + +### func (Float64Data) [Entropy](/data.go?s=5480:5527#L162) +``` go +func (f Float64Data) Entropy() (float64, error) +``` +Entropy provides calculation of the entropy + + + + +### func (Float64Data) [GeometricMean](/data.go?s=1332:1385#L40) +``` go +func (f Float64Data) GeometricMean() (float64, error) +``` +GeometricMean returns the median of the data + + + + +### func (Float64Data) [Get](/data.go?s=129:168#L7) +``` go +func (f Float64Data) Get(i int) float64 +``` +Get item in slice + + + + +### func (Float64Data) [HarmonicMean](/data.go?s=1460:1512#L43) +``` go +func (f Float64Data) HarmonicMean() (float64, error) +``` +HarmonicMean returns the mode of the data + + + + +### func (Float64Data) [InterQuartileRange](/data.go?s=3755:3813#L106) +``` go +func (f Float64Data) InterQuartileRange() (float64, error) +``` +InterQuartileRange finds the range between Q1 and Q3 + + + + +### func (Float64Data) [Len](/data.go?s=217:247#L10) +``` go +func (f Float64Data) Len() int +``` +Len returns length of slice + + + + +### func (Float64Data) [Less](/data.go?s=318:358#L13) +``` go +func (f Float64Data) Less(i, j int) bool +``` +Less returns if one number is less than another + + + + +### func (Float64Data) [Max](/data.go?s=645:688#L22) +``` go +func (f Float64Data) Max() (float64, error) +``` +Max returns the maximum number in the data + + + + +### func (Float64Data) [Mean](/data.go?s=1005:1049#L31) +``` go +func (f Float64Data) Mean() (float64, error) +``` +Mean returns the mean of the data + + + + +### func (Float64Data) [Median](/data.go?s=1111:1157#L34) +``` go +func (f Float64Data) Median() (float64, error) +``` +Median returns the median of the data + + + + +### func (Float64Data) [MedianAbsoluteDeviation](/data.go?s=1630:1693#L46) +``` go +func (f Float64Data) MedianAbsoluteDeviation() (float64, error) +``` +MedianAbsoluteDeviation the median of the absolute deviations from the dataset median + + + + +### func (Float64Data) [MedianAbsoluteDeviationPopulation](/data.go?s=1842:1915#L51) +``` go +func (f Float64Data) MedianAbsoluteDeviationPopulation() (float64, error) +``` +MedianAbsoluteDeviationPopulation finds the median of the absolute deviations from the population median + + + + +### func (Float64Data) [Midhinge](/data.go?s=3912:3973#L111) +``` go +func (f Float64Data) Midhinge(d Float64Data) (float64, error) +``` +Midhinge finds the average of the first and third quartiles + + + + +### func (Float64Data) [Min](/data.go?s=536:579#L19) +``` go +func (f Float64Data) Min() (float64, error) +``` +Min returns the minimum number in the data + + + + +### func (Float64Data) [Mode](/data.go?s=1217:1263#L37) +``` go +func (f Float64Data) Mode() ([]float64, error) +``` +Mode returns the mode of the data + + + + +### func (Float64Data) [Pearson](/data.go?s=3455:3515#L96) +``` go +func (f Float64Data) Pearson(d Float64Data) (float64, error) +``` +Pearson calculates the Pearson product-moment correlation coefficient between two variables. + + + + +### func (Float64Data) [Percentile](/data.go?s=2696:2755#L76) +``` go +func (f Float64Data) Percentile(p float64) (float64, error) +``` +Percentile finds the relative standing in a slice of floats + + + + +### func (Float64Data) [PercentileNearestRank](/data.go?s=2869:2939#L81) +``` go +func (f Float64Data) PercentileNearestRank(p float64) (float64, error) +``` +PercentileNearestRank finds the relative standing using the Nearest Rank method + + + + +### func (Float64Data) [PopulationVariance](/data.go?s=4495:4553#L131) +``` go +func (f Float64Data) PopulationVariance() (float64, error) +``` +PopulationVariance finds the amount of variance within a population + + + + +### func (Float64Data) [Quartile](/data.go?s=3610:3673#L101) +``` go +func (f Float64Data) Quartile(d Float64Data) (Quartiles, error) +``` +Quartile returns the three quartile points from a slice of data + + + + +### func (Float64Data) [QuartileOutliers](/data.go?s=2542:2599#L71) +``` go +func (f Float64Data) QuartileOutliers() (Outliers, error) +``` +QuartileOutliers finds the mild and extreme outliers + + + + +### func (Float64Data) [Sample](/data.go?s=4208:4269#L121) +``` go +func (f Float64Data) Sample(n int, r bool) ([]float64, error) +``` +Sample returns sample from input with replacement or without + + + + +### func (Float64Data) [SampleVariance](/data.go?s=4652:4706#L136) +``` go +func (f Float64Data) SampleVariance() (float64, error) +``` +SampleVariance finds the amount of variance within a sample + + + + +### func (Float64Data) [Sigmoid](/data.go?s=5169:5218#L151) +``` go +func (f Float64Data) Sigmoid() ([]float64, error) +``` +Sigmoid returns the input values along the sigmoid or s-shaped curve + + + + +### func (Float64Data) [SoftMax](/data.go?s=5359:5408#L157) +``` go +func (f Float64Data) SoftMax() ([]float64, error) +``` +SoftMax returns the input values in the range of 0 to 1 +with sum of all the probabilities being equal to one. + + + + +### func (Float64Data) [StandardDeviation](/data.go?s=2026:2083#L56) +``` go +func (f Float64Data) StandardDeviation() (float64, error) +``` +StandardDeviation the amount of variation in the dataset + + + + +### func (Float64Data) [StandardDeviationPopulation](/data.go?s=2199:2266#L61) +``` go +func (f Float64Data) StandardDeviationPopulation() (float64, error) +``` +StandardDeviationPopulation finds the amount of variation from the population + + + + +### func (Float64Data) [StandardDeviationSample](/data.go?s=2382:2445#L66) +``` go +func (f Float64Data) StandardDeviationSample() (float64, error) +``` +StandardDeviationSample finds the amount of variation from a sample + + + + +### func (Float64Data) [Sum](/data.go?s=764:807#L25) +``` go +func (f Float64Data) Sum() (float64, error) +``` +Sum returns the total of all the numbers in the data + + + + +### func (Float64Data) [Swap](/data.go?s=425:460#L16) +``` go +func (f Float64Data) Swap(i, j int) +``` +Swap switches out two numbers in slice + + + + +### func (Float64Data) [Trimean](/data.go?s=4059:4119#L116) +``` go +func (f Float64Data) Trimean(d Float64Data) (float64, error) +``` +Trimean finds the average of the median and the midhinge + + + + +### func (Float64Data) [Variance](/data.go?s=4350:4398#L126) +``` go +func (f Float64Data) Variance() (float64, error) +``` +Variance the amount of variation in the dataset + + + + +## type [Outliers](/outlier.go?s=73:139#L4) +``` go +type Outliers struct { + Mild Float64Data + Extreme Float64Data +} + +``` +Outliers holds mild and extreme outliers found in data + + + + + + + +### func [QuartileOutliers](/outlier.go?s=197:255#L10) +``` go +func QuartileOutliers(input Float64Data) (Outliers, error) +``` +QuartileOutliers finds the mild and extreme outliers + + + + + +## type [Quartiles](/quartile.go?s=75:136#L6) +``` go +type Quartiles struct { + Q1 float64 + Q2 float64 + Q3 float64 +} + +``` +Quartiles holds the three quartile points + + + + + + + +### func [Quartile](/quartile.go?s=205:256#L13) +``` go +func Quartile(input Float64Data) (Quartiles, error) +``` +Quartile returns the three quartile points from a slice of data + + + + + +## type [Series](/regression.go?s=76:100#L6) +``` go +type Series []Coordinate +``` +Series is a container for a series of data + + + + + + + +### func [ExponentialRegression](/regression.go?s=1089:1157#L50) +``` go +func ExponentialRegression(s Series) (regressions Series, err error) +``` +ExponentialRegression returns an exponential regression on data series + + +### func [LinearRegression](/regression.go?s=262:325#L14) +``` go +func LinearRegression(s Series) (regressions Series, err error) +``` +LinearRegression finds the least squares linear regression on data series + + +### func [LogarithmicRegression](/regression.go?s=1903:1971#L85) +``` go +func LogarithmicRegression(s Series) (regressions Series, err error) +``` +LogarithmicRegression returns an logarithmic regression on data series + + + + + + + + + +- - - +Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/entropy.go golang-github-montanaflynn-stats-0.6.4/entropy.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/entropy.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/entropy.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,31 @@ +package stats + +import "math" + +// Entropy provides calculation of the entropy +func Entropy(input Float64Data) (float64, error) { + input, err := normalize(input) + if err != nil { + return math.NaN(), err + } + var result float64 + for i := 0; i < input.Len(); i++ { + v := input.Get(i) + if v == 0 { + continue + } + result += (v * math.Log(v)) + } + return -result, nil +} + +func normalize(input Float64Data) (Float64Data, error) { + sum, err := input.Sum() + if err != nil { + return Float64Data{}, err + } + for i := 0; i < input.Len(); i++ { + input[i] = input[i] / sum + } + return input, nil +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/entropy_test.go golang-github-montanaflynn-stats-0.6.4/entropy_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/entropy_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/entropy_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,52 @@ +package stats_test + +import ( + "fmt" + "testing" + + "github.com/montanaflynn/stats" +) + +func ExampleEntropy() { + d := []float64{1.1, 2.2, 3.3} + e, _ := stats.Entropy(d) + fmt.Println(e) + // Output: 1.0114042647073518 +} + +func TestEntropy(t *testing.T) { + for _, c := range []struct { + in stats.Float64Data + out float64 + }{ + {stats.Float64Data{4, 8, 5, 1}, 1.2110440167801229}, + {stats.Float64Data{0.8, 0.01, 0.4}, 0.6791185708986585}, + {stats.Float64Data{0.8, 1.1, 0, 5}, 0.7759393943707658}, + } { + got, err := stats.Entropy(c.in) + if err != nil { + t.Errorf("Returned an error") + } + if !veryclose(got, c.out) { + t.Errorf("Max(%.1f) => %.1f != %.1f", c.in, got, c.out) + } + } + _, err := stats.Entropy([]float64{}) + if err == nil { + t.Errorf("Empty slice didn't return an error") + } +} + +func BenchmarkEntropySmallFloatSlice(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = stats.Entropy(makeFloatSlice(5)) + } +} + +func BenchmarkEntropyLargeFloatSlice(b *testing.B) { + lf := makeFloatSlice(100000) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = stats.Entropy(lf) + } +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/errors.go golang-github-montanaflynn-stats-0.6.4/errors.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/errors.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/errors.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,21 +1,35 @@ package stats -type statsErr struct { +type statsError struct { err string } -func (s statsErr) Error() string { +func (s statsError) Error() string { + return s.err +} + +func (s statsError) String() string { return s.err } // These are the package-wide error values. // All error identification should use these values. +// https://github.com/golang/go/wiki/Errors#naming var ( - EmptyInput = statsErr{"Input must not be empty."} - SampleSize = statsErr{"Samples number must be less than input length."} - NaNErr = statsErr{"Not a number"} - NegativeErr = statsErr{"Slice must not contain negative values."} - ZeroErr = statsErr{"Slice must not contain zero values."} - BoundsErr = statsErr{"Input is outside of range."} - SizeErr = statsErr{"Slices must be the same length."} + // ErrEmptyInput Input must not be empty + ErrEmptyInput = statsError{"Input must not be empty."} + // ErrNaN Not a number + ErrNaN = statsError{"Not a number."} + // ErrNegative Must not contain negative values + ErrNegative = statsError{"Must not contain negative values."} + // ErrZero Must not contain zero values + ErrZero = statsError{"Must not contain zero values."} + // ErrBounds Input is outside of range + ErrBounds = statsError{"Input is outside of range."} + // ErrSize Must be the same length + ErrSize = statsError{"Must be the same length."} + // ErrInfValue Value is infinite + ErrInfValue = statsError{"Value is infinite."} + // ErrYCoord Y Value must be greater than zero + ErrYCoord = statsError{"Y Value must be greater than zero."} ) diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/errors_test.go golang-github-montanaflynn-stats-0.6.4/errors_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/errors_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/errors_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -5,8 +5,11 @@ ) func TestError(t *testing.T) { - err := statsErr{"test error"} + err := statsError{"test error"} if err.Error() != "test error" { t.Errorf("Error method message didn't match") } + if err.String() != "test error" { + t.Errorf("String method message didn't match") + } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/examples/main.go golang-github-montanaflynn-stats-0.6.4/examples/main.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/examples/main.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/examples/main.go 2021-01-13 11:52:47.000000000 +0000 @@ -8,46 +8,63 @@ func main() { - d := stats.LoadRawData([]interface{}{1.1, "2", 3.0, 4, "5"}) + // d := stats.LoadRawData([]interface{}{1.1, "2", 3.0, 4, "5"}) + d := stats.LoadRawData([]int{1, 2, 3, 4, 5}) a, _ := stats.Min(d) - fmt.Println(a) // 1.1 + fmt.Println(a) + // Output: 1.1 a, _ = stats.Max(d) - fmt.Println(a) // 5 + fmt.Println(a) + // Output: 5 a, _ = stats.Sum([]float64{1.1, 2.2, 3.3}) - fmt.Println(a) // 6.6 + fmt.Println(a) + // Output: 6.6 + + cs, _ := stats.CumulativeSum([]float64{1.1, 2.2, 3.3}) + fmt.Println(cs) // [1.1 3.3000000000000003 6.6] a, _ = stats.Mean([]float64{1, 2, 3, 4, 5}) - fmt.Println(a) // 3 + fmt.Println(a) + // Output: 3 a, _ = stats.Median([]float64{1, 2, 3, 4, 5, 6, 7}) - fmt.Println(a) // 4 + fmt.Println(a) + // Output: 4 m, _ := stats.Mode([]float64{5, 5, 3, 3, 4, 2, 1}) - fmt.Println(m) // [5 3] + fmt.Println(m) + // Output: [5 3] a, _ = stats.PopulationVariance([]float64{1, 2, 3, 4, 5}) - fmt.Println(a) // 2 + fmt.Println(a) + // Output: 2 a, _ = stats.SampleVariance([]float64{1, 2, 3, 4, 5}) - fmt.Println(a) // 2.5 + fmt.Println(a) + // Output: 2.5 a, _ = stats.MedianAbsoluteDeviationPopulation([]float64{1, 2, 3}) - fmt.Println(a) // 1 + fmt.Println(a) + // Output: 1 a, _ = stats.StandardDeviationPopulation([]float64{1, 2, 3}) - fmt.Println(a) // 0.816496580927726 + fmt.Println(a) + // Output: 0.816496580927726 a, _ = stats.StandardDeviationSample([]float64{1, 2, 3}) - fmt.Println(a) // 1 + fmt.Println(a) + // Output: 1 a, _ = stats.Percentile([]float64{1, 2, 3, 4, 5}, 75) - fmt.Println(a) // 4 + fmt.Println(a) + // Output: 4 a, _ = stats.PercentileNearestRank([]float64{35, 20, 15, 40, 50}, 75) - fmt.Println(a) // 40 + fmt.Println(a) + // Output: 40 c := []stats.Coordinate{ {1, 2.3}, @@ -58,41 +75,98 @@ } r, _ := stats.LinearRegression(c) - fmt.Println(r) // [{1 2.3800000000000026} {2 3.0800000000000014} {3 3.7800000000000002} {4 4.479999999999999} {5 5.179999999999998}] + fmt.Println(r) + // Output: [{1 2.3800000000000026} {2 3.0800000000000014} {3 3.7800000000000002} {4 4.479999999999999} {5 5.179999999999998}] r, _ = stats.ExponentialRegression(c) - fmt.Println(r) // [{1 2.5150181024736638} {2 3.032084111136781} {3 3.6554544271334493} {4 4.406984298281804} {5 5.313022222665875}] + fmt.Println(r) + // Output: [{1 2.5150181024736638} {2 3.032084111136781} {3 3.6554544271334493} {4 4.406984298281804} {5 5.313022222665875}] r, _ = stats.LogarithmicRegression(c) - fmt.Println(r) // [{1 2.1520822363811702} {2 3.3305559222492214} {3 4.019918836568674} {4 4.509029608117273} {5 4.888413396683663}] + fmt.Println(r) + // Output: [{1 2.1520822363811702} {2 3.3305559222492214} {3 4.019918836568674} {4 4.509029608117273} {5 4.888413396683663}] s, _ := stats.Sample([]float64{0.1, 0.2, 0.3, 0.4}, 3, false) - fmt.Println(s) // [0.2,0.4,0.3] + fmt.Println(s) + // Output: [0.2,0.4,0.3] s, _ = stats.Sample([]float64{0.1, 0.2, 0.3, 0.4}, 10, true) - fmt.Println(s) // [0.2,0.2,0.4,0.1,0.2,0.4,0.3,0.2,0.2,0.1] + fmt.Println(s) + // Output: [0.2,0.2,0.4,0.1,0.2,0.4,0.3,0.2,0.2,0.1] q, _ := stats.Quartile([]float64{7, 15, 36, 39, 40, 41}) - fmt.Println(q) // {15 37.5 40} + fmt.Println(q) + // Output: {15 37.5 40} iqr, _ := stats.InterQuartileRange([]float64{102, 104, 105, 107, 108, 109, 110, 112, 115, 116, 118}) - fmt.Println(iqr) // 10 + fmt.Println(iqr) + // Output: 10 mh, _ := stats.Midhinge([]float64{1, 3, 4, 4, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13}) - fmt.Println(mh) // 7.5 + fmt.Println(mh) + // Output: 7.5 tr, _ := stats.Trimean([]float64{1, 3, 4, 4, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13}) - fmt.Println(tr) // 7.25 + fmt.Println(tr) + // Output: 7.25 o, _ := stats.QuartileOutliers([]float64{-1000, 1, 3, 4, 4, 6, 6, 6, 6, 7, 8, 15, 18, 100}) - fmt.Printf("%+v\n", o) // {Mild:[15 18] Extreme:[-1000 100]} + fmt.Printf("%+v\n", o) + // Output: {Mild:[15 18] Extreme:[-1000 100]} gm, _ := stats.GeometricMean([]float64{10, 51.2, 8}) - fmt.Println(gm) // 15.999999999999991 + fmt.Println(gm) + // Output: 15.999999999999991 hm, _ := stats.HarmonicMean([]float64{1, 2, 3, 4, 5}) - fmt.Println(hm) // 2.18978102189781 + fmt.Println(hm) + // Output: 2.18978102189781 a, _ = stats.Round(2.18978102189781, 3) - fmt.Println(a) // 2.189 + fmt.Println(a) + // Output: 2.189 + + e, _ := stats.ChebyshevDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}) + fmt.Println(e) + // Output: 6 + + e, _ = stats.ManhattanDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}) + fmt.Println(e) + // Output: 24 + + e, _ = stats.EuclideanDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}) + fmt.Println(e) + // Output: 10.583005244258363 + + e, _ = stats.MinkowskiDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, float64(1)) + fmt.Println(e) + // Output: 24 + + e, _ = stats.MinkowskiDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, float64(2)) + fmt.Println(e) + // Output: 10.583005244258363 + + e, _ = stats.MinkowskiDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, float64(99)) + fmt.Println(e) + // Output: 6 + + cor, _ := stats.Correlation([]float64{1, 2, 3, 4, 5}, []float64{1, 2, 3, 5, 6}) + fmt.Println(cor) + // Output: 0.9912407071619302 + + ac, _ := stats.AutoCorrelation([]float64{1, 2, 3, 4, 5}, 1) + fmt.Println(ac) + // Output: 0.4 + + sig, _ := stats.Sigmoid([]float64{3.0, 1.0, 2.1}) + fmt.Println(sig) + // Output: [0.9525741268224334 0.7310585786300049 0.8909031788043871] + + sm, _ := stats.SoftMax([]float64{3.0, 1.0, 0.2}) + fmt.Println(sm) + // Output: [0.8360188027814407 0.11314284146556013 0.05083835575299916] + + e, _ = stats.Entropy([]float64{1.1, 2.2, 3.3}) + fmt.Println(e) + // Output: 1.0114042647073518 } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/examples/README.md golang-github-montanaflynn-stats-0.6.4/examples/README.md --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/examples/README.md 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/examples/README.md 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,3 @@ +# examples + +The examples directory provides some examples of using the stats package. \ No newline at end of file diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/examples_test.go golang-github-montanaflynn-stats-0.6.4/examples_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/examples_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/examples_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,160 @@ +package stats_test + +// import ( +// "fmt" +// "testing" + +// "github.com/montanaflynn/stats" +// ) + +// func Example() { +// // t.Parallel() +// t.Run("LoadRawData", func(t *testing.T) { +// // t.Parallel() +// data := stats.LoadRawData([]interface{}{1.1, "2", 3}) +// fmt.Println(data) +// // Output: 1.1, 2.0, 3.0, 4 +// }) +// } + +// // func Example() { + +// // // start with some source data to use +// // data := []float64{1.0, 2.1, 3.2, 4.823, 4.1, 5.8} +// // // you could also use different types like this +// // // data := stats.LoadRawData([]int{1, 2, 3, 4, 5}) +// // // data := stats.LoadRawData([]interface{}{1.1, "2", 3}) +// // // etc... + +// // median, _ := Median(data) +// // fmt.Println(median) +// // // Output: 3.65 + +// // roundedMedian, _ := Round(median, 0) +// // fmt.Println(roundedMedian) +// // // Output: 4 + +// // a, _ := Mean([]float64{1, 2, 3, 4, 5}) +// // fmt.Println(a) +// // // Output: 3 + +// // a, _ = Median([]float64{1, 2, 3, 4, 5, 6, 7}) +// // fmt.Println(a) +// // // Output: 4 + +// // m, _ := Mode([]float64{5, 5, 3, 3, 4, 2, 1}) +// // fmt.Println(m) +// // // Output: [5 3] + +// // a, _ = PopulationVariance([]float64{1, 2, 3, 4, 5}) +// // fmt.Println(a) +// // // Output: 2 + +// // a, _ = SampleVariance([]float64{1, 2, 3, 4, 5}) +// // fmt.Println(a) +// // // Output: 2.5 + +// // a, _ = MedianAbsoluteDeviationPopulation([]float64{1, 2, 3}) +// // fmt.Println(a) +// // // Output: 1 + +// // a, _ = StandardDeviationPopulation([]float64{1, 2, 3}) +// // fmt.Println(a) +// // // Output: 0.816496580927726 + +// // a, _ = StandardDeviationSample([]float64{1, 2, 3}) +// // fmt.Println(a) +// // // Output: 1 + +// // a, _ = Percentile([]float64{1, 2, 3, 4, 5}, 75) +// // fmt.Println(a) +// // // Output: 4 + +// // a, _ = PercentileNearestRank([]float64{35, 20, 15, 40, 50}, 75) +// // fmt.Println(a) +// // // Output: 40 + +// // c := []Coordinate{ +// // {1, 2.3}, +// // {2, 3.3}, +// // {3, 3.7}, +// // {4, 4.3}, +// // {5, 5.3}, +// // } + +// // r, _ := LinearRegression(c) +// // fmt.Println(r) +// // // Output: [{1 2.3800000000000026} {2 3.0800000000000014} {3 3.7800000000000002} {4 4.479999999999999} {5 5.179999999999998}] + +// // r, _ = ExponentialRegression(c) +// // fmt.Println(r) +// // // Output: [{1 2.5150181024736638} {2 3.032084111136781} {3 3.6554544271334493} {4 4.406984298281804} {5 5.313022222665875}] + +// // r, _ = LogarithmicRegression(c) +// // fmt.Println(r) +// // // Output: [{1 2.1520822363811702} {2 3.3305559222492214} {3 4.019918836568674} {4 4.509029608117273} {5 4.888413396683663}] + +// // s, _ := Sample([]float64{0.1, 0.2, 0.3, 0.4}, 3, false) +// // fmt.Println(s) +// // // Output: [0.2,0.4,0.3] + +// // s, _ = Sample([]float64{0.1, 0.2, 0.3, 0.4}, 10, true) +// // fmt.Println(s) +// // // Output: [0.2,0.2,0.4,0.1,0.2,0.4,0.3,0.2,0.2,0.1] + +// // q, _ := Quartile([]float64{7, 15, 36, 39, 40, 41}) +// // fmt.Println(q) +// // // Output: {15 37.5 40} + +// // iqr, _ := InterQuartileRange([]float64{102, 104, 105, 107, 108, 109, 110, 112, 115, 116, 118}) +// // fmt.Println(iqr) +// // // Output: 10 + +// // mh, _ := Midhinge([]float64{1, 3, 4, 4, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13}) +// // fmt.Println(mh) +// // // Output: 7.5 + +// // tr, _ := Trimean([]float64{1, 3, 4, 4, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13}) +// // fmt.Println(tr) +// // // Output: 7.25 + +// // o, _ := QuartileOutliers([]float64{-1000, 1, 3, 4, 4, 6, 6, 6, 6, 7, 8, 15, 18, 100}) +// // fmt.Printf("%+v\n", o) +// // // Output: {Mild:[15 18] Extreme:[-1000 100]} + +// // gm, _ := GeometricMean([]float64{10, 51.2, 8}) +// // fmt.Println(gm) +// // // Output: 15.999999999999991 + +// // hm, _ := HarmonicMean([]float64{1, 2, 3, 4, 5}) +// // fmt.Println(hm) +// // // Output: 2.18978102189781 + +// // a, _ = Round(2.18978102189781, 3) +// // fmt.Println(a) +// // // Output: 2.189 + +// // e, _ := ChebyshevDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}) +// // fmt.Println(e) +// // // Output: 6 + +// // e, _ = ManhattanDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}) +// // fmt.Println(e) +// // // Output: 24 + +// // e, _ = EuclideanDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}) +// // fmt.Println(e) +// // // Output: 10.583005244258363 + +// // e, _ = MinkowskiDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, float64(1)) +// // fmt.Println(e) +// // // Output: 24 + +// // e, _ = MinkowskiDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, float64(2)) +// // fmt.Println(e) +// // // Output: 10.583005244258363 + +// // e, _ = MinkowskiDistance([]float64{2, 3, 4, 5, 6, 7, 8}, []float64{8, 7, 6, 5, 4, 3, 2}, float64(99)) +// // fmt.Println(e) +// // // Output: 6 +// // } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/.gitignore golang-github-montanaflynn-stats-0.6.4/.gitignore --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/.gitignore 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/.gitignore 2021-01-13 11:52:47.000000000 +0000 @@ -1,2 +1,4 @@ coverage.out -.directory \ No newline at end of file +release-notes.txt +.directory +.chglog \ No newline at end of file diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/go.mod golang-github-montanaflynn-stats-0.6.4/go.mod --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/go.mod 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/go.mod 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,3 @@ +module github.com/montanaflynn/stats + +go 1.13 diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/legacy.go golang-github-montanaflynn-stats-0.6.4/legacy.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/legacy.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/legacy.go 2021-01-13 11:52:47.000000000 +0000 @@ -34,3 +34,16 @@ func LogReg(s []Coordinate) (regressions []Coordinate, err error) { return LogarithmicRegression(s) } + +// Legacy error names that didn't start with Err +var ( + EmptyInputErr = ErrEmptyInput + NaNErr = ErrNaN + NegativeErr = ErrNegative + ZeroErr = ErrZero + BoundsErr = ErrBounds + SizeErr = ErrSize + InfValue = ErrInfValue + YCoordErr = ErrYCoord + EmptyInput = ErrEmptyInput +) diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/legacy_test.go golang-github-montanaflynn-stats-0.6.4/legacy_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/legacy_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/legacy_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,7 +1,9 @@ -package stats +package stats_test import ( "testing" + + "github.com/montanaflynn/stats" ) // Create working sample data to test if the legacy @@ -12,7 +14,7 @@ s := []float64{-10, -10.001, 5, 1.1, 2, 3, 4.20, 5} // Slice of coordinates - d := []Coordinate{ + d := []stats.Coordinate{ {1, 2.3}, {2, 3.3}, {3, 3.7}, @@ -21,43 +23,43 @@ } // VarP rename compatibility - _, err := VarP(s) + _, err := stats.VarP(s) if err != nil { t.Errorf("VarP not successfully returning PopulationVariance.") } // VarS rename compatibility - _, err = VarS(s) + _, err = stats.VarS(s) if err != nil { t.Errorf("VarS not successfully returning SampleVariance.") } // StdDevP rename compatibility - _, err = StdDevP(s) + _, err = stats.StdDevP(s) if err != nil { t.Errorf("StdDevP not successfully returning StandardDeviationPopulation.") } // StdDevS rename compatibility - _, err = StdDevS(s) + _, err = stats.StdDevS(s) if err != nil { t.Errorf("StdDevS not successfully returning StandardDeviationSample.") } // LinReg rename compatibility - _, err = LinReg(d) + _, err = stats.LinReg(d) if err != nil { t.Errorf("LinReg not successfully returning LinearRegression.") } // ExpReg rename compatibility - _, err = ExpReg(d) + _, err = stats.ExpReg(d) if err != nil { t.Errorf("ExpReg not successfully returning ExponentialRegression.") } // LogReg rename compatibility - _, err = LogReg(d) + _, err = stats.LogReg(d) if err != nil { t.Errorf("LogReg not successfully returning LogarithmicRegression.") } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/LICENSE golang-github-montanaflynn-stats-0.6.4/LICENSE --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/LICENSE 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/LICENSE 2021-01-13 11:52:47.000000000 +0000 @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2015 Montana Flynn (https://anonfunction.com) +Copyright (c) 2014-2020 Montana Flynn (https://montanaflynn.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/load.go golang-github-montanaflynn-stats-0.6.4/load.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/load.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/load.go 2021-01-13 11:52:47.000000000 +0000 @@ -18,10 +18,29 @@ s = append(s, float64(v)) } return s - + case []uint8: + for _, v := range t { + s = append(s, float64(v)) + } + return s + case []uint16: + for _, v := range t { + s = append(s, float64(v)) + } + return s + case []uint32: + for _, v := range t { + s = append(s, float64(v)) + } + return s + case []uint64: + for _, v := range t { + s = append(s, float64(v)) + } + return s case []bool: for _, v := range t { - if v == true { + if v { s = append(s, 1.0) } else { s = append(s, 0.0) @@ -35,6 +54,26 @@ s = append(s, float64(v)) } return s + case []int8: + for _, v := range t { + s = append(s, float64(v)) + } + return s + case []int16: + for _, v := range t { + s = append(s, float64(v)) + } + return s + case []int32: + for _, v := range t { + s = append(s, float64(v)) + } + return s + case []int64: + for _, v := range t { + s = append(s, float64(v)) + } + return s case []string: for _, v := range t { r = append(r, v) @@ -48,6 +87,26 @@ s = append(s, float64(t[i])) } return s + case map[int]int8: + for i := 0; i < len(t); i++ { + s = append(s, float64(t[i])) + } + return s + case map[int]int16: + for i := 0; i < len(t); i++ { + s = append(s, float64(t[i])) + } + return s + case map[int]int32: + for i := 0; i < len(t); i++ { + s = append(s, float64(t[i])) + } + return s + case map[int]int64: + for i := 0; i < len(t); i++ { + s = append(s, float64(t[i])) + } + return s case map[int]string: for i := 0; i < len(t); i++ { r = append(r, t[i]) @@ -57,9 +116,29 @@ s = append(s, float64(t[i])) } return s + case map[int]uint8: + for i := 0; i < len(t); i++ { + s = append(s, float64(t[i])) + } + return s + case map[int]uint16: + for i := 0; i < len(t); i++ { + s = append(s, float64(t[i])) + } + return s + case map[int]uint32: + for i := 0; i < len(t); i++ { + s = append(s, float64(t[i])) + } + return s + case map[int]uint64: + for i := 0; i < len(t); i++ { + s = append(s, float64(t[i])) + } + return s case map[int]bool: for i := 0; i < len(t); i++ { - if t[i] == true { + if t[i] { s = append(s, 1.0) } else { s = append(s, 0.0) @@ -71,6 +150,10 @@ s = append(s, t[i]) } return s + case map[int]time.Duration: + for i := 0; i < len(t); i++ { + r = append(r, t[i]) + } } for _, v := range r { @@ -88,7 +171,7 @@ f = append(f, fl) } case bool: - if t == true { + if t { f = append(f, 1.0) } else { f = append(f, 0.0) diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/load_test.go golang-github-montanaflynn-stats-0.6.4/load_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/load_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/load_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,81 +1,158 @@ -package stats +package stats_test import ( + "fmt" "testing" "time" + + "github.com/montanaflynn/stats" ) +func ExampleLoadRawData() { + data := stats.LoadRawData([]interface{}{1.1, "2", 3}) + fmt.Println(data) + // Output: [1.1 2 3] +} + var allTestData = []struct { actual interface{} - expected Float64Data + expected stats.Float64Data }{ { - []interface{}{1.0, "2", 3.0, 4, "4.0", 5, time.Duration(6), time.Duration(-7)}, - Float64Data{1.0, 2.0, 3.0, 4.0, 4.0, 5.0, 6.0, -7.0}, + []interface{}{1.0, "2", 3.0, uint(4), "4.0", 5, time.Duration(6), time.Duration(-7)}, + stats.Float64Data{1.0, 2.0, 3.0, 4.0, 4.0, 5.0, 6.0, -7.0}, }, { []interface{}{"-345", "223", "-654.4", "194", "898.3"}, - Float64Data{-345.0, 223.0, -654.4, 194.0, 898.3}, + stats.Float64Data{-345.0, 223.0, -654.4, 194.0, 898.3}, }, { []interface{}{7862, 4234, 9872.1, 8794}, - Float64Data{7862.0, 4234.0, 9872.1, 8794.0}, + stats.Float64Data{7862.0, 4234.0, 9872.1, 8794.0}, }, { []interface{}{true, false, true, false, false}, - Float64Data{1.0, 0.0, 1.0, 0.0, 0.0}, + stats.Float64Data{1.0, 0.0, 1.0, 0.0, 0.0}, }, { []interface{}{14.3, 26, 17.7, "shoe"}, - Float64Data{14.3, 26.0, 17.7}, + stats.Float64Data{14.3, 26.0, 17.7}, + }, + { + []bool{true, false, true, true, false}, + stats.Float64Data{1.0, 0.0, 1.0, 1.0, 0.0}, + }, + { + []float64{10230.9823, 93432.9384, 23443.945, 12374.945}, + stats.Float64Data{10230.9823, 93432.9384, 23443.945, 12374.945}, + }, + { + []time.Duration{-843, 923, -398, 1000}, + stats.Float64Data{-843.0, 923.0, -398.0, 1000.0}, + }, + { + []string{"-843.2", "923", "hello", "-398", "1000.5"}, + stats.Float64Data{-843.2, 923.0, -398.0, 1000.5}, }, { []uint{34, 12, 65, 230, 30}, - Float64Data{34.0, 12.0, 65.0, 230.0, 30.0}, + stats.Float64Data{34.0, 12.0, 65.0, 230.0, 30.0}, }, { - []bool{true, false, true, true, false}, - Float64Data{1.0, 0.0, 1.0, 1.0, 0.0}, + []uint8{34, 12, 65, 23, 255}, + stats.Float64Data{34.0, 12.0, 65.0, 23.0, 255.0}, }, { - []float64{10230.9823, 93432.9384, 23443.945, 12374.945}, - Float64Data{10230.9823, 93432.9384, 23443.945, 12374.945}, + []uint16{34, 12, 65, 230, 65535}, + stats.Float64Data{34.0, 12.0, 65.0, 230.0, 65535.0}, + }, + { + []uint32{34, 12, 65, 230, 4294967295}, + stats.Float64Data{34.0, 12.0, 65.0, 230.0, 4294967295.0}, + }, + { + []uint64{34, 12, 65, 230, 18446744073709551615}, + stats.Float64Data{34.0, 12.0, 65.0, 230.0, 18446744073709552000.0}, }, { []int{-843, 923, -398, 1000}, - Float64Data{-843.0, 923.0, -398.0, 1000.0}, + stats.Float64Data{-843.0, 923.0, -398.0, 1000.0}, }, { - []time.Duration{-843, 923, -398, 1000}, - Float64Data{-843.0, 923.0, -398.0, 1000.0}, + []int8{-43, 23, -128, 127}, + stats.Float64Data{-43.0, 23.0, -128.0, 127.0}, }, { - []string{"-843.2", "923", "hello", "-398", "1000.5"}, - Float64Data{-843.2, 923.0, -398.0, 1000.5}, + []int16{-843, 923, -32768, 32767}, + stats.Float64Data{-843.0, 923.0, -32768.0, 32767.0}, }, { - map[int]int{0: 456, 1: 758, 2: -9874, 3: -1981}, - Float64Data{456.0, 758.0, -9874.0, -1981.0}, + []int32{-843, 923, -2147483648, 2147483647}, + stats.Float64Data{-843.0, 923.0, -2147483648.0, 2147483647.0}, + }, + { + []int64{-843, 923, -9223372036854775808, 9223372036854775807, 9223372036854775800}, + stats.Float64Data{-843.0, 923.0, -9223372036854776000.0, 9223372036854776000.0, 9223372036854776000.0}, + }, + { + map[int]bool{0: true, 1: true, 2: false, 3: true, 4: false}, + stats.Float64Data{1.0, 1.0, 0.0, 1.0, 0.0}, }, { map[int]float64{0: 68.6, 1: 72.1, 2: -33.3, 3: -99.2}, - Float64Data{68.6, 72.1, -33.3, -99.2}, + stats.Float64Data{68.6, 72.1, -33.3, -99.2}, }, { - map[int]uint{0: 4567, 1: 7580, 2: 98742, 3: 19817}, - Float64Data{4567.0, 7580.0, 98742.0, 19817.0}, + map[int]time.Duration{0: -843, 1: 923, 2: -398, 3: 1000}, + stats.Float64Data{-843.0, 923.0, -398.0, 1000.0}, }, { map[int]string{0: "456", 1: "758", 2: "-9874", 3: "-1981", 4: "68.6", 5: "72.1", 6: "-33.3", 7: "-99.2"}, - Float64Data{456.0, 758.0, -9874.0, -1981.0, 68.6, 72.1, -33.3, -99.2}, + stats.Float64Data{456.0, 758.0, -9874.0, -1981.0, 68.6, 72.1, -33.3, -99.2}, }, { - map[int]bool{0: true, 1: true, 2: false, 3: true, 4: false}, - Float64Data{1.0, 1.0, 0.0, 1.0, 0.0}, + map[int]uint{0: 4567, 1: 7580, 2: 98742, 3: 19817}, + stats.Float64Data{4567.0, 7580.0, 98742.0, 19817.0}, + }, + { + map[int]uint8{0: 34, 1: 12, 2: 65, 3: 23, 4: 255}, + stats.Float64Data{34.0, 12.0, 65.0, 23.0, 255.0}, + }, + { + map[int]uint16{0: 34, 1: 12, 2: 65, 3: 230, 4: 65535}, + stats.Float64Data{34.0, 12.0, 65.0, 230.0, 65535.0}, + }, + { + map[int]uint32{0: 34, 1: 12, 2: 65, 3: 230, 4: 4294967295}, + stats.Float64Data{34.0, 12.0, 65.0, 230.0, 4294967295.0}, + }, + { + map[int]uint64{0: 34, 1: 12, 2: 65, 3: 230, 4: 18446744073709551615}, + stats.Float64Data{34.0, 12.0, 65.0, 230.0, 18446744073709552000.0}, + }, + { + map[int]int{0: 456, 1: 758, 2: -9874, 3: -1981}, + stats.Float64Data{456.0, 758.0, -9874.0, -1981.0}, + }, + { + map[int]int8{0: -43, 1: 23, 2: -128, 3: 127}, + stats.Float64Data{-43.0, 23.0, -128.0, 127.0}, + }, + { + map[int]int16{0: -843, 1: 923, 2: -32768, 3: 32767}, + stats.Float64Data{-843.0, 923.0, -32768.0, 32767.0}, + }, + { + map[int]int32{0: -843, 1: 923, 2: -2147483648, 3: 2147483647}, + stats.Float64Data{-843.0, 923.0, -2147483648.0, 2147483647.0}, + }, + { + map[int]int64{0: -843, 1: 923, 2: -9223372036854775808, 3: 9223372036854775807, 4: 9223372036854775800}, + stats.Float64Data{-843.0, 923.0, -9223372036854776000.0, 9223372036854776000.0, 9223372036854776000.0}, }, } -func equal(actual, expected Float64Data) bool { +func equal(actual, expected stats.Float64Data) bool { if len(actual) != len(expected) { return false } @@ -91,7 +168,7 @@ func TestLoadRawData(t *testing.T) { for _, data := range allTestData { - actual := LoadRawData(data.actual) + actual := stats.LoadRawData(data.actual) if !equal(actual, data.expected) { t.Fatalf("Transform(%v). Expected [%v], Actual [%v]", data.actual, data.expected, actual) } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/Makefile golang-github-montanaflynn-stats-0.6.4/Makefile --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/Makefile 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/Makefile 2021-01-13 11:52:47.000000000 +0000 @@ -1,13 +1,9 @@ .PHONY: all -doc: - godoc `pwd` - -webdoc: - godoc -http=:44444 +default: test lint format: - go fmt + go fmt . test: go test -race @@ -22,8 +18,20 @@ go tool cover -html="coverage.out" lint: format - go get github.com/alecthomas/gometalinter - gometalinter --install - gometalinter + golangci-lint run . + +changelog: + git-chglog -o CHANGELOG.md + +docs: + godoc2md github.com/montanaflynn/stats | sed -e s#src/target/##g > DOCUMENTATION.md + +release: + git-chglog --next-tag ${TAG} ${TAG} -o CHANGELOG.md + git add CHANGELOG.md + git commit -m "Update changelog with ${TAG} changes" + git tag ${TAG} + git-chglog $(TAG) | tail -n +4 | sed '1s/^/$(TAG)\n/gm' > release-notes.txt + git push origin master ${TAG} + hub release create --copy -F release-notes.txt ${TAG} -default: lint test diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/max.go golang-github-montanaflynn-stats-0.6.4/max.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/max.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/max.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,13 +1,15 @@ package stats -import "math" +import ( + "math" +) // Max finds the highest number in a slice func Max(input Float64Data) (max float64, err error) { // Return an error if there are no numbers if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Get the first value as the starting point diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/max_test.go golang-github-montanaflynn-stats-0.6.4/max_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/max_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/max_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,9 +1,19 @@ -package stats +package stats_test import ( + "fmt" "testing" + + "github.com/montanaflynn/stats" ) +func ExampleMax() { + d := []float64{1.1, 2.3, 3.2, 4.0, 4.01, 5.09} + a, _ := stats.Max(d) + fmt.Println(a) + // Output: 5.09 +} + func TestMax(t *testing.T) { for _, c := range []struct { in []float64 @@ -14,7 +24,7 @@ {[]float64{-20, -1, -5.5}, -1.0}, {[]float64{-1.0}, -1.0}, } { - got, err := Max(c.in) + got, err := stats.Max(c.in) if err != nil { t.Errorf("Returned an error") } @@ -22,7 +32,7 @@ t.Errorf("Max(%.1f) => %.1f != %.1f", c.in, got, c.out) } } - _, err := Max([]float64{}) + _, err := stats.Max([]float64{}) if err == nil { t.Errorf("Empty slice didn't return an error") } @@ -30,7 +40,7 @@ func BenchmarkMaxSmallFloatSlice(b *testing.B) { for i := 0; i < b.N; i++ { - Max(makeFloatSlice(5)) + _, _ = stats.Max(makeFloatSlice(5)) } } @@ -38,6 +48,6 @@ lf := makeFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Max(lf) + _, _ = stats.Max(lf) } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/mean.go golang-github-montanaflynn-stats-0.6.4/mean.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/mean.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/mean.go 2021-01-13 11:52:47.000000000 +0000 @@ -6,7 +6,7 @@ func Mean(input Float64Data) (float64, error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } sum, _ := input.Sum() @@ -19,7 +19,7 @@ l := input.Len() if l == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Get the product of all the numbers @@ -41,7 +41,7 @@ l := input.Len() if l == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Get the sum of all the numbers reciprocals and return an diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/mean_test.go golang-github-montanaflynn-stats-0.6.4/mean_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/mean_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/mean_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,7 +1,9 @@ -package stats +package stats_test import ( "testing" + + "github.com/montanaflynn/stats" ) func TestMean(t *testing.T) { @@ -13,12 +15,12 @@ {[]float64{1, 2, 3, 4, 5, 6}, 3.5}, {[]float64{1}, 1.0}, } { - got, _ := Mean(c.in) + got, _ := stats.Mean(c.in) if got != c.out { t.Errorf("Mean(%.1f) => %.1f != %.1f", c.in, got, c.out) } } - _, err := Mean([]float64{}) + _, err := stats.Mean([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -26,7 +28,7 @@ func BenchmarkMeanSmallFloatSlice(b *testing.B) { for i := 0; i < b.N; i++ { - Mean(makeFloatSlice(5)) + _, _ = stats.Mean(makeFloatSlice(5)) } } @@ -34,7 +36,7 @@ lf := makeFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Mean(lf) + _, _ = stats.Mean(lf) } } @@ -51,18 +53,18 @@ {s2, 16}, {s3, 9}, } { - gm, err := GeometricMean(c.in) + gm, err := stats.GeometricMean(c.in) if err != nil { t.Errorf("Should not have returned an error") } - gm, _ = Round(gm, 0) + gm, _ = stats.Round(gm, 0) if gm != c.out { t.Errorf("Geometric Mean %v != %v", gm, c.out) } } - _, err := GeometricMean([]float64{}) + _, err := stats.GeometricMean([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -73,27 +75,27 @@ s2 := []float64{10, -51.2, 8} s3 := []float64{1, 0, 9, 27, 81} - hm, err := HarmonicMean(s1) + hm, err := stats.HarmonicMean(s1) if err != nil { t.Errorf("Should not have returned an error") } - hm, _ = Round(hm, 2) + hm, _ = stats.Round(hm, 2) if hm != 2.19 { t.Errorf("Geometric Mean %v != %v", hm, 2.19) } - hm, err = HarmonicMean(s2) + _, err = stats.HarmonicMean(s2) if err == nil { t.Errorf("Should have returned a negative number error") } - hm, err = HarmonicMean(s3) + _, err = stats.HarmonicMean(s3) if err == nil { t.Errorf("Should have returned a zero number error") } - _, err = HarmonicMean([]float64{}) + _, err = stats.HarmonicMean([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/median.go golang-github-montanaflynn-stats-0.6.4/median.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/median.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/median.go 2021-01-13 11:52:47.000000000 +0000 @@ -14,11 +14,11 @@ // For odd numbers we just use the middle number l := len(c) if l == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } else if l%2 == 0 { median, _ = Mean(c[l/2-1 : l/2+1]) } else { - median = float64(c[l/2]) + median = c[l/2] } return median, nil diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/median_test.go golang-github-montanaflynn-stats-0.6.4/median_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/median_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/median_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,10 +1,20 @@ -package stats +package stats_test import ( + "fmt" "reflect" "testing" + + "github.com/montanaflynn/stats" ) +func ExampleMedian() { + data := []float64{1.0, 2.1, 3.2, 4.823, 4.1, 5.8} + median, _ := stats.Median(data) + fmt.Println(median) + // Output: 3.65 +} + func TestMedian(t *testing.T) { for _, c := range []struct { in []float64 @@ -14,12 +24,12 @@ {[]float64{6, 3, 2, 4, 5, 1}, 3.5}, {[]float64{1}, 1.0}, } { - got, _ := Median(c.in) + got, _ := stats.Median(c.in) if got != c.out { t.Errorf("Median(%.1f) => %.1f != %.1f", c.in, got, c.out) } } - _, err := Median([]float64{}) + _, err := stats.Median([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -27,7 +37,7 @@ func BenchmarkMedianSmallFloatSlice(b *testing.B) { for i := 0; i < b.N; i++ { - Median(makeFloatSlice(5)) + _, _ = stats.Median(makeFloatSlice(5)) } } @@ -35,14 +45,14 @@ lf := makeFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Median(lf) + _, _ = stats.Median(lf) } } func TestMedianSortSideEffects(t *testing.T) { s := []float64{0.1, 0.3, 0.2, 0.4, 0.5} a := []float64{0.1, 0.3, 0.2, 0.4, 0.5} - Median(s) + _, _ = stats.Median(s) if !reflect.DeepEqual(s, a) { t.Errorf("%.1f != %.1f", s, a) } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/min.go golang-github-montanaflynn-stats-0.6.4/min.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/min.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/min.go 2021-01-13 11:52:47.000000000 +0000 @@ -10,7 +10,7 @@ // Return an error if there are no numbers if l == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Get the first value as the starting point diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/min_test.go golang-github-montanaflynn-stats-0.6.4/min_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/min_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/min_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,9 +1,19 @@ -package stats +package stats_test import ( + "fmt" "testing" + + "github.com/montanaflynn/stats" ) +func ExampleMin() { + d := stats.LoadRawData([]interface{}{1.1, "2", 3.0, 4, "5"}) + a, _ := stats.Min(d) + fmt.Println(a) + // Output: 1.1 +} + func TestMin(t *testing.T) { for _, c := range []struct { in []float64 @@ -14,7 +24,7 @@ {[]float64{-5, 1, 5}, -5.0}, {[]float64{5}, 5}, } { - got, err := Min(c.in) + got, err := stats.Min(c.in) if err != nil { t.Errorf("Returned an error") } @@ -22,7 +32,7 @@ t.Errorf("Min(%.1f) => %.1f != %.1f", c.in, got, c.out) } } - _, err := Min([]float64{}) + _, err := stats.Min([]float64{}) if err == nil { t.Errorf("Empty slice didn't return an error") } @@ -31,7 +41,7 @@ func BenchmarkMinSmallFloatSlice(b *testing.B) { testData := makeFloatSlice(5) for i := 0; i < b.N; i++ { - Min(testData) + _, _ = stats.Min(testData) } } @@ -39,7 +49,7 @@ testData := makeRandFloatSlice(5) b.ResetTimer() for i := 0; i < b.N; i++ { - Min(testData) + _, _ = stats.Min(testData) } } @@ -47,7 +57,7 @@ testData := makeFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Min(testData) + _, _ = stats.Min(testData) } } @@ -55,6 +65,6 @@ testData := makeRandFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Min(testData) + _, _ = stats.Min(testData) } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/mode.go golang-github-montanaflynn-stats-0.6.4/mode.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/mode.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/mode.go 2021-01-13 11:52:47.000000000 +0000 @@ -7,7 +7,7 @@ if l == 1 { return input, nil } else if l == 0 { - return nil, EmptyInput + return nil, EmptyInputErr } c := sortedCopyDif(input) @@ -39,7 +39,7 @@ // Since length must be greater than 1, // check for slices of distinct values - if maxCnt == 1 { + if maxCnt == 1 || len(mode)*maxCnt == l && maxCnt != l { return Float64Data{}, nil } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/mode_test.go golang-github-montanaflynn-stats-0.6.4/mode_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/mode_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/mode_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,9 +1,10 @@ -package stats +package stats_test import ( "reflect" - "sort" "testing" + + "github.com/montanaflynn/stats" ) func TestMode(t *testing.T) { @@ -11,7 +12,9 @@ in []float64 out []float64 }{ + {[]float64{2, 2, 2, 2}, []float64{2}}, {[]float64{5, 3, 4, 2, 1}, []float64{}}, + {[]float64{5, 5, 3, 3, 4, 4, 2, 2, 1, 1}, []float64{}}, {[]float64{5, 5, 3, 4, 2, 1}, []float64{5}}, {[]float64{5, 5, 3, 3, 4, 2, 1}, []float64{3, 5}}, {[]float64{1}, []float64{1}}, @@ -19,16 +22,15 @@ {[]float64{1, 2, 3, 4, 4, 4, 4, 4, 5, 3, 6, 7, 5, 0, 8, 8, 7, 6, 9, 9}, []float64{4}}, {[]float64{76, 76, 110, 76, 76, 76, 76, 119, 76, 76, 76, 76, 31, 31, 31, 31, 83, 83, 83, 78, 78, 78, 78, 78, 78, 78, 78}, []float64{76}}, } { - got, err := Mode(c.in) + got, err := stats.Mode(c.in) if err != nil { t.Errorf("Returned an error") } - sort.Float64s(got) if !reflect.DeepEqual(c.out, got) { t.Errorf("Mode(%.1f) => %.1f != %.1f", c.in, got, c.out) } } - _, err := Mode([]float64{}) + _, err := stats.Mode([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -36,7 +38,7 @@ func BenchmarkModeSmallFloatSlice(b *testing.B) { for i := 0; i < b.N; i++ { - Mode(makeFloatSlice(5)) + _, _ = stats.Mode(makeFloatSlice(5)) } } @@ -44,7 +46,7 @@ lf := makeRandFloatSlice(5) b.ResetTimer() for i := 0; i < b.N; i++ { - Mode(lf) + _, _ = stats.Mode(lf) } } @@ -52,7 +54,7 @@ lf := makeFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Mode(lf) + _, _ = stats.Mode(lf) } } @@ -60,6 +62,6 @@ lf := makeRandFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Mode(lf) + _, _ = stats.Mode(lf) } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/nist_test.go golang-github-montanaflynn-stats-0.6.4/nist_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/nist_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/nist_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,515 @@ +package stats_test + +import ( + "math" + "testing" + + "github.com/montanaflynn/stats" +) + +var ( + lew = stats.Float64Data{ + -213, -564, -35, -15, 141, 115, -420, -360, 203, -338, -431, 194, + -220, -513, 154, -125, -559, 92, -21, -579, -52, 99, -543, -175, + 162, -457, -346, 204, -300, -474, 164, -107, -572, -8, 83, -541, + -224, 180, -420, -374, 201, -236, -531, 83, 27, -564, -112, 131, + -507, -254, 199, -311, -495, 143, -46, -579, -90, 136, -472, -338, + 202, -287, -477, 169, -124, -568, 17, 48, -568, -135, 162, -430, + -422, 172, -74, -577, -13, 92, -534, -243, 194, -355, -465, 156, + -81, -578, -64, 139, -449, -384, 193, -198, -538, 110, -44, -577, + -6, 66, -552, -164, 161, -460, -344, 205, -281, -504, 134, -28, + -576, -118, 156, -437, -381, 200, -220, -540, 83, 11, -568, -160, + 172, -414, -408, 188, -125, -572, -32, 139, -492, -321, 205, -262, + -504, 142, -83, -574, 0, 48, -571, -106, 137, -501, -266, 190, + -391, -406, 194, -186, -553, 83, -13, -577, -49, 103, -515, -280, + 201, 300, -506, 131, -45, -578, -80, 138, -462, -361, 201, -211, + -554, 32, 74, -533, -235, 187, -372, -442, 182, -147, -566, 25, + 68, -535, -244, 194, -351, -463, 174, -125, -570, 15, 72, -550, + -190, 172, -424, -385, 198, -218, -536, 96} + + lottery = stats.Float64Data{ + 162, 671, 933, 414, 788, 730, 817, 33, 536, 875, 670, 236, 473, 167, + 877, 980, 316, 950, 456, 92, 517, 557, 956, 954, 104, 178, 794, 278, + 147, 773, 437, 435, 502, 610, 582, 780, 689, 562, 964, 791, 28, 97, + 848, 281, 858, 538, 660, 972, 671, 613, 867, 448, 738, 966, 139, 636, + 847, 659, 754, 243, 122, 455, 195, 968, 793, 59, 730, 361, 574, 522, + 97, 762, 431, 158, 429, 414, 22, 629, 788, 999, 187, 215, 810, 782, + 47, 34, 108, 986, 25, 644, 829, 630, 315, 567, 919, 331, 207, 412, + 242, 607, 668, 944, 749, 168, 864, 442, 533, 805, 372, 63, 458, 777, + 416, 340, 436, 140, 919, 350, 510, 572, 905, 900, 85, 389, 473, 758, + 444, 169, 625, 692, 140, 897, 672, 288, 312, 860, 724, 226, 884, 508, + 976, 741, 476, 417, 831, 15, 318, 432, 241, 114, 799, 955, 833, 358, + 935, 146, 630, 830, 440, 642, 356, 373, 271, 715, 367, 393, 190, 669, + 8, 861, 108, 795, 269, 590, 326, 866, 64, 523, 862, 840, 219, 382, + 998, 4, 628, 305, 747, 247, 34, 747, 729, 645, 856, 974, 24, 568, 24, + 694, 608, 480, 410, 729, 947, 293, 53, 930, 223, 203, 677, 227, 62, + 455, 387, 318, 562, 242, 428, 968} + + mavro = stats.Float64Data{ + 2.00180, 2.00170, 2.00180, 2.00190, 2.00180, 2.00170, 2.00150, + 2.00140, 2.00150, 2.00150, 2.00170, 2.00180, 2.00180, 2.00190, + 2.00190, 2.00210, 2.00200, 2.00160, 2.00140, 2.00130, 2.00130, + 2.00150, 2.00150, 2.00160, 2.00150, 2.00140, 2.00130, 2.00140, + 2.00150, 2.00140, 2.00150, 2.00160, 2.00150, 2.00160, 2.00190, + 2.00200, 2.00200, 2.00210, 2.00220, 2.00230, 2.00240, 2.00250, + 2.00270, 2.00260, 2.00260, 2.00260, 2.00270, 2.00260, 2.00250, + 2.00240} + + michelson = stats.Float64Data{ + 299.85, 299.74, 299.90, 300.07, 299.93, 299.85, 299.95, 299.98, + 299.98, 299.88, 300.00, 299.98, 299.93, 299.65, 299.76, 299.81, + 300.00, 300.00, 299.96, 299.96, 299.96, 299.94, 299.96, 299.94, + 299.88, 299.80, 299.85, 299.88, 299.90, 299.84, 299.83, 299.79, + 299.81, 299.88, 299.88, 299.83, 299.80, 299.79, 299.76, 299.80, + 299.88, 299.88, 299.88, 299.86, 299.72, 299.72, 299.62, 299.86, + 299.97, 299.95, 299.88, 299.91, 299.85, 299.87, 299.84, 299.84, + 299.85, 299.84, 299.84, 299.84, 299.89, 299.81, 299.81, 299.82, + 299.80, 299.77, 299.76, 299.74, 299.75, 299.76, 299.91, 299.92, + 299.89, 299.86, 299.88, 299.72, 299.84, 299.85, 299.85, 299.78, + 299.89, 299.84, 299.78, 299.81, 299.76, 299.81, 299.79, 299.81, + 299.82, 299.85, 299.87, 299.87, 299.81, 299.74, 299.81, 299.94, + 299.95, 299.80, 299.81, 299.87} + + pidigits = stats.Float64Data{ + 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, + 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5, 0, 2, + 8, 8, 4, 1, 9, 7, 1, 6, 9, 3, 9, 9, 3, 7, 5, 1, 0, 5, 8, 2, 0, 9, + 7, 4, 9, 4, 4, 5, 9, 2, 3, 0, 7, 8, 1, 6, 4, 0, 6, 2, 8, 6, 2, 0, + 8, 9, 9, 8, 6, 2, 8, 0, 3, 4, 8, 2, 5, 3, 4, 2, 1, 1, 7, 0, 6, 7, + 9, 8, 2, 1, 4, 8, 0, 8, 6, 5, 1, 3, 2, 8, 2, 3, 0, 6, 6, 4, 7, 0, + 9, 3, 8, 4, 4, 6, 0, 9, 5, 5, 0, 5, 8, 2, 2, 3, 1, 7, 2, 5, 3, 5, + 9, 4, 0, 8, 1, 2, 8, 4, 8, 1, 1, 1, 7, 4, 5, 0, 2, 8, 4, 1, 0, 2, + 7, 0, 1, 9, 3, 8, 5, 2, 1, 1, 0, 5, 5, 5, 9, 6, 4, 4, 6, 2, 2, 9, + 4, 8, 9, 5, 4, 9, 3, 0, 3, 8, 1, 9, 6, 4, 4, 2, 8, 8, 1, 0, 9, 7, + 5, 6, 6, 5, 9, 3, 3, 4, 4, 6, 1, 2, 8, 4, 7, 5, 6, 4, 8, 2, 3, 3, + 7, 8, 6, 7, 8, 3, 1, 6, 5, 2, 7, 1, 2, 0, 1, 9, 0, 9, 1, 4, 5, 6, + 4, 8, 5, 6, 6, 9, 2, 3, 4, 6, 0, 3, 4, 8, 6, 1, 0, 4, 5, 4, 3, 2, + 6, 6, 4, 8, 2, 1, 3, 3, 9, 3, 6, 0, 7, 2, 6, 0, 2, 4, 9, 1, 4, 1, + 2, 7, 3, 7, 2, 4, 5, 8, 7, 0, 0, 6, 6, 0, 6, 3, 1, 5, 5, 8, 8, 1, + 7, 4, 8, 8, 1, 5, 2, 0, 9, 2, 0, 9, 6, 2, 8, 2, 9, 2, 5, 4, 0, 9, + 1, 7, 1, 5, 3, 6, 4, 3, 6, 7, 8, 9, 2, 5, 9, 0, 3, 6, 0, 0, 1, 1, + 3, 3, 0, 5, 3, 0, 5, 4, 8, 8, 2, 0, 4, 6, 6, 5, 2, 1, 3, 8, 4, 1, + 4, 6, 9, 5, 1, 9, 4, 1, 5, 1, 1, 6, 0, 9, 4, 3, 3, 0, 5, 7, 2, 7, + 0, 3, 6, 5, 7, 5, 9, 5, 9, 1, 9, 5, 3, 0, 9, 2, 1, 8, 6, 1, 1, 7, + 3, 8, 1, 9, 3, 2, 6, 1, 1, 7, 9, 3, 1, 0, 5, 1, 1, 8, 5, 4, 8, 0, + 7, 4, 4, 6, 2, 3, 7, 9, 9, 6, 2, 7, 4, 9, 5, 6, 7, 3, 5, 1, 8, 8, + 5, 7, 5, 2, 7, 2, 4, 8, 9, 1, 2, 2, 7, 9, 3, 8, 1, 8, 3, 0, 1, 1, + 9, 4, 9, 1, 2, 9, 8, 3, 3, 6, 7, 3, 3, 6, 2, 4, 4, 0, 6, 5, 6, 6, + 4, 3, 0, 8, 6, 0, 2, 1, 3, 9, 4, 9, 4, 6, 3, 9, 5, 2, 2, 4, 7, 3, + 7, 1, 9, 0, 7, 0, 2, 1, 7, 9, 8, 6, 0, 9, 4, 3, 7, 0, 2, 7, 7, 0, + 5, 3, 9, 2, 1, 7, 1, 7, 6, 2, 9, 3, 1, 7, 6, 7, 5, 2, 3, 8, 4, 6, + 7, 4, 8, 1, 8, 4, 6, 7, 6, 6, 9, 4, 0, 5, 1, 3, 2, 0, 0, 0, 5, 6, + 8, 1, 2, 7, 1, 4, 5, 2, 6, 3, 5, 6, 0, 8, 2, 7, 7, 8, 5, 7, 7, 1, + 3, 4, 2, 7, 5, 7, 7, 8, 9, 6, 0, 9, 1, 7, 3, 6, 3, 7, 1, 7, 8, 7, + 2, 1, 4, 6, 8, 4, 4, 0, 9, 0, 1, 2, 2, 4, 9, 5, 3, 4, 3, 0, 1, 4, + 6, 5, 4, 9, 5, 8, 5, 3, 7, 1, 0, 5, 0, 7, 9, 2, 2, 7, 9, 6, 8, 9, + 2, 5, 8, 9, 2, 3, 5, 4, 2, 0, 1, 9, 9, 5, 6, 1, 1, 2, 1, 2, 9, 0, + 2, 1, 9, 6, 0, 8, 6, 4, 0, 3, 4, 4, 1, 8, 1, 5, 9, 8, 1, 3, 6, 2, + 9, 7, 7, 4, 7, 7, 1, 3, 0, 9, 9, 6, 0, 5, 1, 8, 7, 0, 7, 2, 1, 1, + 3, 4, 9, 9, 9, 9, 9, 9, 8, 3, 7, 2, 9, 7, 8, 0, 4, 9, 9, 5, 1, 0, + 5, 9, 7, 3, 1, 7, 3, 2, 8, 1, 6, 0, 9, 6, 3, 1, 8, 5, 9, 5, 0, 2, + 4, 4, 5, 9, 4, 5, 5, 3, 4, 6, 9, 0, 8, 3, 0, 2, 6, 4, 2, 5, 2, 2, + 3, 0, 8, 2, 5, 3, 3, 4, 4, 6, 8, 5, 0, 3, 5, 2, 6, 1, 9, 3, 1, 1, + 8, 8, 1, 7, 1, 0, 1, 0, 0, 0, 3, 1, 3, 7, 8, 3, 8, 7, 5, 2, 8, 8, + 6, 5, 8, 7, 5, 3, 3, 2, 0, 8, 3, 8, 1, 4, 2, 0, 6, 1, 7, 1, 7, 7, + 6, 6, 9, 1, 4, 7, 3, 0, 3, 5, 9, 8, 2, 5, 3, 4, 9, 0, 4, 2, 8, 7, + 5, 5, 4, 6, 8, 7, 3, 1, 1, 5, 9, 5, 6, 2, 8, 6, 3, 8, 8, 2, 3, 5, + 3, 7, 8, 7, 5, 9, 3, 7, 5, 1, 9, 5, 7, 7, 8, 1, 8, 5, 7, 7, 3, 0, + 5, 3, 2, 1, 7, 1, 2, 2, 6, 8, 0, 6, 6, 1, 3, 0, 0, 1, 9, 2, 7, 8, + 7, 6, 6, 1, 1, 1, 9, 5, 9, 0, 9, 2, 1, 6, 4, 2, 0, 1, 9, 8, 9, 3, + 8, 0, 9, 5, 2, 5, 7, 2, 0, 1, 0, 6, 5, 4, 8, 5, 8, 6, 3, 2, 7, 8, + 8, 6, 5, 9, 3, 6, 1, 5, 3, 3, 8, 1, 8, 2, 7, 9, 6, 8, 2, 3, 0, 3, + 0, 1, 9, 5, 2, 0, 3, 5, 3, 0, 1, 8, 5, 2, 9, 6, 8, 9, 9, 5, 7, 7, + 3, 6, 2, 2, 5, 9, 9, 4, 1, 3, 8, 9, 1, 2, 4, 9, 7, 2, 1, 7, 7, 5, + 2, 8, 3, 4, 7, 9, 1, 3, 1, 5, 1, 5, 5, 7, 4, 8, 5, 7, 2, 4, 2, 4, + 5, 4, 1, 5, 0, 6, 9, 5, 9, 5, 0, 8, 2, 9, 5, 3, 3, 1, 1, 6, 8, 6, + 1, 7, 2, 7, 8, 5, 5, 8, 8, 9, 0, 7, 5, 0, 9, 8, 3, 8, 1, 7, 5, 4, + 6, 3, 7, 4, 6, 4, 9, 3, 9, 3, 1, 9, 2, 5, 5, 0, 6, 0, 4, 0, 0, 9, + 2, 7, 7, 0, 1, 6, 7, 1, 1, 3, 9, 0, 0, 9, 8, 4, 8, 8, 2, 4, 0, 1, + 2, 8, 5, 8, 3, 6, 1, 6, 0, 3, 5, 6, 3, 7, 0, 7, 6, 6, 0, 1, 0, 4, + 7, 1, 0, 1, 8, 1, 9, 4, 2, 9, 5, 5, 5, 9, 6, 1, 9, 8, 9, 4, 6, 7, + 6, 7, 8, 3, 7, 4, 4, 9, 4, 4, 8, 2, 5, 5, 3, 7, 9, 7, 7, 4, 7, 2, + 6, 8, 4, 7, 1, 0, 4, 0, 4, 7, 5, 3, 4, 6, 4, 6, 2, 0, 8, 0, 4, 6, + 6, 8, 4, 2, 5, 9, 0, 6, 9, 4, 9, 1, 2, 9, 3, 3, 1, 3, 6, 7, 7, 0, + 2, 8, 9, 8, 9, 1, 5, 2, 1, 0, 4, 7, 5, 2, 1, 6, 2, 0, 5, 6, 9, 6, + 6, 0, 2, 4, 0, 5, 8, 0, 3, 8, 1, 5, 0, 1, 9, 3, 5, 1, 1, 2, 5, 3, + 3, 8, 2, 4, 3, 0, 0, 3, 5, 5, 8, 7, 6, 4, 0, 2, 4, 7, 4, 9, 6, 4, + 7, 3, 2, 6, 3, 9, 1, 4, 1, 9, 9, 2, 7, 2, 6, 0, 4, 2, 6, 9, 9, 2, + 2, 7, 9, 6, 7, 8, 2, 3, 5, 4, 7, 8, 1, 6, 3, 6, 0, 0, 9, 3, 4, 1, + 7, 2, 1, 6, 4, 1, 2, 1, 9, 9, 2, 4, 5, 8, 6, 3, 1, 5, 0, 3, 0, 2, + 8, 6, 1, 8, 2, 9, 7, 4, 5, 5, 5, 7, 0, 6, 7, 4, 9, 8, 3, 8, 5, 0, + 5, 4, 9, 4, 5, 8, 8, 5, 8, 6, 9, 2, 6, 9, 9, 5, 6, 9, 0, 9, 2, 7, + 2, 1, 0, 7, 9, 7, 5, 0, 9, 3, 0, 2, 9, 5, 5, 3, 2, 1, 1, 6, 5, 3, + 4, 4, 9, 8, 7, 2, 0, 2, 7, 5, 5, 9, 6, 0, 2, 3, 6, 4, 8, 0, 6, 6, + 5, 4, 9, 9, 1, 1, 9, 8, 8, 1, 8, 3, 4, 7, 9, 7, 7, 5, 3, 5, 6, 6, + 3, 6, 9, 8, 0, 7, 4, 2, 6, 5, 4, 2, 5, 2, 7, 8, 6, 2, 5, 5, 1, 8, + 1, 8, 4, 1, 7, 5, 7, 4, 6, 7, 2, 8, 9, 0, 9, 7, 7, 7, 7, 2, 7, 9, + 3, 8, 0, 0, 0, 8, 1, 6, 4, 7, 0, 6, 0, 0, 1, 6, 1, 4, 5, 2, 4, 9, + 1, 9, 2, 1, 7, 3, 2, 1, 7, 2, 1, 4, 7, 7, 2, 3, 5, 0, 1, 4, 1, 4, + 4, 1, 9, 7, 3, 5, 6, 8, 5, 4, 8, 1, 6, 1, 3, 6, 1, 1, 5, 7, 3, 5, + 2, 5, 5, 2, 1, 3, 3, 4, 7, 5, 7, 4, 1, 8, 4, 9, 4, 6, 8, 4, 3, 8, + 5, 2, 3, 3, 2, 3, 9, 0, 7, 3, 9, 4, 1, 4, 3, 3, 3, 4, 5, 4, 7, 7, + 6, 2, 4, 1, 6, 8, 6, 2, 5, 1, 8, 9, 8, 3, 5, 6, 9, 4, 8, 5, 5, 6, + 2, 0, 9, 9, 2, 1, 9, 2, 2, 2, 1, 8, 4, 2, 7, 2, 5, 5, 0, 2, 5, 4, + 2, 5, 6, 8, 8, 7, 6, 7, 1, 7, 9, 0, 4, 9, 4, 6, 0, 1, 6, 5, 3, 4, + 6, 6, 8, 0, 4, 9, 8, 8, 6, 2, 7, 2, 3, 2, 7, 9, 1, 7, 8, 6, 0, 8, + 5, 7, 8, 4, 3, 8, 3, 8, 2, 7, 9, 6, 7, 9, 7, 6, 6, 8, 1, 4, 5, 4, + 1, 0, 0, 9, 5, 3, 8, 8, 3, 7, 8, 6, 3, 6, 0, 9, 5, 0, 6, 8, 0, 0, + 6, 4, 2, 2, 5, 1, 2, 5, 2, 0, 5, 1, 1, 7, 3, 9, 2, 9, 8, 4, 8, 9, + 6, 0, 8, 4, 1, 2, 8, 4, 8, 8, 6, 2, 6, 9, 4, 5, 6, 0, 4, 2, 4, 1, + 9, 6, 5, 2, 8, 5, 0, 2, 2, 2, 1, 0, 6, 6, 1, 1, 8, 6, 3, 0, 6, 7, + 4, 4, 2, 7, 8, 6, 2, 2, 0, 3, 9, 1, 9, 4, 9, 4, 5, 0, 4, 7, 1, 2, + 3, 7, 1, 3, 7, 8, 6, 9, 6, 0, 9, 5, 6, 3, 6, 4, 3, 7, 1, 9, 1, 7, + 2, 8, 7, 4, 6, 7, 7, 6, 4, 6, 5, 7, 5, 7, 3, 9, 6, 2, 4, 1, 3, 8, + 9, 0, 8, 6, 5, 8, 3, 2, 6, 4, 5, 9, 9, 5, 8, 1, 3, 3, 9, 0, 4, 7, + 8, 0, 2, 7, 5, 9, 0, 0, 9, 9, 4, 6, 5, 7, 6, 4, 0, 7, 8, 9, 5, 1, + 2, 6, 9, 4, 6, 8, 3, 9, 8, 3, 5, 2, 5, 9, 5, 7, 0, 9, 8, 2, 5, 8, + 2, 2, 6, 2, 0, 5, 2, 2, 4, 8, 9, 4, 0, 7, 7, 2, 6, 7, 1, 9, 4, 7, + 8, 2, 6, 8, 4, 8, 2, 6, 0, 1, 4, 7, 6, 9, 9, 0, 9, 0, 2, 6, 4, 0, + 1, 3, 6, 3, 9, 4, 4, 3, 7, 4, 5, 5, 3, 0, 5, 0, 6, 8, 2, 0, 3, 4, + 9, 6, 2, 5, 2, 4, 5, 1, 7, 4, 9, 3, 9, 9, 6, 5, 1, 4, 3, 1, 4, 2, + 9, 8, 0, 9, 1, 9, 0, 6, 5, 9, 2, 5, 0, 9, 3, 7, 2, 2, 1, 6, 9, 6, + 4, 6, 1, 5, 1, 5, 7, 0, 9, 8, 5, 8, 3, 8, 7, 4, 1, 0, 5, 9, 7, 8, + 8, 5, 9, 5, 9, 7, 7, 2, 9, 7, 5, 4, 9, 8, 9, 3, 0, 1, 6, 1, 7, 5, + 3, 9, 2, 8, 4, 6, 8, 1, 3, 8, 2, 6, 8, 6, 8, 3, 8, 6, 8, 9, 4, 2, + 7, 7, 4, 1, 5, 5, 9, 9, 1, 8, 5, 5, 9, 2, 5, 2, 4, 5, 9, 5, 3, 9, + 5, 9, 4, 3, 1, 0, 4, 9, 9, 7, 2, 5, 2, 4, 6, 8, 0, 8, 4, 5, 9, 8, + 7, 2, 7, 3, 6, 4, 4, 6, 9, 5, 8, 4, 8, 6, 5, 3, 8, 3, 6, 7, 3, 6, + 2, 2, 2, 6, 2, 6, 0, 9, 9, 1, 2, 4, 6, 0, 8, 0, 5, 1, 2, 4, 3, 8, + 8, 4, 3, 9, 0, 4, 5, 1, 2, 4, 4, 1, 3, 6, 5, 4, 9, 7, 6, 2, 7, 8, + 0, 7, 9, 7, 7, 1, 5, 6, 9, 1, 4, 3, 5, 9, 9, 7, 7, 0, 0, 1, 2, 9, + 6, 1, 6, 0, 8, 9, 4, 4, 1, 6, 9, 4, 8, 6, 8, 5, 5, 5, 8, 4, 8, 4, + 0, 6, 3, 5, 3, 4, 2, 2, 0, 7, 2, 2, 2, 5, 8, 2, 8, 4, 8, 8, 6, 4, + 8, 1, 5, 8, 4, 5, 6, 0, 2, 8, 5, 0, 6, 0, 1, 6, 8, 4, 2, 7, 3, 9, + 4, 5, 2, 2, 6, 7, 4, 6, 7, 6, 7, 8, 8, 9, 5, 2, 5, 2, 1, 3, 8, 5, + 2, 2, 5, 4, 9, 9, 5, 4, 6, 6, 6, 7, 2, 7, 8, 2, 3, 9, 8, 6, 4, 5, + 6, 5, 9, 6, 1, 1, 6, 3, 5, 4, 8, 8, 6, 2, 3, 0, 5, 7, 7, 4, 5, 6, + 4, 9, 8, 0, 3, 5, 5, 9, 3, 6, 3, 4, 5, 6, 8, 1, 7, 4, 3, 2, 4, 1, + 1, 2, 5, 1, 5, 0, 7, 6, 0, 6, 9, 4, 7, 9, 4, 5, 1, 0, 9, 6, 5, 9, + 6, 0, 9, 4, 0, 2, 5, 2, 2, 8, 8, 7, 9, 7, 1, 0, 8, 9, 3, 1, 4, 5, + 6, 6, 9, 1, 3, 6, 8, 6, 7, 2, 2, 8, 7, 4, 8, 9, 4, 0, 5, 6, 0, 1, + 0, 1, 5, 0, 3, 3, 0, 8, 6, 1, 7, 9, 2, 8, 6, 8, 0, 9, 2, 0, 8, 7, + 4, 7, 6, 0, 9, 1, 7, 8, 2, 4, 9, 3, 8, 5, 8, 9, 0, 0, 9, 7, 1, 4, + 9, 0, 9, 6, 7, 5, 9, 8, 5, 2, 6, 1, 3, 6, 5, 5, 4, 9, 7, 8, 1, 8, + 9, 3, 1, 2, 9, 7, 8, 4, 8, 2, 1, 6, 8, 2, 9, 9, 8, 9, 4, 8, 7, 2, + 2, 6, 5, 8, 8, 0, 4, 8, 5, 7, 5, 6, 4, 0, 1, 4, 2, 7, 0, 4, 7, 7, + 5, 5, 5, 1, 3, 2, 3, 7, 9, 6, 4, 1, 4, 5, 1, 5, 2, 3, 7, 4, 6, 2, + 3, 4, 3, 6, 4, 5, 4, 2, 8, 5, 8, 4, 4, 4, 7, 9, 5, 2, 6, 5, 8, 6, + 7, 8, 2, 1, 0, 5, 1, 1, 4, 1, 3, 5, 4, 7, 3, 5, 7, 3, 9, 5, 2, 3, + 1, 1, 3, 4, 2, 7, 1, 6, 6, 1, 0, 2, 1, 3, 5, 9, 6, 9, 5, 3, 6, 2, + 3, 1, 4, 4, 2, 9, 5, 2, 4, 8, 4, 9, 3, 7, 1, 8, 7, 1, 1, 0, 1, 4, + 5, 7, 6, 5, 4, 0, 3, 5, 9, 0, 2, 7, 9, 9, 3, 4, 4, 0, 3, 7, 4, 2, + 0, 0, 7, 3, 1, 0, 5, 7, 8, 5, 3, 9, 0, 6, 2, 1, 9, 8, 3, 8, 7, 4, + 4, 7, 8, 0, 8, 4, 7, 8, 4, 8, 9, 6, 8, 3, 3, 2, 1, 4, 4, 5, 7, 1, + 3, 8, 6, 8, 7, 5, 1, 9, 4, 3, 5, 0, 6, 4, 3, 0, 2, 1, 8, 4, 5, 3, + 1, 9, 1, 0, 4, 8, 4, 8, 1, 0, 0, 5, 3, 7, 0, 6, 1, 4, 6, 8, 0, 6, + 7, 4, 9, 1, 9, 2, 7, 8, 1, 9, 1, 1, 9, 7, 9, 3, 9, 9, 5, 2, 0, 6, + 1, 4, 1, 9, 6, 6, 3, 4, 2, 8, 7, 5, 4, 4, 4, 0, 6, 4, 3, 7, 4, 5, + 1, 2, 3, 7, 1, 8, 1, 9, 2, 1, 7, 9, 9, 9, 8, 3, 9, 1, 0, 1, 5, 9, + 1, 9, 5, 6, 1, 8, 1, 4, 6, 7, 5, 1, 4, 2, 6, 9, 1, 2, 3, 9, 7, 4, + 8, 9, 4, 0, 9, 0, 7, 1, 8, 6, 4, 9, 4, 2, 3, 1, 9, 6, 1, 5, 6, 7, + 9, 4, 5, 2, 0, 8, 0, 9, 5, 1, 4, 6, 5, 5, 0, 2, 2, 5, 2, 3, 1, 6, + 0, 3, 8, 8, 1, 9, 3, 0, 1, 4, 2, 0, 9, 3, 7, 6, 2, 1, 3, 7, 8, 5, + 5, 9, 5, 6, 6, 3, 8, 9, 3, 7, 7, 8, 7, 0, 8, 3, 0, 3, 9, 0, 6, 9, + 7, 9, 2, 0, 7, 7, 3, 4, 6, 7, 2, 2, 1, 8, 2, 5, 6, 2, 5, 9, 9, 6, + 6, 1, 5, 0, 1, 4, 2, 1, 5, 0, 3, 0, 6, 8, 0, 3, 8, 4, 4, 7, 7, 3, + 4, 5, 4, 9, 2, 0, 2, 6, 0, 5, 4, 1, 4, 6, 6, 5, 9, 2, 5, 2, 0, 1, + 4, 9, 7, 4, 4, 2, 8, 5, 0, 7, 3, 2, 5, 1, 8, 6, 6, 6, 0, 0, 2, 1, + 3, 2, 4, 3, 4, 0, 8, 8, 1, 9, 0, 7, 1, 0, 4, 8, 6, 3, 3, 1, 7, 3, + 4, 6, 4, 9, 6, 5, 1, 4, 5, 3, 9, 0, 5, 7, 9, 6, 2, 6, 8, 5, 6, 1, + 0, 0, 5, 5, 0, 8, 1, 0, 6, 6, 5, 8, 7, 9, 6, 9, 9, 8, 1, 6, 3, 5, + 7, 4, 7, 3, 6, 3, 8, 4, 0, 5, 2, 5, 7, 1, 4, 5, 9, 1, 0, 2, 8, 9, + 7, 0, 6, 4, 1, 4, 0, 1, 1, 0, 9, 7, 1, 2, 0, 6, 2, 8, 0, 4, 3, 9, + 0, 3, 9, 7, 5, 9, 5, 1, 5, 6, 7, 7, 1, 5, 7, 7, 0, 0, 4, 2, 0, 3, + 3, 7, 8, 6, 9, 9, 3, 6, 0, 0, 7, 2, 3, 0, 5, 5, 8, 7, 6, 3, 1, 7, + 6, 3, 5, 9, 4, 2, 1, 8, 7, 3, 1, 2, 5, 1, 4, 7, 1, 2, 0, 5, 3, 2, + 9, 2, 8, 1, 9, 1, 8, 2, 6, 1, 8, 6, 1, 2, 5, 8, 6, 7, 3, 2, 1, 5, + 7, 9, 1, 9, 8, 4, 1, 4, 8, 4, 8, 8, 2, 9, 1, 6, 4, 4, 7, 0, 6, 0, + 9, 5, 7, 5, 2, 7, 0, 6, 9, 5, 7, 2, 2, 0, 9, 1, 7, 5, 6, 7, 1, 1, + 6, 7, 2, 2, 9, 1, 0, 9, 8, 1, 6, 9, 0, 9, 1, 5, 2, 8, 0, 1, 7, 3, + 5, 0, 6, 7, 1, 2, 7, 4, 8, 5, 8, 3, 2, 2, 2, 8, 7, 1, 8, 3, 5, 2, + 0, 9, 3, 5, 3, 9, 6, 5, 7, 2, 5, 1, 2, 1, 0, 8, 3, 5, 7, 9, 1, 5, + 1, 3, 6, 9, 8, 8, 2, 0, 9, 1, 4, 4, 4, 2, 1, 0, 0, 6, 7, 5, 1, 0, + 3, 3, 4, 6, 7, 1, 1, 0, 3, 1, 4, 1, 2, 6, 7, 1, 1, 1, 3, 6, 9, 9, + 0, 8, 6, 5, 8, 5, 1, 6, 3, 9, 8, 3, 1, 5, 0, 1, 9, 7, 0, 1, 6, 5, + 1, 5, 1, 1, 6, 8, 5, 1, 7, 1, 4, 3, 7, 6, 5, 7, 6, 1, 8, 3, 5, 1, + 5, 5, 6, 5, 0, 8, 8, 4, 9, 0, 9, 9, 8, 9, 8, 5, 9, 9, 8, 2, 3, 8, + 7, 3, 4, 5, 5, 2, 8, 3, 3, 1, 6, 3, 5, 5, 0, 7, 6, 4, 7, 9, 1, 8, + 5, 3, 5, 8, 9, 3, 2, 2, 6, 1, 8, 5, 4, 8, 9, 6, 3, 2, 1, 3, 2, 9, + 3, 3, 0, 8, 9, 8, 5, 7, 0, 6, 4, 2, 0, 4, 6, 7, 5, 2, 5, 9, 0, 7, + 0, 9, 1, 5, 4, 8, 1, 4, 1, 6, 5, 4, 9, 8, 5, 9, 4, 6, 1, 6, 3, 7, + 1, 8, 0, 2, 7, 0, 9, 8, 1, 9, 9, 4, 3, 0, 9, 9, 2, 4, 4, 8, 8, 9, + 5, 7, 5, 7, 1, 2, 8, 2, 8, 9, 0, 5, 9, 2, 3, 2, 3, 3, 2, 6, 0, 9, + 7, 2, 9, 9, 7, 1, 2, 0, 8, 4, 4, 3, 3, 5, 7, 3, 2, 6, 5, 4, 8, 9, + 3, 8, 2, 3, 9, 1, 1, 9, 3, 2, 5, 9, 7, 4, 6, 3, 6, 6, 7, 3, 0, 5, + 8, 3, 6, 0, 4, 1, 4, 2, 8, 1, 3, 8, 8, 3, 0, 3, 2, 0, 3, 8, 2, 4, + 9, 0, 3, 7, 5, 8, 9, 8, 5, 2, 4, 3, 7, 4, 4, 1, 7, 0, 2, 9, 1, 3, + 2, 7, 6, 5, 6, 1, 8, 0, 9, 3, 7, 7, 3, 4, 4, 4, 0, 3, 0, 7, 0, 7, + 4, 6, 9, 2, 1, 1, 2, 0, 1, 9, 1, 3, 0, 2, 0, 3, 3, 0, 3, 8, 0, 1, + 9, 7, 6, 2, 1, 1, 0, 1, 1, 0, 0, 4, 4, 9, 2, 9, 3, 2, 1, 5, 1, 6, + 0, 8, 4, 2, 4, 4, 4, 8, 5, 9, 6, 3, 7, 6, 6, 9, 8, 3, 8, 9, 5, 2, + 2, 8, 6, 8, 4, 7, 8, 3, 1, 2, 3, 5, 5, 2, 6, 5, 8, 2, 1, 3, 1, 4, + 4, 9, 5, 7, 6, 8, 5, 7, 2, 6, 2, 4, 3, 3, 4, 4, 1, 8, 9, 3, 0, 3, + 9, 6, 8, 6, 4, 2, 6, 2, 4, 3, 4, 1, 0, 7, 7, 3, 2, 2, 6, 9, 7, 8, + 0, 2, 8, 0, 7, 3, 1, 8, 9, 1, 5, 4, 4, 1, 1, 0, 1, 0, 4, 4, 6, 8, + 2, 3, 2, 5, 2, 7, 1, 6, 2, 0, 1, 0, 5, 2, 6, 5, 2, 2, 7, 2, 1, 1, + 1, 6, 6, 0, 3, 9, 6, 6, 6, 5, 5, 7, 3, 0, 9, 2, 5, 4, 7, 1, 1, 0, + 5, 5, 7, 8, 5, 3, 7, 6, 3, 4, 6, 6, 8, 2, 0, 6, 5, 3, 1, 0, 9, 8, + 9, 6, 5, 2, 6, 9, 1, 8, 6, 2, 0, 5, 6, 4, 7, 6, 9, 3, 1, 2, 5, 7, + 0, 5, 8, 6, 3, 5, 6, 6, 2, 0, 1, 8, 5, 5, 8, 1, 0, 0, 7, 2, 9, 3, + 6, 0, 6, 5, 9, 8, 7, 6, 4, 8, 6, 1, 1, 7, 9, 1, 0, 4, 5, 3, 3, 4, + 8, 8, 5, 0, 3, 4, 6, 1, 1, 3, 6, 5, 7, 6, 8, 6, 7, 5, 3, 2, 4, 9, + 4, 4, 1, 6, 6, 8, 0, 3, 9, 6, 2, 6, 5, 7, 9, 7, 8, 7, 7, 1, 8, 5, + 5, 6, 0, 8, 4, 5, 5, 2, 9, 6, 5, 4, 1, 2, 6, 6, 5, 4, 0, 8, 5, 3, + 0, 6, 1, 4, 3, 4, 4, 4, 3, 1, 8, 5, 8, 6, 7, 6, 9, 7, 5, 1, 4, 5, + 6, 6, 1, 4, 0, 6, 8, 0, 0, 7, 0, 0, 2, 3, 7, 8, 7, 7, 6, 5, 9, 1, + 3, 4, 4, 0, 1, 7, 1, 2, 7, 4, 9, 4, 7, 0, 4, 2, 0, 5, 6, 2, 2, 3, + 0, 5, 3, 8, 9, 9, 4, 5, 6, 1, 3, 1, 4, 0, 7, 1, 1, 2, 7, 0, 0, 0, + 4, 0, 7, 8, 5, 4, 7, 3, 3, 2, 6, 9, 9, 3, 9, 0, 8, 1, 4, 5, 4, 6, + 6, 4, 6, 4, 5, 8, 8, 0, 7, 9, 7, 2, 7, 0, 8, 2, 6, 6, 8, 3, 0, 6, + 3, 4, 3, 2, 8, 5, 8, 7, 8, 5, 6, 9, 8, 3, 0, 5, 2, 3, 5, 8, 0, 8, + 9, 3, 3, 0, 6, 5, 7, 5, 7, 4, 0, 6, 7, 9, 5, 4, 5, 7, 1, 6, 3, 7, + 7, 5, 2, 5, 4, 2, 0, 2, 1, 1, 4, 9, 5, 5, 7, 6, 1, 5, 8, 1, 4, 0, + 0, 2, 5, 0, 1, 2, 6, 2, 2, 8, 5, 9, 4, 1, 3, 0, 2, 1, 6, 4, 7, 1, + 5, 5, 0, 9, 7, 9, 2, 5, 9, 2, 3, 0, 9, 9, 0, 7, 9, 6, 5, 4, 7, 3, + 7, 6, 1, 2, 5, 5, 1, 7, 6, 5, 6, 7, 5, 1, 3, 5, 7, 5, 1, 7, 8, 2, + 9, 6, 6, 6, 4, 5, 4, 7, 7, 9, 1, 7, 4, 5, 0, 1, 1, 2, 9, 9, 6, 1, + 4, 8, 9, 0, 3, 0, 4, 6, 3, 9, 9, 4, 7, 1, 3, 2, 9, 6, 2, 1, 0, 7, + 3, 4, 0, 4, 3, 7, 5, 1, 8, 9, 5, 7, 3, 5, 9, 6, 1, 4, 5, 8, 9, 0, + 1, 9, 3, 8, 9, 7, 1, 3, 1, 1, 1, 7, 9, 0, 4, 2, 9, 7, 8, 2, 8, 5, + 6, 4, 7, 5, 0, 3, 2, 0, 3, 1, 9, 8, 6, 9, 1, 5, 1, 4, 0, 2, 8, 7, + 0, 8, 0, 8, 5, 9, 9, 0, 4, 8, 0, 1, 0, 9, 4, 1, 2, 1, 4, 7, 2, 2, + 1, 3, 1, 7, 9, 4, 7, 6, 4, 7, 7, 7, 2, 6, 2, 2, 4, 1, 4, 2, 5, 4, + 8, 5, 4, 5, 4, 0, 3, 3, 2, 1, 5, 7, 1, 8, 5, 3, 0, 6, 1, 4, 2, 2, + 8, 8, 1, 3, 7, 5, 8, 5, 0, 4, 3, 0, 6, 3, 3, 2, 1, 7, 5, 1, 8, 2, + 9, 7, 9, 8, 6, 6, 2, 2, 3, 7, 1, 7, 2, 1, 5, 9, 1, 6, 0, 7, 7, 1, + 6, 6, 9, 2, 5, 4, 7, 4, 8, 7, 3, 8, 9, 8, 6, 6, 5, 4, 9, 4, 9, 4, + 5, 0, 1, 1, 4, 6, 5, 4, 0, 6, 2, 8, 4, 3, 3, 6, 6, 3, 9, 3, 7, 9, + 0, 0, 3, 9, 7, 6, 9, 2, 6, 5, 6, 7, 2, 1, 4, 6, 3, 8, 5, 3, 0, 6, + 7, 3, 6, 0, 9, 6, 5, 7, 1, 2, 0, 9, 1, 8, 0, 7, 6, 3, 8, 3, 2, 7, + 1, 6, 6, 4, 1, 6, 2, 7, 4, 8, 8, 8, 8, 0, 0, 7, 8, 6, 9, 2, 5, 6, + 0, 2, 9, 0, 2, 2, 8, 4, 7, 2, 1, 0, 4, 0, 3, 1, 7, 2, 1, 1, 8, 6, + 0, 8, 2, 0, 4, 1, 9, 0, 0, 0, 4, 2, 2, 9, 6, 6, 1, 7, 1, 1, 9, 6, + 3, 7, 7, 9, 2, 1, 3, 3, 7, 5, 7, 5, 1, 1, 4, 9, 5, 9, 5, 0, 1, 5, + 6, 6, 0, 4, 9, 6, 3, 1, 8, 6, 2, 9, 4, 7, 2, 6, 5, 4, 7, 3, 6, 4, + 2, 5, 2, 3, 0, 8, 1, 7, 7, 0, 3, 6, 7, 5, 1, 5, 9, 0, 6, 7, 3, 5, + 0, 2, 3, 5, 0, 7, 2, 8, 3, 5, 4, 0, 5, 6, 7, 0, 4, 0, 3, 8, 6, 7, + 4, 3, 5, 1, 3, 6, 2, 2, 2, 2, 4, 7, 7, 1, 5, 8, 9, 1, 5, 0, 4, 9, + 5, 3, 0, 9, 8, 4, 4, 4, 8, 9, 3, 3, 3, 0, 9, 6, 3, 4, 0, 8, 7, 8, + 0, 7, 6, 9, 3, 2, 5, 9, 9, 3, 9, 7, 8, 0, 5, 4, 1, 9, 3, 4, 1, 4, + 4, 7, 3, 7, 7, 4, 4, 1, 8, 4, 2, 6, 3, 1, 2, 9, 8, 6, 0, 8, 0, 9, + 9, 8, 8, 8, 6, 8, 7, 4, 1, 3, 2, 6, 0, 4, 7, 2} + numacc1 = stats.Float64Data{10000001, 10000003, 10000002} + numacc2 = make(stats.Float64Data, 1001) + numacc3 = make(stats.Float64Data, 1001) + numacc4 = make(stats.Float64Data, 1001) +) + +func init() { + numacc2[0] = 1.2 + numacc3[0] = 1000000.2 + numacc4[0] = 10000000.2 + for i := 1; i < 1000; i += 2 { + numacc2[i] = 1.1 + numacc2[i+1] = 1.3 + numacc3[i] = 1000000.1 + numacc3[i+1] = 1000000.3 + numacc4[i] = 10000000.1 + numacc4[i+1] = 10000000.3 + } +} + +func TestLewData(t *testing.T) { + r, e := stats.Mean(lew) + test("Lew Mean", r, -177.435000000000, 1e-15, e, t) + + r, e = stats.StandardDeviationSample(lew) + test("Lew Standard Deviation", r, 277.332168044316, 1e-15, e, t) + + r, e = stats.AutoCorrelation(lew, 1) + test("Lew AutoCorrelate1", r, -0.307304800605679, 1e-14, e, t) +} + +func TestLotteryData(t *testing.T) { + r, e := stats.Mean(lottery) + test("Lottery Mean", r, 518.958715596330, 1e-15, e, t) + + r, e = stats.StandardDeviationSample(lottery) + test("Lottery Standard Deviation", r, 291.699727470969, 1e-15, e, t) + + r, e = stats.AutoCorrelation(lottery, 1) + test("Lottery AutoCorrelate1", r, -0.120948622967393, 1e-14, e, t) +} + +func TestMavroData(t *testing.T) { + r, e := stats.Mean(mavro) + test("Mavro Mean", r, 2.00185600000000, 1e-15, e, t) + + r, e = stats.StandardDeviationSample(mavro) + test("Mavro Standard Deviation", r, 0.000429123454003053, 1e-13, e, t) + + r, e = stats.AutoCorrelation(mavro, 1) + test("Mavro AutoCorrelate1", r, 0.937989183438248, 1e-13, e, t) +} + +func TestMichelsonData(t *testing.T) { + r, e := stats.Mean(michelson) + test("Michelson Mean", r, 299.852400000000, 1e-15, e, t) + + r, e = stats.StandardDeviationSample(michelson) + test("Michelson Standard Deviation", r, 0.0790105478190518, 1e-13, e, t) + + r, e = stats.AutoCorrelation(michelson, 1) + test("Michelson AutoCorrelate1", r, 0.535199668621283, 1e-13, e, t) +} + +func TestPidigitsData(t *testing.T) { + r, e := stats.Mean(pidigits) + test("Pidigits Mean", r, 4.53480000000000, 1e-14, e, t) + + r, e = stats.StandardDeviationSample(pidigits) + test("Pidigits Standard Deviation", r, 2.86733906028871, 1e-14, e, t) + + r, e = stats.AutoCorrelation(pidigits, 1) + test("Pidigits AutoCorrelate1", r, -0.00355099287237972, 1e-13, e, t) +} + +func TestNumacc1Data(t *testing.T) { + r, e := stats.Mean(numacc1) + test("numacc1 Mean", r, 10000002.0, 1e-14, e, t) + + r, e = stats.StandardDeviationSample(numacc1) + test("numacc1 Standard Deviation", r, 1.0, 1e-13, e, t) + + r, e = stats.AutoCorrelation(numacc1, 1) + test("Lew AutoCorrelateNumacc1", r, -0.5, 1e-15, e, t) + +} + +func TestNumacc2Data(t *testing.T) { + r, e := stats.Mean(numacc2) + test("numacc2 Mean", r, 1.2, 1e-10, e, t) + + r, e = stats.StandardDeviationSample(numacc2) + test("numacc2 Standard Deviation", r, 0.1, 1e-10, e, t) + + r, e = stats.AutoCorrelation(numacc2, 1) + test("Lew AutoCorrelateNumacc2", r, -0.999, 1e-10, e, t) +} + +func TestNumacc3Data(t *testing.T) { + r, e := stats.Mean(numacc3) + test("numacc3 Mean", r, 1000000.2, 1e-15, e, t) + + r, e = stats.StandardDeviationSample(numacc3) + test("numacc3 Standard Deviation", r, 0.1, 1e-9, e, t) + + r, e = stats.AutoCorrelation(numacc3, 1) + test("Lew AutoCorrelateNumacc3", r, -0.999, 1e-10, e, t) +} + +func TestNumacc4Data(t *testing.T) { + r, e := stats.Mean(numacc4) + test("numacc4 Mean", r, 10000000.2, 1e-10, e, t) + + r, e = stats.StandardDeviationSample(numacc4) + test("numacc4 Standard Deviation", r, 0.1, 1e-7, e, t) + + r, e = stats.AutoCorrelation(numacc4, 1) + test("Lew AutoCorrelateNumacc4", r, -0.999, 1e-7, e, t) +} + +func bench(d stats.Float64Data) { + _, _ = stats.Mean(d) + _, _ = stats.StdDevS(d) + _, _ = stats.AutoCorrelation(d, 1) +} + +func BenchmarkNistLew(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(lew) + } +} + +func BenchmarkNistLottery(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(lottery) + } +} + +func BenchmarkNistMavro(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(mavro) + } +} + +func BenchmarkNistMichelson(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(michelson) + } +} + +func BenchmarkNistPidigits(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(pidigits) + } +} + +func BenchmarkNistNumacc1(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(numacc1) + } +} + +func BenchmarkNistNumacc2(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(numacc2) + } +} + +func BenchmarkNistNumacc3(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(numacc3) + } +} + +func BenchmarkNistNumacc4(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(numacc4) + } +} + +func BenchmarkNistAll(b *testing.B) { + for i := 0; i < b.N; i++ { + bench(lew) + bench(lottery) + bench(mavro) + bench(michelson) + bench(pidigits) + bench(numacc1) + bench(numacc2) + bench(numacc3) + bench(numacc4) + } +} + +func test(d string, r, a, v float64, e error, t *testing.T) { + if e != nil { + t.Error(e) + } + + var failure bool + if math.IsNaN(r) || math.IsNaN(a) { + failure = math.IsNaN(r) != math.IsNaN(a) + } else if math.IsInf(r, 0) || math.IsInf(a, 0) { + failure = math.IsInf(r, 0) != math.IsInf(a, 0) + } else if a != 0 { + failure = math.Abs(r-a)/math.Abs(a) > v + } else { + failure = math.Abs(r) > v + } + + if failure { + t.Errorf("%s => %v != %v", d, r, a) + } +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/norm.go golang-github-montanaflynn-stats-0.6.4/norm.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/norm.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/norm.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,254 @@ +package stats + +import ( + "math" + "math/rand" + "strings" + "time" +) + +// NormPpfRvs generates random variates using the Point Percentile Function. +// For more information please visit: https://demonstrations.wolfram.com/TheMethodOfInverseTransforms/ +func NormPpfRvs(loc float64, scale float64, size int) []float64 { + rand.Seed(time.Now().UnixNano()) + var toReturn []float64 + for i := 0; i < size; i++ { + toReturn = append(toReturn, NormPpf(rand.Float64(), loc, scale)) + } + return toReturn +} + +// NormBoxMullerRvs generates random variates using the Box–Muller transform. +// For more information please visit: http://mathworld.wolfram.com/Box-MullerTransformation.html +func NormBoxMullerRvs(loc float64, scale float64, size int) []float64 { + rand.Seed(time.Now().UnixNano()) + var toReturn []float64 + for i := 0; i < int(float64(size/2)+float64(size%2)); i++ { + // u1 and u2 are uniformly distributed random numbers between 0 and 1. + u1 := rand.Float64() + u2 := rand.Float64() + // x1 and x2 are normally distributed random numbers. + x1 := loc + (scale * (math.Sqrt(-2*math.Log(u1)) * math.Cos(2*math.Pi*u2))) + toReturn = append(toReturn, x1) + if (i+1)*2 <= size { + x2 := loc + (scale * (math.Sqrt(-2*math.Log(u1)) * math.Sin(2*math.Pi*u2))) + toReturn = append(toReturn, x2) + } + } + return toReturn +} + +// NormPdf is the probability density function. +func NormPdf(x float64, loc float64, scale float64) float64 { + return (math.Pow(math.E, -(math.Pow(x-loc, 2))/(2*math.Pow(scale, 2)))) / (scale * math.Sqrt(2*math.Pi)) +} + +// NormLogPdf is the log of the probability density function. +func NormLogPdf(x float64, loc float64, scale float64) float64 { + return math.Log((math.Pow(math.E, -(math.Pow(x-loc, 2))/(2*math.Pow(scale, 2)))) / (scale * math.Sqrt(2*math.Pi))) +} + +// NormCdf is the cumulative distribution function. +func NormCdf(x float64, loc float64, scale float64) float64 { + return 0.5 * (1 + math.Erf((x-loc)/(scale*math.Sqrt(2)))) +} + +// NormLogCdf is the log of the cumulative distribution function. +func NormLogCdf(x float64, loc float64, scale float64) float64 { + return math.Log(0.5 * (1 + math.Erf((x-loc)/(scale*math.Sqrt(2))))) +} + +// NormSf is the survival function (also defined as 1 - cdf, but sf is sometimes more accurate). +func NormSf(x float64, loc float64, scale float64) float64 { + return 1 - 0.5*(1+math.Erf((x-loc)/(scale*math.Sqrt(2)))) +} + +// NormLogSf is the log of the survival function. +func NormLogSf(x float64, loc float64, scale float64) float64 { + return math.Log(1 - 0.5*(1+math.Erf((x-loc)/(scale*math.Sqrt(2))))) +} + +// NormPpf is the point percentile function. +// This is based on Peter John Acklam's inverse normal CDF. +// algorithm: http://home.online.no/~pjacklam/notes/invnorm/ (no longer visible). +// For more information please visit: https://stackedboxes.org/2017/05/01/acklams-normal-quantile-function/ +func NormPpf(p float64, loc float64, scale float64) (x float64) { + const ( + a1 = -3.969683028665376e+01 + a2 = 2.209460984245205e+02 + a3 = -2.759285104469687e+02 + a4 = 1.383577518672690e+02 + a5 = -3.066479806614716e+01 + a6 = 2.506628277459239e+00 + + b1 = -5.447609879822406e+01 + b2 = 1.615858368580409e+02 + b3 = -1.556989798598866e+02 + b4 = 6.680131188771972e+01 + b5 = -1.328068155288572e+01 + + c1 = -7.784894002430293e-03 + c2 = -3.223964580411365e-01 + c3 = -2.400758277161838e+00 + c4 = -2.549732539343734e+00 + c5 = 4.374664141464968e+00 + c6 = 2.938163982698783e+00 + + d1 = 7.784695709041462e-03 + d2 = 3.224671290700398e-01 + d3 = 2.445134137142996e+00 + d4 = 3.754408661907416e+00 + + plow = 0.02425 + phigh = 1 - plow + ) + + if p < 0 || p > 1 { + return math.NaN() + } else if p == 0 { + return -math.Inf(0) + } else if p == 1 { + return math.Inf(0) + } + + if p < plow { + q := math.Sqrt(-2 * math.Log(p)) + x = (((((c1*q+c2)*q+c3)*q+c4)*q+c5)*q + c6) / + ((((d1*q+d2)*q+d3)*q+d4)*q + 1) + } else if phigh < p { + q := math.Sqrt(-2 * math.Log(1-p)) + x = -(((((c1*q+c2)*q+c3)*q+c4)*q+c5)*q + c6) / + ((((d1*q+d2)*q+d3)*q+d4)*q + 1) + } else { + q := p - 0.5 + r := q * q + x = (((((a1*r+a2)*r+a3)*r+a4)*r+a5)*r + a6) * q / + (((((b1*r+b2)*r+b3)*r+b4)*r+b5)*r + 1) + } + + e := 0.5*math.Erfc(-x/math.Sqrt2) - p + u := e * math.Sqrt(2*math.Pi) * math.Exp(x*x/2) + x = x - u/(1+x*u/2) + + return x*scale + loc +} + +// NormIsf is the inverse survival function (inverse of sf). +func NormIsf(p float64, loc float64, scale float64) (x float64) { + if -NormPpf(p, loc, scale) == 0 { + return 0 + } + return -NormPpf(p, loc, scale) +} + +// NormMoment approximates the non-central (raw) moment of order n. +// For more information please visit: https://math.stackexchange.com/questions/1945448/methods-for-finding-raw-moments-of-the-normal-distribution +func NormMoment(n int, loc float64, scale float64) float64 { + toReturn := 0.0 + for i := 0; i < n+1; i++ { + if (n-i)%2 == 0 { + toReturn += float64(Ncr(n, i)) * (math.Pow(loc, float64(i))) * (math.Pow(scale, float64(n-i))) * + (float64(factorial(n-i)) / ((math.Pow(2.0, float64((n-i)/2))) * + float64(factorial((n-i)/2)))) + } + } + return toReturn +} + +// NormStats returns the mean, variance, skew, and/or kurtosis. +// Mean(‘m’), variance(‘v’), skew(‘s’), and/or kurtosis(‘k’). +// Takes string containing any of 'mvsk'. +// Returns array of m v s k in that order. +func NormStats(loc float64, scale float64, moments string) []float64 { + var toReturn []float64 + if strings.ContainsAny(moments, "m") { + toReturn = append(toReturn, loc) + } + if strings.ContainsAny(moments, "v") { + toReturn = append(toReturn, math.Pow(scale, 2)) + } + if strings.ContainsAny(moments, "s") { + toReturn = append(toReturn, 0.0) + } + if strings.ContainsAny(moments, "k") { + toReturn = append(toReturn, 0.0) + } + return toReturn +} + +// NormEntropy is the differential entropy of the RV. +func NormEntropy(loc float64, scale float64) float64 { + return math.Log(scale * math.Sqrt(2*math.Pi*math.E)) +} + +// NormFit returns the maximum likelihood estimators for the Normal Distribution. +// Takes array of float64 values. +// Returns array of Mean followed by Standard Deviation. +func NormFit(data []float64) [2]float64 { + sum := 0.00 + for i := 0; i < len(data); i++ { + sum += data[i] + } + mean := sum / float64(len(data)) + stdNumerator := 0.00 + for i := 0; i < len(data); i++ { + stdNumerator += math.Pow(data[i]-mean, 2) + } + return [2]float64{mean, math.Sqrt((stdNumerator) / (float64(len(data))))} +} + +// NormMedian is the median of the distribution. +func NormMedian(loc float64, scale float64) float64 { + return loc +} + +// NormMean is the mean/expected value of the distribution. +func NormMean(loc float64, scale float64) float64 { + return loc +} + +// NormVar is the variance of the distribution. +func NormVar(loc float64, scale float64) float64 { + return math.Pow(scale, 2) +} + +// NormStd is the standard deviation of the distribution. +func NormStd(loc float64, scale float64) float64 { + return scale +} + +// NormInterval finds endpoints of the range that contains alpha percent of the distribution. +func NormInterval(alpha float64, loc float64, scale float64) [2]float64 { + q1 := (1.0 - alpha) / 2 + q2 := (1.0 + alpha) / 2 + a := NormPpf(q1, loc, scale) + b := NormPpf(q2, loc, scale) + return [2]float64{a, b} +} + +// factorial is the naive factorial algorithm. +func factorial(x int) int { + if x == 0 { + return 1 + } + return x * factorial(x-1) +} + +// Ncr is an N choose R algorithm. +// Aaron Cannon's algorithm. +func Ncr(n, r int) int { + if n <= 1 || r == 0 || n == r { + return 1 + } + if newR := n - r; newR < r { + r = newR + } + if r == 1 { + return n + } + ret := int(n - r + 1) + for i, j := ret+1, int(2); j <= r; i, j = i+1, j+1 { + ret = ret * i / j + } + return ret +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/norm_test.go golang-github-montanaflynn-stats-0.6.4/norm_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/norm_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/norm_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,187 @@ +package stats_test + +import ( + "math" + "reflect" + "testing" + + "github.com/montanaflynn/stats" +) + +func TestNormPpf(t *testing.T) { + if stats.NormPpf(0.5, 0, 1) != 0 { + t.Error("Input 0.5, Expected 0") + } + if !veryclose(stats.NormPpf(0.1, 0, 1), -1.2815515655446004) { + t.Error("Input 0.1, Expected -1.2815515655446004") + } + if stats.NormPpf(0.002423, 0, 1) != -2.817096255323953 { + t.Error("Input 0.002423, Expected -2.817096255323953") + } + if !close(stats.NormPpf(1-0.002423, 0, 1), 2.817096255323956) { + t.Error("Input 1 - 0.002423, Expected 2.817096255323956") + } + + if !math.IsNaN(stats.NormPpf(1.1, 0, 1)) { + t.Error("Input 1.1, Expected NaN") + } + if !math.IsNaN(stats.NormPpf(-1.1, 0, 1)) { + t.Error("Input -0.1, Expected Nan") + } + if stats.NormPpf(0, 0, 1) != -math.Inf(1) { + t.Error("Input 0, Expected -Inf") + } + if stats.NormPpf(1, 0, 1) != math.Inf(1) { + t.Error("Input 1, Expected Inf") + } +} + +func TestNormCdf(t *testing.T) { + if stats.NormCdf(0, 0, 1) != 0.5 { + t.Error("Input 0, Expected 0.5") + } + if stats.NormCdf(0.5, 0, 1) != 0.6914624612740131 { + t.Error("Input 0.5, Expected 0.6914624612740131") + } + if stats.NormCdf(-0.5, 0, 1) != 0.3085375387259869 { + t.Error("Input -0.5, Expected 0.3085375387259869") + } +} + +func TestNormPdf(t *testing.T) { + if stats.NormPdf(0.5, 0, 1) != 0.35206532676429947 { + t.Error("Input 0.5, Expected 0.35206532676429947") + } + if stats.NormPdf(0, 0, 1) != 0.3989422804014327 { + t.Error("Input 0, Expected 0.3989422804014327") + } + if stats.NormPdf(-0.5, 0, 1) != 0.35206532676429947 { + t.Error("Input -0.5, Expected 0.35206532676429947") + } +} + +func TestNormLogPdf(t *testing.T) { + if stats.NormLogPdf(0, 0, 1) != -0.9189385332046727 { + t.Error("Input 0, Expected -0.9189385332046727") + } + if stats.NormPdf(0, 0, 1) != 0.3989422804014327 { + t.Error("Input 0, Expected 0.3989422804014327") + } + if stats.NormPdf(-0.5, 0, 1) != 0.35206532676429947 { + t.Error("Input -0.5, Expected 0.35206532676429947") + } +} + +func TestNormLogCdf(t *testing.T) { + if stats.NormLogCdf(0.5, 0, 1) != -0.36894641528865635 { + t.Error("Input 0.5, Expected -0.36894641528865635") + } +} + +func TestNormIsf(t *testing.T) { + if stats.NormIsf(0.5, 0, 1) != 0 { + t.Error("Input 0.5, Expected 0") + } + if !veryclose(stats.NormIsf(0.1, 0, 1), 1.2815515655446004) { + t.Error("Input 0.1, Expected 1.2815515655446004") + } +} + +func TestNormSf(t *testing.T) { + if stats.NormSf(0.5, 0, 1) != 0.3085375387259869 { + t.Error("Input 0.5, Expected 0.3085375387259869") + } +} + +func TestNormLogSf(t *testing.T) { + if stats.NormLogSf(0.5, 0, 1) != -1.1759117615936185 { + t.Error("Input 0.5, Expected -1.1759117615936185") + } +} + +func TestNormMoment(t *testing.T) { + if stats.NormMoment(4, 0, 1) != 3 { + t.Error("Input 3, Expected 3") + } + if stats.NormMoment(4, 0, 1) != 3 { + t.Error("Input 3, Expected 3") + } +} + +func TestNormStats(t *testing.T) { + if !reflect.DeepEqual(stats.NormStats(0, 1, "m"), []float64{0}) { + t.Error("Input 'm' , Expected 0") + } + if !reflect.DeepEqual(stats.NormStats(0, 1, "v"), []float64{1}) { + t.Error("Input 'v' , Expected 1") + } + if !reflect.DeepEqual(stats.NormStats(0, 1, "s"), []float64{0}) { + t.Error("Input 's' , Expected 0") + } + if !reflect.DeepEqual(stats.NormStats(0, 1, "k"), []float64{0}) { + t.Error("Input 'k' , Expected 0") + } +} + +func TestNormEntropy(t *testing.T) { + if stats.NormEntropy(0, 1) != 1.4189385332046727 { + t.Error("Input ( 0 , 1 ), Expected 1.4189385332046727") + } +} + +func TestNormFit(t *testing.T) { + if !reflect.DeepEqual(stats.NormFit([]float64{0, 2, 3, 4}), [2]float64{2.25, 1.479019945774904}) { + t.Error("Input (0,2,3,4), Expected {2.25, 1.479019945774904}") + } +} + +func TestNormInterval(t *testing.T) { + if !reflect.DeepEqual(stats.NormInterval(0.5, 0, 1), [2]float64{-0.6744897501960818, 0.674489750196082}) { + t.Error("Input (50 % ), Expected {-0.6744897501960818, 0.674489750196082}") + } +} + +func TestNormMean(t *testing.T) { + if stats.NormMean(0, 1) != 0 { + t.Error("Input (0, 1), Expected 0") + } +} + +func TestNormMedian(t *testing.T) { + if stats.NormMedian(0, 1) != 0 { + t.Error("Input (0, 1), Expected 0") + } +} + +func TestNormVar(t *testing.T) { + if stats.NormVar(0, 1) != 1 { + t.Error("Input (0, 1), Expected 1") + } +} + +func TestNormStd(t *testing.T) { + if stats.NormStd(0, 1) != 1 { + t.Error("Input (0, 1), Expected 1") + } +} + +func TestNormPpfRvs(t *testing.T) { + if len(stats.NormPpfRvs(0, 1, 101)) != 101 { + t.Error("Input size=101, Expected 101") + } +} + +func TestNormBoxMullerRvs(t *testing.T) { + if len(stats.NormBoxMullerRvs(0, 1, 101)) != 101 { + t.Error("Input size=101, Expected 101") + } +} + +func TestNcr(t *testing.T) { + if stats.Ncr(4, 1) != 4 { + t.Error("Input 4 choose 1, Expected 4") + } + if stats.Ncr(4, 3) != 4 { + t.Error("Input 4 choose 3, Expected 4") + } +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/outlier.go golang-github-montanaflynn-stats-0.6.4/outlier.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/outlier.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/outlier.go 2021-01-13 11:52:47.000000000 +0000 @@ -9,7 +9,7 @@ // QuartileOutliers finds the mild and extreme outliers func QuartileOutliers(input Float64Data) (Outliers, error) { if input.Len() == 0 { - return Outliers{}, EmptyInput + return Outliers{}, EmptyInputErr } // Start by sorting a copy of the slice diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/outlier_test.go golang-github-montanaflynn-stats-0.6.4/outlier_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/outlier_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/outlier_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,12 +1,14 @@ -package stats +package stats_test import ( "testing" + + "github.com/montanaflynn/stats" ) func TestQuartileOutliers(t *testing.T) { s1 := []float64{-1000, 1, 3, 4, 4, 6, 6, 6, 6, 7, 8, 15, 18, 100} - o, _ := QuartileOutliers(s1) + o, _ := stats.QuartileOutliers(s1) if o.Mild[0] != 15 { t.Errorf("First Mild Outlier %v != 15", o.Mild[0]) @@ -24,7 +26,7 @@ t.Errorf("Second Extreme Outlier %v != 100", o.Extreme[1]) } - _, err := QuartileOutliers([]float64{}) + _, err := stats.QuartileOutliers([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/percentile.go golang-github-montanaflynn-stats-0.6.4/percentile.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/percentile.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/percentile.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,12 +1,18 @@ package stats -import "math" +import ( + "math" +) // Percentile finds the relative standing in a slice of floats func Percentile(input Float64Data, percent float64) (percentile float64, err error) { + length := input.Len() + if length == 0 { + return math.NaN(), EmptyInputErr + } - if input.Len() == 0 { - return math.NaN(), EmptyInput + if length == 1 { + return input[0], nil } if percent <= 0 || percent > 100 { @@ -52,7 +58,7 @@ // Return an error for empty slices if il == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Return error for less than 0 or greater than 100 percentages diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/percentile_test.go golang-github-montanaflynn-stats-0.6.4/percentile_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/percentile_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/percentile_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,41 +1,47 @@ -package stats +package stats_test import ( "reflect" "testing" + + "github.com/montanaflynn/stats" ) func TestPercentile(t *testing.T) { - m, _ := Percentile([]float64{43, 54, 56, 61, 62, 66}, 90) + m, _ := stats.Percentile([]float64{43, 54, 56, 61, 62, 66}, 90) if m != 64.0 { t.Errorf("%.1f != %.1f", m, 64.0) } - m, _ = Percentile([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 50) + m, _ = stats.Percentile([]float64{43}, 90) + if m != 43.0 { + t.Errorf("%.1f != %.1f", m, 43.0) + } + m, _ = stats.Percentile([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 50) if m != 5.0 { t.Errorf("%.1f != %.1f", m, 5.0) } - m, _ = Percentile([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 99.9) + m, _ = stats.Percentile([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 99.9) if m != 9.5 { t.Errorf("%.1f != %.1f", m, 9.5) } - m, _ = Percentile([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 100) + m, _ = stats.Percentile([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 100) if m != 10.0 { t.Errorf("%.1f != %.1f", m, 10.0) } - _, err := Percentile([]float64{}, 99.9) - if err != EmptyInput { + _, err := stats.Percentile([]float64{}, 99.9) + if err != stats.EmptyInputErr { t.Errorf("Empty slice didn't return expected error; got %v", err) } - _, err = Percentile([]float64{1, 2, 3, 4, 5}, 0) - if err != BoundsErr { + _, err = stats.Percentile([]float64{1, 2, 3, 4, 5}, 0) + if err != stats.BoundsErr { t.Errorf("Zero percent didn't return expected error; got %v", err) } - _, err = Percentile([]float64{1, 2, 3, 4, 5}, 0.13) - if err != BoundsErr { + _, err = stats.Percentile([]float64{1, 2, 3, 4, 5}, 0.13) + if err != stats.BoundsErr { t.Errorf("Too low percent didn't return expected error; got %v", err) } - _, err = Percentile([]float64{1, 2, 3, 4, 5}, 101) - if err != BoundsErr { + _, err = stats.Percentile([]float64{1, 2, 3, 4, 5}, 101) + if err != stats.BoundsErr { t.Errorf("Too high percent didn't return expected error; got %v", err) } } @@ -43,7 +49,7 @@ func TestPercentileSortSideEffects(t *testing.T) { s := []float64{43, 54, 56, 44, 62, 66} a := []float64{43, 54, 56, 44, 62, 66} - Percentile(s, 90) + _, _ = stats.Percentile(s, 90) if !reflect.DeepEqual(s, a) { t.Errorf("%.1f != %.1f", s, a) } @@ -51,7 +57,7 @@ func BenchmarkPercentileSmallFloatSlice(b *testing.B) { for i := 0; i < b.N; i++ { - Percentile(makeFloatSlice(5), 50) + _, _ = stats.Percentile(makeFloatSlice(5), 50) } } @@ -59,7 +65,7 @@ lf := makeFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Percentile(lf, 50) + _, _ = stats.Percentile(lf, 50) } } @@ -88,8 +94,9 @@ {f3, 1, 100}, {f3, 99, 9900}, {f3, 100, 10000}, + {f3, 0, 0}, } { - got, err := PercentileNearestRank(c.sample, c.percent) + got, err := stats.PercentileNearestRank(c.sample, c.percent) if err != nil { t.Errorf("Should not have returned an error") } @@ -98,17 +105,17 @@ } } - _, err := PercentileNearestRank([]float64{}, 50) + _, err := stats.PercentileNearestRank([]float64{}, 50) if err == nil { t.Errorf("Should have returned an empty slice error") } - _, err = PercentileNearestRank([]float64{1, 2, 3, 4, 5}, -0.01) + _, err = stats.PercentileNearestRank([]float64{1, 2, 3, 4, 5}, -0.01) if err == nil { t.Errorf("Should have returned an percentage must be above 0 error") } - _, err = PercentileNearestRank([]float64{1, 2, 3, 4, 5}, 110) + _, err = stats.PercentileNearestRank([]float64{1, 2, 3, 4, 5}, 110) if err == nil { t.Errorf("Should have returned an percentage must not be above 100 error") } @@ -117,7 +124,7 @@ func BenchmarkPercentileNearestRankSmallFloatSlice(b *testing.B) { for i := 0; i < b.N; i++ { - PercentileNearestRank(makeFloatSlice(5), 50) + _, _ = stats.PercentileNearestRank(makeFloatSlice(5), 50) } } @@ -125,6 +132,6 @@ lf := makeFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - PercentileNearestRank(lf, 50) + _, _ = stats.PercentileNearestRank(lf, 50) } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/quartile.go golang-github-montanaflynn-stats-0.6.4/quartile.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/quartile.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/quartile.go 2021-01-13 11:52:47.000000000 +0000 @@ -14,7 +14,7 @@ il := input.Len() if il == 0 { - return Quartiles{}, EmptyInput + return Quartiles{}, EmptyInputErr } // Start by sorting a copy of the slice @@ -44,7 +44,7 @@ // InterQuartileRange finds the range between Q1 and Q3 func InterQuartileRange(input Float64Data) (float64, error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } qs, _ := Quartile(input) iqr := qs.Q3 - qs.Q1 @@ -54,7 +54,7 @@ // Midhinge finds the average of the first and third quartiles func Midhinge(input Float64Data) (float64, error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } qs, _ := Quartile(input) mh := (qs.Q1 + qs.Q3) / 2 @@ -64,7 +64,7 @@ // Trimean finds the average of the median and the midhinge func Trimean(input Float64Data) (float64, error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } c := sortedCopy(input) diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/quartile_test.go golang-github-montanaflynn-stats-0.6.4/quartile_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/quartile_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/quartile_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,7 +1,9 @@ -package stats +package stats_test import ( "testing" + + "github.com/montanaflynn/stats" ) func TestQuartile(t *testing.T) { @@ -17,7 +19,7 @@ {s1, 15, 40, 43}, {s2, 15, 37.5, 40}, } { - quartiles, err := Quartile(c.in) + quartiles, err := stats.Quartile(c.in) if err != nil { t.Errorf("Should not have returned an error") } @@ -33,7 +35,7 @@ } } - _, err := Quartile([]float64{}) + _, err := stats.Quartile([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -41,13 +43,13 @@ func TestInterQuartileRange(t *testing.T) { s1 := []float64{102, 104, 105, 107, 108, 109, 110, 112, 115, 116, 118} - iqr, _ := InterQuartileRange(s1) + iqr, _ := stats.InterQuartileRange(s1) if iqr != 10 { t.Errorf("IQR %v != 10", iqr) } - _, err := InterQuartileRange([]float64{}) + _, err := stats.InterQuartileRange([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -55,13 +57,13 @@ func TestMidhinge(t *testing.T) { s1 := []float64{1, 3, 4, 4, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13} - mh, _ := Midhinge(s1) + mh, _ := stats.Midhinge(s1) if mh != 7.5 { t.Errorf("Midhinge %v != 7.5", mh) } - _, err := Midhinge([]float64{}) + _, err := stats.Midhinge([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -69,13 +71,13 @@ func TestTrimean(t *testing.T) { s1 := []float64{1, 3, 4, 4, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13} - tr, _ := Trimean(s1) + tr, _ := stats.Trimean(s1) if tr != 7.25 { t.Errorf("Trimean %v != 7.25", tr) } - _, err := Trimean([]float64{}) + _, err := stats.Trimean([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/ranksum.go golang-github-montanaflynn-stats-0.6.4/ranksum.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/ranksum.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/ranksum.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,183 @@ +package stats + +// import "math" +// +// // WilcoxonRankSum tests the null hypothesis that two sets +// // of data are drawn from the same distribution. It does +// // not handle ties between measurements in x and y. +// // +// // Parameters: +// // data1 Float64Data: First set of data points. +// // data2 Float64Data: Second set of data points. +// // Length of both data samples must be equal. +// // +// // Return: +// // statistic float64: The test statistic under the +// // large-sample approximation that the +// // rank sum statistic is normally distributed. +// // pvalue float64: The two-sided p-value of the test +// // err error: Any error from the input data parameters +// // +// // https://en.wikipedia.org/wiki/Wilcoxon_rank-sum_test +// func WilcoxonRankSum(data1, data2 Float64Data) (float64, float64, error) { +// +// l1 := data1.Len() +// l2 := data2.Len() +// +// if l1 == 0 || l2 == 0 { +// return math.NaN(), math.NaN(), EmptyInputErr +// } +// +// if l1 != l2 { +// return math.NaN(), math.NaN(), SizeErr +// } +// +// alldata := Float64Data{} +// alldata = append(alldata, data1...) +// alldata = append(alldata, data2...) +// +// // ranked := +// +// return 0.0, 0.0, nil +// } +// +// // x, y = map(np.asarray, (x, y)) +// // n1 = len(x) +// // n2 = len(y) +// // alldata = np.concatenate((x, y)) +// // ranked = rankdata(alldata) +// // x = ranked[:n1] +// // s = np.sum(x, axis=0) +// // expected = n1 * (n1+n2+1) / 2.0 +// // z = (s - expected) / np.sqrt(n1*n2*(n1+n2+1)/12.0) +// // prob = 2 * distributions.norm.sf(abs(z)) +// // +// // return RanksumsResult(z, prob) +// +// // def rankdata(a, method='average'): +// // """ +// // Assign ranks to data, dealing with ties appropriately. +// // Ranks begin at 1. The `method` argument controls how ranks are assigned +// // to equal values. See [1]_ for further discussion of ranking methods. +// // Parameters +// // ---------- +// // a : array_like +// // The array of values to be ranked. The array is first flattened. +// // method : str, optional +// // The method used to assign ranks to tied elements. +// // The options are 'average', 'min', 'max', 'dense' and 'ordinal'. +// // 'average': +// // The average of the ranks that would have been assigned to +// // all the tied values is assigned to each value. +// // 'min': +// // The minimum of the ranks that would have been assigned to all +// // the tied values is assigned to each value. (This is also +// // referred to as "competition" ranking.) +// // 'max': +// // The maximum of the ranks that would have been assigned to all +// // the tied values is assigned to each value. +// // 'dense': +// // Like 'min', but the rank of the next highest element is assigned +// // the rank immediately after those assigned to the tied elements. +// // 'ordinal': +// // All values are given a distinct rank, corresponding to the order +// // that the values occur in `a`. +// // The default is 'average'. +// // Returns +// // ------- +// // ranks : ndarray +// // An array of length equal to the size of `a`, containing rank +// // scores. +// // References +// // ---------- +// // .. [1] "Ranking", https://en.wikipedia.org/wiki/Ranking +// // Examples +// // -------- +// // >>> from scipy.stats import rankdata +// // >>> rankdata([0, 2, 3, 2]) +// // array([ 1. , 2.5, 4. , 2.5]) +// // """ +// // +// // arr = np.ravel(np.asarray(a)) +// // algo = 'quicksort' +// // sorter = np.argsort(arr, kind=algo) +// // +// // inv = np.empty(sorter.size, dtype=np.intp) +// // inv[sorter] = np.arange(sorter.size, dtype=np.intp) +// // +// // +// // arr = arr[sorter] +// // obs = np.r_[True, arr[1:] != arr[:-1]] +// // dense = obs.cumsum()[inv] +// // +// // +// // # cumulative counts of each unique value +// // count = np.r_[np.nonzero(obs)[0], len(obs)] +// // +// // # average method +// // return .5 * (count[dense] + count[dense - 1] + 1) +// +// type rankable interface { +// Len() int +// RankEqual(int, int) bool +// } +// +// func StandardRank(d rankable) []float64 { +// r := make([]float64, d.Len()) +// var k int +// for i := range r { +// if i == 0 || !d.RankEqual(i, i-1) { +// k = i + 1 +// } +// r[i] = float64(k) +// } +// return r +// } +// +// func ModifiedRank(d rankable) []float64 { +// r := make([]float64, d.Len()) +// for i := range r { +// k := i + 1 +// for j := i + 1; j < len(r) && d.RankEqual(i, j); j++ { +// k = j + 1 +// } +// r[i] = float64(k) +// } +// return r +// } +// +// func DenseRank(d rankable) []float64 { +// r := make([]float64, d.Len()) +// var k int +// for i := range r { +// if i == 0 || !d.RankEqual(i, i-1) { +// k++ +// } +// r[i] = float64(k) +// } +// return r +// } +// +// func OrdinalRank(d rankable) []float64 { +// r := make([]float64, d.Len()) +// for i := range r { +// r[i] = float64(i + 1) +// } +// return r +// } +// +// func FractionalRank(d rankable) []float64 { +// r := make([]float64, d.Len()) +// for i := 0; i < len(r); { +// var j int +// f := float64(i + 1) +// for j = i + 1; j < len(r) && d.RankEqual(i, j); j++ { +// f += float64(j + 1) +// } +// f /= float64(j - i) +// for ; i < j; i++ { +// r[i] = f +// } +// } +// return r +// } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/ranksum_test.go golang-github-montanaflynn-stats-0.6.4/ranksum_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/ranksum_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/ranksum_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,39 @@ +package stats_test + +// import ( +// "testing" +// ) +// +// // >>> y1=[125,115,130,140,140,115,140,125,140,135] +// // >>> y2=[110,122,125,120,140,124,123,137,135,145] +// // >>> ss.wilcoxon(y1, y2) +// // (18.0, 0.5936305914425295) +// +// // func ExampleWilcoxonRankSum() { +// // t, p, err := WilcoxonRankSum([]float64{3.0, 1.0, 0.2}, []float64{3.1, 1.2, 1.2}) +// // fmt.Println(t, p, err) +// // // Output: 18.0, 0.5936305914425295, nil +// // +// // } +// +// func TestRanked(t *testing.T) { +// +// var data = []float64{0.1, 3.2, 3.2} +// +// StandardRank(data) +// // show := func(name string, fn func(rankable) []float64) { +// // fmt.Println(name, "Ranking:") +// // r := fn(data) +// // for i, d := range data { +// // fmt.Printf("%4v\n", r[i]) +// // } +// // } +// // +// // sort.Sort(data) +// // show("Standard", StandardRank) +// // show("\nModified", ModifiedRank) +// // show("\nDense", DenseRank) +// // show("\nOrdinal", OrdinalRank) +// // show("\nFractional", FractionalRank) +// +// } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/README.md golang-github-montanaflynn-stats-0.6.4/README.md --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/README.md 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/README.md 2021-01-13 11:52:47.000000000 +0000 @@ -1,8 +1,10 @@ -# Stats [![][travis-svg]][travis-url] [![][coveralls-svg]][coveralls-url] [![][godoc-svg]][godoc-url] [![][license-svg]][license-url] +# Stats - Golang Statistics Package -A statistics package with many functions missing from the Golang standard library. See the [CHANGELOG.md](https://github.com/montanaflynn/stats/blob/master/CHANGELOG.md) for API changes and tagged releases you can vendor into your projects. +[![][travis-svg]][travis-url] [![][coveralls-svg]][coveralls-url] [![][goreport-svg]][goreport-url] [![][godoc-svg]][godoc-url] [![][pkggodev-svg]][pkggodev-url] [![][license-svg]][license-url] -> Statistics are used much like a drunk uses a lamppost: for support, not illumination. **- Vin Scully** +A well tested and comprehensive Golang statistics library / package / module with no dependencies. + +If you have any suggestions, problems or bug reports please [create an issue](https://github.com/montanaflynn/stats/issues) and I'll do my best to accommodate you. In addition simply starring the repo would show your support for the project and be very much appreciated! ## Installation @@ -10,79 +12,199 @@ go get github.com/montanaflynn/stats ``` -**Protip:** `go get -u github.com/montanaflynn/stats` updates stats to the latest version. - -## Usage - -The [entire API documentation](http://godoc.org/github.com/montanaflynn/stats) is available on GoDoc.org - -You can view docs offline with the following commands: - -``` -godoc ./ -godoc ./ Median -godoc ./ Float64Data -``` - -**Protip:** Generate HTML docs with `godoc -http=:4444` +## Example Usage -## Example - -All the functions can be seen in [examples/main.go](https://github.com/montanaflynn/stats/blob/master/examples/main.go) but here's a little taste: +All the functions can be seen in [examples/main.go](examples/main.go) but here's a little taste: ```go -// start with the some source data to use -var data = []float64{1, 2, 3, 4, 4, 5} +// start with some source data to use +data := []float64{1.0, 2.1, 3.2, 4.823, 4.1, 5.8} + +// you could also use different types like this +// data := stats.LoadRawData([]int{1, 2, 3, 4, 5}) +// data := stats.LoadRawData([]interface{}{1.1, "2", 3}) +// etc... median, _ := stats.Median(data) -fmt.Println(median) // 3.5 +fmt.Println(median) // 3.65 roundedMedian, _ := stats.Round(median, 0) fmt.Println(roundedMedian) // 4 ``` -**Protip:** You can [call methods](https://github.com/montanaflynn/stats/blob/master/examples/methods.go) on the data if using the Float64Data type: +## Documentation + +The entire API documentation is available on [GoDoc.org](http://godoc.org/github.com/montanaflynn/stats) or [pkg.go.dev](https://pkg.go.dev/github.com/montanaflynn/stats). + +You can also view docs offline with the following commands: ``` -var d stats.Float64Data = data +# Command line +godoc . # show all exported apis +godoc . Median # show a single function +godoc -ex . Round # show function with example +godoc . Float64Data # show the type and methods -max, _ := d.Max() -fmt.Println(max) // 5 +# Local website +godoc -http=:4444 # start the godoc server on port 4444 +open http://localhost:4444/pkg/github.com/montanaflynn/stats/ ``` -## Contributing +The exported API is as follows: -If you have any suggestions, criticism or bug reports please [create an issue](https://github.com/montanaflynn/stats/issues) and I'll do my best to accommodate you. In addition simply starring the repo would show your support for the project and be very much appreciated! +```go +var ( + ErrEmptyInput = statsError{"Input must not be empty."} + ErrNaN = statsError{"Not a number."} + ErrNegative = statsError{"Must not contain negative values."} + ErrZero = statsError{"Must not contain zero values."} + ErrBounds = statsError{"Input is outside of range."} + ErrSize = statsError{"Must be the same length."} + ErrInfValue = statsError{"Value is infinite."} + ErrYCoord = statsError{"Y Value must be greater than zero."} +) + +func Round(input float64, places int) (rounded float64, err error) {} + +type Float64Data []float64 + +func LoadRawData(raw interface{}) (f Float64Data) {} + +func AutoCorrelation(data Float64Data, lags int) (float64, error) {} +func ChebyshevDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) {} +func Correlation(data1, data2 Float64Data) (float64, error) {} +func Covariance(data1, data2 Float64Data) (float64, error) {} +func CovariancePopulation(data1, data2 Float64Data) (float64, error) {} +func CumulativeSum(input Float64Data) ([]float64, error) {} +func Entropy(input Float64Data) (float64, error) {} +func EuclideanDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) {} +func GeometricMean(input Float64Data) (float64, error) {} +func HarmonicMean(input Float64Data) (float64, error) {} +func InterQuartileRange(input Float64Data) (float64, error) {} +func ManhattanDistance(dataPointX, dataPointY Float64Data) (distance float64, err error) {} +func Max(input Float64Data) (max float64, err error) {} +func Mean(input Float64Data) (float64, error) {} +func Median(input Float64Data) (median float64, err error) {} +func MedianAbsoluteDeviation(input Float64Data) (mad float64, err error) {} +func MedianAbsoluteDeviationPopulation(input Float64Data) (mad float64, err error) {} +func Midhinge(input Float64Data) (float64, error) {} +func Min(input Float64Data) (min float64, err error) {} +func MinkowskiDistance(dataPointX, dataPointY Float64Data, lambda float64) (distance float64, err error) {} +func Mode(input Float64Data) (mode []float64, err error) {} +func NormBoxMullerRvs(loc float64, scale float64, size int) []float64 {} +func NormCdf(x float64, loc float64, scale float64) float64 {} +func NormEntropy(loc float64, scale float64) float64 {} +func NormFit(data []float64) [2]float64{} +func NormInterval(alpha float64, loc float64, scale float64 ) [2]float64 {} +func NormIsf(p float64, loc float64, scale float64) (x float64) {} +func NormLogCdf(x float64, loc float64, scale float64) float64 {} +func NormLogPdf(x float64, loc float64, scale float64) float64 {} +func NormLogSf(x float64, loc float64, scale float64) float64 {} +func NormMean(loc float64, scale float64) float64 {} +func NormMedian(loc float64, scale float64) float64 {} +func NormMoment(n int, loc float64, scale float64) float64 {} +func NormPdf(x float64, loc float64, scale float64) float64 {} +func NormPpf(p float64, loc float64, scale float64) (x float64) {} +func NormPpfRvs(loc float64, scale float64, size int) []float64 {} +func NormSf(x float64, loc float64, scale float64) float64 {} +func NormStats(loc float64, scale float64, moments string) []float64 {} +func NormStd(loc float64, scale float64) float64 {} +func NormVar(loc float64, scale float64) float64 {} +func Pearson(data1, data2 Float64Data) (float64, error) {} +func Percentile(input Float64Data, percent float64) (percentile float64, err error) {} +func PercentileNearestRank(input Float64Data, percent float64) (percentile float64, err error) {} +func PopulationVariance(input Float64Data) (pvar float64, err error) {} +func Sample(input Float64Data, takenum int, replacement bool) ([]float64, error) {} +func SampleVariance(input Float64Data) (svar float64, err error) {} +func Sigmoid(input Float64Data) ([]float64, error) {} +func SoftMax(input Float64Data) ([]float64, error) {} +func StableSample(input Float64Data, takenum int) ([]float64, error) {} +func StandardDeviation(input Float64Data) (sdev float64, err error) {} +func StandardDeviationPopulation(input Float64Data) (sdev float64, err error) {} +func StandardDeviationSample(input Float64Data) (sdev float64, err error) {} +func StdDevP(input Float64Data) (sdev float64, err error) {} +func StdDevS(input Float64Data) (sdev float64, err error) {} +func Sum(input Float64Data) (sum float64, err error) {} +func Trimean(input Float64Data) (float64, error) {} +func VarP(input Float64Data) (sdev float64, err error) {} +func VarS(input Float64Data) (sdev float64, err error) {} +func Variance(input Float64Data) (sdev float64, err error) {} + +type Coordinate struct { + X, Y float64 +} + +type Series []Coordinate + +func ExponentialRegression(s Series) (regressions Series, err error) {} +func LinearRegression(s Series) (regressions Series, err error) {} +func LogarithmicRegression(s Series) (regressions Series, err error) {} + +type Outliers struct { + Mild Float64Data + Extreme Float64Data +} + +type Quartiles struct { + Q1 float64 + Q2 float64 + Q3 float64 +} -### Pull Requests +func Quartile(input Float64Data) (Quartiles, error) {} +func QuartileOutliers(input Float64Data) (Outliers, error) {} +``` -Pull request are always welcome no matter how big or small. Here's an easy way to do it: +## Contributing -1. Fork it and clone your fork +Pull request are always welcome no matter how big or small. I've included a [Makefile](https://github.com/montanaflynn/stats/blob/master/Makefile) that has a lot of helper targets for common actions such as linting, testing, code coverage reporting and more. + +1. Fork the repo and clone your fork 2. Create new branch (`git checkout -b some-thing`) 3. Make the desired changes 4. Ensure tests pass (`go test -cover` or `make test`) -5. Commit changes (`git commit -am 'Did something'`) -6. Push branch (`git push origin some-thing`) -7. Submit pull request +5. Run lint and fix problems (`go vet .` or `make lint`) +6. Commit changes (`git commit -am 'Did something'`) +7. Push branch (`git push origin some-thing`) +8. Submit pull request To make things as seamless as possible please also consider the following steps: -- Update `README.md` to include new public types or functions in the documentation section. -- Update `examples/main.go` with a simple example of the new feature. -- Keep 100% code coverage (you can check with `make coverage`). -- Run [`gometalinter`](https://github.com/alecthomas/gometalinter) and make your code pass. -- Squash needless commits into single units of work with `git rebase -i new-feature`. +- Update `examples/main.go` with a simple example of the new feature +- Update `README.md` documentation section with any new exported API +- Keep 100% code coverage (you can check with `make coverage`) +- Squash commits into single units of work with `git rebase -i new-feature` + +## Releasing + +To release a new version we should update the [CHANGELOG.md](/changelog.md) and [DOC.md](/DOC.md). + +First install the tools used to generate the markdown files: -#### Makefile +``` +go get github.com/davecheney/godoc2md +go get github.com/golangci/golangci-lint/cmd/golangci-lint +``` -I've included a [Makefile](https://github.com/montanaflynn/stats/blob/master/Makefile) that has a lot of helper targets for common actions such as linting, testing, code coverage reporting and more. +Then you can run these `make` directives: -**Protip:** `watch -n 1 make check` will continuously format and test your code. +``` +# Generate CHANGELOG.md +make changelog + +# Generate DOCUMENTATION.md +make documentation +``` + +Then we will create a new git tag and github release: + +``` +make release TAG=v0.x.x +``` ## MIT License -Copyright (c) 2014-2015 Montana Flynn +Copyright (c) 2014-2020 Montana Flynn (https://montanaflynn.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -96,8 +218,14 @@ [coveralls-url]: https://coveralls.io/r/montanaflynn/stats?branch=master [coveralls-svg]: https://img.shields.io/coveralls/montanaflynn/stats.svg +[goreport-url]: https://goreportcard.com/report/github.com/montanaflynn/stats +[goreport-svg]: https://goreportcard.com/badge/github.com/montanaflynn/stats + [godoc-url]: https://godoc.org/github.com/montanaflynn/stats [godoc-svg]: https://godoc.org/github.com/montanaflynn/stats?status.svg +[pkggodev-url]: https://pkg.go.dev/github.com/montanaflynn/stats +[pkggodev-svg]: https://gistcdn.githack.com/montanaflynn/b02f1d78d8c0de8435895d7e7cd0d473/raw/17f2a5a69f1323ecd42c00e0683655da96d9ecc8/badge.svg + [license-url]: https://github.com/montanaflynn/stats/blob/master/LICENSE [license-svg]: https://img.shields.io/badge/license-MIT-blue.svg diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/regression.go golang-github-montanaflynn-stats-0.6.4/regression.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/regression.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/regression.go 2021-01-13 11:52:47.000000000 +0000 @@ -14,7 +14,7 @@ func LinearRegression(s Series) (regressions Series, err error) { if len(s) == 0 { - return nil, EmptyInput + return nil, EmptyInputErr } // Placeholder for the math to be done @@ -44,19 +44,21 @@ } return regressions, nil - } // ExponentialRegression returns an exponential regression on data series func ExponentialRegression(s Series) (regressions Series, err error) { if len(s) == 0 { - return nil, EmptyInput + return nil, EmptyInputErr } var sum [6]float64 for i := 0; i < len(s); i++ { + if s[i].Y < 0 { + return nil, YCoordErr + } sum[0] += s[i].X sum[1] += s[i].Y sum[2] += s[i].X * s[i].X * s[i].Y @@ -77,14 +79,13 @@ } return regressions, nil - } // LogarithmicRegression returns an logarithmic regression on data series func LogarithmicRegression(s Series) (regressions Series, err error) { if len(s) == 0 { - return nil, EmptyInput + return nil, EmptyInputErr } var sum [4]float64 @@ -109,5 +110,4 @@ } return regressions, nil - } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/regression_test.go golang-github-montanaflynn-stats-0.6.4/regression_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/regression_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/regression_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,11 +1,26 @@ -package stats +package stats_test import ( + "fmt" "testing" + + "github.com/montanaflynn/stats" ) +func ExampleLinearRegression() { + data := []stats.Coordinate{ + {1, 2.3}, + {2, 3.3}, + {3, 3.7}, + } + + r, _ := stats.LinearRegression(data) + fmt.Println(r) + // Output: [{1 2.400000000000001} {2 3.1} {3 3.7999999999999994}] +} + func TestLinearRegression(t *testing.T) { - data := []Coordinate{ + data := []stats.Coordinate{ {1, 2.3}, {2, 3.3}, {3, 3.7}, @@ -13,36 +28,36 @@ {5, 5.3}, } - r, _ := LinearRegression(data) + r, _ := stats.LinearRegression(data) a := 2.3800000000000026 - if r[0].Y != a { - t.Errorf("%v != %v", r, a) + if !close(r[0].Y, a) { + t.Errorf("%v != %v", r[0].Y, a) } a = 3.0800000000000014 - if r[1].Y != a { - t.Errorf("%v != %v", r, a) + if !veryclose(r[1].Y, a) { + t.Errorf("%v != %v", r[1].Y, a) } a = 3.7800000000000002 if r[2].Y != a { - t.Errorf("%v != %v", r, a) + t.Errorf("%v != %v", r[2].Y, a) } a = 4.479999999999999 - if r[3].Y != a { - t.Errorf("%v != %v", r, a) + if !veryclose(r[3].Y, a) { + t.Errorf("%v != %v", r[3].Y, a) } a = 5.179999999999998 - if r[4].Y != a { - t.Errorf("%v != %v", r, a) + if !veryclose(r[4].Y, a) { + t.Errorf("%v != %v", r[4].Y, a) } - _, err := LinearRegression([]Coordinate{}) + _, err := stats.LinearRegression([]stats.Coordinate{}) if err == nil { t.Errorf("Empty slice should have returned an error") } } func TestExponentialRegression(t *testing.T) { - data := []Coordinate{ + data := []stats.Coordinate{ {1, 2.3}, {2, 3.3}, {3, 3.7}, @@ -50,37 +65,44 @@ {5, 5.3}, } - r, _ := ExponentialRegression(data) - a, _ := Round(r[0].Y, 3) + r, _ := stats.ExponentialRegression(data) + a, _ := stats.Round(r[0].Y, 3) if a != 2.515 { - t.Errorf("%v != %v", r, 2.515) + t.Errorf("%v != %v", r[0].Y, 2.515) } - a, _ = Round(r[1].Y, 3) + a, _ = stats.Round(r[1].Y, 3) if a != 3.032 { - t.Errorf("%v != %v", r, 3.032) + t.Errorf("%v != %v", r[1].Y, 3.032) } - a, _ = Round(r[2].Y, 3) + a, _ = stats.Round(r[2].Y, 3) if a != 3.655 { - t.Errorf("%v != %v", r, 3.655) + t.Errorf("%v != %v", r[2].Y, 3.655) } - a, _ = Round(r[3].Y, 3) + a, _ = stats.Round(r[3].Y, 3) if a != 4.407 { - t.Errorf("%v != %v", r, 4.407) + t.Errorf("%v != %v", r[3].Y, 4.407) } - a, _ = Round(r[4].Y, 3) + a, _ = stats.Round(r[4].Y, 3) if a != 5.313 { - t.Errorf("%v != %v", r, 5.313) + t.Errorf("%v != %v", r[4].Y, 5.313) } - _, err := ExponentialRegression([]Coordinate{}) + _, err := stats.ExponentialRegression([]stats.Coordinate{}) if err == nil { - t.Errorf("Empty slice should have returned an error") } } +func TestExponentialRegressionYCoordErr(t *testing.T) { + c := []stats.Coordinate{{1, -5}, {4, 25}, {6, 5}} + _, err := stats.ExponentialRegression(c) + if err != stats.YCoordErr { + t.Errorf(err.Error()) + } +} + func TestLogarithmicRegression(t *testing.T) { - data := []Coordinate{ + data := []stats.Coordinate{ {1, 2.3}, {2, 3.3}, {3, 3.7}, @@ -88,31 +110,30 @@ {5, 5.3}, } - r, _ := LogarithmicRegression(data) + r, _ := stats.LogarithmicRegression(data) a := 2.1520822363811702 - if r[0].Y != a { - t.Errorf("%v != %v", r, a) + if !close(r[0].Y, a) { + t.Errorf("%v != %v", r[0].Y, a) } a = 3.3305559222492214 - if r[1].Y != a { - t.Errorf("%v != %v", r, a) + if !veryclose(r[1].Y, a) { + t.Errorf("%v != %v", r[1].Y, a) } a = 4.019918836568674 - if r[2].Y != a { - t.Errorf("%v != %v", r, a) + if !veryclose(r[2].Y, a) { + t.Errorf("%v != %v", r[2].Y, a) } a = 4.509029608117273 - if r[3].Y != a { - t.Errorf("%v != %v", r, a) + if !veryclose(r[3].Y, a) { + t.Errorf("%v != %v", r[3].Y, a) } a = 4.888413396683663 - if r[4].Y != a { - t.Errorf("%v != %v", r, a) + if !veryclose(r[4].Y, a) { + t.Errorf("%v != %v", r[4].Y, a) } - _, err := LogarithmicRegression([]Coordinate{}) + _, err := stats.LogarithmicRegression([]stats.Coordinate{}) if err == nil { - t.Errorf("Empty slice should have returned an error") } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/round_test.go golang-github-montanaflynn-stats-0.6.4/round_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/round_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/round_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,10 +1,19 @@ -package stats +package stats_test import ( + "fmt" "math" "testing" + + "github.com/montanaflynn/stats" ) +func ExampleRound() { + rounded, _ := stats.Round(1.534424, 1) + fmt.Println(rounded) + // Output: 1.5 +} + func TestRound(t *testing.T) { for _, c := range []struct { number float64 @@ -18,7 +27,7 @@ {5.3253, 0, 5.0}, {5.55, 1, 5.6}, } { - m, err := Round(c.number, c.decimals) + m, err := stats.Round(c.number, c.decimals) if err != nil { t.Errorf("Returned an error") } @@ -27,7 +36,7 @@ } } - _, err := Round(math.NaN(), 2) + _, err := stats.Round(math.NaN(), 2) if err == nil { t.Errorf("Round should error on NaN") } @@ -35,6 +44,6 @@ func BenchmarkRound(b *testing.B) { for i := 0; i < b.N; i++ { - Round(0.1111, 1) + _, _ = stats.Round(0.1111, 1) } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sample.go golang-github-montanaflynn-stats-0.6.4/sample.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sample.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/sample.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,12 +1,15 @@ package stats -import "math/rand" +import ( + "math/rand" + "sort" +) // Sample returns sample from input with replacement or without func Sample(input Float64Data, takenum int, replacement bool) ([]float64, error) { if input.Len() == 0 { - return nil, EmptyInput + return nil, EmptyInputErr } length := input.Len() @@ -36,6 +39,35 @@ result = append(result, input[idx]) } + return result, nil + + } + + return nil, BoundsErr +} + +// StableSample like stable sort, it returns samples from input while keeps the order of original data. +func StableSample(input Float64Data, takenum int) ([]float64, error) { + if input.Len() == 0 { + return nil, EmptyInputErr + } + + length := input.Len() + + if takenum <= length { + + rand.Seed(unixnano()) + + perm := rand.Perm(length) + perm = perm[0:takenum] + // Sort perm before applying + sort.Ints(perm) + result := Float64Data{} + + for _, idx := range perm { + result = append(result, input[idx]) + } + return result, nil } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sample_test.go golang-github-montanaflynn-stats-0.6.4/sample_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sample_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/sample_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,24 +1,26 @@ -package stats +package stats_test import ( "testing" + + "github.com/montanaflynn/stats" ) func TestSample(t *testing.T) { - _, err := Sample([]float64{}, 10, false) + _, err := stats.Sample([]float64{}, 10, false) if err == nil { - t.Errorf("Returned an error") + t.Errorf("should return an error") } - _, err2 := Sample([]float64{0.1, 0.2}, 10, false) - if err2 == nil { - t.Errorf("Returned an error") + _, err = stats.Sample([]float64{0.1, 0.2}, 10, false) + if err == nil { + t.Errorf("should return an error") } } func TestSampleWithoutReplacement(t *testing.T) { arr := []float64{0.1, 0.2, 0.3, 0.4, 0.5} - result, _ := Sample(arr, 5, false) + result, _ := stats.Sample(arr, 5, false) checks := map[float64]bool{} for _, res := range result { _, ok := checks[res] @@ -32,8 +34,36 @@ func TestSampleWithReplacement(t *testing.T) { arr := []float64{0.1, 0.2, 0.3, 0.4, 0.5} numsamples := 100 - result, _ := Sample(arr, numsamples, true) + result, _ := stats.Sample(arr, numsamples, true) if len(result) != numsamples { t.Errorf("%v != %v", len(result), numsamples) } } + +func TestStableSample(t *testing.T) { + _, err := stats.StableSample(stats.Float64Data{}, 10) + if err != stats.EmptyInputErr { + t.Errorf("should return EmptyInputError when sampling an empty data") + } + _, err = stats.StableSample(stats.Float64Data{1.0, 2.0}, 10) + if err != stats.BoundsErr { + t.Errorf("should return BoundsErr when sampling size exceeds the maximum element size of data") + } + arr := []float64{1.0, 3.0, 2.0, -1.0, 5.0} + locations := map[float64]int{ + 1.0: 0, + 3.0: 1, + 2.0: 2, + -1.0: 3, + 5.0: 4, + } + ret, _ := stats.StableSample(arr, 3) + if len(ret) != 3 { + t.Errorf("returned wrong sample size") + } + for i := 1; i < 3; i++ { + if locations[ret[i]] < locations[ret[i-1]] { + t.Errorf("doesn't keep order") + } + } +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sigmoid.go golang-github-montanaflynn-stats-0.6.4/sigmoid.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sigmoid.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/sigmoid.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,18 @@ +package stats + +import "math" + +// Sigmoid returns the input values in the range of -1 to 1 +// along the sigmoid or s-shaped curve, commonly used in +// machine learning while training neural networks as an +// activation function. +func Sigmoid(input Float64Data) ([]float64, error) { + if input.Len() == 0 { + return Float64Data{}, EmptyInput + } + s := make([]float64, len(input)) + for i, v := range input { + s[i] = 1 / (1 + math.Exp(-v)) + } + return s, nil +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sigmoid_test.go golang-github-montanaflynn-stats-0.6.4/sigmoid_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sigmoid_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/sigmoid_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,43 @@ +package stats_test + +import ( + "fmt" + "testing" + + "github.com/montanaflynn/stats" +) + +func ExampleSigmoid() { + s, _ := stats.Sigmoid([]float64{3.0, 1.0, 2.1}) + fmt.Println(s) + // Output: [0.9525741268224334 0.7310585786300049 0.8909031788043871] +} + +func TestSigmoidEmptyInput(t *testing.T) { + _, err := stats.Sigmoid([]float64{}) + if err != stats.EmptyInputErr { + t.Errorf("Should have returned empty input error") + } +} + +func TestSigmoid(t *testing.T) { + sm, err := stats.Sigmoid([]float64{-0.54761371, 17.04850603, 4.86054302}) + if err != nil { + t.Error(err) + } + + a := 0.3664182235138545 + if sm[0] != a { + t.Errorf("%v != %v", sm[0], a) + } + + a = 0.9999999605608187 + if sm[1] != a { + t.Errorf("%v != %v", sm[1], a) + } + + a = 0.9923132671908277 + if sm[2] != a { + t.Errorf("%v != %v", sm[2], a) + } +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/softmax.go golang-github-montanaflynn-stats-0.6.4/softmax.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/softmax.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/softmax.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,25 @@ +package stats + +import "math" + +// SoftMax returns the input values in the range of 0 to 1 +// with sum of all the probabilities being equal to one. It +// is commonly used in machine learning neural networks. +func SoftMax(input Float64Data) ([]float64, error) { + if input.Len() == 0 { + return Float64Data{}, EmptyInput + } + + s := 0.0 + c, _ := Max(input) + for _, e := range input { + s += math.Exp(e - c) + } + + sm := make([]float64, len(input)) + for i, v := range input { + sm[i] = math.Exp(v-c) / s + } + + return sm, nil +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/softmax_test.go golang-github-montanaflynn-stats-0.6.4/softmax_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/softmax_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/softmax_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,43 @@ +package stats_test + +import ( + "fmt" + "testing" + + "github.com/montanaflynn/stats" +) + +func ExampleSoftMax() { + sm, _ := stats.SoftMax([]float64{3.0, 1.0, 0.2}) + fmt.Println(sm) + // Output: [0.8360188027814407 0.11314284146556013 0.05083835575299916] +} + +func TestSoftMaxEmptyInput(t *testing.T) { + _, err := stats.SoftMax([]float64{}) + if err != stats.EmptyInputErr { + t.Errorf("Should have returned empty input error") + } +} + +func TestSoftMax(t *testing.T) { + sm, err := stats.SoftMax([]float64{3.0, 1.0, 0.2}) + if err != nil { + t.Error(err) + } + + a := 0.8360188027814407 + if sm[0] != a { + t.Errorf("%v != %v", sm[0], a) + } + + a = 0.11314284146556013 + if sm[1] != a { + t.Errorf("%v != %v", sm[1], a) + } + + a = 0.05083835575299916 + if sm[2] != a { + t.Errorf("%v != %v", sm[1], a) + } +} diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sum.go golang-github-montanaflynn-stats-0.6.4/sum.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sum.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/sum.go 2021-01-13 11:52:47.000000000 +0000 @@ -6,7 +6,7 @@ func Sum(input Float64Data) (sum float64, err error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Add em up diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sum_test.go golang-github-montanaflynn-stats-0.6.4/sum_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/sum_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/sum_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,10 +1,20 @@ -package stats +package stats_test import ( + "fmt" "reflect" "testing" + + "github.com/montanaflynn/stats" ) +func ExampleSum() { + d := []float64{1.1, 2.2, 3.3} + a, _ := stats.Sum(d) + fmt.Println(a) + // Output: 6.6 +} + func TestSum(t *testing.T) { for _, c := range []struct { in []float64 @@ -14,7 +24,7 @@ {[]float64{1.0, 1.1, 1.2, 2.2}, 5.5}, {[]float64{1, -1, 2, -3}, -1}, } { - got, err := Sum(c.in) + got, err := stats.Sum(c.in) if err != nil { t.Errorf("Returned an error") } @@ -22,7 +32,7 @@ t.Errorf("Sum(%.1f) => %.1f != %.1f", c.in, got, c.out) } } - _, err := Sum([]float64{}) + _, err := stats.Sum([]float64{}) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -30,7 +40,7 @@ func BenchmarkSumSmallFloatSlice(b *testing.B) { for i := 0; i < b.N; i++ { - Sum(makeFloatSlice(5)) + _, _ = stats.Sum(makeFloatSlice(5)) } } @@ -38,6 +48,6 @@ lf := makeFloatSlice(100000) b.ResetTimer() for i := 0; i < b.N; i++ { - Sum(lf) + _, _ = stats.Sum(lf) } } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/test_utils_test.go golang-github-montanaflynn-stats-0.6.4/test_utils_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/test_utils_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/test_utils_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -0,0 +1,28 @@ +package stats_test + +// Approximate float comparisons +// Taken from the standard library's math/all_test.go +func tolerance(a, b, e float64) bool { + // Multiplying by e here can underflow denormal values to zero. + // Check a==b so that at least if a and b are small and identical + // we say they match. + if a == b { + return true + } + d := a - b + if d < 0 { + d = -d + } + + // note: b is correct (expected) value, a is actual value. + // make error tolerance a fraction of b, not a. + if b != 0 { + e = e * b + if e < 0 { + e = -e + } + } + return d < e +} +func close(a, b float64) bool { return tolerance(a, b, 1e-14) } +func veryclose(a, b float64) bool { return tolerance(a, b, 4e-16) } diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/.travis.yml golang-github-montanaflynn-stats-0.6.4/.travis.yml --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/.travis.yml 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/.travis.yml 2021-01-13 11:52:47.000000000 +0000 @@ -1,17 +1,23 @@ language: go go: - - 1.1 - - 1.2 - - 1.3 - - 1.4 - - 1.5 - - tip + - "1.7" + - "1.8" + - "1.9" + - "1.10" + - "1.11" + - "1.12" + - "1.13" + - stable + - master +arch: + - amd64 + - arm64 before_install: - - sudo pip install codecov + - go get github.com/mattn/goveralls script: - - go test + - go test -v -covermode=count -coverprofile=coverage.out after_success: - - codecov + - $GOPATH/bin/goveralls -coverprofile=coverage.out -service=travis-ci notifications: email: recipients: diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/util_test.go golang-github-montanaflynn-stats-0.6.4/util_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/util_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/util_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,30 +1,9 @@ package stats import ( - "math/rand" "testing" ) -// makeFloatSlice makes a slice of float64s -func makeFloatSlice(c int) []float64 { - lf := make([]float64, 0, c) - for i := 0; i < c; i++ { - f := float64(i * 100) - lf = append(lf, f) - } - return lf -} - -func makeRandFloatSlice(c int) []float64 { - lf := make([]float64, 0, c) - rand.Seed(unixnano()) - for i := 0; i < c; i++ { - f := float64(i * 100) - lf = append(lf, f) - } - return lf -} - func TestFloat64ToInt(t *testing.T) { m := float64ToInt(234.0234) if m != 234 { diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/variance.go golang-github-montanaflynn-stats-0.6.4/variance.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/variance.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/variance.go 2021-01-13 11:52:47.000000000 +0000 @@ -6,14 +6,14 @@ func _variance(input Float64Data, sample int) (variance float64, err error) { if input.Len() == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } // Sum the square of the mean subtracted from each number m, _ := Mean(input) for _, n := range input { - variance += (float64(n) - m) * (float64(n) - m) + variance += (n - m) * (n - m) } // When getting the mean of the squared differences @@ -56,7 +56,7 @@ l2 := data2.Len() if l1 == 0 || l2 == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } if l1 != l2 { @@ -84,7 +84,7 @@ l2 := data2.Len() if l1 == 0 || l2 == 0 { - return math.NaN(), EmptyInput + return math.NaN(), EmptyInputErr } if l1 != l2 { diff -Nru golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/variance_test.go golang-github-montanaflynn-stats-0.6.4/variance_test.go --- golang-github-montanaflynn-stats-0.2.0+git20170729.66.4a16327/variance_test.go 2017-08-08 06:39:08.000000000 +0000 +++ golang-github-montanaflynn-stats-0.6.4/variance_test.go 2021-01-13 11:52:47.000000000 +0000 @@ -1,28 +1,30 @@ -package stats +package stats_test import ( "math" "testing" + + "github.com/montanaflynn/stats" ) func TestVariance(t *testing.T) { - _, err := Variance([]float64{1, 2, 3}) + _, err := stats.Variance([]float64{1, 2, 3}) if err != nil { t.Errorf("Returned an error") } } func TestPopulationVariance(t *testing.T) { - e, err := PopulationVariance([]float64{}) + e, err := stats.PopulationVariance([]float64{}) if !math.IsNaN(e) { t.Errorf("%.1f != %.1f", e, math.NaN()) } - if err != EmptyInput { - t.Errorf("%v != %v", err, EmptyInput) + if err != stats.EmptyInputErr { + t.Errorf("%v != %v", err, stats.EmptyInputErr) } - pv, _ := PopulationVariance([]float64{1, 2, 3}) - a, err := Round(pv, 1) + pv, _ := stats.PopulationVariance([]float64{1, 2, 3}) + a, err := stats.Round(pv, 1) if err != nil { t.Errorf("Returned an error") } @@ -32,14 +34,14 @@ } func TestSampleVariance(t *testing.T) { - m, err := SampleVariance([]float64{}) + m, err := stats.SampleVariance([]float64{}) if !math.IsNaN(m) { t.Errorf("%.1f != %.1f", m, math.NaN()) } - if err != EmptyInput { - t.Errorf("%v != %v", err, EmptyInput) + if err != stats.EmptyInputErr { + t.Errorf("%v != %v", err, stats.EmptyInputErr) } - m, _ = SampleVariance([]float64{1, 2, 3}) + m, _ = stats.SampleVariance([]float64{1, 2, 3}) if m != 1.0 { t.Errorf("%.1f != %.1f", m, 1.0) } @@ -51,12 +53,12 @@ s3 := []float64{1, 2, 3, 5, 6} s4 := []float64{} - _, err := Covariance(s1, s2) + _, err := stats.Covariance(s1, s2) if err == nil { t.Errorf("Mismatched slice lengths should have returned an error") } - a, err := Covariance(s1, s3) + a, err := stats.Covariance(s1, s3) if err != nil { t.Errorf("Should not have returned an error") } @@ -65,7 +67,7 @@ t.Errorf("Covariance %v != %v", a, 3.2499999999999996) } - _, err = Covariance(s1, s4) + _, err = stats.Covariance(s1, s4) if err == nil { t.Errorf("Empty slice should have returned an error") } @@ -77,12 +79,12 @@ s3 := []float64{0.5, 1, 2.1, 3.4, 3.4, 4} s4 := []float64{} - _, err := CovariancePopulation(s1, s2) + _, err := stats.CovariancePopulation(s1, s2) if err == nil { t.Errorf("Mismatched slice lengths should have returned an error") } - a, err := CovariancePopulation(s1, s3) + a, err := stats.CovariancePopulation(s1, s3) if err != nil { t.Errorf("Should not have returned an error") } @@ -91,7 +93,7 @@ t.Errorf("CovariancePopulation %v != %v", a, 4.191666666666666) } - _, err = CovariancePopulation(s1, s4) + _, err = stats.CovariancePopulation(s1, s4) if err == nil { t.Errorf("Empty slice should have returned an error") }