ngt 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +35 -2
- data/lib/ngt/ffi.rb +4 -5
- data/lib/ngt/index.rb +31 -23
- data/lib/ngt/optimizer.rb +8 -2
- data/lib/ngt/version.rb +1 -1
- data/vendor/libngt.dylib +0 -0
- data/vendor/libngt.so +0 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d00cfd25aa3d93228994f1f490c27e5c7bd0566013c6d4af9c9ec22157cd5bf0
|
4
|
+
data.tar.gz: a33f524d222fc6b9c7733039217349e9897926b19854faff58f088a80bb55b58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e1431ab3453ce24ab8d3886fc4ce201cc48ec239eb8eb083bb72d9880d8bf554e2e45ce7252e207d7e7da7f10323023364ff1b33ca95ab6bd6795fdbf79e5c0
|
7
|
+
data.tar.gz: 3a932a1da2b75baac08ac477f9e92d1d6f203237f3b94e6962c749d906eb7c63a4a5f0162395f39db21734338ba147a10acb4210cb37d5397d024aef00f32795
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 0.2.4 (2020-03-09)
|
2
|
+
|
3
|
+
- Updated NGT to 1.9.1
|
4
|
+
- Added support for passing an index to optimizers
|
5
|
+
- Added `dimensions`, `distance_type`, `edge_size_for_creation`, `edge_size_for_search`, and `object_type` methods
|
6
|
+
|
1
7
|
## 0.2.3 (2020-03-08)
|
2
8
|
|
3
9
|
- Added `load` method
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ Add this line to your application’s Gemfile:
|
|
12
12
|
gem 'ngt'
|
13
13
|
```
|
14
14
|
|
15
|
-
NGT is not available for Windows
|
15
|
+
NGT is not available for Windows
|
16
16
|
|
17
17
|
## Getting Started
|
18
18
|
|
@@ -84,7 +84,8 @@ Optimize the index
|
|
84
84
|
|
85
85
|
```ruby
|
86
86
|
optimizer = Ngt::Optimizer.new(outgoing: 10, incoming: 120)
|
87
|
-
optimizer.
|
87
|
+
optimizer.adjust_search_coefficients(index)
|
88
|
+
optimizer.execute(index, new_path)
|
88
89
|
```
|
89
90
|
|
90
91
|
## Full Example
|
@@ -108,6 +109,38 @@ result.each do |res|
|
|
108
109
|
end
|
109
110
|
```
|
110
111
|
|
112
|
+
## Index Options
|
113
|
+
|
114
|
+
Defaults shown below
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
Ngt::Index.new(dimensions,
|
118
|
+
edge_size_for_creation: 10,
|
119
|
+
edge_size_for_search: 40,
|
120
|
+
object_type: :float, # :float, :integer
|
121
|
+
distance_type: :l2, # :l1, :l2, :hamming, :angle, :cosine, or :jaccard
|
122
|
+
path: nil
|
123
|
+
)
|
124
|
+
```
|
125
|
+
|
126
|
+
## Optimizer Options
|
127
|
+
|
128
|
+
Defaults shown below
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
Ngt::Optimizer.new(
|
132
|
+
outgoing: 10,
|
133
|
+
incoming: 120,
|
134
|
+
queries: 100,
|
135
|
+
low_accuracy_from: 0.3,
|
136
|
+
low_accuracy_to: 0.5,
|
137
|
+
high_accuracy_from: 0.8,
|
138
|
+
high_accuracy_to: 0.9,
|
139
|
+
gt_epsilon: 0.1,
|
140
|
+
merge: 0.2
|
141
|
+
)
|
142
|
+
```
|
143
|
+
|
111
144
|
## Data
|
112
145
|
|
113
146
|
Data can be an array of arrays
|
data/lib/ngt/ffi.rb
CHANGED
@@ -2,11 +2,7 @@ module Ngt
|
|
2
2
|
module FFI
|
3
3
|
extend ::FFI::Library
|
4
4
|
|
5
|
-
|
6
|
-
ffi_lib Ngt.ffi_lib
|
7
|
-
rescue LoadError => e
|
8
|
-
raise e
|
9
|
-
end
|
5
|
+
ffi_lib Ngt.ffi_lib
|
10
6
|
|
11
7
|
# https://github.com/yahoojapan/NGT/blob/master/lib/NGT/Capi.h
|
12
8
|
# keep same order
|
@@ -52,6 +48,9 @@ module Ngt
|
|
52
48
|
attach_function :ngt_get_object_as_integer, %i[pointer int pointer], :pointer
|
53
49
|
attach_function :ngt_destroy_property, %i[pointer], :void
|
54
50
|
attach_function :ngt_close_index, %i[pointer], :void
|
51
|
+
attach_function :ngt_get_property_edge_size_for_creation, %i[pointer pointer], :int16
|
52
|
+
attach_function :ngt_get_property_edge_size_for_search, %i[pointer pointer], :int16
|
53
|
+
attach_function :ngt_get_property_distance_type, %i[pointer pointer], :int32
|
55
54
|
attach_function :ngt_create_error_object, %i[], :pointer
|
56
55
|
attach_function :ngt_get_error_string, %i[pointer], :string
|
57
56
|
attach_function :ngt_destroy_error_object, %i[pointer], :void
|
data/lib/ngt/index.rb
CHANGED
@@ -2,6 +2,10 @@ module Ngt
|
|
2
2
|
class Index
|
3
3
|
include Utils
|
4
4
|
|
5
|
+
DISTANCE_TYPES = [:l1, :l2, :hamming, :angle, :cosine, :normalized_angle, :normalized_cosine, :jaccard]
|
6
|
+
|
7
|
+
attr_reader :dimensions, :distance_type, :edge_size_for_creation, :edge_size_for_search, :object_type, :path
|
8
|
+
|
5
9
|
def initialize(path)
|
6
10
|
@path = path
|
7
11
|
@error = FFI.ngt_create_error_object
|
@@ -10,10 +14,14 @@ module Ngt
|
|
10
14
|
property = ffi(:ngt_create_property)
|
11
15
|
ffi(:ngt_get_property, @index, property)
|
12
16
|
|
13
|
-
@
|
17
|
+
@dimensions = ffi(:ngt_get_property_dimension, property)
|
18
|
+
@distance_type = DISTANCE_TYPES[ffi(:ngt_get_property_distance_type, property)]
|
19
|
+
@edge_size_for_creation = ffi(:ngt_get_property_edge_size_for_creation, property)
|
20
|
+
@edge_size_for_search = ffi(:ngt_get_property_edge_size_for_search, property)
|
14
21
|
|
15
22
|
object_type = ffi(:ngt_get_property_object_type, property)
|
16
23
|
@float = FFI.ngt_is_property_object_type_float(object_type)
|
24
|
+
@object_type = @float ? :float : :integer
|
17
25
|
|
18
26
|
@object_space = ffi(:ngt_get_object_space, @index)
|
19
27
|
|
@@ -21,7 +29,7 @@ module Ngt
|
|
21
29
|
end
|
22
30
|
|
23
31
|
def insert(object)
|
24
|
-
ffi(:ngt_insert_index, @index, c_object(object.to_a), @
|
32
|
+
ffi(:ngt_insert_index, @index, c_object(object.to_a), @dimensions)
|
25
33
|
end
|
26
34
|
|
27
35
|
def batch_insert(objects, num_threads: 8)
|
@@ -53,10 +61,10 @@ module Ngt
|
|
53
61
|
def object(id)
|
54
62
|
if float?
|
55
63
|
res = ffi(:ngt_get_object_as_float, @object_space, id)
|
56
|
-
res.read_array_of_float(@
|
64
|
+
res.read_array_of_float(@dimensions)
|
57
65
|
else
|
58
66
|
res = ffi(:ngt_get_object_as_integer, @object_space, id)
|
59
|
-
res.read_array_of_uint8(@
|
67
|
+
res.read_array_of_uint8(@dimensions)
|
60
68
|
end
|
61
69
|
end
|
62
70
|
|
@@ -67,7 +75,7 @@ module Ngt
|
|
67
75
|
def search(query, size: 20, epsilon: 0.1, radius: nil)
|
68
76
|
radius ||= -1.0
|
69
77
|
results = ffi(:ngt_create_empty_results)
|
70
|
-
ffi(:ngt_search_index, @index, c_object(query.to_a), @
|
78
|
+
ffi(:ngt_search_index, @index, c_object(query.to_a), @dimensions, size, epsilon, radius, results)
|
71
79
|
result_size = ffi(:ngt_get_result_size, results)
|
72
80
|
ret = []
|
73
81
|
result_size.times do |i|
|
@@ -90,47 +98,47 @@ module Ngt
|
|
90
98
|
FFI.ngt_close_index(@index)
|
91
99
|
end
|
92
100
|
|
93
|
-
def self.new(
|
94
|
-
edge_size_for_search: 40, object_type:
|
101
|
+
def self.new(dimensions, path: nil, edge_size_for_creation: 10,
|
102
|
+
edge_size_for_search: 40, object_type: :float, distance_type: :l2)
|
95
103
|
|
96
104
|
# called from load
|
97
|
-
return super(path) if path &&
|
105
|
+
return super(path) if path && dimensions.nil?
|
98
106
|
|
99
107
|
# TODO remove in 0.3.0
|
100
|
-
create =
|
108
|
+
create = dimensions.is_a?(Integer) || path
|
101
109
|
unless create
|
102
110
|
warn "[ngt] Passing a path to new is deprecated - use load instead"
|
103
|
-
return super(
|
111
|
+
return super(dimensions)
|
104
112
|
end
|
105
113
|
|
106
114
|
path ||= Dir.mktmpdir
|
107
115
|
error = FFI.ngt_create_error_object
|
108
116
|
property = ffi(:ngt_create_property, error)
|
109
|
-
ffi(:ngt_set_property_dimension, property,
|
117
|
+
ffi(:ngt_set_property_dimension, property, dimensions, error)
|
110
118
|
ffi(:ngt_set_property_edge_size_for_creation, property, edge_size_for_creation, error)
|
111
119
|
ffi(:ngt_set_property_edge_size_for_search, property, edge_size_for_search, error)
|
112
120
|
|
113
|
-
case object_type.to_s
|
114
|
-
when "
|
121
|
+
case object_type.to_s.downcase
|
122
|
+
when "float"
|
115
123
|
ffi(:ngt_set_property_object_type_float, property, error)
|
116
|
-
when "
|
124
|
+
when "integer"
|
117
125
|
ffi(:ngt_set_property_object_type_integer, property, error)
|
118
126
|
else
|
119
127
|
raise ArgumentError, "Unknown object type: #{object_type}"
|
120
128
|
end
|
121
129
|
|
122
|
-
case distance_type.to_s
|
123
|
-
when "
|
130
|
+
case distance_type.to_s.downcase
|
131
|
+
when "l1"
|
124
132
|
ffi(:ngt_set_property_distance_type_l1, property, error)
|
125
|
-
when "
|
133
|
+
when "l2"
|
126
134
|
ffi(:ngt_set_property_distance_type_l2, property, error)
|
127
|
-
when "
|
135
|
+
when "angle"
|
128
136
|
ffi(:ngt_set_property_distance_type_angle, property, error)
|
129
|
-
when "
|
137
|
+
when "hamming"
|
130
138
|
ffi(:ngt_set_property_distance_type_hamming, property, error)
|
131
|
-
when "
|
139
|
+
when "jaccard"
|
132
140
|
ffi(:ngt_set_property_distance_type_jaccard, property, error)
|
133
|
-
when "
|
141
|
+
when "cosine"
|
134
142
|
ffi(:ngt_set_property_distance_type_cosine, property, error)
|
135
143
|
else
|
136
144
|
raise ArgumentError, "Unknown distance type: #{distance_type}"
|
@@ -151,9 +159,9 @@ module Ngt
|
|
151
159
|
new(nil, path: path)
|
152
160
|
end
|
153
161
|
|
154
|
-
def self.create(path,
|
162
|
+
def self.create(path, dimensions, **options)
|
155
163
|
warn "[ngt] create is deprecated - use new instead"
|
156
|
-
new(
|
164
|
+
new(dimensions, path: path, **options)
|
157
165
|
end
|
158
166
|
|
159
167
|
# private
|
data/lib/ngt/optimizer.rb
CHANGED
@@ -15,11 +15,11 @@ module Ngt
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def execute(in_index_path, out_index_path)
|
18
|
-
ffi(:ngt_optimizer_execute, @optimizer, in_index_path, out_index_path)
|
18
|
+
ffi(:ngt_optimizer_execute, @optimizer, path(in_index_path), out_index_path)
|
19
19
|
end
|
20
20
|
|
21
21
|
def adjust_search_coefficients(index_path)
|
22
|
-
ffi(:ngt_optimizer_adjust_search_coefficients, @optimizer, index_path)
|
22
|
+
ffi(:ngt_optimizer_adjust_search_coefficients, @optimizer, path(index_path))
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.finalize(optimizer, error)
|
@@ -29,5 +29,11 @@ module Ngt
|
|
29
29
|
FFI.ngt_destroy_error_object(error)
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def path(obj)
|
36
|
+
obj.is_a?(Ngt::Index) ? obj.path : obj
|
37
|
+
end
|
32
38
|
end
|
33
39
|
end
|
data/lib/ngt/version.rb
CHANGED
data/vendor/libngt.dylib
CHANGED
Binary file
|
data/vendor/libngt.so
CHANGED
Binary file
|