ngt 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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