// Deterministic KNN contract example: noncontiguous classes and exact ties.
import aner.ml
import aner.tensor

let features: Tensor = [[0.0, 0.0], [0.0, 2.0], [2.0, 0.0],
                        [10.0, 10.0], [10.0, 12.0], [12.0, 10.0]]
let labels: Tensor = [[10.0], [10.0], [20.0], [30.0], [30.0], [40.0]]
let queries: Tensor = [[1.0, 0.0], [11.0, 10.0]]
let model = ml.fit_knn(features: features, labels: labels, k: 3)
let predicted = model.predict(input: queries)
let probabilities = model.predict_proba(input: queries)
let known_classes = model.classes()
let neighbors = model.neighbor_indices(input: queries)
let distances = model.neighbor_distances(input: queries)

print(tensor.rows(known_classes))
print(tensor.value(known_classes, row: 0, column: 0))
print(tensor.value(predicted, row: 0, column: 0))
print(tensor.value(predicted, row: 1, column: 0))
print(tensor.value(probabilities, row: 0, column: 0))
print(tensor.value(probabilities, row: 0, column: 1))
print(tensor.value(neighbors, row: 0, column: 0))
print(tensor.value(neighbors, row: 0, column: 1))
print(tensor.value(neighbors, row: 0, column: 2))
print(tensor.value(distances, row: 0, column: 0))
print(tensor.value(distances, row: 0, column: 1))

// Two equally distant neighbors vote for different labels; smallest ID wins.
let tied = ml.fit_knn(features: [[0.0], [2.0]], labels: [[20.0], [10.0]], k: 2)
print(tensor.value(tied.predict(input: [[1.0]]), row: 0, column: 0))
