func round(a float64) float64 {
	if a < 0 {
		return math.Ceil(a - 0.5)
	}
	return math.Floor(a + 0.5)
}
round rounds a float64
package cluster
import (
	"fmt"
	"math"
	"github.com/cdipaolo/goml/base"
)
type KNN struct {
	Distance base.DistanceMeasure
	K int
	trainingSet     [][]float64
	expectedResults []float64
}
type nn struct {
	X []float64
	Y float64
	Distance float64
}
func NewKNN(k int, trainingSet [][]float64, expectedResults []float64, distanceMeasure base.DistanceMeasure) *KNN {
	return &KNN{
		Distance:        distanceMeasure,
		K:               k,
		trainingSet:     trainingSet,
		expectedResults: expectedResults,
	}
}
func (k *KNN) UpdateTrainingSet(trainingSet [][]float64, expectedResults []float64) error {
	if len(trainingSet) == 0 || len(expectedResults) == 0 {
		return fmt.Errorf("Error: length of given data is 0! Need data!")
	}
	if len(trainingSet) != len(expectedResults) {
		return fmt.Errorf("Datasets given do not match in length")
	}
	k.trainingSet = trainingSet
	k.expectedResults = expectedResults
	return nil
}
func (k *KNN) Examples() int {
	return len(k.trainingSet)
}
func insertSorted(u nn, v []nn, K int) []nn {
	low := 0
	high := len(v) - 1
	for low <= high {
		mid := (low + high) / 2
		if u.Distance < v[mid].Distance {
			high = mid - 1
		} else if u.Distance >= v[mid].Distance {
			low = mid + 1
		}
	}
	if low >= len(v) && len(v) >= K {
		return v
	}
	sorted := append(v[:low], append([]nn{u}, v[low:]...)...)
	if len(v) < K {
		return sorted
	}
	return sorted[:len(v)]
}