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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bff3db4fe839a13d6c1d0c5c959c4e42bf738670c69b0fd4792a1209c7e7165f
4
- data.tar.gz: ed3c9d563903be2c8d550bccbeb7efd40cb78b1f5d78e8d6846e9dc4063f78f6
3
+ metadata.gz: d00cfd25aa3d93228994f1f490c27e5c7bd0566013c6d4af9c9ec22157cd5bf0
4
+ data.tar.gz: a33f524d222fc6b9c7733039217349e9897926b19854faff58f088a80bb55b58
5
5
  SHA512:
6
- metadata.gz: 7e85cd285bac398611fcae5d3bae99f9b13422b1dab068387f787d91b9137eb7ffdf6b96e1d64a5719ce6eef8fef8c2a2e7f8553893ee535f8f9f09ca55ca9b3
7
- data.tar.gz: 9645e1859e2c65d88688b23006a94bb272b8ad19c6df64a43427c8842d1e49b26fe3431524c02c74eefacfa0c20360760fb6c31691583190d1d323efb688a7ed
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 yet
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.execute(path, new_path)
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
- begin
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
- @dimension = ffi(:ngt_get_property_dimension, property)
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), @dimension)
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(@dimension)
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(@dimension)
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), @dimension, size, epsilon, radius, results)
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(dimension, path: nil, edge_size_for_creation: 10,
94
- edge_size_for_search: 40, object_type: "Float", distance_type: "L2")
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 && dimension.nil?
105
+ return super(path) if path && dimensions.nil?
98
106
 
99
107
  # TODO remove in 0.3.0
100
- create = dimension.is_a?(Integer) || path
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(dimension)
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, dimension, error)
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 "Float", "float"
121
+ case object_type.to_s.downcase
122
+ when "float"
115
123
  ffi(:ngt_set_property_object_type_float, property, error)
116
- when "Integer", "integer"
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 "L1"
130
+ case distance_type.to_s.downcase
131
+ when "l1"
124
132
  ffi(:ngt_set_property_distance_type_l1, property, error)
125
- when "L2"
133
+ when "l2"
126
134
  ffi(:ngt_set_property_distance_type_l2, property, error)
127
- when "Angle"
135
+ when "angle"
128
136
  ffi(:ngt_set_property_distance_type_angle, property, error)
129
- when "Hamming"
137
+ when "hamming"
130
138
  ffi(:ngt_set_property_distance_type_hamming, property, error)
131
- when "Jaccard"
139
+ when "jaccard"
132
140
  ffi(:ngt_set_property_distance_type_jaccard, property, error)
133
- when "Cosine"
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, dimension, **options)
162
+ def self.create(path, dimensions, **options)
155
163
  warn "[ngt] create is deprecated - use new instead"
156
- new(dimension, path: path, **options)
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
@@ -1,3 +1,3 @@
1
1
  module Ngt
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
data/vendor/libngt.dylib CHANGED
Binary file
data/vendor/libngt.so CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ngt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane