go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/rank.go (about) 1 package fu 2 3 import ( 4 "math" 5 "sort" 6 ) 7 8 type rankarr struct { 9 d []float32 10 n []int 11 } 12 13 func (a rankarr) Len() int { 14 return len(a.d) 15 } 16 func (a rankarr) Swap(i, j int) { 17 a.d[i], a.d[j] = a.d[j], a.d[i] 18 a.n[i], a.n[j] = a.n[j], a.n[i] 19 } 20 21 func (a rankarr) Less(i, j int) bool { 22 return a.d[i] < a.d[j] 23 } 24 25 func Rank(a []float32, first ...bool) []float32 { 26 r := make([]float32, len(a)) 27 n := make([]int, len(a)) 28 for i, v := range a { 29 r[i] = Round32(v, 4) 30 n[i] = i 31 } 32 sort.Stable(rankarr{r, n}) 33 for i := 0; i < len(r); { 34 j := i 35 for i++; i < len(r) && r[j] == r[i]; i++ { 36 } 37 x := float32(j) 38 if !Fnzb(first...) { 39 x = float32(i-j)/2 + x 40 } 41 for ; j < i+1 && j < len(r); j++ { 42 r[j] = x 43 } 44 } 45 rank := make([]float32, len(a)) 46 for i, j := range n { 47 rank[j] = r[i] 48 } 49 return rank 50 } 51 52 func RankPct(a []float32, first ...bool) []float32 { 53 rank := Rank(a, first...) 54 max := Maxr(float32(math.Inf(-1)), rank...) 55 for i, x := range rank { 56 rank[i] = x / max 57 } 58 return rank 59 }