Class: Flann::Index
- Inherits:
-
Object
- Object
- Flann::Index
- Defined in:
- lib/flann/index.rb
Instance Attribute Summary collapse
-
#dataset ⇒ Object
Returns the value of attribute dataset.
-
#dtype ⇒ Object
readonly
Returns the value of attribute dtype.
-
#index_ptr ⇒ Object
readonly
Returns the value of attribute index_ptr.
-
#parameters ⇒ Object
readonly
Returns the value of attribute parameters.
-
#parameters_ptr ⇒ Object
readonly
Returns the value of attribute parameters_ptr.
Instance Method Summary collapse
-
#build! ⇒ Object
Build an index.
-
#free!(parameters = {}) ⇒ Object
Free an index.
-
#initialize(index_dataset = nil, dtype: :float64, parameters: Flann::Parameters::DEFAULT) {|@parameters| ... } ⇒ Index
constructor
Constructor takes a block where we set each of the parameters.
-
#load!(filename) ⇒ Object
Load an index from a file (with the dataset already known!).
-
#nearest_neighbors(testset, k, parameters = {}) ⇒ Object
Get the nearest neighbors based on this index.
-
#radius_search(query, radius, max_k = nil, parameters = {}) ⇒ Object
Perform a radius search on a single query point.
-
#save(filename) ⇒ Object
Save an index to a file (without the dataset).
Constructor Details
#initialize(index_dataset = nil, dtype: :float64, parameters: Flann::Parameters::DEFAULT) {|@parameters| ... } ⇒ Index
Constructor takes a block where we set each of the parameters. We need to be careful to do this since we’re using the C API and not C++; so everything important needs to be initialized or there could be a segfault. For reasonable default definitions, see:
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/flann/index.rb', line 48 def initialize index_dataset = nil, dtype: :float64, parameters: Flann::Parameters::DEFAULT @dataset = index_dataset #require 'pry' #binding.pry if @dataset.nil? @dtype = (!index_dataset.nil? && index_dataset.is_a?(NMatrix)) ? index_dataset.dtype : dtype @index_ptr = nil @parameters_ptr, @parameters = Flann::handle_parameters(parameters) yield @parameters if block_given? end |
Instance Attribute Details
#dataset ⇒ Object
Returns the value of attribute dataset.
59 60 61 |
# File 'lib/flann/index.rb', line 59 def dataset @dataset end |
#dtype ⇒ Object (readonly)
Returns the value of attribute dtype.
59 60 61 |
# File 'lib/flann/index.rb', line 59 def dtype @dtype end |
#index_ptr ⇒ Object (readonly)
Returns the value of attribute index_ptr.
59 60 61 |
# File 'lib/flann/index.rb', line 59 def index_ptr @index_ptr end |
#parameters ⇒ Object (readonly)
Returns the value of attribute parameters.
59 60 61 |
# File 'lib/flann/index.rb', line 59 def parameters @parameters end |
#parameters_ptr ⇒ Object (readonly)
Returns the value of attribute parameters_ptr.
59 60 61 |
# File 'lib/flann/index.rb', line 59 def parameters_ptr @parameters_ptr end |
Instance Method Details
#build! ⇒ Object
Build an index
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/flann/index.rb', line 68 def build! raise("no dataset specified") if dataset.nil? c_type = Flann::dtype_to_c(dtype) c_method = "flann_build_index_#{c_type}".to_sym speedup_float_ptr = FFI::MemoryPointer.new(:float) @index_ptr = Flann.send(c_method, FFI::Pointer.new_from_nmatrix(dataset), dataset.shape[0], dataset.shape[1], speedup_float_ptr, parameters_ptr) if index_ptr.address == 0 require 'pry' binding.pry raise("failed to allocate index_ptr") end # Return the speedup speedup_float_ptr.read_float end |
#free!(parameters = {}) ⇒ Object
Free an index
152 153 154 155 156 157 158 159 |
# File 'lib/flann/index.rb', line 152 def free! parameters = {} parameters = Parameters.new(Flann::Parameters::DEFAULT.merge(parameters)) c_method = "flann_free_index_#{Flann::dtype_to_c(dtype)}".to_sym parameters_ptr, parameters = Flann::handle_parameters(parameters) Flann.send(c_method, index_ptr, parameters_ptr) @index_ptr = nil self end |
#load!(filename) ⇒ Object
Load an index from a file (with the dataset already known!).
FIXME: This needs to free the previous dataset first.
144 145 146 147 148 149 |
# File 'lib/flann/index.rb', line 144 def load! filename c_method = "flann_load_index_#{Flann::dtype_to_c(dtype)}".to_sym @index_ptr = Flann.send(c_method, filename, FFI::Pointer.new_from_nmatrix(dataset), dataset.shape[0], dataset.shape[1]) self end |
#nearest_neighbors(testset, k, parameters = {}) ⇒ Object
Get the nearest neighbors based on this index. Forces a build of the index if one hasn’t been done yet.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/flann/index.rb', line 86 def nearest_neighbors testset, k, parameters = {} parameters = Parameters.new(Flann::Parameters::DEFAULT.merge(parameters)) self.build! if index_ptr.nil? parameters_ptr, parameters = Flann::handle_parameters(parameters) result_size = testset.shape[0] * k c_type = Flann::dtype_to_c(dataset.dtype) c_method = "flann_find_nearest_neighbors_index_#{c_type}".to_sym indices_int_ptr, distances_t_ptr = Flann::allocate_results_space(result_size, c_type) Flann.send c_method, index_ptr, FFI::Pointer.new_from_nmatrix(testset), testset.shape[0], indices_int_ptr, distances_t_ptr, k, parameters_ptr [indices_int_ptr.read_array_of_int(result_size), c_type == :double ? distances_t_ptr.read_array_of_double(result_size) : distances_t_ptr.read_array_of_float(result_size)] end |
#radius_search(query, radius, max_k = nil, parameters = {}) ⇒ Object
Perform a radius search on a single query point
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/flann/index.rb', line 111 def radius_search query, radius, max_k=nil, parameters = {} max_k ||= dataset.shape[0] parameters = Parameters.new(Flann::Parameters::DEFAULT.merge(parameters)) self.build! if index_ptr.nil? parameters_ptr, parameters = Flann::handle_parameters(parameters) c_type = Flann::dtype_to_c(dataset.dtype) c_method = "flann_radius_search_#{c_type}".to_sym indices_int_ptr, distances_t_ptr = Flann::allocate_results_space(max_k, c_type) Flann.send(c_method, index_ptr, FFI::Pointer.new_from_nmatrix(query), indices_int_ptr, distances_t_ptr, max_k, radius, parameters_ptr) # Return results: two arrays, one of indices and one of distances. indices = indices_int_ptr.read_array_of_int(max_k) distances = c_type == :double ? distances_t_ptr.read_array_of_double(max_k) : distances_t_ptr.read_array_of_float(max_k) # Stop where indices == -1 cutoff = indices.find_index(-1) cutoff.nil? ? [indices, distances] : [indices[0...cutoff], distances[0...cutoff]] end |
#save(filename) ⇒ Object
Save an index to a file (without the dataset).
134 135 136 137 138 139 |
# File 'lib/flann/index.rb', line 134 def save filename raise(IOError, "Cannot write an unbuilt index") if index_ptr.nil? # FIXME: This should probably have its own exception type. c_method = "flann_save_index_#{Flann::dtype_to_c(dtype)}".to_sym Flann.send(c_method, index_ptr, filename) self end |