File size: 2,006 Bytes
ca7217f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 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
}
|