function distances({ vectors, distanceType }) {
const D = {
one: (a, b) => 1,
random: (a, b) => Math.random(),
euclidian: (a, b) =>
Math.sqrt(a.map((_, i) => (a[i] - b[i]) ** 2).reduce((a, b) => a + b, 0)),
cosine: (a, b) => {
const dot = a.map((_, i) => a[i] * b[i]).reduce((a, b) => a + b, 0),
norm2A = a.map(u => u ** 2).reduce((a, b) => a + b, 0),
norm2B = norm2A ? b.map(u => u ** 2).reduce((a, b) => a + b, 0) : 0,
N = norm2A * norm2B;
return !N ? 1 : Math.acos(dot / Math.sqrt(N)) / Math.PI;
}
};
const distance = D[distanceType] || D["euclidian"];
const N = vectors.length,
distances = Float32Array.from({ length: N ** 2 });
for (let i = 0; i < N; i++) {
const a = vectors[i];
distances[i + N * i] = 0;
for (let j = 0; j < i; j++) {
const b = vectors[j];
distances[i + N * j] = distances[j + N * i] = distance(a, b);
}
}
return distances;
}