12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- package stats
- import (
- "math"
- )
- // Validate data for distance calculation
- func validateData(dataPointX, dataPointY []float64) error {
- if len(dataPointX) == 0 || len(dataPointY) == 0 {
- return EmptyInput
- }
- if len(dataPointX) != len(dataPointY) {
- return SizeErr
- }
- return nil
- }
- // Computes Chebyshev distance between two data sets
- func ChebyshevDistance(dataPointX, dataPointY []float64) (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
- }
- //
- // Computes Euclidean distance between two data sets
- //
- func EuclideanDistance(dataPointX, dataPointY []float64) (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
- }
- //
- // Computes Manhattan distance between two data sets
- //
- func ManhattanDistance(dataPointX, dataPointY []float64) (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
- }
- //
- // Computes minkowski distance between two data sets.
- //
- // Input:
- // 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.
- // Output:
- // Distance or error
- //
- func MinkowskiDistance(dataPointX, dataPointY []float64, 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, float64(1/lambda))
- if math.IsInf(distance, 1) == true {
- return math.NaN(), InfValue
- }
- return distance, nil
- }
|