Unit testing for def/ module.

Added unit tests to test code in def/ module.
This commit is contained in:
Pradyumna Kaushik 2019-10-12 06:48:45 +00:00
parent e24b8a08c9
commit bac60e872a
396 changed files with 83991 additions and 13209 deletions

View file

@ -1,17 +1,13 @@
language: go
go:
- 1.1
- 1.2
- 1.3
- 1.4
- 1.5
- tip
- stable
- master
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:

View file

@ -1,8 +1,9 @@
# Stats [![][travis-svg]][travis-url] [![][coveralls-svg]][coveralls-url] [![][godoc-svg]][godoc-url] [![][license-svg]][license-url]
# Stats [![][travis-svg]][travis-url] [![][coveralls-svg]][coveralls-url] [![][goreport-svg]][goreport-url] [![][godoc-svg]][godoc-url] [![][license-svg]][license-url]
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.
A well tested and comprehensive Golang statistics library package 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!
> Statistics are used much like a drunk uses a lamppost: for support, not illumination. **- Vin Scully**
## Installation
@ -10,55 +11,130 @@ A statistics package with many functions missing from the Golang standard librar
go get github.com/montanaflynn/stats
```
**Protip:** `go get -u github.com/montanaflynn/stats` updates stats to the latest version.
## Example Usage
## Usage
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:
```go
// 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
```
## Documentation
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:
```
# Command line
godoc ./
godoc ./ Median
godoc ./ Float64Data
# Local website
godoc -http=:4444
open http://localhost:4444/pkg/github.com/montanaflynn/stats/
```
**Protip:** Generate HTML docs with `godoc -http=:4444`
## 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:
The exported API is as follows:
```go
// start with the some source data to use
var data = []float64{1, 2, 3, 4, 4, 5}
var (
EmptyInputErr = statsErr{"Input must not be empty."}
NaNErr = statsErr{"Not a number."}
NegativeErr = statsErr{"Must not contain negative values."}
ZeroErr = statsErr{"Must not contain zero values."}
BoundsErr = statsErr{"Input is outside of range."}
SizeErr = statsErr{"Must be the same length."}
InfValue = statsErr{"Value is infinite."}
YCoordErr = statsErr{"Y Value must be greater than zero."}
)
median, _ := stats.Median(data)
fmt.Println(median) // 3.5
type Float64Data []float64
roundedMedian, _ := stats.Round(median, 0)
fmt.Println(roundedMedian) // 4
```
func LoadRawData(raw interface{}) (f Float64Data) {}
func AutoCorrelation(data Float64Data, lags int) (float64, error) {}
func ChebyshevDistance(dataPointX, dataPointY []float64) (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 EuclideanDistance(dataPointX, dataPointY []float64) (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 []float64) (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 []float64, lambda float64) (distance float64, err error) {}
func Mode(input Float64Data) (mode []float64, err error) {}
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 Round(input float64, places int) (rounded 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 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) {}
**Protip:** You can [call methods](https://github.com/montanaflynn/stats/blob/master/examples/methods.go) on the data if using the Float64Data type:
type Coordinate struct {
X, Y float64
}
```
var d stats.Float64Data = data
type Series []Coordinate
max, _ := d.Max()
fmt.Println(max) // 5
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
}
func Quartile(input Float64Data) (Quartiles, error) {}
func QuartileOutliers(input Float64Data) (Outliers, error) {}
```
## Contributing
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!
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.
### Pull Requests
Pull request are always welcome no matter how big or small. Here's an easy way to do it:
1. Fork it and clone your fork
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`)
@ -68,21 +144,14 @@ Pull request are always welcome no matter how big or small. Here's an easy way t
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`.
#### Makefile
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.
**Protip:** `watch -n 1 make check` will continuously format and test your code.
- 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`
## MIT License
Copyright (c) 2014-2015 Montana Flynn <http://anonfunction.com>
Copyright (c) 2014-2019 Montana Flynn <http://anonfunction.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,6 +165,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
[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

View file

@ -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 @@ func Correlation(data1, data2 Float64Data) (float64, error) {
l2 := data2.Len()
if l1 == 0 || l2 == 0 {
return math.NaN(), EmptyInput
return math.NaN(), EmptyInputErr
}
if l1 != l2 {
@ -27,7 +29,32 @@ func Correlation(data1, data2 Float64Data) (float64, error) {
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
}

21
vendor/github.com/montanaflynn/stats/cumulative_sum.go generated vendored Normal file
View file

@ -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
}

View file

@ -24,6 +24,9 @@ func (f Float64Data) Max() (float64, error) { return Max(f) }
// 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 @@ func (f Float64Data) Correlation(d Float64Data) (float64, error) {
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)

View file

@ -10,7 +10,7 @@ func MedianAbsoluteDeviation(input Float64Data) (mad float64, err error) {
// 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 StandardDeviation(input Float64Data) (sdev float64, err error) {
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 StandardDeviationPopulation(input Float64Data) (sdev float64, err error) {
func StandardDeviationSample(input Float64Data) (sdev float64, err error) {
if input.Len() == 0 {
return math.NaN(), EmptyInput
return math.NaN(), EmptyInputErr
}
// Get the sample variance

View file

@ -7,7 +7,7 @@ import (
// Validate data for distance calculation
func validateData(dataPointX, dataPointY []float64) error {
if len(dataPointX) == 0 || len(dataPointY) == 0 {
return EmptyInput
return EmptyInputErr
}
if len(dataPointX) != len(dataPointY) {
@ -16,7 +16,7 @@ func validateData(dataPointX, dataPointY []float64) error {
return nil
}
// Computes Chebyshev distance between two data sets
// ChebyshevDistance computes the Chebyshev distance between two data sets
func ChebyshevDistance(dataPointX, dataPointY []float64) (distance float64, err error) {
err = validateData(dataPointX, dataPointY)
if err != nil {
@ -32,9 +32,7 @@ func ChebyshevDistance(dataPointX, dataPointY []float64) (distance float64, err
return distance, nil
}
//
// Computes Euclidean distance between two data sets
//
// EuclideanDistance computes the Euclidean distance between two data sets
func EuclideanDistance(dataPointX, dataPointY []float64) (distance float64, err error) {
err = validateData(dataPointX, dataPointY)
@ -48,9 +46,7 @@ func EuclideanDistance(dataPointX, dataPointY []float64) (distance float64, err
return math.Sqrt(distance), nil
}
//
// Computes Manhattan distance between two data sets
//
// ManhattanDistance computes the Manhattan distance between two data sets
func ManhattanDistance(dataPointX, dataPointY []float64) (distance float64, err error) {
err = validateData(dataPointX, dataPointY)
if err != nil {
@ -63,10 +59,9 @@ func ManhattanDistance(dataPointX, dataPointY []float64) (distance float64, err
return distance, nil
}
// MinkowskiDistance computes the Minkowski distance between two data sets
//
// Computes minkowski distance between two data sets.
//
// Input:
// Arguments:
// dataPointX: First set of data points
// dataPointY: Second set of data points. Length of both data
// sets must be equal.
@ -75,9 +70,8 @@ func ManhattanDistance(dataPointX, dataPointY []float64) (distance float64, err
// lambda = 2; it is euclidean distance. Lambda
// reaching to infinite - distance would be chebysev
// distance.
// Output:
// Return:
// Distance or error
//
func MinkowskiDistance(dataPointX, dataPointY []float64, lambda float64) (distance float64, err error) {
err = validateData(dataPointX, dataPointY)
if err != nil {
@ -86,8 +80,8 @@ func MinkowskiDistance(dataPointX, dataPointY []float64, lambda float64) (distan
for i := 0; i < len(dataPointY); i++ {
distance = distance + math.Pow(math.Abs(dataPointX[i]-dataPointY[i]), lambda)
}
distance = math.Pow(distance, float64(1/lambda))
if math.IsInf(distance, 1) == true {
distance = math.Pow(distance, 1/lambda)
if math.IsInf(distance, 1) {
return math.NaN(), InfValue
}
return distance, nil

View file

@ -8,15 +8,19 @@ func (s statsErr) Error() string {
return s.err
}
func (s statsErr) String() string {
return s.err
}
// These are the package-wide error values.
// All error identification should use these values.
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."}
InfValue = statsErr{"Value is infinite."}
EmptyInputErr = statsErr{"Input must not be empty."}
NaNErr = statsErr{"Not a number."}
NegativeErr = statsErr{"Must not contain negative values."}
ZeroErr = statsErr{"Must not contain zero values."}
BoundsErr = statsErr{"Input is outside of range."}
SizeErr = statsErr{"Must be the same length."}
InfValue = statsErr{"Value is infinite."}
YCoordErr = statsErr{"Y Value must be greater than zero."}
)

View file

@ -34,3 +34,6 @@ func ExpReg(s []Coordinate) (regressions []Coordinate, err error) {
func LogReg(s []Coordinate) (regressions []Coordinate, err error) {
return LogarithmicRegression(s)
}
// EmptyInput legacy error name didn't end with Err
var EmptyInput = EmptyInputErr

View file

@ -40,7 +40,7 @@ func LoadRawData(raw interface{}) (f Float64Data) {
return s
case []bool:
for _, v := range t {
if v == true {
if v {
s = append(s, 1.0)
} else {
s = append(s, 0.0)
@ -138,7 +138,7 @@ func LoadRawData(raw interface{}) (f Float64Data) {
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)
@ -171,7 +171,7 @@ func LoadRawData(raw interface{}) (f Float64Data) {
f = append(f, fl)
}
case bool:
if t == true {
if t {
f = append(f, 1.0)
} else {
f = append(f, 0.0)

View file

@ -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

View file

@ -6,7 +6,7 @@ import "math"
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 @@ func GeometricMean(input Float64Data) (float64, error) {
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 @@ func HarmonicMean(input Float64Data) (float64, error) {
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

View file

@ -14,11 +14,11 @@ func Median(input Float64Data) (median float64, err error) {
// 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

View file

@ -10,7 +10,7 @@ func Min(input Float64Data) (min float64, err error) {
// 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

View file

@ -7,7 +7,7 @@ func Mode(input Float64Data) (mode []float64, err error) {
if l == 1 {
return input, nil
} else if l == 0 {
return nil, EmptyInput
return nil, EmptyInputErr
}
c := sortedCopyDif(input)

View file

@ -9,7 +9,7 @@ type Outliers struct {
// 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

View file

@ -1,12 +1,14 @@
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) {
if input.Len() == 0 {
return math.NaN(), EmptyInput
return math.NaN(), EmptyInputErr
}
if percent <= 0 || percent > 100 {
@ -52,7 +54,7 @@ func PercentileNearestRank(input Float64Data, percent float64) (percentile float
// 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

View file

@ -14,7 +14,7 @@ func Quartile(input Float64Data) (Quartiles, error) {
il := input.Len()
if il == 0 {
return Quartiles{}, EmptyInput
return Quartiles{}, EmptyInputErr
}
// Start by sorting a copy of the slice
@ -44,7 +44,7 @@ func Quartile(input Float64Data) (Quartiles, error) {
// 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 @@ func InterQuartileRange(input Float64Data) (float64, error) {
// 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 @@ func Midhinge(input Float64Data) (float64, error) {
// 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)

View file

@ -14,7 +14,7 @@ type Coordinate struct {
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 @@ func LinearRegression(s Series) (regressions Series, err error) {
}
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 @@ func ExponentialRegression(s Series) (regressions Series, err error) {
}
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 @@ func LogarithmicRegression(s Series) (regressions Series, err error) {
}
return regressions, nil
}

View file

@ -6,7 +6,7 @@ import "math/rand"
func Sample(input Float64Data, takenum int, replacement bool) ([]float64, error) {
if input.Len() == 0 {
return nil, EmptyInput
return nil, EmptyInputErr
}
length := input.Len()

18
vendor/github.com/montanaflynn/stats/sigmoid.go generated vendored Normal file
View file

@ -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
}

25
vendor/github.com/montanaflynn/stats/softmax.go generated vendored Normal file
View file

@ -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
}

View file

@ -6,7 +6,7 @@ import "math"
func Sum(input Float64Data) (sum float64, err error) {
if input.Len() == 0 {
return math.NaN(), EmptyInput
return math.NaN(), EmptyInputErr
}
// Add em up

View file

@ -6,14 +6,14 @@ import "math"
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 @@ func Covariance(data1, data2 Float64Data) (float64, error) {
l2 := data2.Len()
if l1 == 0 || l2 == 0 {
return math.NaN(), EmptyInput
return math.NaN(), EmptyInputErr
}
if l1 != l2 {
@ -84,7 +84,7 @@ func CovariancePopulation(data1, data2 Float64Data) (float64, error) {
l2 := data2.Len()
if l1 == 0 || l2 == 0 {
return math.NaN(), EmptyInput
return math.NaN(), EmptyInputErr
}
if l1 != l2 {