henry99a's picture
Clean commit for Hugging Face Spaces without binary files
ca7217f
package position
import (
"math"
"strings"
"github.com/metatube-community/metatube-sdk-go/common/cluster"
)
var (
_ cluster.Locatable[Vector, float64] = (*Vector)(nil)
_ cluster.WeightedLocatable[WeightedVector, float64, float64] = (*WeightedVector)(nil)
)
type Vector struct {
vector []Position
}
func NewVector(pos ...Position) Vector {
return Vector{append([]Position(nil), pos...)}
}
func (v Vector) At(i int) Position {
if i < 0 || i >= len(v.vector) {
panic("index out of range")
}
return v.vector[i]
}
func (v Vector) Dim() int {
return len(v.vector)
}
func (v Vector) DistanceTo(o Vector) float64 {
if v.Dim() != o.Dim() {
panic("dimension mismatch")
}
switch v.Dim() {
case 0:
return 0.0
case 1:
return v.vector[0].DistanceTo(o.vector[0])
case 2:
return math.Hypot(
v.vector[0].DistanceTo(o.vector[0]),
v.vector[1].DistanceTo(o.vector[1]),
)
default:
var sum float64
for i := range v.vector {
d := v.vector[i].DistanceTo(o.vector[i])
sum += d * d
}
return math.Sqrt(sum)
}
}
func (v Vector) IsValid() bool {
for _, p := range v.vector {
if !p.IsValid() {
return false
}
}
return true
}
func (v Vector) Select(dims ...int) Vector {
vec := make([]Position, len(dims))
for i, d := range dims {
if d < 0 || d >= len(v.vector) {
panic("index out of range")
}
vec[i] = v.vector[d]
}
return Vector{vec}
}
func (v Vector) String() string {
var parts []string
for _, p := range v.vector {
parts = append(parts, p.String())
}
return "(" + strings.Join(parts, ",") + ")"
}
type WeightedVector struct {
Vector
weight float64
}
func NewWeightedVector(vector Vector, weight float64) WeightedVector {
if weight < 0 {
panic("weight must be non-negative")
}
return WeightedVector{
Vector: vector,
weight: weight,
}
}
func (v WeightedVector) DistanceTo(o WeightedVector) float64 {
return v.Vector.DistanceTo(o.Vector)
}
func (v WeightedVector) Weight() float64 {
return v.weight
}