flann 1.8.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +36 -0
- data/LICENSE.txt +10 -0
- data/Manifest.txt +12 -0
- data/Rakefile +111 -0
- data/flann.gemspec +59 -0
- data/lib/flann.rb +293 -0
- data/lib/flann/index.rb +162 -0
- data/lib/flann/version.rb +37 -0
- data/spec/flann_spec.rb +104 -0
- data/spec/index_spec.rb +114 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/test.dataset +65536 -0
- metadata +144 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eda82086ba025d33f5d04c795c317d6d715b3f95
|
4
|
+
data.tar.gz: 6ac2848e7d00daaa0251e75dca7b820e8620b5f1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3ed41bef247412d4e8c684a4bb99a23a5612d683d622738329784368b38b0e9b075696c98e225d33cda748d0cb191162e6f6dd5e27ef704553c2bde2b0648fb2
|
7
|
+
data.tar.gz: 76ea17138b788c049c47fd998bf53f853d43ececb87e4afdfb48301cc7b1ec52f11b3421e328d0e9612b043c1091404ff1c872985144e86b197340c9d879b61b
|
data/Gemfile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright 2014 John O. Woods (john.o.woods@gmail.com), West Virginia
|
2
|
+
# University's Applied Space Exploration Lab, and West Virginia Robotic
|
3
|
+
# Technology Center. All rights reserved.
|
4
|
+
#
|
5
|
+
# THE BSD LICENSE
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions
|
9
|
+
# are met:
|
10
|
+
#
|
11
|
+
# 1. Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
28
|
+
source 'https://rubygems.org'
|
29
|
+
gemspec
|
30
|
+
|
31
|
+
gem "ffi"
|
32
|
+
gem "nmatrix"
|
33
|
+
|
34
|
+
group :development do
|
35
|
+
|
36
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Copyright (c) 2014, John Woods, WVU Applied Space Exploration Laboratory, and West Virginia Robotic Technology Center.
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
7
|
+
|
8
|
+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
9
|
+
|
10
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Manifest.txt
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# Copyright 2014 John O. Woods (john.o.woods@gmail.com), West Virginia
|
2
|
+
# University's Applied Space Exploration Lab, and West Virginia Robotic
|
3
|
+
# Technology Center. All rights reserved.
|
4
|
+
#
|
5
|
+
# THE BSD LICENSE
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions
|
9
|
+
# are met:
|
10
|
+
#
|
11
|
+
# 1. Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
28
|
+
require 'rubygems'
|
29
|
+
require 'rubygems/package_task'
|
30
|
+
require 'bundler'
|
31
|
+
begin
|
32
|
+
Bundler.setup(:default, :development)
|
33
|
+
rescue
|
34
|
+
$stderr.puts e.message
|
35
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
36
|
+
exit e.status_code
|
37
|
+
end
|
38
|
+
|
39
|
+
require 'rake'
|
40
|
+
|
41
|
+
gemspec = eval(IO.read("flann.gemspec"))
|
42
|
+
|
43
|
+
Gem::PackageTask.new(gemspec).define
|
44
|
+
|
45
|
+
desc "install the gem locally"
|
46
|
+
task :install => [:package] do
|
47
|
+
sh %{gem install pkg/flann-#{NMatrix::VERSION}.gem}
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
require 'rspec/core/rake_task'
|
52
|
+
require 'rspec/core'
|
53
|
+
require 'rspec/core/rake_task'
|
54
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
55
|
+
spec.pattern = FileList['spec/**/*_spec.rb'].uniq
|
56
|
+
end
|
57
|
+
|
58
|
+
task :console do |task|
|
59
|
+
cmd = [ 'irb', "-r './lib/flann.rb'" ]
|
60
|
+
run *cmd
|
61
|
+
end
|
62
|
+
|
63
|
+
task :pry do |task|
|
64
|
+
cmd = [ 'pry', "-r './lib/flann.rb'" ]
|
65
|
+
run *cmd
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
task :default => :spec
|
70
|
+
|
71
|
+
def run *cmd
|
72
|
+
sh(cmd.join(" "))
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
desc "Check the manifest for correctness"
|
77
|
+
task :check_manifest do |task|
|
78
|
+
manifest_files = File.read("Manifest.txt").split
|
79
|
+
|
80
|
+
git_files = `git ls-files |grep -v 'spec/'`.split
|
81
|
+
ignore_files = %w{.gitignore .rspec}
|
82
|
+
|
83
|
+
possible_files = git_files - ignore_files
|
84
|
+
|
85
|
+
missing_files = possible_files - manifest_files
|
86
|
+
extra_files = manifest_files - possible_files
|
87
|
+
|
88
|
+
unless missing_files.empty?
|
89
|
+
STDERR.puts "The following files are in the git repo but not the Manifest:"
|
90
|
+
missing_files.each { |f| STDERR.puts " -- #{f}"}
|
91
|
+
end
|
92
|
+
|
93
|
+
unless extra_files.empty?
|
94
|
+
STDERR.puts "The following files are in the Manifest but may not be necessary:"
|
95
|
+
extra_files.each { |f| STDERR.puts " -- #{f}"}
|
96
|
+
end
|
97
|
+
|
98
|
+
if extra_files.empty? && missing_files.empty?
|
99
|
+
STDERR.puts "Manifest looks good!"
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
require "rdoc/task"
|
106
|
+
RDoc::Task.new do |rdoc|
|
107
|
+
rdoc.main = "README.rdoc"
|
108
|
+
rdoc.rdoc_files.include(%w{README.rdoc History.txt LICENSE.txt lib/flann/**/*.rb})
|
109
|
+
end
|
110
|
+
|
111
|
+
# vim: syntax=ruby
|
data/flann.gemspec
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright 2014 John O. Woods (john.o.woods@gmail.com), West Virginia
|
2
|
+
# University's Applied Space Exploration Lab, and West Virginia Robotic
|
3
|
+
# Technology Center. All rights reserved.
|
4
|
+
#
|
5
|
+
# THE BSD LICENSE
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions
|
9
|
+
# are met:
|
10
|
+
#
|
11
|
+
# 1. Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
28
|
+
lib = File.expand_path('../lib/', __FILE__)
|
29
|
+
$:.unshift lib unless $:.include?(lib)
|
30
|
+
|
31
|
+
require 'flann/version'
|
32
|
+
|
33
|
+
Gem::Specification.new do |gem|
|
34
|
+
gem.name = "flann"
|
35
|
+
gem.version = Flann::VERSION::STRING
|
36
|
+
gem.summary = "Ruby interface for FLANN, approximate nearest neighbors methods in C"
|
37
|
+
gem.description = "Ruby interface for FLANN, approximate nearest neighbors methods in C"
|
38
|
+
gem.homepage = 'http://www.cs.ubc.ca/research/flann/'
|
39
|
+
gem.authors = ['John Woods']
|
40
|
+
gem.email = ['john.o.woods@gmail.com']
|
41
|
+
gem.license = 'BSD 2-clause'
|
42
|
+
#gem.post_install_message = <<-EOF
|
43
|
+
#EOF
|
44
|
+
|
45
|
+
gem.files = `git ls-files`.split("\n")
|
46
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
47
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
48
|
+
gem.require_paths = ["lib"]
|
49
|
+
|
50
|
+
gem.required_ruby_version = '>= 2.0'
|
51
|
+
|
52
|
+
gem.add_dependency 'rdoc'
|
53
|
+
gem.add_development_dependency 'rake'
|
54
|
+
gem.add_development_dependency 'bundler'
|
55
|
+
gem.add_development_dependency 'rspec'
|
56
|
+
gem.add_development_dependency 'rspec-longrun'
|
57
|
+
gem.add_development_dependency 'pry'
|
58
|
+
end
|
59
|
+
|
data/lib/flann.rb
ADDED
@@ -0,0 +1,293 @@
|
|
1
|
+
# Copyright 2014 John O. Woods (john.o.woods@gmail.com), West Virginia
|
2
|
+
# University's Applied Space Exploration Lab, and West Virginia Robotic
|
3
|
+
# Technology Center. All rights reserved.
|
4
|
+
#
|
5
|
+
# THE BSD LICENSE
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions
|
9
|
+
# are met:
|
10
|
+
#
|
11
|
+
# 1. Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
28
|
+
require 'ffi'
|
29
|
+
require 'nmatrix'
|
30
|
+
|
31
|
+
require_relative "flann/version.rb"
|
32
|
+
require_relative "flann/index.rb"
|
33
|
+
|
34
|
+
|
35
|
+
module Flann
|
36
|
+
extend FFI::Library
|
37
|
+
ffi_lib "libflann"
|
38
|
+
|
39
|
+
# Declare enumerators
|
40
|
+
Algorithm = enum(:algorithm, [:linear, :kdtree, :kmeans, :composite, :kdtree_single, :hierarchical, :lsh, :kdtree_cuda, :saved, 254, :autotuned, 255])
|
41
|
+
CentersInit = enum(:centers_init, [:random, :gonzales, :kmeanspp])
|
42
|
+
LogLevel = enum(:log_level, [:none, :fatal, :error, :warn, :info, :debug])
|
43
|
+
|
44
|
+
# Note that Hamming and beyond are not supported in the C API. We include them here just in case of future improvements.
|
45
|
+
DistanceType = enum(:distance_type, [:undefined, :euclidean, :l2, :manhattan, :l1, :minkowski, :max, :hist_intersect, :hellinger, :chi_square, :kullback_leibler, :hamming, :hamming_lut, :hamming_popcnt, :l2_simple])
|
46
|
+
|
47
|
+
# For NMatrix compatibility
|
48
|
+
typedef :float, :float32
|
49
|
+
typedef :double, :float64
|
50
|
+
typedef :char, :byte
|
51
|
+
typedef :pointer, :index_params_ptr
|
52
|
+
typedef :pointer, :index_ptr
|
53
|
+
|
54
|
+
|
55
|
+
class InitializableStruct < FFI::Struct
|
56
|
+
def initialize pointer=nil, *layout, &block
|
57
|
+
if pointer.respond_to?(:each_pair)
|
58
|
+
options = pointer
|
59
|
+
pointer = nil
|
60
|
+
else
|
61
|
+
options
|
62
|
+
end
|
63
|
+
|
64
|
+
super(pointer, *layout, &block)
|
65
|
+
|
66
|
+
if defined?(self.class::DEFAULTS)
|
67
|
+
options = self.class::DEFAULTS.merge(options)
|
68
|
+
end
|
69
|
+
|
70
|
+
options.each_pair do |key, value|
|
71
|
+
self[key] = value
|
72
|
+
end unless options.nil?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# A nearest neighbor search index for a given dataset.
|
78
|
+
class Parameters < InitializableStruct
|
79
|
+
layout :algorithm, Flann::Algorithm, # The algorithm to use (linear, kdtree, kmeans, composite, kdtree_single, saved, autotuned)
|
80
|
+
:checks, :int, # How many leaves (features) to use (for kdtree)
|
81
|
+
:eps, :float, # eps parameter for eps-knn search
|
82
|
+
:sorted, :int, # indicates if results returned by radius search should be sorted or not
|
83
|
+
:max_neighbors, :int, # limits the maximum number of neighbors returned
|
84
|
+
:cores, :int, # number of parallel cores to use for searching
|
85
|
+
|
86
|
+
:trees, :int, # Number of randomized trees to use (for kdtree)
|
87
|
+
:leaf_max_size, :int, # ?
|
88
|
+
|
89
|
+
:branching, :int, # Branching factor (for kmeans tree)
|
90
|
+
:iterations, :int, # Max iterations to perform in one kmeans clustering (kmeans tree)
|
91
|
+
:centers_init, Flann::CentersInit, # Algorithm used (random, gonzales, kmeanspp)
|
92
|
+
:cluster_boundary_index, :float, # Cluster boundary index. Used when searching the kmeans tree
|
93
|
+
|
94
|
+
:target_precision, :float, # Precision desired (used for auto-tuning, -1 otherwise)
|
95
|
+
:build_weight, :float, # Build tree time weighting factor
|
96
|
+
:memory_weight, :float, # Index memory weighting factor
|
97
|
+
:sample_fraction, :float, # What fraction of the dataset to use for autotuning
|
98
|
+
|
99
|
+
:table_number, :uint, # The number of hash tables to use
|
100
|
+
:key_size, :uint, # The length of the key to use in the hash tables
|
101
|
+
:multi_probe_level, :uint, # Number of levels to use in multi-probe LSH, 0 for standard LSH
|
102
|
+
|
103
|
+
:log_level, Flann::LogLevel, # Determines the verbosity of each flann function
|
104
|
+
:random_seed, :long # Random seed to use
|
105
|
+
|
106
|
+
DEFAULT = {algorithm: :kdtree,
|
107
|
+
checks: 32, eps: 0.0,
|
108
|
+
sorted: 1, max_neighbors: -1, cores: 0,
|
109
|
+
trees: 1, leaf_max_size: 4,
|
110
|
+
branching: 32, iterations: 5,
|
111
|
+
centers_init: :random,
|
112
|
+
cluster_boundary_index: 0.5,
|
113
|
+
target_precision: 0.9,
|
114
|
+
build_weight: 0.01,
|
115
|
+
memory_weight: 0.0,
|
116
|
+
sample_fraction: 0.1,
|
117
|
+
table_number: 12,
|
118
|
+
key_size: 20,
|
119
|
+
multi_probe_level: 2,
|
120
|
+
log_level: :warn, random_seed: -1}
|
121
|
+
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
class << self
|
126
|
+
|
127
|
+
|
128
|
+
DTYPE_TO_C = {:float32 => :float, :float64 => :double, :int32 => :int, :byte => :byte, :int8 => :byte}
|
129
|
+
|
130
|
+
def dtype_to_c d #:nodoc:
|
131
|
+
return DTYPE_TO_C[d] if DTYPE_TO_C.has_key?(d)
|
132
|
+
raise(NMatrix::DataTypeError, "FLANN does not support this dtype")
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# Allocates index space and distance space for storing results from various searches. For a k-nearest neighbors
|
137
|
+
# search, for example, you want trows (the number of rows in the testset) times k (the number of nearest neighbors
|
138
|
+
# being searched for).
|
139
|
+
#
|
140
|
+
# Note that c_type will produce float for everything except double, which produces double.
|
141
|
+
def allocate_results_space result_size, c_type #:nodoc:
|
142
|
+
[FFI::MemoryPointer.new(:int, result_size), FFI::MemoryPointer.new(c_type == :double ? :double : :float, result_size)]
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
# Don't know if these will be a hash, a static struct, or a pointer to a struct. Return the pointer and the struct.
|
147
|
+
def handle_parameters parameters #:nodoc:
|
148
|
+
parameters ||= Parameters::DEFAULT unless block_given?
|
149
|
+
|
150
|
+
if parameters.is_a?(FFI::MemoryPointer) # User supplies us with the necessary parameters already in the correct form.
|
151
|
+
c_parameters_ptr = parameters
|
152
|
+
c_parameters = Flann::Parameters.new(c_parameters_ptr)
|
153
|
+
elsif parameters.is_a?(Flann::Parameters)
|
154
|
+
c_parameters = parameters
|
155
|
+
c_parameters_ptr = parameters.pointer
|
156
|
+
else
|
157
|
+
# Set the old fasioned way
|
158
|
+
c_parameters_ptr = FFI::MemoryPointer.new(Flann::Parameters.size)
|
159
|
+
c_parameters = Flann::Parameters.new(c_parameters_ptr)
|
160
|
+
if parameters.is_a?(Hash)
|
161
|
+
parameters.each_pair do |key, value|
|
162
|
+
c_parameters[key] = value
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# There may also be a block.
|
168
|
+
yield c_parameters if block_given?
|
169
|
+
|
170
|
+
[c_parameters_ptr, c_parameters]
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
# Find the k nearest neighbors.
|
175
|
+
#
|
176
|
+
# If no index parameters are given, FLANN_Parameters::DEFAULT are used. A block is accepted as well.
|
177
|
+
def nearest_neighbors dataset, testset, k, parameters = {}
|
178
|
+
parameters = Parameters.new(Flann::Parameters::DEFAULT.merge(parameters))
|
179
|
+
# Get a pointer and a struct regardless of how the arguments are supplied.
|
180
|
+
parameters_ptr, parameters = handle_parameters(parameters)
|
181
|
+
result_size = testset.shape[0] * k
|
182
|
+
|
183
|
+
c_type = Flann::dtype_to_c(dataset.dtype)
|
184
|
+
c_method = "flann_find_nearest_neighbors_#{c_type}".to_sym
|
185
|
+
indices_int_ptr, distances_t_ptr = allocate_results_space(result_size, c_type)
|
186
|
+
|
187
|
+
# dataset, rows, cols, testset, trows, indices, dists, nn, flann_params
|
188
|
+
Flann.send c_method, FFI::Pointer.new_from_nmatrix(dataset), dataset.shape[0], dataset.shape[1],
|
189
|
+
FFI::Pointer.new_from_nmatrix(testset), testset.shape[0],
|
190
|
+
indices_int_ptr, distances_t_ptr, k, parameters_ptr
|
191
|
+
|
192
|
+
# Return results: two arrays, one of indices and one of distances.
|
193
|
+
[indices_int_ptr.read_array_of_int(result_size),
|
194
|
+
c_type == :double ? distances_t_ptr.read_array_of_double(result_size) : distances_t_ptr.read_array_of_float(result_size)]
|
195
|
+
end
|
196
|
+
alias :nn :nearest_neighbors
|
197
|
+
|
198
|
+
# Set the distance function to use when computing distances between data points.
|
199
|
+
def set_distance_type! distance_function
|
200
|
+
Flann.send(:flann_set_distance_type, distance_function, get_distance_order)
|
201
|
+
self
|
202
|
+
end
|
203
|
+
alias :set_distance_type_and_order! :set_distance_type!
|
204
|
+
|
205
|
+
# Get the distance type and order
|
206
|
+
def get_distance_type_and_order
|
207
|
+
[Flann.flann_get_distance_type, Flann.flann_get_distance_order]
|
208
|
+
end
|
209
|
+
def get_distance_type
|
210
|
+
Flann.flann_get_distance_type
|
211
|
+
end
|
212
|
+
def get_distance_order
|
213
|
+
Flann.flann_get_distance_order
|
214
|
+
end
|
215
|
+
alias :distance_type :get_distance_type
|
216
|
+
alias :distance_order :get_distance_order
|
217
|
+
|
218
|
+
|
219
|
+
# Perform hierarchical clustering of a set of points.
|
220
|
+
#
|
221
|
+
# Arguments:
|
222
|
+
# * dataset: NMatrix of points
|
223
|
+
# * parameters:
|
224
|
+
def cluster dataset, clusters, parameters = {}
|
225
|
+
parameters = Parameters.new(Flann::Parameters::DEFAULT.merge(parameters))
|
226
|
+
c_method = "flann_compute_cluster_centers_#{Flann::dtype_to_c(dataset.dtype)}".to_sym
|
227
|
+
|
228
|
+
result = dataset.clone_structure
|
229
|
+
parameters_ptr, parameters = handle_parameters(parameters)
|
230
|
+
|
231
|
+
#err_code =
|
232
|
+
Flann.send(c_method, FFI::Pointer.new_from_nmatrix(dataset), dataset.shape[0], dataset.shape[1], clusters, FFI::Pointer.new_from_nmatrix(result), parameters_ptr)
|
233
|
+
#raise("unknown error in cluster") if err_code < 0
|
234
|
+
|
235
|
+
result
|
236
|
+
end
|
237
|
+
alias :compute_cluster_centers :cluster
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
protected
|
242
|
+
|
243
|
+
# byte: unsigned char*dataset, int rows, int cols, float* speedup, FLANNParameters* flann_params
|
244
|
+
# only thing that changes is the pointer type for the first arg.
|
245
|
+
attach_function :flann_build_index_byte, [:pointer, :int, :int, :pointer, :index_params_ptr], :index_ptr
|
246
|
+
attach_function :flann_build_index_int, [:pointer, :int, :int, :pointer, :index_params_ptr], :index_ptr
|
247
|
+
attach_function :flann_build_index_float, [:pointer, :int, :int, :pointer, :index_params_ptr], :index_ptr
|
248
|
+
attach_function :flann_build_index_double, [:pointer, :int, :int, :pointer, :index_params_ptr], :index_ptr
|
249
|
+
|
250
|
+
# index, testset, trows, indices, dists, nn, flann_params
|
251
|
+
attach_function :flann_find_nearest_neighbors_index_byte, [:index_ptr, :pointer, :int, :pointer, :pointer, :int, :index_params_ptr], :int
|
252
|
+
attach_function :flann_find_nearest_neighbors_index_int, [:index_ptr, :pointer, :int, :pointer, :pointer, :int, :index_params_ptr], :int
|
253
|
+
attach_function :flann_find_nearest_neighbors_index_float, [:index_ptr, :pointer, :int, :pointer, :pointer, :int, :index_params_ptr], :int
|
254
|
+
attach_function :flann_find_nearest_neighbors_index_double, [:index_ptr, :pointer, :int, :pointer, :pointer, :int, :index_params_ptr], :int
|
255
|
+
|
256
|
+
# dataset, rows, cols, testset, trows, indices, dists, nn, flann_params
|
257
|
+
attach_function :flann_find_nearest_neighbors_byte, [:pointer, :int, :int, :pointer, :int, :pointer, :pointer, :int, :index_params_ptr], :int
|
258
|
+
attach_function :flann_find_nearest_neighbors_int, [:pointer, :int, :int, :pointer, :int, :pointer, :pointer, :int, :index_params_ptr], :int
|
259
|
+
attach_function :flann_find_nearest_neighbors_float, [:pointer, :int, :int, :pointer, :int, :pointer, :pointer, :int, :index_params_ptr], :int
|
260
|
+
attach_function :flann_find_nearest_neighbors_double, [:pointer, :int, :int, :pointer, :int, :pointer, :pointer, :int, :index_params_ptr], :int
|
261
|
+
|
262
|
+
# index, query point, result indices, result distances, max_nn, radius, flann_params
|
263
|
+
attach_function :flann_radius_search_byte, [:index_ptr, :pointer, :pointer, :pointer, :int, :float, :index_params_ptr], :int
|
264
|
+
attach_function :flann_radius_search_int, [:index_ptr, :pointer, :pointer, :pointer, :int, :float, :index_params_ptr], :int
|
265
|
+
attach_function :flann_radius_search_float, [:index_ptr, :pointer, :pointer, :pointer, :int, :float, :index_params_ptr], :int
|
266
|
+
attach_function :flann_radius_search_double, [:index_ptr, :pointer, :pointer, :pointer, :int, :float, :index_params_ptr], :int
|
267
|
+
|
268
|
+
attach_function :flann_save_index_byte, [:index_ptr, :string], :int
|
269
|
+
attach_function :flann_save_index_int, [:index_ptr, :string], :int
|
270
|
+
attach_function :flann_save_index_float, [:index_ptr, :string], :int
|
271
|
+
attach_function :flann_save_index_double, [:index_ptr, :string], :int
|
272
|
+
|
273
|
+
attach_function :flann_load_index_byte, [:string, :pointer, :int, :int], :index_ptr
|
274
|
+
attach_function :flann_load_index_int, [:string, :pointer, :int, :int], :index_ptr
|
275
|
+
attach_function :flann_load_index_float, [:string, :pointer, :int, :int], :index_ptr
|
276
|
+
attach_function :flann_load_index_double, [:string, :pointer, :int, :int], :index_ptr
|
277
|
+
|
278
|
+
attach_function :flann_free_index_byte, [:index_ptr, :index_params_ptr], :int
|
279
|
+
attach_function :flann_free_index_int, [:index_ptr, :index_params_ptr], :int
|
280
|
+
attach_function :flann_free_index_float, [:index_ptr, :index_params_ptr], :int
|
281
|
+
attach_function :flann_free_index_double, [:index_ptr, :index_params_ptr], :int
|
282
|
+
|
283
|
+
attach_function :flann_set_distance_type, [:distance_type, :int], :void
|
284
|
+
|
285
|
+
attach_function :flann_get_distance_type, [], :distance_type
|
286
|
+
attach_function :flann_get_distance_order, [], :int
|
287
|
+
|
288
|
+
attach_function :flann_compute_cluster_centers_byte, [:pointer, :int, :int, :int, :pointer, :index_params_ptr], :int
|
289
|
+
attach_function :flann_compute_cluster_centers_int, [:pointer, :int, :int, :int, :pointer, :index_params_ptr], :int
|
290
|
+
attach_function :flann_compute_cluster_centers_float, [:pointer, :int, :int, :int, :pointer, :index_params_ptr], :int
|
291
|
+
attach_function :flann_compute_cluster_centers_double, [:pointer, :int, :int, :int, :pointer, :index_params_ptr], :int
|
292
|
+
|
293
|
+
end
|