-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
139 lines (127 loc) · 3.55 KB
/
util.go
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// +build cublas
package goFeature
import (
"math"
"math/rand"
"reflect"
"sort"
"time"
"unsafe"
)
func FeatureToFeatureValue1D(features ...Feature) (ret FeatureValue) {
for _, feature := range features {
ret = append(ret, feature.Value...)
}
return
}
func FeatureValueTranspose1D(precision int, features ...FeatureValue) (ret FeatureValue, err error) {
// little endian feature value
if len(features) == 0 {
return
}
if len(features[0])%precision != 0 {
return nil, ErrBadTransposeValue
}
col := len(features[0]) / precision
row := len(features)
ret = make(FeatureValue, col*row*precision)
for i := 0; i < col; i++ {
for j := 0; j < row; j++ {
copy(ret[(i*row+j)*precision:(i*row+j+1)*precision], features[j][i*precision:(i+1)*precision])
}
}
return
}
func TFeatureValue(value interface{}) (FeatureValue, error) {
switch value.(type) {
case FeatureValue:
return value.(FeatureValue), nil
case []byte:
return FeatureValue(value.([]byte)), nil
case []int16:
return *(*FeatureValue)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(&value.([]int16)[0])),
Len: len(value.([]int16)) * 2,
Cap: len(value.([]int16)) * 2,
})), nil
case []int32:
return *(*FeatureValue)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(&value.([]int32)[0])),
Len: len(value.([]int32)) * 4,
Cap: len(value.([]int32)) * 4,
})), nil
case []float32:
return *(*FeatureValue)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(&value.([]float32)[0])),
Len: len(value.([]float32)) * 4,
Cap: len(value.([]float32)) * 4,
})), nil
case []float64:
return *(*FeatureValue)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(&value.([]float64)[0])),
Len: len(value.([]float64)) * 8,
Cap: len(value.([]float64)) * 8,
})), nil
}
return nil, ErrInvalidBufferData
}
func MaxNFloat32(vector []float32, limit int) ([]int, []float32) {
type _result struct {
Value float32
Index int
}
var scores []_result
for k, v := range vector {
scores = append(scores, _result{Value: v, Index: k})
}
sort.Slice(scores, func(i, j int) bool { return scores[i].Value > scores[j].Value })
var index []int
var max []float32
for i := 0; i < limit && i < len(scores); i++ {
index = append(index, scores[i].Index)
max = append(max, scores[i].Value)
}
return index, max
}
func MaxNFeatureResult(vector []FeatureSearchResult, limit int) ([]int, []FeatureSearchResult) {
type _result struct {
Value FeatureSearchResult
Index int
}
var scores []_result
for k, v := range vector {
scores = append(scores, _result{Value: v, Index: k})
}
sort.Slice(scores, func(i, j int) bool { return scores[i].Value.Score > scores[j].Value.Score })
var index []int
var max []FeatureSearchResult
for i := 0; i < limit && i < len(scores); i++ {
index = append(index, scores[i].Index)
max = append(max, scores[i].Value)
}
return index, max
}
func GetRandomString(length int) string {
str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < length; i++ {
result = append(result, bytes[r.Intn(len(str))])
}
return string(result)
}
func NoramlizeFloat32(feature []float32) (ret []float32) {
var mode float32
for _, value := range feature {
mode += value * value
}
mode = float32(math.Pow(float64(mode), 0.5))
if mode == 0 {
return make([]float32, len(feature), len(feature))
}
for _, value := range feature {
ret = append(ret, value/mode)
}
return
}