├── CMakeLists.txt ├── COPYING ├── ChangeLog ├── README.md ├── bin ├── download_checkmd5.py ├── indent.sh ├── make_release.sh ├── run_test.py └── uncrustify.cfg ├── cmake ├── CMakeLists.txt ├── Config.cmake.in ├── FindFlann.cmake ├── UseLATEX.cmake ├── flann.pc.in ├── flann_utils.cmake └── uninstall_target.cmake.in ├── datasets ├── brief100K.h5 ├── cloud.h5 ├── sift100K.h5 ├── sift100K_byte.h5 ├── sift10K.h5 └── sift10K_byte.h5 ├── doc ├── CMakeLists.txt ├── images │ └── cmake-gui.png ├── manual.tex └── references.bib ├── examples ├── CMakeLists.txt ├── README ├── flann_example.c ├── flann_example.cpp └── flann_example_mpi.cpp ├── src ├── CMakeLists.txt ├── cpp │ ├── CMakeLists.txt │ ├── dummy.c │ └── flann │ │ ├── algorithms │ │ ├── all_indices.h │ │ ├── autotuned_index.h │ │ ├── center_chooser.h │ │ ├── composite_index.h │ │ ├── dist.h │ │ ├── hierarchical_clustering_index.h │ │ ├── kdtree_cuda_3d_index.cu │ │ ├── kdtree_cuda_3d_index.h │ │ ├── kdtree_cuda_builder.h │ │ ├── kdtree_index.h │ │ ├── kdtree_single_index.h │ │ ├── kmeans_index.h │ │ ├── linear_index.h │ │ ├── lsh_index.h │ │ └── nn_index.h │ │ ├── config.h │ │ ├── config.h.in │ │ ├── defines.h │ │ ├── flann.cpp │ │ ├── flann.h │ │ ├── flann.hpp │ │ ├── flann_cpp.cpp │ │ ├── general.h │ │ ├── io │ │ └── hdf5.h │ │ ├── mpi │ │ ├── client.h │ │ ├── flann_mpi_client.cpp │ │ ├── flann_mpi_server.cpp │ │ ├── index.h │ │ ├── matrix.h │ │ ├── queries.h │ │ └── server.h │ │ ├── nn │ │ ├── ground_truth.h │ │ ├── index_testing.h │ │ └── simplex_downhill.h │ │ └── util │ │ ├── allocator.h │ │ ├── any.h │ │ ├── cuda │ │ ├── heap.h │ │ └── result_set.h │ │ ├── cutil_math.h │ │ ├── dynamic_bitset.h │ │ ├── heap.h │ │ ├── logger.h │ │ ├── lsh_table.h │ │ ├── matrix.h │ │ ├── object_factory.h │ │ ├── params.h │ │ ├── random.h │ │ ├── result_set.h │ │ ├── sampling.h │ │ ├── saving.h │ │ ├── serialization.h │ │ └── timer.h ├── matlab │ ├── CMakeLists.txt │ ├── flann_build_index.m │ ├── flann_free_index.m │ ├── flann_load_index.m │ ├── flann_save_index.m │ ├── flann_search.m │ ├── flann_set_distance_type.m │ ├── nearest_neighbors.cpp │ └── test_flann.m ├── python │ ├── CMakeLists.txt │ ├── pyflann │ │ ├── __init__.py │ │ ├── exceptions.py │ │ ├── flann_ctypes.py │ │ └── index.py │ └── setup.py.tpl └── ruby │ ├── Gemfile │ ├── LICENSE.txt │ ├── Manifest.txt │ ├── Rakefile │ ├── flann.gemspec │ ├── lib │ ├── flann.rb │ └── flann │ │ ├── index.rb │ │ └── version.rb │ └── spec │ ├── flann_spec.rb │ ├── index_spec.rb │ ├── spec_helper.rb │ └── test.dataset └── test ├── CMakeLists.txt ├── flann_autotuned_test.cpp ├── flann_cuda_test.cu ├── flann_hierarchical_test.cpp ├── flann_kdtree_single_test.cpp ├── flann_kdtree_test.cpp ├── flann_kmeans_test.cpp ├── flann_linear_test.cpp ├── flann_lsh_test.cpp ├── flann_multithreaded_test.cpp ├── flann_tests.h ├── memusage_clustering.py ├── memusage_nn.py ├── test_clustering.py ├── test_index_save.py ├── test_nn.py ├── test_nn_autotune.py └── test_nn_index.py /COPYING: -------------------------------------------------------------------------------- 1 | 2 | The BSD License 3 | 4 | Copyright (c) 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | Copyright (c) 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | Copyright (c) 2015 Google Inc (Jack Rae, jwrae@google.com). All Rights Reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 11 | * 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. 12 | * Neither the name of the "University of British Columbia" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | 15 | 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 OWNER 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. 16 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | Version 1.9.2 2 | * Removed redundant assignment (issue #422 @fluber) 3 | * Removed unnecessary null checks before delete (issue #420 @elfring) 4 | * Reverted PR #424 due to lack of portability 5 | * fscanf fix (PR #467 @rdelfin) 6 | * Out of bounds check (modified PR #455 @legrosbuffle, also included in PR #319 @seth-planet) 7 | * Fixed MacOS build (PR #470 @johnhe4, modified for linux) 8 | * Fixed build system with dummy.c hack (PR #457 @pemmanuelviel) 9 | * Fixed misleading indentation in util/any.h (PR #365 @psteinb, also PR #428, #430, #459) 10 | * Included datasets in repo 11 | * Correct typo in definition (PR #419 @SergioRAgostinho) 12 | * Fix typos (PR #279 @gadomski) 13 | * CMakefile CUDA sources fix (PR #458 @pemmanuelviel) 14 | * Documentation fix (PR #456 @pemmanuelviel) 15 | * Scoping issue fix (PR #405 @greenbrettmichael, also PR #469, issue #386) 16 | * Documentation fixes (PR #460 @pemmanuelviel) 17 | * Changed return value (PR #461 @pemmanuelviel) 18 | * Fixed CUDA crash - guarantee prealloc > 0 (PR #437 @neka-rat) 19 | * Fixed wrong variable use (PR #433 @XinyiYS) 20 | * Fixed RNG initialization (PR #424 @SiddhantRanade) 21 | * Updated link to PDF (PR #474 @kleinma) 22 | 23 | Version 1.6.11 24 | * bug fixes 25 | 26 | Version 1.6.10 27 | * fixed a radiusSearch bug introduced in 1.6.9 28 | 29 | Version 1.6.9 30 | * bug fixes 31 | * fixed radius search bug on MSVC compiler 32 | * fixed windows linking problems 33 | 34 | Version 1.6.8 35 | * bug fixes, low dimensional search speedup 36 | 37 | Version 1.6.7 38 | * bug fixes 39 | 40 | Version 1.6.6 41 | * misc bug fixes 42 | 43 | Version 1.6.5 44 | * fix compilation problem on some C++ compilers 45 | * fixes in the python bindings 46 | 47 | Version 1.6.4 48 | * small bug fix 49 | 50 | Version 1.6.3 51 | * radius search speedup 52 | 53 | Version 1.6.2 54 | * slight API changes to the C++ bindings, now the main index type is templated 55 | * on the distance functor which makes it easier to use custom distances 56 | * new kd-tree implementation optimized for low dimensionality data 57 | * experimental MPI support for cluster computing 58 | 59 | Version 1.5 60 | * new C++ templated API 61 | * saving/loading of indices to disk 62 | * threadsafe search 63 | * new distance types (thanks to Radu Bogdan Rusu and Romain Thibaux for the patch) 64 | * (api change) autotuned is no longer selected by passing a precision >0, it's used when the algorithm type is set to autotuned 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FLANN - Fast Library for Approximate Nearest Neighbors 2 | ====================================================== 3 | 4 | FLANN is a library for performing fast approximate nearest neighbor searches in high dimensional spaces. It contains a collection of algorithms we found to work best for nearest neighbor search and a system for automatically choosing the best algorithm and optimum parameters depending on the dataset. 5 | FLANN is written in C++ and contains bindings for the following languages: C, MATLAB, Python, and Ruby. 6 | 7 | 8 | Documentation 9 | ------------- 10 | 11 | Check FLANN web page [here](http://www.cs.ubc.ca/research/flann). 12 | 13 | Documentation on how to use the library can be found in the doc/manual.pdf file included in the release archives. 14 | 15 | More information and experimental results can be found in the following paper: 16 | 17 | * Marius Muja and David G. Lowe, "Fast Approximate Nearest Neighbors with Automatic Algorithm Configuration", in International Conference on Computer Vision Theory and Applications (VISAPP'09), 2009 [(PDF)](https://www.cs.ubc.ca/research/flann/uploads/FLANN/flann_visapp09.pdf) [(BibTex)](http://people.cs.ubc.ca/~mariusm/index.php/FLANN/BibTex) 18 | 19 | 20 | Getting FLANN 21 | ------------- 22 | 23 | If you want to try out the latest changes or contribute to FLANN, then it's recommended that you checkout the git source repository: `git clone git://github.com/mariusmuja/flann.git` 24 | 25 | If you just want to browse the repository, you can do so by going [here](https://github.com/mariusmuja/flann). 26 | 27 | 28 | Conditions of use 29 | ----------------- 30 | 31 | FLANN is distributed under the terms of the [BSD License](https://github.com/mariusmuja/flann/blob/master/COPYING). 32 | 33 | Bug reporting 34 | ------------- 35 | 36 | Please report bugs or feature requests using [github's issue tracker](http://github.com/mariusmuja/flann/issues). 37 | -------------------------------------------------------------------------------- /bin/download_checkmd5.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import urllib, hashlib, sys, os 4 | from optparse import OptionParser 5 | 6 | class AppURLopener(urllib.FancyURLopener): 7 | version ="Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" 8 | 9 | def prompt_user_passwd(self, host, realm): 10 | raise Exception() 11 | urllib._urlopener = AppURLopener() 12 | 13 | def file_md5(file): 14 | m = hashlib.md5() 15 | m.update(open(dest).read()) 16 | return m.hexdigest() 17 | 18 | 19 | def main(): 20 | parser = OptionParser(usage="usage: %prog URI dest [md5sum]", prog=sys.argv[0]) 21 | options, args = parser.parse_args() 22 | md5sum = None 23 | 24 | if len(args)==2: 25 | uri, dest = args 26 | elif len(args)==3: 27 | uri, dest, md5 = args 28 | else: 29 | parser.error("Wrong arguments") 30 | 31 | fresh = False 32 | if not os.path.exists(dest): 33 | print "Downloading from %s to %s..."%(uri, dest), 34 | sys.stdout.flush() 35 | urllib.urlretrieve(uri, dest) 36 | print "done" 37 | fresh = True 38 | 39 | if md5sum: 40 | print "Computing md5sum on downloaded file", 41 | sys.stdout.flush() 42 | checksum = md5_file(dest) 43 | print "done" 44 | 45 | if checksum!=md5sum: 46 | if not fresh: 47 | print "Checksum mismatch (%s != %s), re-downloading file %s"%(checksum, md5sum, dest), 48 | sys.stdout.flush() 49 | os.remove(dest) 50 | urllib.urlretrieve(uri, dest) 51 | print "done" 52 | 53 | print "Computing md5sum on downloaded file", 54 | sys.stdout.flush() 55 | checksum = md5_file(dest) 56 | print "done" 57 | 58 | if checksum!=md5sum: 59 | print "ERROR, checksum mismatch (%s != %s) on %d",(checksum, md5sum, dest) 60 | return 1 61 | return 0 62 | 63 | 64 | if __name__ == '__main__': 65 | try: 66 | sys.exit(main()) 67 | except Exception as e: 68 | print "ERROR, ",e 69 | sys.exit(1) 70 | -------------------------------------------------------------------------------- /bin/indent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR=`dirname $0` 4 | uncrustify --no-backup -c ${DIR}/uncrustify.cfg $1 5 | 6 | -------------------------------------------------------------------------------- /bin/make_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | VERSION=`grep "set(FLANN_VERSION" CMakeLists.txt | sed 's/[^0-9]*\([0-9]*\.[0-9]*\.[0-9]*\)[^0-9]*/\1/'` 3 | 4 | echo "Creating flann-$VERSION-src.zip" 5 | 6 | git archive --prefix=flann-$VERSION-src/ -o flann-$VERSION-src.zip $VERSION-src 7 | -------------------------------------------------------------------------------- /bin/run_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | 4 | import sys 5 | import os.path as op 6 | import unittest 7 | 8 | if __name__ == "__main__": 9 | if len(sys.argv)==1: 10 | print "Usage: %s file"%sys.argv[0] 11 | sys.exit(1) 12 | 13 | python_path = op.abspath(op.join( op.dirname(__file__),"..","src","python")) 14 | sys.path.append(python_path) 15 | 16 | test_file = sys.argv[1] 17 | sys.argv = sys.argv[1:] 18 | execfile(test_file) 19 | -------------------------------------------------------------------------------- /bin/uncrustify.cfg: -------------------------------------------------------------------------------- 1 | indent_align_string=false 2 | indent_braces=false 3 | indent_braces_no_func=false 4 | indent_brace_parent=false 5 | indent_namespace=false 6 | indent_extern=false 7 | indent_class=true 8 | indent_class_colon=false 9 | indent_else_if=false 10 | indent_func_call_param=false 11 | indent_func_def_param=false 12 | indent_func_proto_param=false 13 | indent_func_class_param=false 14 | indent_func_ctor_var_param=false 15 | indent_template_param=false 16 | indent_func_param_double=false 17 | indent_relative_single_line_comments=true 18 | indent_col1_comment=true 19 | indent_access_spec_body=false 20 | indent_paren_nl=false 21 | indent_comma_paren=false 22 | indent_bool_paren=false 23 | indent_square_nl=false 24 | indent_preserve_sql=false 25 | indent_align_assign=true 26 | sp_balance_nested_parens=false 27 | align_keep_tabs=false 28 | align_with_tabs=false 29 | align_on_tabstop=false 30 | align_number_left=false 31 | align_func_params=false 32 | align_same_func_call_params=false 33 | align_var_def_colon=false 34 | align_var_def_attribute=false 35 | align_var_def_inline=false 36 | align_right_cmt_mix=false 37 | align_on_operator=false 38 | align_mix_var_proto=false 39 | align_single_line_func=false 40 | align_single_line_brace=false 41 | align_nl_cont=false 42 | align_left_shift=true 43 | nl_collapse_empty_body=false 44 | nl_assign_leave_one_liners=true 45 | nl_class_leave_one_liners=true 46 | nl_enum_leave_one_liners=true 47 | nl_getset_leave_one_liners=true 48 | nl_func_leave_one_liners=true 49 | nl_if_leave_one_liners=true 50 | nl_multi_line_cond=false 51 | nl_multi_line_define=false 52 | nl_before_case=false 53 | nl_after_case=false 54 | nl_after_return=false 55 | nl_after_semicolon=false 56 | nl_after_brace_open=false 57 | nl_after_brace_open_cmt=false 58 | nl_after_vbrace_open=false 59 | nl_after_brace_close=false 60 | nl_define_macro=false 61 | nl_squeeze_ifdef=false 62 | nl_ds_struct_enum_cmt=false 63 | nl_ds_struct_enum_close_brace=false 64 | nl_create_if_one_liner=true 65 | nl_create_for_one_liner=true 66 | nl_create_while_one_liner=true 67 | ls_for_split_full=false 68 | ls_func_split_full=false 69 | nl_after_multiline_comment=false 70 | eat_blanks_after_open_brace=false 71 | eat_blanks_before_close_brace=false 72 | mod_pawn_semicolon=false 73 | mod_full_paren_if_bool=true 74 | mod_remove_extra_semicolon=true 75 | mod_sort_import=false 76 | mod_sort_using=false 77 | mod_sort_include=false 78 | mod_move_case_break=false 79 | mod_remove_empty_return=false 80 | cmt_indent_multi=true 81 | cmt_c_group=false 82 | cmt_c_nl_start=false 83 | cmt_c_nl_end=false 84 | cmt_cpp_group=false 85 | cmt_cpp_nl_start=false 86 | cmt_cpp_nl_end=false 87 | cmt_cpp_to_c=false 88 | cmt_star_cont=false 89 | cmt_multi_check_last=true 90 | cmt_insert_before_preproc=false 91 | pp_indent_at_level=false 92 | pp_region_indent_code=false 93 | pp_if_indent_code=false 94 | pp_define_at_level=false 95 | input_tab_size=4 96 | indent_columns=4 97 | indent_with_tabs=0 98 | sp_before_ptr_star=remove 99 | sp_between_ptr_star=remove 100 | sp_after_ptr_star=add 101 | sp_before_byref=remove 102 | sp_after_byref=add 103 | sp_after_type=ignore 104 | sp_else_brace=add 105 | sp_catch_brace=add 106 | sp_finally_brace=add 107 | sp_try_brace=add 108 | nl_end_of_file=add 109 | nl_fcall_brace=remove 110 | nl_enum_brace=add 111 | nl_struct_brace=add 112 | nl_union_brace=remove 113 | nl_if_brace=remove 114 | nl_brace_else=add 115 | nl_else_brace=remove 116 | nl_else_if=remove 117 | nl_brace_finally=add 118 | nl_finally_brace=remove 119 | nl_try_brace=remove 120 | nl_for_brace=remove 121 | nl_catch_brace=remove 122 | nl_brace_catch=add 123 | nl_while_brace=remove 124 | nl_do_brace=remove 125 | nl_brace_while=remove 126 | nl_switch_brace=remove 127 | nl_namespace_brace=add 128 | nl_template_class=add 129 | nl_class_brace=add 130 | nl_fdef_brace=add 131 | mod_full_brace_function=add 132 | mod_paren_on_return=remove 133 | -------------------------------------------------------------------------------- /cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PKG_DESC "Fast Library for Approximate Nearest Neighbors") 2 | set(pkg_conf_file ${CMAKE_CURRENT_BINARY_DIR}/flann.pc) 3 | configure_file(flann.pc.in ${pkg_conf_file} @ONLY) 4 | install(FILES ${pkg_conf_file} 5 | DESTINATION ${FLANN_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT pkgconfig) 6 | 7 | -------------------------------------------------------------------------------- /cmake/Config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") 4 | check_required_components("flann") 5 | 6 | -------------------------------------------------------------------------------- /cmake/FindFlann.cmake: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Find Flann 3 | # 4 | # This sets the following variables: 5 | # FLANN_FOUND - True if FLANN was found. 6 | # FLANN_INCLUDE_DIRS - Directories containing the FLANN include files. 7 | # FLANN_LIBRARIES - Libraries needed to use FLANN. 8 | # FLANN_DEFINITIONS - Compiler flags for FLANN. 9 | 10 | find_package(PkgConfig) 11 | pkg_check_modules(PC_FLANN flann) 12 | set(FLANN_DEFINITIONS ${PC_FLANN_CFLAGS_OTHER}) 13 | 14 | find_path(FLANN_INCLUDE_DIR flann/flann.hpp 15 | HINTS ${PC_FLANN_INCLUDEDIR} ${PC_FLANN_INCLUDE_DIRS}) 16 | 17 | find_library(FLANN_LIBRARY flann 18 | HINTS ${PC_FLANN_LIBDIR} ${PC_FLANN_LIBRARY_DIRS}) 19 | 20 | set(FLANN_INCLUDE_DIRS ${FLANN_INCLUDE_DIR}) 21 | set(FLANN_LIBRARIES ${FLANN_LIBRARY}) 22 | 23 | include(FindPackageHandleStandardArgs) 24 | find_package_handle_standard_args(Flann DEFAULT_MSG 25 | FLANN_LIBRARY FLANN_INCLUDE_DIR) 26 | 27 | mark_as_advanced(FLANN_LIBRARY FLANN_INCLUDE_DIR) 28 | 29 | -------------------------------------------------------------------------------- /cmake/flann.pc.in: -------------------------------------------------------------------------------- 1 | # This file was generated by CMake for @PROJECT_NAME@ 2 | prefix=@CMAKE_INSTALL_PREFIX@ 3 | exec_prefix=${prefix} 4 | libdir=${prefix}/@FLANN_LIB_INSTALL_DIR@ 5 | includedir=${prefix}/include 6 | 7 | Name: @PROJECT_NAME@ 8 | Description: @PKG_DESC@ 9 | Version: @FLANN_VERSION@ 10 | Requires: @PKG_EXTERNAL_DEPS@ 11 | Libs: -L${libdir} @LZ4_STATIC_LDFLAGS@ -lflann -lflann_cpp 12 | Cflags: -I${includedir} 13 | 14 | -------------------------------------------------------------------------------- /cmake/flann_utils.cmake: -------------------------------------------------------------------------------- 1 | macro(GET_OS_INFO) 2 | string(REGEX MATCH "Linux" OS_IS_LINUX ${CMAKE_SYSTEM_NAME}) 3 | set(FLANN_LIB_INSTALL_DIR "lib${LIB_SUFFIX}") 4 | set(FLANN_INCLUDE_INSTALL_DIR 5 | "include/${PROJECT_NAME_LOWER}-${FLANN_MAJOR_VERSION}.${FLANN_MINOR_VERSION}") 6 | endmacro(GET_OS_INFO) 7 | 8 | 9 | macro(DISSECT_VERSION) 10 | # Find version components 11 | string(REGEX REPLACE "^([0-9]+).*" "\\1" 12 | FLANN_VERSION_MAJOR "${FLANN_VERSION}") 13 | string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" 14 | FLANN_VERSION_MINOR "${FLANN_VERSION}") 15 | string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" 16 | FLANN_VERSION_PATCH ${FLANN_VERSION}) 17 | string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+(.*)" "\\1" 18 | FLANN_VERSION_CANDIDATE ${FLANN_VERSION}) 19 | set(FLANN_SOVERSION "${FLANN_VERSION_MAJOR}.${FLANN_VERSION_MINOR}") 20 | endmacro(DISSECT_VERSION) 21 | 22 | 23 | # workaround a FindHDF5 bug 24 | macro(find_hdf5) 25 | find_package(HDF5) 26 | 27 | set( HDF5_IS_PARALLEL FALSE ) 28 | foreach( _dir ${HDF5_INCLUDE_DIRS} ) 29 | if( EXISTS "${_dir}/H5pubconf.h" ) 30 | file( STRINGS "${_dir}/H5pubconf.h" 31 | HDF5_HAVE_PARALLEL_DEFINE 32 | REGEX "HAVE_PARALLEL 1" ) 33 | if( HDF5_HAVE_PARALLEL_DEFINE ) 34 | set( HDF5_IS_PARALLEL TRUE ) 35 | endif() 36 | endif() 37 | endforeach() 38 | set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL 39 | "HDF5 library compiled with parallel IO support" ) 40 | mark_as_advanced( HDF5_IS_PARALLEL ) 41 | endmacro(find_hdf5) 42 | 43 | 44 | # Enable ExternalProject CMake module 45 | include(ExternalProject) 46 | 47 | # Add gtest 48 | ExternalProject_Add( 49 | googletest 50 | PREFIX ${CMAKE_BINARY_DIR}/googletest 51 | URL https://github.com/google/googletest/archive/refs/tags/release-1.12.1.zip 52 | URL_MD5 2648d4138129812611cf6b6b4b497a3b 53 | TIMEOUT 10 54 | # Force separate output paths for debug and release builds to allow easy 55 | # identification of correct lib in subsequent TARGET_LINK_LIBRARIES commands 56 | CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 57 | # Disable install step 58 | INSTALL_COMMAND "" 59 | # Disable update step 60 | UPDATE_COMMAND "" 61 | # Wrap download, configure and build steps in a script to log output 62 | LOG_DOWNLOAD ON 63 | LOG_CONFIGURE ON 64 | LOG_BUILD ON) 65 | set_target_properties(googletest PROPERTIES EXCLUDE_FROM_ALL TRUE) 66 | 67 | ExternalProject_Get_Property(googletest source_dir) 68 | set(googletest_INCLUDE_DIRS ${source_dir}/googletest/include) 69 | ExternalProject_Get_Property(googletest binary_dir) 70 | set(googletest_LIBRARIES ${binary_dir}/lib/libgtest.a) 71 | include_directories(${googletest_INCLUDE_DIRS}) 72 | 73 | 74 | macro(flann_add_gtest exe src) 75 | # add build target 76 | add_executable(${exe} EXCLUDE_FROM_ALL ${src}) 77 | target_link_libraries(${exe} ${googletest_LIBRARIES} ${ARGN}) 78 | # add dependency to 'tests' target 79 | add_dependencies(${exe} googletest) 80 | add_dependencies(flann_gtests ${exe}) 81 | 82 | # add target for running test 83 | string(REPLACE "/" "_" _testname ${exe}) 84 | add_test( 85 | NAME test_${_testname} 86 | COMMAND ${exe} --gtest_print_time 87 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test 88 | ) 89 | endmacro(flann_add_gtest) 90 | 91 | macro(flann_add_cuda_gtest exe src) 92 | # add build target 93 | cuda_add_executable(${exe} EXCLUDE_FROM_ALL ${src}) 94 | target_link_libraries(${exe} ${googletest_LIBRARIES} ${ARGN}) 95 | add_dependencies(${exe} googletest) 96 | 97 | # add target for running test 98 | string(REPLACE "/" "_" _testname ${exe}) 99 | add_test( 100 | NAME test_${_testname} 101 | COMMAND ${exe} --gtest_print_time 102 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test 103 | ) 104 | endmacro(flann_add_cuda_gtest) 105 | 106 | macro(flann_add_pyunit file) 107 | # find test file 108 | set(_file_name _file_name-NOTFOUND) 109 | find_file(_file_name ${file} ${CMAKE_CURRENT_SOURCE_DIR}) 110 | if(NOT _file_name) 111 | message(FATAL_ERROR "Can't find pyunit file \"${file}\"") 112 | endif(NOT _file_name) 113 | 114 | # add target for running test 115 | string(REPLACE "/" "_" _testname ${file}) 116 | add_test( 117 | NAME pyunit_${_testname} 118 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/bin/run_test.py ${_file_name} 119 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test 120 | ) 121 | # add dependency to 'test' target 122 | endmacro(flann_add_pyunit) 123 | -------------------------------------------------------------------------------- /cmake/uninstall_target.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@PROJECT_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: \"@PROJECT_BINARY_DIR@/install_manifest.txt\"") 3 | endif(NOT EXISTS "@PROJECT_BINARY_DIR@/install_manifest.txt") 4 | 5 | file(READ "@PROJECT_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 9 | if(EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 11 | OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval) 12 | if(NOT "${rm_retval}" STREQUAL 0) 13 | message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 14 | endif(NOT "${rm_retval}" STREQUAL 0) 15 | else(EXISTS "$ENV{DESTDIR}${file}") 16 | message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 17 | endif(EXISTS "$ENV{DESTDIR}${file}") 18 | endforeach(file) 19 | 20 | -------------------------------------------------------------------------------- /datasets/brief100K.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flann-lib/flann/f9caaf609d8b8cb2b7104a85cf59eb92c275a25d/datasets/brief100K.h5 -------------------------------------------------------------------------------- /datasets/cloud.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flann-lib/flann/f9caaf609d8b8cb2b7104a85cf59eb92c275a25d/datasets/cloud.h5 -------------------------------------------------------------------------------- /datasets/sift100K.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flann-lib/flann/f9caaf609d8b8cb2b7104a85cf59eb92c275a25d/datasets/sift100K.h5 -------------------------------------------------------------------------------- /datasets/sift100K_byte.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flann-lib/flann/f9caaf609d8b8cb2b7104a85cf59eb92c275a25d/datasets/sift100K_byte.h5 -------------------------------------------------------------------------------- /datasets/sift10K.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flann-lib/flann/f9caaf609d8b8cb2b7104a85cf59eb92c275a25d/datasets/sift10K.h5 -------------------------------------------------------------------------------- /datasets/sift10K_byte.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flann-lib/flann/f9caaf609d8b8cb2b7104a85cf59eb92c275a25d/datasets/sift10K_byte.h5 -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(LATEX) 2 | 3 | if (NOT DOCDIR) 4 | set(DOCDIR share/doc/flann) 5 | endif () 6 | 7 | if (EXISTS ${PDFLATEX_COMPILER} AND EXISTS ${BIBTEX_COMPILER}) 8 | include(${PROJECT_SOURCE_DIR}/cmake/UseLATEX.cmake) 9 | 10 | add_latex_document(manual.tex BIBFILES references.bib IMAGE_DIRS images DEFAULT_PDF) 11 | 12 | add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/manual.pdf 13 | COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/manual.pdf ${CMAKE_CURRENT_SOURCE_DIR}/manual.pdf 14 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/manual.pdf 15 | ) 16 | add_custom_target(doc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/manual.pdf) 17 | endif() 18 | 19 | install( 20 | FILES manual.pdf 21 | DESTINATION ${DOCDIR} 22 | OPTIONAL 23 | ) 24 | -------------------------------------------------------------------------------- /doc/images/cmake-gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flann-lib/flann/f9caaf609d8b8cb2b7104a85cf59eb92c275a25d/doc/images/cmake-gui.png -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_target(examples ALL) 2 | 3 | if (BUILD_C_BINDINGS) 4 | add_executable(flann_example_c flann_example.c) 5 | target_link_libraries(flann_example_c ${LZ4_LINK_LIBRARIES}) 6 | target_link_libraries(flann_example_c flann) 7 | set_target_properties(flann_example_c PROPERTIES COMPILE_FLAGS -std=c99) 8 | 9 | add_dependencies(examples flann_example_c) 10 | install (TARGETS flann_example_c DESTINATION bin ) 11 | endif() 12 | 13 | if (HDF5_FOUND) 14 | include_directories(${HDF5_INCLUDE_DIR}) 15 | 16 | add_executable(flann_example_cpp flann_example.cpp) 17 | target_link_libraries(flann_example_cpp ${LZ4_LINK_LIBRARIES}) 18 | target_link_libraries(flann_example_cpp ${HDF5_LIBRARIES} flann_cpp) 19 | if (HDF5_IS_PARALLEL) 20 | target_link_libraries(flann_example_cpp ${MPI_LIBRARIES}) 21 | endif() 22 | 23 | add_dependencies(examples flann_example_cpp) 24 | install (TARGETS flann_example_cpp DESTINATION bin) 25 | 26 | 27 | if (USE_MPI AND HDF5_IS_PARALLEL) 28 | add_executable(flann_example_mpi flann_example_mpi.cpp) 29 | target_link_libraries(flann_example_mpi ${LZ4_LINK_LIBRARIES}) 30 | target_link_libraries(flann_example_mpi flann_cpp ${HDF5_LIBRARIES} ${MPI_LIBRARIES} ${Boost_LIBRARIES}) 31 | 32 | add_dependencies(examples flann_example_mpi) 33 | install (TARGETS flann_example_mpi DESTINATION bin) 34 | endif() 35 | else() 36 | message("hdf5 library not found, not compiling flann_example.cpp") 37 | endif() 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | 2 | These examples use some datasets that are not included in the source distribution. You can download the datasets from here: 3 | 4 | http://www.cs.ubc.ca/research/flann/uploads/FLANN/datasets/dataset.hdf5 5 | http://www.cs.ubc.ca/research/flann/uploads/FLANN/datasets/dataset.dat 6 | http://www.cs.ubc.ca/research/flann/uploads/FLANN/datasets/testset.dat 7 | -------------------------------------------------------------------------------- /examples/flann_example.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | 9 | float* read_points(const char* filename, int rows, int cols) 10 | { 11 | float* data; 12 | float *p; 13 | FILE* fin; 14 | int i,j; 15 | 16 | fin = fopen(filename,"r"); 17 | if (!fin) { 18 | printf("Cannot open input file.\n"); 19 | exit(1); 20 | } 21 | 22 | data = (float*) malloc(rows*cols*sizeof(float)); 23 | if (!data) { 24 | printf("Cannot allocate memory.\n"); 25 | exit(1); 26 | } 27 | p = data; 28 | 29 | for (i=0;i 3 | #include 4 | 5 | #include 6 | 7 | using namespace flann; 8 | 9 | int main(int argc, char** argv) 10 | { 11 | int nn = 3; 12 | 13 | Matrix dataset; 14 | Matrix query; 15 | load_from_file(dataset, "dataset.hdf5","dataset"); 16 | load_from_file(query, "dataset.hdf5","query"); 17 | 18 | Matrix indices(new int[query.rows*nn], query.rows, nn); 19 | Matrix dists(new float[query.rows*nn], query.rows, nn); 20 | 21 | // construct an randomized kd-tree index using 4 kd-trees 22 | Index > index(dataset, flann::KDTreeIndexParams(4)); 23 | index.buildIndex(); 24 | 25 | // do a knn search, using 128 checks 26 | index.knnSearch(query, indices, dists, nn, flann::SearchParams(128)); 27 | 28 | flann::save_to_file(indices,"result.hdf5","result"); 29 | 30 | delete[] dataset.ptr(); 31 | delete[] query.ptr(); 32 | delete[] indices.ptr(); 33 | delete[] dists.ptr(); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /examples/flann_example_mpi.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #define IF_RANK0 if (world.rank()==0) 10 | 11 | timeval start_time_; 12 | void start_timer(const std::string& message = "") 13 | { 14 | if (!message.empty()) { 15 | printf("%s", message.c_str()); 16 | fflush(stdout); 17 | } 18 | gettimeofday(&start_time_,NULL); 19 | } 20 | 21 | double stop_timer() 22 | { 23 | timeval end_time; 24 | gettimeofday(&end_time,NULL); 25 | 26 | return double(end_time.tv_sec-start_time_.tv_sec)+ double(end_time.tv_usec-start_time_.tv_usec)/1000000; 27 | } 28 | 29 | float compute_precision(const flann::Matrix& match, const flann::Matrix& indices) 30 | { 31 | int count = 0; 32 | 33 | assert(match.rows == indices.rows); 34 | size_t nn = std::min(match.cols, indices.cols); 35 | 36 | for(size_t i=0; i >* index) 52 | { 53 | boost::mpi::communicator world; 54 | 55 | int nn = 1; 56 | 57 | flann::Matrix query; 58 | flann::Matrix match; 59 | // flann::Matrix gt_dists; 60 | IF_RANK0 { 61 | flann::load_from_file(query, "sift100K.h5","query"); 62 | flann::load_from_file(match, "sift100K.h5","match"); 63 | // flann::load_from_file(gt_dists, "sift100K.h5","dists"); 64 | } 65 | 66 | 67 | boost::mpi::broadcast(world, query, 0); 68 | boost::mpi::broadcast(world, match, 0); 69 | 70 | flann::Matrix indices(new int[query.rows*nn], query.rows, nn); 71 | flann::Matrix dists(new float[query.rows*nn], query.rows, nn); 72 | 73 | IF_RANK0 { 74 | indices = flann::Matrix(new int[query.rows*nn], query.rows, nn); 75 | dists = flann::Matrix(new float[query.rows*nn], query.rows, nn); 76 | } 77 | 78 | // do a knn search, using 128 checks0 79 | IF_RANK0 start_timer("Performing search...\n"); 80 | index->knnSearch(query, indices, dists, nn, flann::SearchParams(128)); 81 | IF_RANK0 { 82 | printf("Search done (%g seconds)\n", stop_timer()); 83 | printf("Indices size: (%d,%d)\n", (int)indices.rows, (int)indices.cols); 84 | printf("Checking results\n"); 85 | float precision = compute_precision(match, indices); 86 | printf("Precision is: %g\n", precision); 87 | } 88 | delete[] query.ptr(); 89 | delete[] match.ptr(); 90 | 91 | IF_RANK0 { 92 | delete[] indices.ptr(); 93 | delete[] dists.ptr(); 94 | } 95 | 96 | } 97 | 98 | 99 | int main(int argc, char** argv) 100 | { 101 | boost::mpi::environment env(argc, argv); 102 | boost::mpi::communicator world; 103 | 104 | //flann::Matrix dataset; 105 | 106 | IF_RANK0 start_timer("Loading data...\n"); 107 | // construct an randomized kd-tree index using 4 kd-trees 108 | flann::mpi::Index > index("sift100K.h5", "dataset", flann::KDTreeIndexParams(4)); 109 | //flann::load_from_file(dataset, "sift100K.h5","dataset"); 110 | //flann::Index > index( dataset, flann::KDTreeIndexParams(4)); 111 | world.barrier(); 112 | IF_RANK0 printf("Loading data done (%g seconds)\n", stop_timer()); 113 | IF_RANK0 printf("Index size: (%d,%d)\n", index.size(), index.veclen()); 114 | 115 | start_timer("Building index...\n"); 116 | index.buildIndex(); 117 | printf("Building index done (%g seconds)\n", stop_timer()); 118 | world.barrier(); 119 | 120 | printf("Searching...\n"); 121 | 122 | 123 | boost::thread t(boost::bind(search, &index)); 124 | t.join(); 125 | boost::thread t2(boost::bind(search, &index)); 126 | 127 | 128 | for(;;){}; 129 | 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_subdirectory( cpp ) 3 | 4 | if (BUILD_MATLAB_BINDINGS) 5 | add_subdirectory( matlab ) 6 | endif() 7 | 8 | if (BUILD_PYTHON_BINDINGS) 9 | add_subdirectory( python ) 10 | endif() 11 | -------------------------------------------------------------------------------- /src/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #include_directories(${CMAKE_SOURCE_DIR}/include algorithms ext util nn .) 2 | 3 | add_definitions(-D_FLANN_VERSION=${FLANN_VERSION}) 4 | 5 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/flann/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/flann/config.h) 6 | 7 | file(GLOB_RECURSE C_SOURCES flann.cpp) 8 | file(GLOB_RECURSE CPP_SOURCES flann_cpp.cpp) 9 | file(GLOB_RECURSE CU_SOURCES *.cu) 10 | 11 | add_library(flann_cpp_s STATIC ${CPP_SOURCES}) 12 | target_link_libraries(flann_cpp_s PUBLIC ${LZ4_LINK_LIBRARIES}) 13 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) 14 | set_target_properties(flann_cpp_s PROPERTIES COMPILE_FLAGS -fPIC) 15 | endif() 16 | if (CMAKE_BUILD_STATIC_LIBS) 17 | list(APPEND flann_install_targets flann_cpp_s) 18 | else() 19 | set_target_properties(flann_cpp_s PROPERTIES EXCLUDE_FROM_ALL true) 20 | endif() 21 | 22 | add_library(flann_cpp SHARED ${CPP_SOURCES}) 23 | target_link_libraries(flann_cpp ${LZ4_LINK_LIBRARIES}) 24 | # export lz4 headers, so that MSVC to creates flann_cpp.lib 25 | set_target_properties(flann_cpp PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS YES) 26 | 27 | set(flann_install_targets flann_cpp) 28 | 29 | if (BUILD_CUDA_LIB) 30 | SET(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-DFLANN_USE_CUDA;-Xcudafe \"--diag_suppress=partial_override\" ;-gencode=arch=compute_52,code=\"sm_52,compute_52\";-gencode=arch=compute_61,code=\"sm_61,compute_61\"") 31 | if(CMAKE_COMPILER_IS_GNUCC) 32 | set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-Xcompiler;-fPIC;" ) 33 | if (NVCC_COMPILER_BINDIR) 34 | set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};--compiler-bindir=${NVCC_COMPILER_BINDIR}") 35 | endif() 36 | else() 37 | set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};" ) 38 | endif() 39 | cuda_add_library(flann_cuda_s STATIC ${CU_SOURCES}) 40 | set_property(TARGET flann_cuda_s PROPERTY COMPILE_DEFINITIONS FLANN_STATIC) 41 | if (CMAKE_BUILD_STATIC_LIBS) 42 | list(APPEND flann_install_targets flann_cuda_s) 43 | else() 44 | set_target_properties(flann_cuda_s PROPERTIES EXCLUDE_FROM_ALL true) 45 | endif() 46 | 47 | cuda_add_library(flann_cuda SHARED ${CU_SOURCES}) 48 | list(APPEND flann_install_targets flann_cuda) 49 | set_property(TARGET flann_cpp PROPERTY COMPILE_DEFINITIONS FLANN_USE_CUDA) 50 | set_property(TARGET flann_cpp_s PROPERTY COMPILE_DEFINITIONS FLANN_STATIC FLANN_USE_CUDA) 51 | else() 52 | set_property(TARGET flann_cpp_s PROPERTY COMPILE_DEFINITIONS FLANN_STATIC) 53 | endif() 54 | 55 | set_target_properties(flann_cpp PROPERTIES 56 | VERSION ${FLANN_VERSION} 57 | SOVERSION ${FLANN_SOVERSION} 58 | DEFINE_SYMBOL FLANN_EXPORTS 59 | ) 60 | 61 | if (BUILD_CUDA_LIB) 62 | set_target_properties(flann_cuda PROPERTIES 63 | VERSION ${FLANN_VERSION} 64 | SOVERSION ${FLANN_SOVERSION} 65 | DEFINE_SYMBOL FLANN_EXPORTS 66 | ) 67 | endif() 68 | 69 | 70 | if (USE_MPI AND HDF5_IS_PARALLEL) 71 | add_executable(flann_mpi_server flann/mpi/flann_mpi_server.cpp) 72 | target_link_libraries(flann_mpi_server flann_cpp ${HDF5_LIBRARIES} ${MPI_LIBRARIES} ${Boost_LIBRARIES}) 73 | 74 | add_executable(flann_mpi_client flann/mpi/flann_mpi_client.cpp) 75 | target_link_libraries(flann_mpi_client flann_cpp ${HDF5_LIBRARIES} ${MPI_LIBRARIES} ${Boost_LIBRARIES}) 76 | 77 | install (TARGETS flann_mpi_client flann_mpi_server 78 | DESTINATION bin) 79 | endif() 80 | 81 | 82 | if (BUILD_C_BINDINGS) 83 | add_library(flann_s STATIC ${C_SOURCES}) 84 | target_link_libraries(flann_s ${LZ4_LINK_LIBRARIES}) 85 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) 86 | set_target_properties(flann_s PROPERTIES COMPILE_FLAGS -fPIC) 87 | endif() 88 | set_property(TARGET flann_s PROPERTY COMPILE_DEFINITIONS FLANN_STATIC) 89 | if (CMAKE_BUILD_STATIC_LIBS) 90 | list(APPEND flann_install_targets flann_s) 91 | else() 92 | set_target_properties(flann_s PROPERTIES EXCLUDE_FROM_ALL true) 93 | endif() 94 | 95 | add_library(flann SHARED ${C_SOURCES}) 96 | target_link_libraries(flann ${LZ4_LINK_LIBRARIES}) 97 | list(APPEND flann_install_targets flann) 98 | 99 | if(MINGW AND OPENMP_FOUND) 100 | target_link_libraries(flann gomp) 101 | endif() 102 | 103 | set_target_properties(flann PROPERTIES 104 | VERSION ${FLANN_VERSION} 105 | SOVERSION ${FLANN_SOVERSION} 106 | DEFINE_SYMBOL FLANN_EXPORTS 107 | ) 108 | endif() 109 | 110 | if(WIN32) 111 | if (BUILD_C_BINDINGS AND BUILD_MATLAB_BINDINGS) 112 | install ( 113 | TARGETS flann 114 | RUNTIME DESTINATION share/flann/matlab 115 | ) 116 | endif() 117 | endif(WIN32) 118 | 119 | 120 | install ( 121 | TARGETS ${flann_install_targets} 122 | EXPORT ${targets_export_name} 123 | INCLUDES DESTINATION include 124 | RUNTIME DESTINATION bin 125 | LIBRARY DESTINATION ${FLANN_LIB_INSTALL_DIR} 126 | ARCHIVE DESTINATION ${FLANN_LIB_INSTALL_DIR} 127 | ) 128 | 129 | 130 | install ( 131 | DIRECTORY flann 132 | DESTINATION include 133 | FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp" 134 | ) 135 | -------------------------------------------------------------------------------- /src/cpp/dummy.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flann-lib/flann/f9caaf609d8b8cb2b7104a85cf59eb92c275a25d/src/cpp/dummy.c -------------------------------------------------------------------------------- /src/cpp/flann/algorithms/linear_index.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | #ifndef FLANN_LINEAR_INDEX_H_ 32 | #define FLANN_LINEAR_INDEX_H_ 33 | 34 | #include "flann/general.h" 35 | #include "flann/algorithms/nn_index.h" 36 | 37 | namespace flann 38 | { 39 | 40 | struct LinearIndexParams : public IndexParams 41 | { 42 | LinearIndexParams() 43 | { 44 | (* this)["algorithm"] = FLANN_INDEX_LINEAR; 45 | } 46 | }; 47 | 48 | template 49 | class LinearIndex : public NNIndex 50 | { 51 | public: 52 | 53 | typedef typename Distance::ElementType ElementType; 54 | typedef typename Distance::ResultType DistanceType; 55 | 56 | typedef NNIndex BaseClass; 57 | 58 | LinearIndex(const IndexParams& params = LinearIndexParams(), Distance d = Distance()) : 59 | BaseClass(params, d) 60 | { 61 | } 62 | 63 | LinearIndex(const Matrix& input_data, const IndexParams& params = LinearIndexParams(), Distance d = Distance()) : 64 | BaseClass(params, d) 65 | { 66 | setDataset(input_data); 67 | } 68 | 69 | LinearIndex(const LinearIndex& other) : BaseClass(other) 70 | { 71 | } 72 | 73 | LinearIndex& operator=(LinearIndex other) 74 | { 75 | this->swap(other); 76 | return *this; 77 | } 78 | 79 | virtual ~LinearIndex() 80 | { 81 | } 82 | 83 | BaseClass* clone() const 84 | { 85 | return new LinearIndex(*this); 86 | } 87 | 88 | void addPoints(const Matrix& points, float rebuild_threshold = 2) 89 | { 90 | assert(points.cols==veclen_); 91 | extendDataset(points); 92 | } 93 | 94 | flann_algorithm_t getType() const 95 | { 96 | return FLANN_INDEX_LINEAR; 97 | } 98 | 99 | 100 | int usedMemory() const 101 | { 102 | return 0; 103 | } 104 | 105 | template 106 | void serialize(Archive& ar) 107 | { 108 | ar.setObject(this); 109 | 110 | ar & *static_cast*>(this); 111 | 112 | if (Archive::is_loading::value) { 113 | index_params_["algorithm"] = getType(); 114 | } 115 | } 116 | 117 | void saveIndex(FILE* stream) 118 | { 119 | serialization::SaveArchive sa(stream); 120 | sa & *this; 121 | } 122 | 123 | void loadIndex(FILE* stream) 124 | { 125 | serialization::LoadArchive la(stream); 126 | la & *this; 127 | } 128 | 129 | void findNeighbors(ResultSet& resultSet, const ElementType* vec, const SearchParams& /*searchParams*/) const 130 | { 131 | if (removed_) { 132 | for (size_t i = 0; i < points_.size(); ++i) { 133 | if (removed_points_.test(i)) continue; 134 | DistanceType dist = distance_(points_[i], vec, veclen_); 135 | resultSet.addPoint(dist, i); 136 | } 137 | } 138 | else { 139 | for (size_t i = 0; i < points_.size(); ++i) { 140 | DistanceType dist = distance_(points_[i], vec, veclen_); 141 | resultSet.addPoint(dist, i); 142 | } 143 | } 144 | } 145 | protected: 146 | void buildIndexImpl() 147 | { 148 | /* nothing to do here for linear search */ 149 | } 150 | 151 | void freeIndex() 152 | { 153 | /* nothing to do here for linear search */ 154 | } 155 | 156 | private: 157 | 158 | USING_BASECLASS_SYMBOLS 159 | }; 160 | 161 | } 162 | 163 | #endif // FLANN_LINEAR_INDEX_H_ 164 | -------------------------------------------------------------------------------- /src/cpp/flann/config.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #ifndef FLANN_CONFIG_H_ 31 | #define FLANN_CONFIG_H_ 32 | 33 | #ifdef FLANN_VERSION_ 34 | #undef FLANN_VERSION_ 35 | #endif 36 | #define FLANN_VERSION_ "1.9.2" 37 | 38 | #ifdef FLANN_VERSION_MAJOR_ 39 | #undef FLANN_VERSION_MAJOR_ 40 | #endif 41 | #define FLANN_VERSION_MAJOR_ 1 42 | 43 | #ifdef FLANN_VERSION_MINOR_ 44 | #undef FLANN_VERSION_MINOR_ 45 | #endif 46 | #define FLANN_VERSION_MINOR_ 9 47 | 48 | #ifdef FLANN_VERSION_PATCH_ 49 | #undef FLANN_VERSION_PATCH_ 50 | #endif 51 | #define FLANN_VERSION_PATCH_ 2 52 | 53 | 54 | #endif /* FLANN_CONFIG_H_ */ 55 | -------------------------------------------------------------------------------- /src/cpp/flann/config.h.in: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #ifndef FLANN_CONFIG_H_ 31 | #define FLANN_CONFIG_H_ 32 | 33 | #ifdef FLANN_VERSION_ 34 | #undef FLANN_VERSION_ 35 | #endif 36 | #define FLANN_VERSION_ "${FLANN_VERSION}" 37 | 38 | #ifdef FLANN_VERSION_MAJOR_ 39 | #undef FLANN_VERSION_MAJOR_ 40 | #endif 41 | #define FLANN_VERSION_MAJOR_ ${FLANN_VERSION_MAJOR} 42 | 43 | #ifdef FLANN_VERSION_MINOR_ 44 | #undef FLANN_VERSION_MINOR_ 45 | #endif 46 | #define FLANN_VERSION_MINOR_ ${FLANN_VERSION_MINOR} 47 | 48 | #ifdef FLANN_VERSION_PATCH_ 49 | #undef FLANN_VERSION_PATCH_ 50 | #endif 51 | #define FLANN_VERSION_PATCH_ ${FLANN_VERSION_PATCH} 52 | 53 | 54 | #endif /* FLANN_CONFIG_H_ */ 55 | -------------------------------------------------------------------------------- /src/cpp/flann/defines.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | #ifndef FLANN_DEFINES_H_ 30 | #define FLANN_DEFINES_H_ 31 | 32 | #include "config.h" 33 | 34 | #ifdef FLANN_EXPORT 35 | #undef FLANN_EXPORT 36 | #endif 37 | #ifdef WIN32 38 | /* win32 dll export/import directives */ 39 | #ifdef FLANN_EXPORTS 40 | #define FLANN_EXPORT __declspec(dllexport) 41 | #elif defined(FLANN_STATIC) 42 | #define FLANN_EXPORT 43 | #else 44 | #define FLANN_EXPORT __declspec(dllimport) 45 | #endif 46 | #else 47 | /* unix needs nothing */ 48 | #define FLANN_EXPORT 49 | #endif 50 | 51 | #ifdef FLANN_DEPRECATED 52 | #undef FLANN_DEPRECATED 53 | #endif 54 | #ifdef __GNUC__ 55 | #define FLANN_DEPRECATED __attribute__ ((deprecated)) 56 | #elif defined(_MSC_VER) 57 | #define FLANN_DEPRECATED __declspec(deprecated) 58 | #else 59 | #pragma message("WARNING: You need to implement FLANN_DEPRECATED for this compiler") 60 | #define FLANN_DEPRECATED 61 | #endif 62 | 63 | #undef FLANN_PLATFORM_64_BIT 64 | #undef FLANN_PLATFORM_32_BIT 65 | #if __amd64__ || __x86_64__ || _WIN64 || _M_X64 66 | #define FLANN_PLATFORM_64_BIT 67 | #else 68 | #define FLANN_PLATFORM_32_BIT 69 | #endif 70 | 71 | #undef FLANN_ARRAY_LEN 72 | #define FLANN_ARRAY_LEN(a) (sizeof(a)/sizeof(a[0])) 73 | 74 | #ifdef __cplusplus 75 | namespace flann { 76 | #endif 77 | 78 | /* Nearest neighbour index algorithms */ 79 | enum flann_algorithm_t 80 | { 81 | FLANN_INDEX_LINEAR = 0, 82 | FLANN_INDEX_KDTREE = 1, 83 | FLANN_INDEX_KMEANS = 2, 84 | FLANN_INDEX_COMPOSITE = 3, 85 | FLANN_INDEX_KDTREE_SINGLE = 4, 86 | FLANN_INDEX_HIERARCHICAL = 5, 87 | FLANN_INDEX_LSH = 6, 88 | #ifdef FLANN_USE_CUDA 89 | FLANN_INDEX_KDTREE_CUDA = 7, 90 | #endif 91 | FLANN_INDEX_SAVED = 254, 92 | FLANN_INDEX_AUTOTUNED = 255, 93 | }; 94 | 95 | enum flann_centers_init_t 96 | { 97 | FLANN_CENTERS_RANDOM = 0, 98 | FLANN_CENTERS_GONZALES = 1, 99 | FLANN_CENTERS_KMEANSPP = 2, 100 | FLANN_CENTERS_GROUPWISE = 3, 101 | }; 102 | 103 | enum flann_log_level_t 104 | { 105 | FLANN_LOG_NONE = 0, 106 | FLANN_LOG_FATAL = 1, 107 | FLANN_LOG_ERROR = 2, 108 | FLANN_LOG_WARN = 3, 109 | FLANN_LOG_INFO = 4, 110 | FLANN_LOG_DEBUG = 5 111 | }; 112 | 113 | enum flann_distance_t 114 | { 115 | FLANN_DIST_EUCLIDEAN = 1, 116 | FLANN_DIST_L2 = 1, 117 | FLANN_DIST_MANHATTAN = 2, 118 | FLANN_DIST_L1 = 2, 119 | FLANN_DIST_MINKOWSKI = 3, 120 | FLANN_DIST_MAX = 4, 121 | FLANN_DIST_HIST_INTERSECT = 5, 122 | FLANN_DIST_HELLINGER = 6, 123 | FLANN_DIST_CHI_SQUARE = 7, 124 | FLANN_DIST_KULLBACK_LEIBLER = 8, 125 | FLANN_DIST_HAMMING = 9, 126 | FLANN_DIST_HAMMING_LUT = 10, 127 | FLANN_DIST_HAMMING_POPCNT = 11, 128 | FLANN_DIST_L2_SIMPLE = 12, 129 | }; 130 | 131 | enum flann_datatype_t 132 | { 133 | FLANN_NONE = -1, 134 | FLANN_INT8 = 0, 135 | FLANN_INT16 = 1, 136 | FLANN_INT32 = 2, 137 | FLANN_INT64 = 3, 138 | FLANN_UINT8 = 4, 139 | FLANN_UINT16 = 5, 140 | FLANN_UINT32 = 6, 141 | FLANN_UINT64 = 7, 142 | FLANN_FLOAT32 = 8, 143 | FLANN_FLOAT64 = 9 144 | }; 145 | 146 | enum flann_checks_t { 147 | FLANN_CHECKS_UNLIMITED = -1, 148 | FLANN_CHECKS_AUTOTUNED = -2, 149 | }; 150 | 151 | #ifdef __cplusplus 152 | } 153 | #endif 154 | 155 | 156 | #endif /* FLANN_DEFINES_H_ */ 157 | -------------------------------------------------------------------------------- /src/cpp/flann/flann_cpp.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #include "flann/flann.hpp" 31 | -------------------------------------------------------------------------------- /src/cpp/flann/general.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | #ifndef FLANN_GENERAL_H_ 32 | #define FLANN_GENERAL_H_ 33 | 34 | #include "defines.h" 35 | #include 36 | #include 37 | #include 38 | 39 | namespace flann 40 | { 41 | 42 | class FLANNException : public std::runtime_error 43 | { 44 | public: 45 | FLANNException(const char* message) : std::runtime_error(message) { } 46 | 47 | FLANNException(const std::string& message) : std::runtime_error(message) { } 48 | }; 49 | 50 | 51 | template 52 | struct flann_datatype_value 53 | { 54 | static const flann_datatype_t value = FLANN_NONE; 55 | }; 56 | 57 | template<> 58 | struct flann_datatype_value 59 | { 60 | static const flann_datatype_t value = FLANN_INT8; 61 | }; 62 | 63 | template<> 64 | struct flann_datatype_value 65 | { 66 | static const flann_datatype_t value = FLANN_INT16; 67 | }; 68 | 69 | template<> 70 | struct flann_datatype_value 71 | { 72 | static const flann_datatype_t value = FLANN_INT32; 73 | }; 74 | 75 | #ifdef LLONG_MAX 76 | template<> 77 | struct flann_datatype_value 78 | { 79 | static const flann_datatype_t value = FLANN_INT64; 80 | }; 81 | #endif 82 | 83 | template<> 84 | struct flann_datatype_value 85 | { 86 | static const flann_datatype_t value = FLANN_UINT8; 87 | }; 88 | 89 | template<> 90 | struct flann_datatype_value 91 | { 92 | static const flann_datatype_t value = FLANN_UINT16; 93 | }; 94 | 95 | template<> 96 | struct flann_datatype_value 97 | { 98 | static const flann_datatype_t value = FLANN_UINT32; 99 | }; 100 | 101 | #ifdef ULLONG_MAX 102 | template<> 103 | struct flann_datatype_value 104 | { 105 | static const flann_datatype_t value = FLANN_UINT64; 106 | }; 107 | #endif 108 | 109 | 110 | template<> 111 | struct flann_datatype_value 112 | { 113 | static const flann_datatype_t value = FLANN_FLOAT32; 114 | }; 115 | 116 | template<> 117 | struct flann_datatype_value 118 | { 119 | static const flann_datatype_t value = FLANN_FLOAT64; 120 | }; 121 | 122 | 123 | 124 | template 125 | struct flann_datatype_type 126 | { 127 | typedef void type; 128 | }; 129 | 130 | template<> 131 | struct flann_datatype_type 132 | { 133 | typedef char type; 134 | }; 135 | 136 | template<> 137 | struct flann_datatype_type 138 | { 139 | typedef short type; 140 | }; 141 | 142 | template<> 143 | struct flann_datatype_type 144 | { 145 | typedef int type; 146 | }; 147 | 148 | #ifdef LLONG_MAX 149 | template<> 150 | struct flann_datatype_type 151 | { 152 | typedef long long type; 153 | }; 154 | #endif 155 | 156 | template<> 157 | struct flann_datatype_type 158 | { 159 | typedef unsigned char type; 160 | }; 161 | 162 | 163 | template<> 164 | struct flann_datatype_type 165 | { 166 | typedef unsigned short type; 167 | }; 168 | 169 | template<> 170 | struct flann_datatype_type 171 | { 172 | typedef unsigned int type; 173 | }; 174 | 175 | #ifdef ULLONG_MAX 176 | template<> 177 | struct flann_datatype_type 178 | { 179 | typedef unsigned long long type; 180 | }; 181 | #endif 182 | 183 | template<> 184 | struct flann_datatype_type 185 | { 186 | typedef float type; 187 | }; 188 | 189 | template<> 190 | struct flann_datatype_type 191 | { 192 | typedef double type; 193 | }; 194 | 195 | 196 | inline size_t flann_datatype_size(flann_datatype_t type) 197 | { 198 | switch (type) { 199 | case FLANN_INT8: 200 | return sizeof(flann_datatype_type::type); 201 | case FLANN_INT16: 202 | return sizeof(flann_datatype_type::type); 203 | case FLANN_INT32: 204 | return sizeof(flann_datatype_type::type); 205 | case FLANN_INT64: 206 | return sizeof(flann_datatype_type::type); 207 | case FLANN_UINT8: 208 | return sizeof(flann_datatype_type::type); 209 | case FLANN_UINT16: 210 | return sizeof(flann_datatype_type::type); 211 | case FLANN_UINT32: 212 | return sizeof(flann_datatype_type::type); 213 | case FLANN_UINT64: 214 | return sizeof(flann_datatype_type::type); 215 | case FLANN_FLOAT32: 216 | return sizeof(flann_datatype_type::type); 217 | case FLANN_FLOAT64: 218 | return sizeof(flann_datatype_type::type); 219 | default: 220 | return 0; 221 | } 222 | } 223 | 224 | } 225 | 226 | 227 | #endif /* FLANN_GENERAL_H_ */ 228 | -------------------------------------------------------------------------------- /src/cpp/flann/mpi/client.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #ifndef MPI_CLIENT_H_ 31 | #define MPI_CLIENT_H_ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "queries.h" 38 | 39 | namespace flann { 40 | namespace mpi { 41 | 42 | 43 | class Client 44 | { 45 | public: 46 | Client(const std::string& host, const std::string& service) 47 | { 48 | tcp::resolver resolver(io_service_); 49 | tcp::resolver::query query(tcp::v4(), host, service); 50 | iterator_ = resolver.resolve(query); 51 | } 52 | 53 | 54 | template 55 | void knnSearch(const flann::Matrix& queries, flann::Matrix& indices, flann::Matrix& dists, int knn, const SearchParams& params) 56 | { 57 | tcp::socket sock(io_service_); 58 | sock.connect(*iterator_); 59 | 60 | Request req; 61 | req.nn = knn; 62 | req.queries = queries; 63 | req.checks = params.checks; 64 | // send request 65 | write_object(sock,req); 66 | 67 | Response resp; 68 | // read response 69 | read_object(sock, resp); 70 | 71 | for (size_t i=0;i 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | 12 | #define IF_RANK0 if (world.rank()==0) 13 | 14 | timeval start_time_; 15 | void start_timer(const std::string& message = "") 16 | { 17 | if (!message.empty()) { 18 | printf("%s", message.c_str()); 19 | fflush(stdout); 20 | } 21 | gettimeofday(&start_time_,NULL); 22 | } 23 | 24 | double stop_timer() 25 | { 26 | timeval end_time; 27 | gettimeofday(&end_time,NULL); 28 | 29 | return double(end_time.tv_sec-start_time_.tv_sec)+ double(end_time.tv_usec-start_time_.tv_usec)/1000000; 30 | } 31 | 32 | float compute_precision(const flann::Matrix& match, const flann::Matrix& indices) 33 | { 34 | int count = 0; 35 | 36 | assert(match.rows == indices.rows); 37 | size_t nn = std::min(match.cols, indices.cols); 38 | 39 | for(size_t i=0; i query; 58 | flann::Matrix match; 59 | 60 | flann::load_from_file(query, "sift100K.h5","query"); 61 | flann::load_from_file(match, "sift100K.h5","match"); 62 | // flann::load_from_file(gt_dists, "sift100K.h5","dists"); 63 | 64 | flann::mpi::Client index("localhost","9999"); 65 | 66 | int nn = 1; 67 | flann::Matrix indices(new int[query.rows*nn], query.rows, nn); 68 | flann::Matrix dists(new float[query.rows*nn], query.rows, nn); 69 | 70 | start_timer("Performing search...\n"); 71 | index.knnSearch(query, indices, dists, nn, flann::SearchParams(64)); 72 | printf("Search done (%g seconds)\n", stop_timer()); 73 | 74 | printf("Checking results\n"); 75 | float precision = compute_precision(match, indices); 76 | printf("Precision is: %g\n", precision); 77 | 78 | } 79 | catch (std::exception& e) { 80 | std::cerr << "Exception: " << e.what() << "\n"; 81 | } 82 | 83 | return 0; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/cpp/flann/mpi/flann_mpi_server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char* argv[]) 7 | { 8 | boost::mpi::environment env(argc, argv); 9 | 10 | try { 11 | if (argc != 4) { 12 | std::cout << "Usage: " << argv[0] << " \n"; 13 | return 1; 14 | } 15 | flann::mpi::Server > server(argv[1], argv[2], std::atoi(argv[3]), 16 | flann::KDTreeIndexParams(4)); 17 | 18 | server.run(); 19 | } 20 | catch (std::exception& e) { 21 | std::cerr << "Exception: " << e.what() << "\n"; 22 | } 23 | 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/cpp/flann/mpi/matrix.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #ifndef MPI_MATRIX_H_ 31 | #define MPI_MATRIX_H_ 32 | 33 | #include 34 | #include 35 | 36 | 37 | namespace boost { 38 | namespace serialization { 39 | 40 | template 41 | void serialize(Archive & ar, flann::Matrix & matrix, const unsigned int version) 42 | { 43 | ar & matrix.rows & matrix.cols & matrix.stride; 44 | if (Archive::is_loading::value) { 45 | matrix = flann::Matrix(new T[matrix.rows*matrix.cols], matrix.rows, matrix.cols, matrix.stride); 46 | } 47 | ar & boost::serialization::make_array(matrix.ptr(), matrix.rows*matrix.cols); 48 | } 49 | 50 | } 51 | } 52 | 53 | 54 | #endif /* MPI_MATRIX_H_ */ 55 | -------------------------------------------------------------------------------- /src/cpp/flann/mpi/queries.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #ifndef MPI_QUERIES_H_ 31 | #define MPI_QUERIES_H_ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | namespace flann 39 | { 40 | 41 | template 42 | struct Request 43 | { 44 | flann::Matrix queries; 45 | int nn; 46 | int checks; 47 | 48 | template 49 | void serialize(Archive& ar, const unsigned int version) 50 | { 51 | ar & queries & nn & checks; 52 | } 53 | }; 54 | 55 | template 56 | struct Response 57 | { 58 | flann::Matrix indices; 59 | flann::Matrix dists; 60 | 61 | template 62 | void serialize(Archive& ar, const unsigned int version) 63 | { 64 | ar & indices & dists; 65 | } 66 | }; 67 | 68 | 69 | using boost::asio::ip::tcp; 70 | 71 | template 72 | void read_object(tcp::socket& sock, T& val) 73 | { 74 | uint32_t size; 75 | boost::asio::read(sock, boost::asio::buffer(&size, sizeof(size))); 76 | size = ntohl(size); 77 | 78 | boost::asio::streambuf archive_stream; 79 | boost::asio::read(sock, archive_stream, boost::asio::transfer_at_least(size)); 80 | 81 | boost::archive::binary_iarchive archive(archive_stream); 82 | archive >> val; 83 | } 84 | 85 | template 86 | void write_object(tcp::socket& sock, const T& val) 87 | { 88 | boost::asio::streambuf archive_stream; 89 | boost::archive::binary_oarchive archive(archive_stream); 90 | archive << val; 91 | 92 | uint32_t size = archive_stream.size(); 93 | size = htonl(size); 94 | boost::asio::write(sock, boost::asio::buffer(&size, sizeof(size))); 95 | boost::asio::write(sock, archive_stream); 96 | 97 | } 98 | 99 | } 100 | 101 | 102 | 103 | #endif /* MPI_QUERIES_H_ */ 104 | -------------------------------------------------------------------------------- /src/cpp/flann/mpi/server.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #ifndef MPI_SERVER_H_ 31 | #define MPI_SERVER_H_ 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #include "queries.h" 45 | 46 | namespace flann { 47 | 48 | namespace mpi { 49 | 50 | template 51 | class Server 52 | { 53 | 54 | typedef typename Distance::ElementType ElementType; 55 | typedef typename Distance::ResultType DistanceType; 56 | typedef boost::shared_ptr socket_ptr; 57 | typedef flann::mpi::Index FlannIndex; 58 | 59 | void session(socket_ptr sock) 60 | { 61 | boost::mpi::communicator world; 62 | try { 63 | Request req; 64 | if (world.rank()==0) { 65 | read_object(*sock,req); 66 | std::cout << "Received query\n"; 67 | } 68 | // broadcast request to all MPI processes 69 | boost::mpi::broadcast(world, req, 0); 70 | 71 | Response resp; 72 | if (world.rank()==0) { 73 | int rows = req.queries.rows; 74 | int cols = req.nn; 75 | resp.indices = flann::Matrix(new int[rows*cols], rows, cols); 76 | resp.dists = flann::Matrix(new DistanceType[rows*cols], rows, cols); 77 | } 78 | 79 | std::cout << "Searching in process " << world.rank() << "\n"; 80 | index_->knnSearch(req.queries, resp.indices, resp.dists, req.nn, flann::SearchParams(req.checks)); 81 | 82 | if (world.rank()==0) { 83 | std::cout << "Sending result\n"; 84 | write_object(*sock,resp); 85 | } 86 | 87 | delete[] req.queries.ptr(); 88 | if (world.rank()==0) { 89 | delete[] resp.indices.ptr(); 90 | delete[] resp.dists.ptr(); 91 | } 92 | 93 | } 94 | catch (std::exception& e) { 95 | std::cerr << "Exception in thread: " << e.what() << "\n"; 96 | } 97 | } 98 | 99 | 100 | 101 | public: 102 | Server(const std::string& filename, const std::string& dataset, short port, const IndexParams& params) : 103 | port_(port) 104 | { 105 | boost::mpi::communicator world; 106 | if (world.rank()==0) { 107 | std::cout << "Reading dataset and building index..."; 108 | std::flush(std::cout); 109 | } 110 | index_ = new FlannIndex(filename, dataset, params); 111 | index_->buildIndex(); 112 | world.barrier(); // wait for data to be loaded and indexes to be created 113 | if (world.rank()==0) { 114 | std::cout << "done.\n"; 115 | } 116 | } 117 | 118 | 119 | void run() 120 | { 121 | boost::mpi::communicator world; 122 | boost::shared_ptr io_service; 123 | boost::shared_ptr acceptor; 124 | 125 | if (world.rank()==0) { 126 | io_service.reset(new boost::asio::io_service()); 127 | acceptor.reset(new tcp::acceptor(*io_service, tcp::endpoint(tcp::v4(), port_))); 128 | std::cout << "Start listening for queries...\n"; 129 | } 130 | for (;;) { 131 | socket_ptr sock; 132 | if (world.rank()==0) { 133 | sock.reset(new tcp::socket(*io_service)); 134 | acceptor->accept(*sock); 135 | std::cout << "Accepted connection\n"; 136 | } 137 | world.barrier(); // everybody waits here for a connection 138 | boost::thread t(boost::bind(&Server::session, this, sock)); 139 | t.join(); 140 | } 141 | 142 | } 143 | 144 | private: 145 | FlannIndex* index_; 146 | short port_; 147 | }; 148 | 149 | 150 | } // namespace mpi 151 | } // namespace flann 152 | 153 | #endif // MPI_SERVER_H_ 154 | -------------------------------------------------------------------------------- /src/cpp/flann/nn/ground_truth.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | #ifndef FLANN_GROUND_TRUTH_H_ 32 | #define FLANN_GROUND_TRUTH_H_ 33 | 34 | #include "flann/algorithms/dist.h" 35 | #include "flann/util/matrix.h" 36 | 37 | 38 | namespace flann 39 | { 40 | 41 | template 42 | void find_nearest(const Matrix& dataset, typename Distance::ElementType* query, size_t* matches, size_t nn, 43 | size_t skip = 0, Distance distance = Distance()) 44 | { 45 | //typedef typename Distance::ElementType ElementType; 46 | typedef typename Distance::ResultType DistanceType; 47 | int n = nn + skip; 48 | 49 | int* match = new int[n]; 50 | DistanceType* dists = new DistanceType[n]; 51 | 52 | dists[0] = distance(dataset[0], query, dataset.cols); 53 | match[0] = 0; 54 | int dcnt = 1; 55 | 56 | for (size_t i=1; i=1 && dists[j] 87 | void compute_ground_truth(const Matrix& dataset, const Matrix& testset, Matrix& matches, 88 | int skip=0, Distance d = Distance()) 89 | { 90 | for (size_t i=0; i(dataset, testset[i], matches[i], matches.cols, skip, d); 92 | } 93 | } 94 | 95 | 96 | } 97 | 98 | #endif //FLANN_GROUND_TRUTH_H_ 99 | -------------------------------------------------------------------------------- /src/cpp/flann/util/cuda/heap.h: -------------------------------------------------------------------------------- 1 | #ifndef FLANN_UTIL_CUDA_HEAP_H 2 | #define FLANN_UTIL_CUDA_HEAP_H 3 | 4 | /* 5 | Copyright (c) 2011, Andreas Mützel 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of the nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY Andreas Mützel ''AS IS'' AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL Andreas Mützel BE LIABLE FOR ANY 23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | namespace flann 32 | { 33 | namespace cuda 34 | { 35 | template 36 | __device__ __host__ void swap( T& x, T& y ) 37 | { 38 | T t=x; 39 | x=y; 40 | y=t; 41 | } 42 | 43 | namespace heap 44 | { 45 | 46 | //! moves an element down the heap until all children are smaller than the element 47 | //! if c is a less-than comparator, it do this until all children are larger 48 | template 49 | __host__ __device__ void 50 | sift_down( RandomAccessIterator array, size_t begin, size_t length, GreaterThan c = GreaterThan() ) 51 | { 52 | 53 | while( 2*begin+1 < length ) { 54 | size_t left = 2*begin+1; 55 | size_t right = 2*begin+2; 56 | size_t largest=begin; 57 | if((left < length)&& c(array[left], array[largest]) ) largest=left; 58 | 59 | if((right < length)&& c(array[right], array[largest]) ) largest=right; 60 | 61 | if( largest != begin ) { 62 | cuda::swap( array[begin], array[largest] ); 63 | begin=largest; 64 | } 65 | else return; 66 | } 67 | } 68 | 69 | //! creates a max-heap in the array beginning at begin of length "length" 70 | //! if c is a less-than comparator, it will create a min-heap 71 | template 72 | __host__ __device__ void 73 | make_heap( RandomAccessIterator begin, size_t length, GreaterThan c = GreaterThan() ) 74 | { 75 | int i=length/2-1; 76 | while( i>=0 ) { 77 | sift_down( begin, i, length, c ); 78 | i--; 79 | } 80 | } 81 | 82 | 83 | //! verifies if the array is a max-heap 84 | //! if c is a less-than comparator, it will verify if it is a min-heap 85 | template 86 | __host__ __device__ bool 87 | is_heap( RandomAccessIterator begin, size_t length, GreaterThan c = GreaterThan() ) 88 | { 89 | for( unsigned i=0; i 100 | __host__ __device__ void 101 | sift_down( RandomAccessIterator key, RandomAccessIterator2 value, size_t begin, size_t length, GreaterThan c = GreaterThan() ) 102 | { 103 | 104 | while( 2*begin+1 < length ) { 105 | size_t left = 2*begin+1; 106 | size_t right = 2*begin+2; 107 | size_t largest=begin; 108 | if((left < length)&& c(key[left], key[largest]) ) largest=left; 109 | 110 | if((right < length)&& c(key[right], key[largest]) ) largest=right; 111 | 112 | if( largest != begin ) { 113 | cuda::swap( key[begin], key[largest] ); 114 | cuda::swap( value[begin], value[largest] ); 115 | begin=largest; 116 | } 117 | else return; 118 | } 119 | } 120 | 121 | //! creates a max-heap in the array beginning at begin of length "length" 122 | //! if c is a less-than comparator, it will create a min-heap 123 | template 124 | __host__ __device__ void 125 | make_heap( RandomAccessIterator key, RandomAccessIterator2 value, size_t length, GreaterThan c = GreaterThan() ) 126 | { 127 | int i=length/2-1; 128 | while( i>=0 ) { 129 | sift_down( key, value, i, length, c ); 130 | i--; 131 | } 132 | } 133 | 134 | } 135 | 136 | } 137 | } 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /src/cpp/flann/util/dynamic_bitset.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | /*********************************************************************** 32 | * Author: Vincent Rabaud 33 | *************************************************************************/ 34 | 35 | #ifndef FLANN_DYNAMIC_BITSET_H_ 36 | #define FLANN_DYNAMIC_BITSET_H_ 37 | 38 | //#define FLANN_USE_BOOST 1 39 | #if FLANN_USE_BOOST 40 | #include 41 | typedef boost::dynamic_bitset<> DynamicBitset; 42 | #else 43 | 44 | #include 45 | 46 | namespace flann { 47 | 48 | /** Class re-implementing the boost version of it 49 | * This helps not depending on boost, it also does not do the bound checks 50 | * and has a way to reset a block for speed 51 | */ 52 | class DynamicBitset 53 | { 54 | public: 55 | /** default constructor 56 | */ 57 | DynamicBitset() : size_(0) 58 | { 59 | } 60 | 61 | /** only constructor we use in our code 62 | * @param the size of the bitset (in bits) 63 | */ 64 | DynamicBitset(size_t size) 65 | { 66 | resize(size); 67 | reset(); 68 | } 69 | 70 | /** Sets all the bits to 0 71 | */ 72 | void clear() 73 | { 74 | std::fill(bitset_.begin(), bitset_.end(), 0); 75 | } 76 | 77 | /** @brief checks if the bitset is empty 78 | * @return true if the bitset is empty 79 | */ 80 | bool empty() const 81 | { 82 | return bitset_.empty(); 83 | } 84 | 85 | /** set all the bits to 0 86 | */ 87 | void reset() 88 | { 89 | std::fill(bitset_.begin(), bitset_.end(), 0); 90 | } 91 | 92 | /** @brief set one bit to 0 93 | * @param index 94 | */ 95 | void reset(size_t index) 96 | { 97 | bitset_[index / cell_bit_size_] &= ~(size_t(1) << (index % cell_bit_size_)); 98 | } 99 | 100 | /** @brief sets a specific bit to 0, and more bits too 101 | * This function is useful when resetting a given set of bits so that the 102 | * whole bitset ends up being 0: if that's the case, we don't care about setting 103 | * other bits to 0 104 | * @param index 105 | */ 106 | void reset_block(size_t index) 107 | { 108 | bitset_[index / cell_bit_size_] = 0; 109 | } 110 | 111 | /** resize the bitset so that it contains at least size bits 112 | * @param size 113 | */ 114 | void resize(size_t size) 115 | { 116 | size_ = size; 117 | bitset_.resize(size / cell_bit_size_ + 1); 118 | } 119 | 120 | /** set a bit to true 121 | * @param index the index of the bit to set to 1 122 | */ 123 | void set(size_t index) 124 | { 125 | bitset_[index / cell_bit_size_] |= size_t(1) << (index % cell_bit_size_); 126 | } 127 | 128 | /** gives the number of contained bits 129 | */ 130 | size_t size() const 131 | { 132 | return size_; 133 | } 134 | 135 | /** check if a bit is set 136 | * @param index the index of the bit to check 137 | * @return true if the bit is set 138 | */ 139 | bool test(size_t index) const 140 | { 141 | return (bitset_[index / cell_bit_size_] & (size_t(1) << (index % cell_bit_size_))) != 0; 142 | } 143 | 144 | private: 145 | template 146 | void serialize(Archive& ar) 147 | { 148 | ar & size_; 149 | ar & bitset_; 150 | } 151 | friend struct serialization::access; 152 | 153 | private: 154 | std::vector bitset_; 155 | size_t size_; 156 | static const unsigned int cell_bit_size_ = CHAR_BIT * sizeof(size_t); 157 | }; 158 | 159 | } // namespace flann 160 | 161 | #endif 162 | 163 | #endif // FLANN_DYNAMIC_BITSET_H_ 164 | -------------------------------------------------------------------------------- /src/cpp/flann/util/logger.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | #ifndef FLANN_LOGGER_H 32 | #define FLANN_LOGGER_H 33 | 34 | #include 35 | #include 36 | 37 | #include "flann/defines.h" 38 | 39 | 40 | namespace flann 41 | { 42 | 43 | class Logger 44 | { 45 | Logger() : stream(stdout), logLevel(FLANN_LOG_WARN) {} 46 | 47 | ~Logger() 48 | { 49 | if ((stream!=NULL)&&(stream!=stdout)) { 50 | fclose(stream); 51 | } 52 | } 53 | 54 | static Logger& instance() 55 | { 56 | static Logger logger; 57 | return logger; 58 | } 59 | 60 | void _setDestination(const char* name) 61 | { 62 | if (name==NULL) { 63 | stream = stdout; 64 | } 65 | else { 66 | stream = fopen(name,"w"); 67 | if (stream == NULL) { 68 | stream = stdout; 69 | } 70 | } 71 | } 72 | 73 | int _log(int level, const char* fmt, va_list arglist) 74 | { 75 | if (level > logLevel ) return -1; 76 | int ret = vfprintf(stream, fmt, arglist); 77 | return ret; 78 | } 79 | 80 | public: 81 | /** 82 | * Sets the logging level. All messages with lower priority will be ignored. 83 | * @param level Logging level 84 | */ 85 | static void setLevel(int level) { instance().logLevel = level; } 86 | 87 | /** 88 | * Returns the currently set logging level. 89 | * @return current logging level 90 | */ 91 | static int getLevel() { return instance().logLevel; } 92 | 93 | /** 94 | * Sets the logging destination 95 | * @param name Filename or NULL for console 96 | */ 97 | static void setDestination(const char* name) { instance()._setDestination(name); } 98 | 99 | /** 100 | * Print log message 101 | * @param level Log level 102 | * @param fmt Message format 103 | * @return 104 | */ 105 | static int log(int level, const char* fmt, ...) 106 | { 107 | va_list arglist; 108 | va_start(arglist, fmt); 109 | int ret = instance()._log(level,fmt,arglist); 110 | va_end(arglist); 111 | return ret; 112 | } 113 | 114 | #define LOG_METHOD(NAME,LEVEL) \ 115 | static int NAME(const char* fmt, ...) \ 116 | { \ 117 | va_list ap; \ 118 | va_start(ap, fmt); \ 119 | int ret = instance()._log(LEVEL, fmt, ap); \ 120 | va_end(ap); \ 121 | return ret; \ 122 | } 123 | 124 | LOG_METHOD(fatal, FLANN_LOG_FATAL) 125 | LOG_METHOD(error, FLANN_LOG_ERROR) 126 | LOG_METHOD(warn, FLANN_LOG_WARN) 127 | LOG_METHOD(info, FLANN_LOG_INFO) 128 | LOG_METHOD(debug, FLANN_LOG_DEBUG) 129 | 130 | private: 131 | FILE* stream; 132 | int logLevel; 133 | }; 134 | 135 | } 136 | 137 | #endif //FLANN_LOGGER_H 138 | -------------------------------------------------------------------------------- /src/cpp/flann/util/matrix.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | #ifndef FLANN_DATASET_H_ 32 | #define FLANN_DATASET_H_ 33 | 34 | #include "flann/general.h" 35 | #include "flann/util/serialization.h" 36 | #include 37 | 38 | namespace flann 39 | { 40 | 41 | typedef unsigned char uchar; 42 | 43 | class Matrix_ 44 | { 45 | public: 46 | 47 | Matrix_() : rows(0), cols(0), stride(0), type(FLANN_NONE), data(NULL) 48 | { 49 | }; 50 | 51 | Matrix_(void* data_, size_t rows_, size_t cols_, flann_datatype_t type_, size_t stride_ = 0) : 52 | rows(rows_), cols(cols_), stride(stride_), type(type_) 53 | { 54 | data = static_cast(data_); 55 | 56 | if (stride==0) stride = flann_datatype_size(type)*cols; 57 | } 58 | 59 | /** 60 | * Operator that returns a (pointer to a) row of the data. 61 | */ 62 | inline void* operator[](size_t index) const 63 | { 64 | return data+index*stride; 65 | } 66 | 67 | void* ptr() const 68 | { 69 | return data; 70 | } 71 | 72 | size_t rows; 73 | size_t cols; 74 | size_t stride; 75 | flann_datatype_t type; 76 | protected: 77 | uchar* data; 78 | 79 | template 80 | void serialize(Archive& ar) 81 | { 82 | ar & rows; 83 | ar & cols; 84 | ar & stride; 85 | ar & type; 86 | if (Archive::is_loading::value) { 87 | data = new uchar[rows*stride]; 88 | } 89 | ar & serialization::make_binary_object(data, rows*stride); 90 | } 91 | friend struct serialization::access; 92 | }; 93 | 94 | 95 | /** 96 | * Class that implements a simple rectangular matrix stored in a memory buffer and 97 | * provides convenient matrix-like access using the [] operators. 98 | * 99 | * This class has the same memory structure as the un-templated class flann::Matrix_ and 100 | * it's directly convertible from it. 101 | */ 102 | template 103 | class Matrix : public Matrix_ 104 | { 105 | public: 106 | typedef T type; 107 | 108 | Matrix() : Matrix_() 109 | { 110 | } 111 | 112 | Matrix(T* data_, size_t rows_, size_t cols_, size_t stride_ = 0) : 113 | Matrix_(data_, rows_, cols_, flann_datatype_value::value, stride_) 114 | { 115 | if (stride==0) stride = sizeof(T)*cols; 116 | } 117 | 118 | /** 119 | * Operator that returns a (pointer to a) row of the data. 120 | */ 121 | inline T* operator[](size_t index) const 122 | { 123 | return reinterpret_cast(data+index*stride); 124 | } 125 | 126 | 127 | T* ptr() const 128 | { 129 | return reinterpret_cast(data); 130 | } 131 | }; 132 | 133 | } 134 | 135 | #endif //FLANN_DATASET_H_ 136 | -------------------------------------------------------------------------------- /src/cpp/flann/util/object_factory.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | #ifndef FLANN_OBJECT_FACTORY_H_ 32 | #define FLANN_OBJECT_FACTORY_H_ 33 | 34 | #include 35 | 36 | namespace flann 37 | { 38 | 39 | class CreatorNotFound 40 | { 41 | }; 42 | 43 | template 46 | class ObjectFactory 47 | { 48 | typedef ObjectFactory ThisClass; 49 | typedef std::map ObjectRegistry; 50 | 51 | // singleton class, private constructor 52 | ObjectFactory() {} 53 | 54 | public: 55 | 56 | bool subscribe(UniqueIdType id, ObjectCreator creator) 57 | { 58 | if (object_registry.find(id) != object_registry.end()) return false; 59 | 60 | object_registry[id] = creator; 61 | return true; 62 | } 63 | 64 | bool unregister(UniqueIdType id) 65 | { 66 | return object_registry.erase(id) == 1; 67 | } 68 | 69 | ObjectCreator create(UniqueIdType id) 70 | { 71 | typename ObjectRegistry::const_iterator iter = object_registry.find(id); 72 | 73 | if (iter == object_registry.end()) { 74 | throw CreatorNotFound(); 75 | } 76 | 77 | return iter->second; 78 | } 79 | 80 | static ThisClass& instance() 81 | { 82 | static ThisClass the_factory; 83 | return the_factory; 84 | } 85 | private: 86 | ObjectRegistry object_registry; 87 | }; 88 | 89 | } 90 | 91 | #endif /* FLANN_OBJECT_FACTORY_H_ */ 92 | -------------------------------------------------------------------------------- /src/cpp/flann/util/params.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #ifndef FLANN_PARAMS_H_ 31 | #define FLANN_PARAMS_H_ 32 | 33 | #include "any.h" 34 | #include "flann/general.h" 35 | #include 36 | #include 37 | 38 | 39 | namespace flann 40 | { 41 | 42 | namespace anyimpl 43 | { 44 | SMALL_POLICY(flann_algorithm_t); 45 | SMALL_POLICY(flann_centers_init_t); 46 | SMALL_POLICY(flann_log_level_t); 47 | SMALL_POLICY(flann_datatype_t); 48 | } 49 | 50 | 51 | typedef std::map IndexParams; 52 | 53 | 54 | typedef enum { 55 | FLANN_False = 0, 56 | FLANN_True = 1, 57 | FLANN_Undefined 58 | } tri_type; 59 | 60 | 61 | struct SearchParams 62 | { 63 | SearchParams(int checks_ = 32, float eps_ = 0.0, bool sorted_ = true ) : 64 | checks(checks_), eps(eps_), sorted(sorted_) 65 | { 66 | max_neighbors = -1; 67 | use_heap = FLANN_Undefined; 68 | cores = 1; 69 | matrices_in_gpu_ram = false; 70 | } 71 | 72 | // how many leafs to visit when searching for neighbours (-1 for unlimited) 73 | int checks; 74 | // search for eps-approximate neighbours (default: 0) 75 | float eps; 76 | // only for radius search, require neighbours sorted by distance (default: true) 77 | bool sorted; 78 | // maximum number of neighbors radius search should return (-1 for unlimited) 79 | int max_neighbors; 80 | // use a heap to manage the result set (default: FLANN_Undefined) 81 | tri_type use_heap; 82 | // how many cores to assign to the search (used only if compiled with OpenMP capable compiler) (0 for auto) 83 | int cores; 84 | // for GPU search indicates if matrices are already in GPU ram 85 | bool matrices_in_gpu_ram; 86 | }; 87 | 88 | 89 | inline bool has_param(const IndexParams& params, std::string name) 90 | { 91 | return params.find(name)!=params.end(); 92 | } 93 | 94 | template 95 | T get_param(const IndexParams& params, std::string name, const T& default_value) 96 | { 97 | IndexParams::const_iterator it = params.find(name); 98 | if (it != params.end()) { 99 | return it->second.cast(); 100 | } 101 | else { 102 | return default_value; 103 | } 104 | } 105 | 106 | template 107 | T get_param(const IndexParams& params, std::string name) 108 | { 109 | IndexParams::const_iterator it = params.find(name); 110 | if (it != params.end()) { 111 | return it->second.cast(); 112 | } 113 | else { 114 | throw FLANNException(std::string("Missing parameter '")+name+std::string("' in the parameters given")); 115 | } 116 | } 117 | 118 | inline void print_params(const IndexParams& params) 119 | { 120 | IndexParams::const_iterator it; 121 | 122 | for(it=params.begin(); it!=params.end(); ++it) { 123 | std::cout << it->first << " : " << it->second << std::endl; 124 | } 125 | } 126 | 127 | inline void print_params(const SearchParams& params) 128 | { 129 | std::cout << "checks : " << params.checks << std::endl; 130 | std::cout << "eps : " << params.eps << std::endl; 131 | std::cout << "sorted : " << params.sorted << std::endl; 132 | std::cout << "max_neighbors : " << params.max_neighbors << std::endl; 133 | } 134 | 135 | 136 | } 137 | 138 | 139 | #endif /* FLANN_PARAMS_H_ */ 140 | -------------------------------------------------------------------------------- /src/cpp/flann/util/random.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | #ifndef FLANN_RANDOM_H 32 | #define FLANN_RANDOM_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "flann/general.h" 41 | 42 | namespace flann 43 | { 44 | 45 | /** 46 | * Seeds the random number generator 47 | * @param seed Random seed 48 | */ 49 | inline void seed_random(unsigned int seed) 50 | { 51 | srand(seed); 52 | } 53 | 54 | /** 55 | * Generates a random double value. 56 | * @param high Upper limit 57 | * @param low Lower limit 58 | * @return Random double value 59 | */ 60 | inline double rand_double(double high = 1.0, double low = 0) 61 | { 62 | return low + ((high - low) * (std::rand() / (RAND_MAX + 1.0))); 63 | } 64 | 65 | /** 66 | * Generates a random integer value. 67 | * @param high Upper limit 68 | * @param low Lower limit 69 | * @return Random integer value 70 | */ 71 | inline int rand_int(int high = RAND_MAX, int low = 0) 72 | { 73 | return low + (int)(double(high - low) * (std::rand() / (RAND_MAX + 1.0))); 74 | } 75 | 76 | 77 | /** 78 | * Random number generator that returns a distinct number from 79 | * the [0,n) interval each time. 80 | */ 81 | class UniqueRandom 82 | { 83 | std::vector vals_; 84 | int size_; 85 | int counter_; 86 | 87 | public: 88 | /** 89 | * Constructor. 90 | * @param n Size of the interval from which to generate 91 | * @return 92 | */ 93 | UniqueRandom(int n) 94 | { 95 | init(n); 96 | } 97 | 98 | /** 99 | * Initializes the number generator. 100 | * @param n the size of the interval from which to generate random numbers. 101 | */ 102 | void init(int n) 103 | { 104 | // create and initialize an array of size n 105 | vals_.resize(n); 106 | size_ = n; 107 | for (int i = 0; i < size_; ++i) vals_[i] = i; 108 | 109 | std::random_device rd; 110 | std::mt19937 g(rd()); 111 | std::shuffle(vals_.begin(), vals_.end(), g); 112 | 113 | counter_ = 0; 114 | } 115 | 116 | /** 117 | * Return a distinct random integer in greater or equal to 0 and less 118 | * than 'n' on each call. It should be called maximum 'n' times. 119 | * Returns: a random integer 120 | */ 121 | int next() 122 | { 123 | if (counter_ == size_) { 124 | return -1; 125 | } 126 | else { 127 | return vals_[counter_++]; 128 | } 129 | } 130 | }; 131 | 132 | } 133 | 134 | #endif //FLANN_RANDOM_H 135 | 136 | 137 | -------------------------------------------------------------------------------- /src/cpp/flann/util/sampling.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 | 29 | 30 | #ifndef FLANN_SAMPLING_H_ 31 | #define FLANN_SAMPLING_H_ 32 | 33 | #include "flann/util/matrix.h" 34 | #include "flann/util/random.h" 35 | 36 | namespace flann 37 | { 38 | 39 | template 40 | Matrix random_sample(Matrix& srcMatrix, size_t size, bool remove = false) 41 | { 42 | UniqueRandom rand_unique(srcMatrix.rows); 43 | Matrix newSet(new T[size * srcMatrix.cols], size,srcMatrix.cols); 44 | 45 | T* src,* dest; 46 | for (size_t i=0; i(rand_int(srcMatrix.rows-i)); 50 | } 51 | else { 52 | r = static_cast(rand_unique.next()); 53 | } 54 | dest = newSet[i]; 55 | src = srcMatrix[r]; 56 | std::copy(src, src+srcMatrix.cols, dest); 57 | if (remove) { 58 | src = srcMatrix[srcMatrix.rows-i-1]; 59 | dest = srcMatrix[r]; 60 | std::copy(src, src+srcMatrix.cols, dest); 61 | } 62 | } 63 | if (remove) { 64 | srcMatrix.rows -= size; 65 | } 66 | return newSet; 67 | } 68 | 69 | } // namespace 70 | 71 | 72 | #endif /* FLANN_SAMPLING_H_ */ 73 | -------------------------------------------------------------------------------- /src/cpp/flann/util/saving.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 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 NNIndexGOODS 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 | 29 | #ifndef FLANN_SAVING_H_ 30 | #define FLANN_SAVING_H_ 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include "flann/general.h" 37 | #include "flann/util/serialization.h" 38 | 39 | 40 | #ifdef FLANN_SIGNATURE_ 41 | #undef FLANN_SIGNATURE_ 42 | #endif 43 | #define FLANN_SIGNATURE_ "FLANN_INDEX_v1.1" 44 | 45 | namespace flann 46 | { 47 | 48 | /** 49 | * Structure representing the index header. 50 | */ 51 | struct IndexHeader 52 | { 53 | IndexHeaderStruct h; 54 | 55 | IndexHeader() 56 | { 57 | memset(h.signature, 0, sizeof(h.signature)); 58 | strcpy(h.signature, FLANN_SIGNATURE_); 59 | memset(h.version, 0, sizeof(h.version)); 60 | strcpy(h.version, FLANN_VERSION_); 61 | 62 | h.compression = 0; 63 | h.first_block_size = 0; 64 | } 65 | 66 | private: 67 | template 68 | void serialize(Archive& ar) 69 | { 70 | ar & h.signature; 71 | ar & h.version; 72 | ar & h.data_type; 73 | ar & h.index_type; 74 | ar & h.rows; 75 | ar & h.cols; 76 | ar & h.compression; 77 | ar & h.first_block_size; 78 | } 79 | friend struct serialization::access; 80 | }; 81 | 82 | /** 83 | * Saves index header to stream 84 | * 85 | * @param stream - Stream to save to 86 | * @param index - The index to save 87 | */ 88 | template 89 | void save_header(FILE* stream, const Index& index) 90 | { 91 | IndexHeader header; 92 | header.h.data_type = flann_datatype_value::value; 93 | header.h.index_type = index.getType(); 94 | header.h.rows = index.size(); 95 | header.h.cols = index.veclen(); 96 | 97 | fwrite(&header, sizeof(header),1,stream); 98 | } 99 | 100 | 101 | /** 102 | * 103 | * @param stream - Stream to load from 104 | * @return Index header 105 | */ 106 | inline IndexHeader load_header(FILE* stream) 107 | { 108 | IndexHeader header; 109 | int read_size = fread(&header,sizeof(header),1,stream); 110 | 111 | if (read_size != 1) { 112 | throw FLANNException("Invalid index file, cannot read"); 113 | } 114 | 115 | if (strncmp(header.h.signature, 116 | FLANN_SIGNATURE_, 117 | strlen(FLANN_SIGNATURE_) - strlen("v0.0")) != 0) { 118 | throw FLANNException("Invalid index file, wrong signature"); 119 | } 120 | 121 | return header; 122 | } 123 | 124 | 125 | namespace serialization 126 | { 127 | ENUM_SERIALIZER(flann_algorithm_t); 128 | ENUM_SERIALIZER(flann_centers_init_t); 129 | ENUM_SERIALIZER(flann_log_level_t); 130 | ENUM_SERIALIZER(flann_datatype_t); 131 | } 132 | 133 | } 134 | 135 | #endif /* FLANN_SAVING_H_ */ 136 | -------------------------------------------------------------------------------- /src/cpp/flann/util/timer.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 6 | * 7 | * THE BSD LICENSE 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *************************************************************************/ 30 | 31 | #ifndef FLANN_TIMER_H 32 | #define FLANN_TIMER_H 33 | 34 | #include 35 | 36 | 37 | namespace flann 38 | { 39 | 40 | /** 41 | * A start-stop timer class. 42 | * 43 | * Can be used to time portions of code. 44 | */ 45 | class StartStopTimer 46 | { 47 | clock_t startTime; 48 | 49 | public: 50 | /** 51 | * Value of the timer. 52 | */ 53 | double value; 54 | 55 | 56 | /** 57 | * Constructor. 58 | */ 59 | StartStopTimer() 60 | { 61 | reset(); 62 | } 63 | 64 | /** 65 | * Starts the timer. 66 | */ 67 | void start() 68 | { 69 | startTime = clock(); 70 | } 71 | 72 | /** 73 | * Stops the timer and updates timer value. 74 | */ 75 | double stop() 76 | { 77 | clock_t stopTime = clock(); 78 | value += ( (double)stopTime - startTime) / CLOCKS_PER_SEC; 79 | 80 | return value; 81 | } 82 | 83 | /** 84 | * Resets the timer value to 0. 85 | */ 86 | void reset() 87 | { 88 | value = 0; 89 | } 90 | 91 | }; 92 | 93 | } 94 | 95 | #endif // FLANN_TIMER_H 96 | -------------------------------------------------------------------------------- /src/matlab/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #IF(WIN32) 2 | # SET(MEXEXT_CMD cmd /C mexext) 3 | #ELSE(WIN32) 4 | # SET(MEXEXT_CMD mexext) 5 | #ENDIF(WIN32) 6 | 7 | SET(MEX_NAME nearest_neighbors) 8 | 9 | if(WIN32) 10 | find_program(MEX_CMD mex.bat) 11 | find_program(MEXEXT_CMD mexext.bat) 12 | else() 13 | find_program(MEX_CMD mex) 14 | find_program(MEXEXT_CMD mexext) 15 | endif() 16 | 17 | find_program(OCT_CMD mkoctfile) 18 | 19 | get_property(FLANN_LIB_LOCATION TARGET flann_s PROPERTY LOCATION) 20 | get_filename_component(FLANN_LIB_PATH ${FLANN_LIB_LOCATION} PATH) 21 | 22 | if(MEX_CMD AND MEXEXT_CMD) 23 | 24 | get_filename_component(MEX_REAL_CMD ${MEX_CMD} ABSOLUTE) 25 | get_filename_component(MEX_PATH ${MEX_REAL_CMD} PATH) 26 | 27 | get_filename_component(MEXEXT_REAL_CMD ${MEXEXT_CMD} ABSOLUTE) 28 | get_filename_component(MEXEXT_PATH ${MEXEXT_REAL_CMD} PATH) 29 | 30 | if (MEX_PATH STREQUAL MEXEXT_PATH) 31 | message(STATUS "Found MATLAB at: " ${MEX_PATH}) 32 | 33 | EXECUTE_PROCESS(COMMAND ${MEXEXT_REAL_CMD} OUTPUT_VARIABLE MEX_EXTENSION OUTPUT_STRIP_TRAILING_WHITESPACE) 34 | SET(MEX_FILE ${CMAKE_CURRENT_BINARY_DIR}/${MEX_NAME}.${MEX_EXTENSION}) 35 | 36 | 37 | if (WIN32) 38 | if (MSVC_IDE) 39 | set(MEX_BUILD_FLAGS "COMPFLAGS=\"$COMPFLAGS ${OpenMP_CXX_FLAGS}\" LINKFLAGS=\"$LINKFLAGS ${OpenMP_CXX_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}\"") 40 | else() 41 | set(MEX_BUILD_FLAGS "COMPFLAGS=\"$$COMPFLAGS ${OpenMP_CXX_FLAGS}\" LINKFLAGS=\"$$LINKFLAGS ${OpenMP_CXX_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}\"") 42 | endif() 43 | else() 44 | set(MEX_BUILD_FLAGS "CFLAGS='$$CFLAGS ${OpenMP_CXX_FLAGS}' LDFLAGS='$$LDFLAGS ${OpenMP_CXX_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}'") 45 | endif() 46 | separate_arguments(MEX_BUILD_FLAGS) 47 | 48 | ADD_CUSTOM_COMMAND( 49 | OUTPUT ${MEX_FILE} 50 | COMMAND ${MEX_REAL_CMD} 51 | ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${MEX_NAME}.cpp -I${PROJECT_SOURCE_DIR}/src/cpp -L${FLANN_LIB_PATH} -lflann_s ${MEX_BUILD_FLAGS} 52 | DEPENDS flann_s ${CMAKE_CURRENT_SOURCE_DIR}/${MEX_NAME}.cpp 53 | COMMENT "Building MEX extension ${MEX_FILE}" 54 | ) 55 | 56 | ADD_CUSTOM_TARGET(mex_${MEX_NAME} ALL DEPENDS ${MEX_FILE}) 57 | 58 | FILE(GLOB MATLAB_SOURCES *.m) 59 | 60 | INSTALL ( 61 | FILES ${MEX_FILE} ${MATLAB_SOURCES} 62 | DESTINATION share/flann/matlab 63 | ) 64 | else() 65 | message(WARNING "The 'mex' and 'mexext' programs have been found in different locations. It's likely that one of them is not part of the MATLAB instalation. Make sure that the 'bin' directory from the MATLAB instalation is in PATH") 66 | set(BUILD_MATLAB_BINDINGS OFF) 67 | endif() 68 | elseif(OCT_CMD) 69 | SET(MEX_FILE ${CMAKE_CURRENT_BINARY_DIR}/${MEX_NAME}.mex) 70 | ADD_CUSTOM_COMMAND( 71 | OUTPUT ${MEX_FILE} 72 | COMMAND ${OCT_CMD} 73 | ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${MEX_NAME}.cpp -I${PROJECT_SOURCE_DIR}/src/cpp -L${FLANN_LIB_PATH} -DFLANN_STATIC -lflann_s -lgomp --mex 74 | DEPENDS flann_s ${CMAKE_CURRENT_SOURCE_DIR}/${MEX_NAME}.cpp 75 | COMMENT "Building MEX extension ${MEX_FILE}" 76 | ) 77 | 78 | ADD_CUSTOM_TARGET(mex_${MEX_NAME} ALL DEPENDS ${MEX_FILE}) 79 | 80 | FILE(GLOB MATLAB_SOURCES *.m) 81 | 82 | INSTALL ( 83 | FILES ${MEX_FILE} ${MATLAB_SOURCES} 84 | DESTINATION share/flann/octave 85 | ) 86 | else() 87 | message(WARNING "Cannot find MATLAB or Octave instalation. Make sure that the 'bin' directory from the MATLAB instalation or that mkoctfile is in PATH") 88 | set(BUILD_MATLAB_BINDINGS OFF) 89 | endif() 90 | 91 | -------------------------------------------------------------------------------- /src/matlab/flann_build_index.m: -------------------------------------------------------------------------------- 1 | function [index, params, speedup] = flann_build_index(dataset, build_params) 2 | %FLANN_BUILD_INDEX Builds an index for fast approximate nearest neighbors search 3 | % 4 | % [index, params, speedup] = flann_build_index(dataset, build_params) - Constructs the 5 | % index from the provided 'dataset' and (optionally) computes the optimal parameters. 6 | 7 | % Marius Muja, January 2008 8 | 9 | algos = struct( 'linear', 0, 'kdtree', 1, 'kmeans', 2, 'composite', 3, 'kdtree_single', 4, 'hierarchical', 5, 'lsh', 6, 'saved', 254, 'autotuned', 255 ); 10 | center_algos = struct('random', 0, 'gonzales', 1, 'kmeanspp', 2 ); 11 | log_levels = struct('none', 0, 'fatal', 1, 'error', 2, 'warning', 3, 'info', 4); 12 | 13 | default_params = struct('algorithm', 'kdtree' ,'checks', 32, 'eps', 0.0, 'sorted', 1, 'max_neighbors', -1, 'cores', 1, 'trees', 4, 'branching', 32, 'iterations', 5, 'centers_init', 'random', 'cb_index', 0.4, 'target_precision', 0.9,'build_weight', 0.01, 'memory_weight', 0, 'sample_fraction', 0.1, 'table_number', 12, 'key_size', 20, 'multi_probe_level', 2, 'log_level', 'warning', 'random_seed', 0); 14 | 15 | if ~isstruct(build_params) 16 | error('The "build_params" argument must be a structure'); 17 | end 18 | 19 | params = default_params; 20 | fn = fieldnames(build_params); 21 | for i = [1:length(fn)], 22 | name = cell2mat(fn(i)); 23 | params.(name) = build_params.(name); 24 | end 25 | if ~isnumeric(params.algorithm), 26 | params.algorithm = value2id(algos,params.algorithm); 27 | end 28 | if ~isnumeric(params.centers_init), 29 | params.centers_init = value2id(center_algos,params.centers_init); 30 | end 31 | if ~isnumeric(params.log_level), 32 | params.log_level = value2id(log_levels,params.log_level); 33 | end 34 | 35 | [index, params, speedup] = nearest_neighbors('build_index',dataset, params); 36 | 37 | if isnumeric(params.algorithm), 38 | params.algorithm = id2value(algos,params.algorithm); 39 | end 40 | if isnumeric(params.centers_init), 41 | params.centers_init = id2value(center_algos,params.centers_init); 42 | end 43 | end 44 | 45 | function value = id2value(map, id) 46 | fields = fieldnames(map); 47 | for i = 1:length(fields), 48 | val = cell2mat(fields(i)); 49 | if map.(val) == id 50 | value = val; 51 | break; 52 | end 53 | end 54 | end 55 | function id = value2id(map,value) 56 | id = map.(value); 57 | end 58 | -------------------------------------------------------------------------------- /src/matlab/flann_free_index.m: -------------------------------------------------------------------------------- 1 | %Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 2 | %Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 3 | % 4 | %THE BSD LICENSE 5 | % 6 | %Redistribution and use in source and binary forms, with or without 7 | %modification, are permitted provided that the following conditions 8 | %are met: 9 | % 10 | %1. Redistributions of source code must retain the above copyright 11 | % notice, this list of conditions and the following disclaimer. 12 | %2. Redistributions in binary form must reproduce the above copyright 13 | % notice, this list of conditions and the following disclaimer in the 14 | % documentation and/or other materials provided with the distribution. 15 | % 16 | %THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | %IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | %OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | %IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | %INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | %NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | %DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | %THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | %(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | %THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | function flann_free_index(index_id) 28 | %FLANN_FREE_INDEX Deletes the nearest-neighbors index 29 | % 30 | % Deletes an index constructed using flann_build_index. 31 | 32 | % Marius Muja, January 2008 33 | 34 | nearest_neighbors('free_index',index_id); 35 | end -------------------------------------------------------------------------------- /src/matlab/flann_load_index.m: -------------------------------------------------------------------------------- 1 | %Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 2 | %Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 3 | % 4 | %THE BSD LICENSE 5 | % 6 | %Redistribution and use in source and binary forms, with or without 7 | %modification, are permitted provided that the following conditions 8 | %are met: 9 | % 10 | %1. Redistributions of source code must retain the above copyright 11 | % notice, this list of conditions and the following disclaimer. 12 | %2. Redistributions in binary form must reproduce the above copyright 13 | % notice, this list of conditions and the following disclaimer in the 14 | % documentation and/or other materials provided with the distribution. 15 | % 16 | %THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | %IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | %OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | %IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | %INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | %NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | %DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | %THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | %(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | %THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | function index = flann_load_index(filename, dataset) 28 | %FLANN_LOAD_INDEX Loads an index from disk 29 | % 30 | % Marius Muja, March 2009 31 | 32 | index = nearest_neighbors('load_index', filename, dataset); 33 | end -------------------------------------------------------------------------------- /src/matlab/flann_save_index.m: -------------------------------------------------------------------------------- 1 | %Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 2 | %Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 3 | % 4 | %THE BSD LICENSE 5 | % 6 | %Redistribution and use in source and binary forms, with or without 7 | %modification, are permitted provided that the following conditions 8 | %are met: 9 | % 10 | %1. Redistributions of source code must retain the above copyright 11 | % notice, this list of conditions and the following disclaimer. 12 | %2. Redistributions in binary form must reproduce the above copyright 13 | % notice, this list of conditions and the following disclaimer in the 14 | % documentation and/or other materials provided with the distribution. 15 | % 16 | %THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | %IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | %OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | %IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | %INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | %NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | %DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | %THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | %(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | %THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | function flann_save_index(index_id, filename) 28 | %FLANN_SAVE_INDEX Saves an index to disk 29 | % 30 | 31 | % Marius Muja, March 2010 32 | 33 | nearest_neighbors('save_index',index_id, filename); 34 | end -------------------------------------------------------------------------------- /src/matlab/flann_search.m: -------------------------------------------------------------------------------- 1 | %Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 2 | %Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 3 | % 4 | %THE BSD LICENSE 5 | % 6 | %Redistribution and use in source and binary forms, with or without 7 | %modification, are permitted provided that the following conditions 8 | %are met: 9 | % 10 | %1. Redistributions of source code must retain the above copyright 11 | % notice, this list of conditions and the following disclaimer. 12 | %2. Redistributions in binary form must reproduce the above copyright 13 | % notice, this list of conditions and the following disclaimer in the 14 | % documentation and/or other materials provided with the distribution. 15 | % 16 | %THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | %IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | %OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | %IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | %INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | %NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | %DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | %THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | %(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | %THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | function [indices, dists] = flann_search(data, testset, n, search_params) 28 | %NN_SEARCH Fast approximate nearest neighbors search 29 | % 30 | % Performs a fast approximate nearest neighbor search using an 31 | % index constructed using flann_build_index or directly a 32 | % dataset. 33 | 34 | % Marius Muja, January 2008 35 | 36 | 37 | algos = struct( 'linear', 0, 'kdtree', 1, 'kmeans', 2, 'composite', 3, 'lsh', 6, 'saved', 254, 'autotuned', 255 ); 38 | center_algos = struct('random', 0, 'gonzales', 1, 'kmeanspp', 2 ); 39 | log_levels = struct('none', 0, 'fatal', 1, 'error', 2, 'warning', 3, 'info', 4); 40 | 41 | default_params = struct('algorithm', 'kdtree' ,'checks', 32, 'eps', 0.0, 'sorted', 1, 'max_neighbors', -1, 'cores', 1, 'trees', 4, 'branching', 32, 'iterations', 5, 'centers_init', 'random', 'cb_index', 0.4, 'target_precision', 0.9,'build_weight', 0.01, 'memory_weight', 0, 'sample_fraction', 0.1, 'table_number', 12, 'key_size', 20, 'multi_probe_level', 2, 'log_level', 'warning', 'random_seed', 0); 42 | 43 | if ~isstruct(search_params) 44 | error('The "search_params" argument must be a structure'); 45 | end 46 | 47 | params = default_params; 48 | fn = fieldnames(search_params); 49 | for i = [1:length(fn)], 50 | name = cell2mat(fn(i)); 51 | params.(name) = search_params.(name); 52 | end 53 | if ~isnumeric(params.algorithm), 54 | params.algorithm = value2id(algos,params.algorithm); 55 | end 56 | if ~isnumeric(params.centers_init), 57 | params.centers_init = value2id(center_algos,params.centers_init); 58 | end 59 | if ~isnumeric(params.log_level), 60 | params.log_level = value2id(log_levels,params.log_level); 61 | end 62 | 63 | if (size(data,1)==1 && size(data,2)==1) 64 | % we already have an index 65 | [indices,dists] = nearest_neighbors('index_find_nn', data, testset, n, params); 66 | else 67 | % create the index and search 68 | [indices,dists] = nearest_neighbors('find_nn', data, testset, n, params); 69 | end 70 | end 71 | 72 | function value = id2value(map, id) 73 | fields = fieldnames(map); 74 | for i = 1:length(fields), 75 | val = cell2mat(fields(i)); 76 | if map.(val) == id 77 | value = val; 78 | break; 79 | end 80 | end 81 | end 82 | function id = value2id(map,value) 83 | id = map.(value); 84 | end 85 | -------------------------------------------------------------------------------- /src/matlab/flann_set_distance_type.m: -------------------------------------------------------------------------------- 1 | %Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 2 | %Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 3 | % 4 | %THE BSD LICENSE 5 | % 6 | %Redistribution and use in source and binary forms, with or without 7 | %modification, are permitted provided that the following conditions 8 | %are met: 9 | % 10 | %1. Redistributions of source code must retain the above copyright 11 | % notice, this list of conditions and the following disclaimer. 12 | %2. Redistributions in binary form must reproduce the above copyright 13 | % notice, this list of conditions and the following disclaimer in the 14 | % documentation and/or other materials provided with the distribution. 15 | % 16 | %THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | %IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | %OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | %IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | %INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | %NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | %DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | %THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | %(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | %THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | function flann_set_distance_type(type, order) 28 | %FLANN_LOAD_INDEX Loads an index from disk 29 | % 30 | % Marius Muja, March 2009 31 | 32 | distances = struct('euclidean', 1, 'manhattan', 2, 'minkowski', 3, 'max_dist', 4, 'hik', 5, 'hellinger', 6, 'chi_square', 7, 'cs', 7, 'kullback_leibler', 8, 'kl', 8); 33 | 34 | if ~isnumeric(type), 35 | type = value2id(distances,type); 36 | end 37 | if type~=3 38 | order = 0; 39 | end 40 | nearest_neighbors('set_distance_type', type, order); 41 | end 42 | 43 | function id = value2id(map,value) 44 | id = map.(value); 45 | end 46 | -------------------------------------------------------------------------------- /src/python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | configure_file( setup.py.tpl setup.py ) 2 | 3 | install( DIRECTORY pyflann DESTINATION share/flann/python ) 4 | install( FILES ${CMAKE_CURRENT_BINARY_DIR}/setup.py DESTINATION share/flann/python ) 5 | 6 | 7 | # python instalation 8 | if (PYTHON_EXECUTABLE) 9 | install(CODE "execute_process( 10 | COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py install 11 | WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\")") 12 | endif() 13 | -------------------------------------------------------------------------------- /src/python/pyflann/__init__.py: -------------------------------------------------------------------------------- 1 | #Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 2 | #Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 3 | # 4 | #THE BSD LICENSE 5 | # 6 | #Redistribution and use in source and binary forms, with or without 7 | #modification, are permitted provided that the following conditions 8 | #are met: 9 | # 10 | #1. Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | #2. Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # 16 | #THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | #IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | #OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | #IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | #INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | #NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | #DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | #THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | #(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | #THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #import sys 28 | #import os 29 | #sys.path.insert(0, os.path.split(__file__)[0]) # make python3 happy 30 | 31 | from pyflann.index import * 32 | -------------------------------------------------------------------------------- /src/python/pyflann/exceptions.py: -------------------------------------------------------------------------------- 1 | #Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. 2 | #Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. 3 | # 4 | #THE BSD LICENSE 5 | # 6 | #Redistribution and use in source and binary forms, with or without 7 | #modification, are permitted provided that the following conditions 8 | #are met: 9 | # 10 | #1. Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | #2. Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # 16 | #THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | #IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | #OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | #IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | #INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | #NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | #DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | #THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | #(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | #THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | 28 | # This module defines exceptions that are used by the flann python bindings 29 | 30 | class FLANNException(Exception): 31 | def __init__(self, *args): 32 | Exception.__init__(self, *args) 33 | -------------------------------------------------------------------------------- /src/python/setup.py.tpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from distutils.core import setup 4 | from os.path import exists, abspath, dirname, join 5 | import os 6 | import sys 7 | 8 | 9 | def find_path(): 10 | lib_paths = [ os.path.abspath('@LIBRARY_OUTPUT_PATH@'), abspath(join(dirname(dirname(sys.argv[0])), '../../../lib')) ] 11 | possible_libs = ['libflann.so', 'flann.dll', 'libflann.dll', 'libflann.dylib'] 12 | 13 | for path in lib_paths: 14 | for lib in possible_libs: 15 | if exists(join(path,lib)): 16 | return path 17 | 18 | setup(name='flann', 19 | version='@FLANN_VERSION@', 20 | description='Fast Library for Approximate Nearest Neighbors', 21 | author='Marius Muja', 22 | author_email='mariusm@cs.ubc.ca', 23 | license='BSD', 24 | url='http://www.cs.ubc.ca/~mariusm/flann/', 25 | packages=['pyflann', 'pyflann.lib'], 26 | package_dir={'pyflann.lib': find_path() }, 27 | package_data={'pyflann.lib': ['libflann.so', 'flann.dll', 'libflann.dll', 'libflann.dylib']}, 28 | ) 29 | -------------------------------------------------------------------------------- /src/ruby/Gemfile: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /src/ruby/LICENSE.txt: -------------------------------------------------------------------------------- 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. 11 | -------------------------------------------------------------------------------- /src/ruby/Manifest.txt: -------------------------------------------------------------------------------- 1 | Rakefile 2 | Gemfile 3 | LICENSE.txt 4 | Manifest.txt 5 | flann.gemspec 6 | lib/flann.rb 7 | lib/index.rb 8 | lib/flann/index.rb 9 | lib/flann/version.rb 10 | spec/spec_helper.rb 11 | spec/flann_spec.rb 12 | spec/index_spec.rb -------------------------------------------------------------------------------- /src/ruby/Rakefile: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /src/ruby/flann.gemspec: -------------------------------------------------------------------------------- 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 | 60 | -------------------------------------------------------------------------------- /src/ruby/lib/flann/version.rb: -------------------------------------------------------------------------------- 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 | module Flann 29 | module VERSION 30 | MAJOR = 1 31 | MINOR = 8 32 | TINY = 4 33 | MINISCULE = 2 34 | 35 | STRING = [MAJOR, MINOR, TINY, MINISCULE].compact.join('.') 36 | end 37 | end -------------------------------------------------------------------------------- /src/ruby/spec/flann_spec.rb: -------------------------------------------------------------------------------- 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 File.dirname(__FILE__) + "/spec_helper.rb" 29 | 30 | describe Flann do 31 | 32 | it "::VERSION::STRING matches #define FLANN_VERSION_ in config.h" do 33 | found = false 34 | File.open(File.dirname(__FILE__) + "/../../cpp/flann/config.h", "r") do |f| 35 | while line = f.gets 36 | next unless line =~ /#[\s]*define[\s]+FLANN_VERSION_[\s]+"\d.\d.\d"/ 37 | fields = line.split 38 | found = true 39 | expect(fields.last[1...-1]).to eq(Flann::VERSION::STRING.split('.')[0...-1].join('.')) 40 | end 41 | end 42 | 43 | raise("could not find version string in config.h") unless found 44 | end 45 | 46 | it "works on the example given in the manual" do 47 | dataset = NMatrix.random([10000,128]) 48 | testset = NMatrix.random([1000,128]) 49 | 50 | index = Flann::Index.new(dataset) do |params| 51 | params[:algorithm] = :kmeans 52 | params[:branching] = 32 53 | params[:iterations] = 7 54 | params[:checks] = 16 55 | end 56 | speedup = index.build! # this is optional 57 | 58 | results, distances = index.nearest_neighbors(testset, 5) 59 | 60 | # Skip saving, as that's tested elsewhere, and I don't feel like cleaning up. 61 | # index.save "my_index.save" 62 | 63 | # Alternatively, without an index: 64 | results, distances = Flann.nearest_neighbors(dataset, testset, 5, 65 | algorithm: :kmeans, branching: 32, 66 | iterations: 7, checks: 16) 67 | end 68 | 69 | context "#set_distance_type!" do 70 | it "sets the distance functor without error" do 71 | Flann.set_distance_type! :euclidean 72 | 73 | # Version check needed before attempting get_distance_type 74 | if Flann.respond_to?(:flann_get_distance_type) 75 | d = Flann.get_distance_type 76 | expect(d).to eq(:euclidean) 77 | end 78 | end 79 | end 80 | 81 | [:byte, :int32, :float32, :float64].each do |dtype| 82 | before :each do 83 | scale = [:byte, :int32, :int64].include?(dtype) ? 255 : 1.0 84 | @dataset = NMatrix.random([1000,128], dtype: dtype, scale: scale) 85 | @testset = NMatrix.random([100,128], dtype: dtype, scale: scale) 86 | end 87 | 88 | context "#nearest_neighbors" do 89 | it "computes the nearest neighbors without an index" do 90 | Flann.nearest_neighbors @dataset, @testset, 5 91 | end 92 | end 93 | 94 | context "#cluster" do 95 | it "calls flann_compute_cluster_centers_... properly" do 96 | Flann.cluster(@dataset, 5) 97 | end 98 | end 99 | 100 | 101 | end 102 | 103 | 104 | end 105 | -------------------------------------------------------------------------------- /src/ruby/spec/index_spec.rb: -------------------------------------------------------------------------------- 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 File.dirname(__FILE__) + "/spec_helper.rb" 29 | 30 | 31 | describe Flann::Index do 32 | [:byte, :int32, :float32, :float64].each do |dtype| 33 | context dtype.inspect do 34 | before :each do 35 | scale = [:byte, :int32, :int64].include?(dtype) ? 255 : 1.0 36 | 37 | @dataset = NMatrix.random([1000,128], dtype: dtype, scale: scale) 38 | @testset = NMatrix.random([100,128], dtype: dtype, scale: scale) 39 | @index = Flann::Index.new(@dataset) do |t| 40 | t[:algorithm] = :kdtree 41 | t[:trees] = 4 42 | end 43 | @index.build! 44 | end 45 | 46 | 47 | context "#nearest_neighbors" do 48 | it "runs without error" do 49 | @index.nearest_neighbors @testset, 5 50 | end 51 | 52 | if dtype == :float32 53 | it "runs a :kdtree_single search correctly" do 54 | @dataset = read_dataset "test.dataset" 55 | @testset = @dataset[0,:*].clone 56 | @index = Flann::Index.new(@dataset) do |t| 57 | t[:algorithm] = :kdtree_single 58 | end 59 | @index.build! 60 | indices, distances = @index.nearest_neighbors @testset, 11 61 | #expect(indices).to eq([0,1,256,257,2,512,258,513,514,3,768]) 62 | expect(indices[0]).to eq(0) 63 | expect(indices[1..2].sort).to eq([1,256]) 64 | expect(indices[3]).to eq(257) 65 | expect(indices[4..5].sort).to eq([2,512]) 66 | expect(indices[6..7].sort).to eq([258,513]) 67 | expect(indices[8]).to eq(514) 68 | expect(indices[9..10].sort).to eq([3,768]) 69 | 70 | expect(distances[0]).to be_within(1E-16).of(0.0) 71 | expect(distances[1]).to be_within(1E-4).of(2.614689) 72 | expect(distances[2]).to be_within(1E-4).of(2.614689) 73 | expect(distances[3]).to be_within(1E-4).of(5.229378) 74 | expect(distances[4]).to be_within(1E-4).of(10.465225) 75 | expect(distances[5]).to be_within(1E-4).of(10.465225) 76 | expect(distances[6]).to be_within(1E-4).of(13.079914) 77 | expect(distances[7]).to be_within(1E-4).of(13.079914) 78 | expect(distances[8]).to be_within(1E-4).of(20.93045) 79 | expect(distances[9]).to be_within(1E-4).of(23.541904) 80 | end 81 | end 82 | end 83 | 84 | 85 | context "#radius_search" do 86 | it "runs without error" do 87 | query = NMatrix.random([1,128]) 88 | @index.radius_search query, 0.4 89 | end 90 | end 91 | 92 | 93 | context "#save" do 94 | it "saves an index to a file which can be loaded again" do 95 | FileUtils.rm("temp_index.save_file", :force => true) 96 | @index.save("temp_index.save_file") 97 | 98 | raise(IOError, "save failed") unless File.exists?("temp_index.save_file") 99 | 100 | post_index = Flann::Index.new(@dataset) 101 | post_index.load!("temp_index.save_file") 102 | FileUtils.rm("temp_index.save_file", :force => true) 103 | end 104 | end 105 | 106 | 107 | context "#free!" do 108 | it "frees an index" do 109 | @index.free! 110 | end 111 | end 112 | end 113 | end 114 | end -------------------------------------------------------------------------------- /src/ruby/spec/spec_helper.rb: -------------------------------------------------------------------------------- 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 'rspec' 29 | require 'rspec/longrun' 30 | 31 | require "./lib/flann" 32 | 33 | # Helper function for reading a test dataset so we can test nearest neighbors 34 | # and radius search and such. 35 | def read_dataset filename 36 | Dir.chdir("spec") do 37 | f = File.new(filename, 'r') 38 | n = NMatrix.new([65536, 3], dtype: :float32) 39 | i = 0 40 | while line = f.gets 41 | line.chomp! 42 | fields = line.split 43 | n[i,:*] = fields.map { |field| field.to_f } 44 | 45 | i += 1 46 | end 47 | 48 | n 49 | end 50 | end -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_custom_target(tests) 3 | add_custom_target(flann_gtests) 4 | 5 | add_dependencies(tests flann_gtests) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}) 8 | 9 | if (HDF5_FOUND) 10 | include_directories(${HDF5_INCLUDE_DIR}) 11 | 12 | set(TEST_LIBRARIES "${HDF5_LIBRARIES}") 13 | if (HDF5_IS_PARALLEL) 14 | set(TEST_LIBRARIES "${TEST_LIBRARIES};${MPI_LIBRARIES}") 15 | endif() 16 | 17 | flann_add_gtest(flann_linear_test flann_linear_test.cpp flann_cpp ${TEST_LIBRARIES}) 18 | flann_add_gtest(flann_kdtree_test flann_kdtree_test.cpp flann_cpp ${TEST_LIBRARIES}) 19 | flann_add_gtest(flann_kmeans_test flann_kmeans_test.cpp flann_cpp ${TEST_LIBRARIES}) 20 | flann_add_gtest(flann_kdtree_single_test flann_kdtree_single_test.cpp flann_cpp ${TEST_LIBRARIES}) 21 | flann_add_gtest(flann_hierarchical_test flann_hierarchical_test.cpp flann_cpp ${TEST_LIBRARIES}) 22 | flann_add_gtest(flann_lsh_test flann_lsh_test.cpp flann_cpp ${TEST_LIBRARIES}) 23 | flann_add_gtest(flann_autotuned_test flann_autotuned_test.cpp flann_cpp ${TEST_LIBRARIES}) 24 | if (OPENMP_FOUND) 25 | flann_add_gtest(flann_multithreaded_test flann_multithreaded_test.cpp flann_cpp ${TEST_LIBRARIES}) 26 | endif() 27 | 28 | endif() 29 | 30 | if (HDF5_FOUND AND BUILD_CUDA_LIB) 31 | set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-Xcompiler;-fPIC;-Xcudafe \"--diag_suppress=partial_override\" ;-gencode=arch=compute_52,code=\"sm_52,compute_52\";-gencode=arch=compute_61,code=\"sm_61,compute_61\"" ) 32 | if (NVCC_COMPILER_BINDIR) 33 | set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};--compiler-bindir=${NVCC_COMPILER_BINDIR}") 34 | endif() 35 | flann_add_cuda_gtest(flann_cuda_test flann_cuda_test.cu flann_cpp ${HDF5_LIBRARIES} flann_cuda) 36 | endif() 37 | 38 | 39 | #---------- pyunit tests -------------- 40 | if (BUILD_PYTHON_BINDINGS) 41 | flann_add_pyunit(test_nn.py) 42 | flann_add_pyunit(test_nn_index.py) 43 | flann_add_pyunit(test_index_save.py) 44 | flann_add_pyunit(test_nn_autotune.py) 45 | flann_add_pyunit(test_clustering.py) 46 | endif() 47 | 48 | #---------- ruby spec ---------------- 49 | #if (BUILD_C_BINDINGS) 50 | # add_custom_target(flann_ruby_spec 51 | # COMMAND bundle exec rake spec 52 | # WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/ruby) 53 | # add_dependencies(test flann_ruby_spec) 54 | #endif() 55 | -------------------------------------------------------------------------------- /test/flann_autotuned_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "flann_tests.h" 9 | 10 | using namespace flann; 11 | 12 | 13 | 14 | 15 | 16 | class Autotuned_SIFT100K : public FLANNTestFixture { 17 | protected: 18 | flann::Matrix data; 19 | flann::Matrix query; 20 | flann::Matrix match; 21 | flann::Matrix dists; 22 | flann::Matrix indices; 23 | 24 | void SetUp() 25 | { 26 | dists = flann::Matrix(new float[1000*5], 1000, 5); 27 | indices = flann::Matrix(new size_t[1000*5], 1000, 5); 28 | printf("Reading test data..."); 29 | fflush(stdout); 30 | flann::load_from_file(data, "../datasets/sift100K.h5","dataset"); 31 | flann::load_from_file(query,"../datasets/sift100K.h5","query"); 32 | flann::load_from_file(match,"../datasets/sift100K.h5","match"); 33 | printf("done\n"); 34 | } 35 | 36 | void TearDown() 37 | { 38 | delete[] data.ptr(); 39 | delete[] query.ptr(); 40 | delete[] match.ptr(); 41 | delete[] dists.ptr(); 42 | delete[] indices.ptr(); 43 | } 44 | }; 45 | 46 | 47 | TEST_F(Autotuned_SIFT100K, TestSearch) 48 | { 49 | flann::log_verbosity(FLANN_LOG_INFO); 50 | 51 | Index > index(data, flann::AutotunedIndexParams(0.8,0.01,0,0.1)); // 80% precision 52 | 53 | start_timer("Building autotuned index..."); 54 | index.buildIndex(); 55 | printf("done (%g seconds)\n", stop_timer()); 56 | 57 | index.save("autotuned.idx"); 58 | 59 | start_timer("Searching KNN..."); 60 | index.knnSearch(query, indices, dists, 5, flann::SearchParams(FLANN_CHECKS_AUTOTUNED) ); 61 | printf("done (%g seconds)\n", stop_timer()); 62 | 63 | float precision = compute_precision(match, indices); 64 | EXPECT_GE(precision, 0.75); 65 | printf("Precision: %g\n", precision); 66 | } 67 | 68 | 69 | TEST_F(Autotuned_SIFT100K, SavedTest) 70 | { 71 | float precision; 72 | 73 | // ------------------------------------- 74 | // autotuned index 75 | printf("Loading autotuned index\n"); 76 | flann::Index > autotuned_index(data, flann::SavedIndexParams("autotuned.idx")); 77 | 78 | const flann::IndexParams index_params = autotuned_index.getParameters(); 79 | printf("The index has the following parameters:\n"); 80 | flann::print_params(index_params); 81 | 82 | printf("Index type is: %d\n", autotuned_index.getType()); 83 | 84 | start_timer("Searching KNN..."); 85 | autotuned_index.knnSearch(query, indices, dists, 5, flann::SearchParams(-2) ); 86 | printf("done (%g seconds)\n", stop_timer()); 87 | 88 | precision = compute_precision(match, indices); 89 | EXPECT_GE(precision, 0.75); 90 | printf("Precision: %g\n", precision); 91 | } 92 | 93 | TEST_F(Autotuned_SIFT100K, TestCopy) 94 | { 95 | float precision; 96 | 97 | // ------------------------------------- 98 | // autotuned index 99 | printf("Loading autotuned index\n"); 100 | flann::Index > index(data, flann::SavedIndexParams("autotuned.idx")); 101 | 102 | start_timer("Searching KNN..."); 103 | index.knnSearch(query, indices, dists, 5, flann::SearchParams(-2) ); 104 | printf("done (%g seconds)\n", stop_timer()); 105 | 106 | precision = compute_precision(match, indices); 107 | EXPECT_GE(precision, 0.75); 108 | printf("Precision: %g\n", precision); 109 | 110 | 111 | // test copy constructor 112 | Index > index2(index); 113 | 114 | start_timer("Searching KNN..."); 115 | index2.knnSearch(query, indices, dists, 5, flann::SearchParams(-2) ); 116 | printf("done (%g seconds)\n", stop_timer()); 117 | 118 | float precision2 = compute_precision(match, indices); 119 | printf("Precision: %g\n", precision2); 120 | EXPECT_EQ(precision, precision2); 121 | 122 | // test assignment operator 123 | Index > index3(data, flann::LinearIndexParams()); 124 | index3 = index; 125 | 126 | start_timer("Searching KNN..."); 127 | index3.knnSearch(query, indices, dists, 5, flann::SearchParams(-2) ); 128 | printf("done (%g seconds)\n", stop_timer()); 129 | 130 | float precision3 = compute_precision(match, indices); 131 | printf("Precision: %g\n", precision3); 132 | EXPECT_EQ(precision, precision3); 133 | } 134 | 135 | 136 | TEST_F(Autotuned_SIFT100K, TestCopy2) 137 | { 138 | float precision; 139 | 140 | // ------------------------------------- 141 | // autotuned index 142 | printf("Loading autotuned index\n"); 143 | flann::AutotunedIndex > index(data); 144 | FILE* f = fopen("autotuned.idx", "r"); 145 | index.loadIndex(f); 146 | fclose(f); 147 | 148 | start_timer("Searching KNN..."); 149 | index.knnSearch(query, indices, dists, 5, flann::SearchParams(-2) ); 150 | printf("done (%g seconds)\n", stop_timer()); 151 | 152 | precision = compute_precision(match, indices); 153 | EXPECT_GE(precision, 0.75); 154 | printf("Precision: %g\n", precision); 155 | 156 | 157 | // test copy constructor 158 | AutotunedIndex > index2(index); 159 | 160 | start_timer("Searching KNN..."); 161 | index2.knnSearch(query, indices, dists, 5, flann::SearchParams(-2) ); 162 | printf("done (%g seconds)\n", stop_timer()); 163 | 164 | float precision2 = compute_precision(match, indices); 165 | printf("Precision: %g\n", precision2); 166 | EXPECT_EQ(precision, precision2); 167 | 168 | // test assignment operator 169 | AutotunedIndex > index3(data); 170 | index3 = index; 171 | 172 | start_timer("Searching KNN..."); 173 | index3.knnSearch(query, indices, dists, 5, flann::SearchParams(-2) ); 174 | printf("done (%g seconds)\n", stop_timer()); 175 | 176 | float precision3 = compute_precision(match, indices); 177 | printf("Precision: %g\n", precision3); 178 | EXPECT_EQ(precision, precision3); 179 | } 180 | 181 | 182 | 183 | int main(int argc, char** argv) 184 | { 185 | testing::InitGoogleTest(&argc, argv); 186 | return RUN_ALL_TESTS(); 187 | } 188 | -------------------------------------------------------------------------------- /test/flann_hierarchical_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "flann_tests.h" 8 | 9 | using namespace flann; 10 | 11 | 12 | class HierarchicalIndex_Brief100K : public FLANNTestFixture 13 | { 14 | protected: 15 | typedef flann::Hamming Distance; 16 | typedef Distance::ElementType ElementType; 17 | typedef Distance::ResultType DistanceType; 18 | flann::Matrix data; 19 | flann::Matrix query; 20 | flann::Matrix gt_indices; 21 | flann::Matrix dists; 22 | flann::Matrix gt_dists; 23 | flann::Matrix indices; 24 | unsigned int k_nn_; 25 | 26 | void SetUp() 27 | { 28 | k_nn_ = 3; 29 | printf("Reading test data..."); 30 | fflush(stdout); 31 | flann::load_from_file(data, "../datasets/brief100K.h5", "dataset"); 32 | flann::load_from_file(query, "../datasets/brief100K.h5", "query"); 33 | printf("done\n"); 34 | 35 | flann::Index index(data, flann::LinearIndexParams()); 36 | index.buildIndex(); 37 | 38 | start_timer("Searching KNN for ground truth..."); 39 | gt_indices = flann::Matrix(new size_t[query.rows * k_nn_], query.rows, k_nn_); 40 | gt_dists = flann::Matrix(new DistanceType[query.rows * k_nn_], query.rows, k_nn_); 41 | index.knnSearch(query, gt_indices, gt_dists, k_nn_, flann::SearchParams(-1)); 42 | printf("done (%g seconds)\n", stop_timer()); 43 | 44 | dists = flann::Matrix(new DistanceType[query.rows * k_nn_], query.rows, k_nn_); 45 | indices = flann::Matrix(new size_t[query.rows * k_nn_], query.rows, k_nn_); 46 | } 47 | 48 | void TearDown() 49 | { 50 | delete[] data.ptr(); 51 | delete[] query.ptr(); 52 | delete[] dists.ptr(); 53 | delete[] indices.ptr(); 54 | delete[] gt_indices.ptr(); 55 | delete[] gt_dists.ptr(); 56 | } 57 | }; 58 | 59 | 60 | TEST_F(HierarchicalIndex_Brief100K, TestSearch) 61 | { 62 | TestSearch(data, flann::HierarchicalClusteringIndexParams(), 63 | query, indices, dists, k_nn_, flann::SearchParams(2000), 0.9, gt_indices, gt_dists); 64 | } 65 | 66 | TEST_F(HierarchicalIndex_Brief100K, TestSearch2) 67 | { 68 | TestSearch2(data, flann::HierarchicalClusteringIndexParams(), 69 | query, indices, dists, k_nn_, flann::SearchParams(2000), 0.9, gt_indices, gt_dists); 70 | } 71 | 72 | 73 | TEST_F(HierarchicalIndex_Brief100K, TestAddIncremental) 74 | { 75 | TestAddIncremental(data, flann::HierarchicalClusteringIndexParams(), 76 | query, indices, dists, k_nn_, flann::SearchParams(2000), 0.87, gt_indices, gt_dists); 77 | } 78 | 79 | TEST_F(HierarchicalIndex_Brief100K, TestAddIncremental2) 80 | { 81 | TestAddIncremental2(data, flann::HierarchicalClusteringIndexParams(), 82 | query, indices, dists, k_nn_, flann::SearchParams(2000), 0.87, gt_indices, gt_dists); 83 | } 84 | 85 | TEST_F(HierarchicalIndex_Brief100K, TestRemove) 86 | { 87 | TestRemove(data, flann::HierarchicalClusteringIndexParams(), 88 | query, indices, dists, k_nn_, flann::SearchParams(2000)); 89 | } 90 | 91 | TEST_F(HierarchicalIndex_Brief100K, TestSave) 92 | { 93 | TestSave(data, flann::HierarchicalClusteringIndexParams(), 94 | query, indices, dists, k_nn_, flann::SearchParams(2000), 0.87, gt_indices, gt_dists); 95 | } 96 | 97 | 98 | TEST_F(HierarchicalIndex_Brief100K, TestCopy) 99 | { 100 | TestCopy(data, flann::HierarchicalClusteringIndexParams(), 101 | query, indices, dists, k_nn_, flann::SearchParams(2000), 0.87, gt_indices, gt_dists); 102 | } 103 | 104 | TEST_F(HierarchicalIndex_Brief100K, TestCopy2) 105 | { 106 | TestCopy2 >(data, flann::HierarchicalClusteringIndexParams(), 107 | query, indices, dists, k_nn_, flann::SearchParams(2000), 0.87, gt_indices, gt_dists); 108 | } 109 | 110 | 111 | 112 | 113 | 114 | int main(int argc, char** argv) 115 | { 116 | testing::InitGoogleTest(&argc, argv); 117 | return RUN_ALL_TESTS(); 118 | } 119 | -------------------------------------------------------------------------------- /test/flann_kdtree_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "flann_tests.h" 8 | 9 | using namespace flann; 10 | 11 | /** 12 | * Test fixture for SIFT 10K dataset 13 | */ 14 | class KDTree_SIFT10K : public DatasetTestFixture { 15 | protected: 16 | KDTree_SIFT10K() : DatasetTestFixture("../datasets/sift10K.h5") {} 17 | }; 18 | 19 | TEST_F(KDTree_SIFT10K, TestSearch) 20 | { 21 | TestSearch >(data, flann::KDTreeIndexParams(4), query, indices, 22 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 23 | } 24 | 25 | TEST_F(KDTree_SIFT10K, TestSearch2) 26 | { 27 | TestSearch2 >(data, flann::KDTreeIndexParams(4), query, indices, 28 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 29 | } 30 | 31 | 32 | TEST_F(KDTree_SIFT10K, TestAddIncremental) 33 | { 34 | TestAddIncremental >(data, flann::KDTreeIndexParams(4), query, indices, 35 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 36 | } 37 | 38 | TEST_F(KDTree_SIFT10K, TestAddIncremental2) 39 | { 40 | TestAddIncremental2 >(data, flann::KDTreeIndexParams(4), query, indices, 41 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 42 | } 43 | 44 | TEST_F(KDTree_SIFT10K, TestRemove) 45 | { 46 | TestRemove >(data, flann::KDTreeIndexParams(4), query, indices, 47 | dists, knn, flann::SearchParams(256) ); 48 | } 49 | 50 | 51 | TEST_F(KDTree_SIFT10K, TestSave) 52 | { 53 | TestSave >(data, flann::KDTreeIndexParams(4), query, indices, 54 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 55 | } 56 | 57 | 58 | TEST_F(KDTree_SIFT10K, TestCopy) 59 | { 60 | TestCopy >(data, flann::KDTreeIndexParams(4), query, indices, 61 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 62 | } 63 | 64 | TEST_F(KDTree_SIFT10K, TestCopy2) 65 | { 66 | TestCopy2 > >(data, flann::KDTreeIndexParams(4), query, indices, 67 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 68 | } 69 | 70 | /** 71 | * Test fixture for SIFT 100K dataset 72 | */ 73 | class KDTree_SIFT100K : public DatasetTestFixture { 74 | protected: 75 | KDTree_SIFT100K() : DatasetTestFixture("../datasets/sift100K.h5") {} 76 | }; 77 | 78 | 79 | TEST_F(KDTree_SIFT100K, TestSearch) 80 | { 81 | TestSearch >(data, flann::KDTreeIndexParams(4), query, indices, 82 | dists, knn, flann::SearchParams(128), 0.75, gt_indices); 83 | } 84 | 85 | 86 | TEST_F(KDTree_SIFT100K, TestAddIncremental) 87 | { 88 | TestAddIncremental >(data, flann::KDTreeIndexParams(4), query, indices, 89 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 90 | } 91 | 92 | 93 | 94 | TEST_F(KDTree_SIFT100K, TestAddIncremental2) 95 | { 96 | TestAddIncremental2 >(data, flann::KDTreeIndexParams(4), query, indices, 97 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 98 | } 99 | 100 | 101 | TEST_F(KDTree_SIFT100K, TestRemove) 102 | { 103 | TestRemove >(data, flann::KDTreeIndexParams(4), query, indices, 104 | dists, knn, flann::SearchParams(128) ); 105 | } 106 | 107 | 108 | /** 109 | * Test fixture for SIFT 10K dataset with byte feature elements 110 | */ 111 | class KDTree_SIFT10K_byte : public DatasetTestFixture { 112 | protected: 113 | KDTree_SIFT10K_byte() : DatasetTestFixture("../datasets/sift10K_byte.h5") {} 114 | }; 115 | 116 | 117 | TEST_F(KDTree_SIFT10K_byte, TestSearch) 118 | { 119 | TestSearch >(data, flann::KDTreeIndexParams(4), query, indices, 120 | dists, knn, flann::SearchParams(256), 0.75, gt_indices); 121 | } 122 | 123 | 124 | class KDTree_SIFT100K_byte : public DatasetTestFixture { 125 | protected: 126 | KDTree_SIFT100K_byte() : DatasetTestFixture("../datasets/sift100K_byte.h5") {} 127 | }; 128 | 129 | 130 | TEST_F(KDTree_SIFT100K_byte, TestSearch) 131 | { 132 | TestSearch >(data, flann::KDTreeIndexParams(4), query, indices, 133 | dists, knn, flann::SearchParams(128), 0.75, gt_indices); 134 | } 135 | 136 | 137 | int main(int argc, char** argv) 138 | { 139 | testing::InitGoogleTest(&argc, argv); 140 | return RUN_ALL_TESTS(); 141 | } 142 | -------------------------------------------------------------------------------- /test/flann_kmeans_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "flann_tests.h" 8 | 9 | using namespace flann; 10 | 11 | /** 12 | * Test fixture for SIFT 10K dataset 13 | */ 14 | class KMeans_SIFT10K : public DatasetTestFixture { 15 | protected: 16 | KMeans_SIFT10K() : DatasetTestFixture("../datasets/sift10K.h5") {} 17 | }; 18 | 19 | 20 | 21 | 22 | TEST_F(KMeans_SIFT10K, TestSearch) 23 | { 24 | TestSearch >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 25 | query, indices, dists, knn, flann::SearchParams(128), 0.75, gt_indices); 26 | } 27 | 28 | TEST_F(KMeans_SIFT10K, TestSearch2) 29 | { 30 | TestSearch2 >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 31 | query, indices, dists, knn, flann::SearchParams(128), 0.75, gt_indices); 32 | } 33 | 34 | 35 | TEST_F(KMeans_SIFT10K, TestAddIncremental) 36 | { 37 | TestAddIncremental >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 38 | query, indices, dists, knn, flann::SearchParams(110), 0.75, gt_indices); 39 | } 40 | 41 | TEST_F(KMeans_SIFT10K, TestAddIncremental2) 42 | { 43 | TestAddIncremental2 >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 44 | query, indices, dists, knn, flann::SearchParams(110), 0.75, gt_indices); 45 | } 46 | 47 | TEST_F(KMeans_SIFT10K, TestRemove) 48 | { 49 | TestRemove >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 50 | query, indices, dists, knn, flann::SearchParams(128)); 51 | } 52 | 53 | 54 | 55 | TEST_F(KMeans_SIFT10K, TestSave) 56 | { 57 | TestSave >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 58 | query, indices, dists, knn, flann::SearchParams(128), 0.75, gt_indices); 59 | } 60 | 61 | 62 | TEST_F(KMeans_SIFT10K, TestCopy) 63 | { 64 | TestCopy >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 65 | query, indices, dists, knn, flann::SearchParams(128), 0.75, gt_indices); 66 | } 67 | 68 | 69 | TEST_F(KMeans_SIFT10K, TestCopy2) 70 | { 71 | TestCopy2 > >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 72 | query, indices, dists, knn, flann::SearchParams(128), 0.75, gt_indices); 73 | } 74 | 75 | /** 76 | * Test fixture for SIFT 100K dataset 77 | */ 78 | class KMeans_SIFT100K : public DatasetTestFixture { 79 | protected: 80 | KMeans_SIFT100K() : DatasetTestFixture("../datasets/sift100K.h5") {} 81 | }; 82 | 83 | 84 | TEST_F(KMeans_SIFT100K, TestSearch) 85 | { 86 | TestSearch >(data, flann::KMeansIndexParams(32, 11, FLANN_CENTERS_RANDOM, 0.4), 87 | query, indices, dists, knn, flann::SearchParams(96), 0.75, gt_indices); 88 | } 89 | 90 | 91 | TEST_F(KMeans_SIFT100K, TestAddIncremental) 92 | { 93 | TestAddIncremental >(data, flann::KMeansIndexParams(32, 11, FLANN_CENTERS_RANDOM, 0.4), 94 | query, indices, dists, knn, flann::SearchParams(128), 0.75, gt_indices); 95 | } 96 | 97 | TEST_F(KMeans_SIFT100K, TestAddIncremental2) 98 | { 99 | TestAddIncremental2 >(data, flann::KMeansIndexParams(32, 11, FLANN_CENTERS_RANDOM, 0.4), 100 | query, indices, dists, knn, flann::SearchParams(128), 0.75, gt_indices); 101 | } 102 | 103 | 104 | TEST_F(KMeans_SIFT100K, TestRemove) 105 | { 106 | TestRemove >(data, flann::KMeansIndexParams(32, 11, FLANN_CENTERS_RANDOM, 0.4), query, indices, 107 | dists, knn, flann::SearchParams(128) ); 108 | } 109 | 110 | TEST_F(KMeans_SIFT100K, TestSave) 111 | { 112 | TestSave >(data, flann::KMeansIndexParams(32, 11, FLANN_CENTERS_RANDOM, 0.4), 113 | query, indices, dists, knn, flann::SearchParams(96), 0.75, gt_indices); 114 | } 115 | 116 | 117 | 118 | /** 119 | * Test fixture for SIFT 10K dataset with byte feature elements 120 | */ 121 | class KMeans_SIFT10K_byte : public DatasetTestFixture { 122 | protected: 123 | KMeans_SIFT10K_byte() : DatasetTestFixture("../datasets/sift10K_byte.h5") {} 124 | }; 125 | 126 | TEST_F(KMeans_SIFT10K_byte, TestSearch) 127 | { 128 | TestSearch >(data, flann::KMeansIndexParams(7, 3, FLANN_CENTERS_RANDOM, 0.4), 129 | query, indices, dists, knn, flann::SearchParams(128), 0.75, gt_indices); 130 | } 131 | 132 | 133 | 134 | class KMeans_SIFT100K_byte : public DatasetTestFixture { 135 | protected: 136 | KMeans_SIFT100K_byte() : DatasetTestFixture("../datasets/sift100K_byte.h5") {} 137 | }; 138 | 139 | TEST_F(KMeans_SIFT100K_byte, TestSearch) 140 | { 141 | TestSearch >(data, flann::KMeansIndexParams(32, 11, FLANN_CENTERS_RANDOM, 0.4), 142 | query, indices, dists, knn, flann::SearchParams(80), 0.75, gt_indices); 143 | } 144 | 145 | 146 | int main(int argc, char** argv) 147 | { 148 | testing::InitGoogleTest(&argc, argv); 149 | return RUN_ALL_TESTS(); 150 | } 151 | -------------------------------------------------------------------------------- /test/flann_linear_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "flann_tests.h" 8 | 9 | using namespace flann; 10 | 11 | /** 12 | * Test fixture for SIFT 10K dataset 13 | */ 14 | class Linear_SIFT10K : public DatasetTestFixture { 15 | protected: 16 | Linear_SIFT10K() : DatasetTestFixture("../datasets/sift10K.h5") {} 17 | }; 18 | 19 | 20 | TEST_F(Linear_SIFT10K, TestSearch) 21 | { 22 | TestSearch >(data, flann::LinearIndexParams(), 23 | query, indices, dists, knn, flann::SearchParams(0), 1.0, gt_indices); 24 | } 25 | 26 | TEST_F(Linear_SIFT10K, TestSearch2) 27 | { 28 | TestSearch2 >(data, flann::LinearIndexParams(), 29 | query, indices, dists, knn, flann::SearchParams(0), 1.0, gt_indices); 30 | } 31 | 32 | TEST_F(Linear_SIFT10K, TestRemove) 33 | { 34 | TestRemove >(data, flann::LinearIndexParams(), 35 | query, indices, dists, knn, flann::SearchParams(0)); 36 | } 37 | 38 | 39 | TEST_F(Linear_SIFT10K, TestSave) 40 | { 41 | TestSave >(data, flann::LinearIndexParams(), 42 | query, indices, dists, knn, flann::SearchParams(0), 1.0, gt_indices); 43 | } 44 | 45 | TEST_F(Linear_SIFT10K, TestCopy) 46 | { 47 | TestCopy >(data, flann::LinearIndexParams(), 48 | query, indices, dists, knn, flann::SearchParams(0), 1.0, gt_indices); 49 | } 50 | 51 | 52 | TEST_F(Linear_SIFT10K, TestCopy2) 53 | { 54 | TestCopy >(data, flann::LinearIndexParams(), 55 | query, indices, dists, knn, flann::SearchParams(0), 1.0, gt_indices); 56 | } 57 | 58 | 59 | /** 60 | * Test fixture for SIFT 100K dataset 61 | */ 62 | class Linear_SIFT100K : public DatasetTestFixture { 63 | protected: 64 | Linear_SIFT100K() : DatasetTestFixture("../datasets/sift100K.h5") {} 65 | }; 66 | 67 | 68 | TEST_F(Linear_SIFT100K, TestSearch) 69 | { 70 | TestSearch >(data, flann::LinearIndexParams(), 71 | query, indices, dists, knn, flann::SearchParams(0), 1.0, gt_indices); 72 | } 73 | 74 | 75 | /** 76 | * Test fixture for SIFT 10K dataset with byte feature elements 77 | */ 78 | class Linear_SIFT10K_byte : public DatasetTestFixture { 79 | protected: 80 | Linear_SIFT10K_byte() : DatasetTestFixture("../datasets/sift10K_byte.h5") {} 81 | }; 82 | 83 | 84 | 85 | TEST_F(Linear_SIFT10K_byte, Linear) 86 | { 87 | TestSearch >(data, flann::LinearIndexParams(), 88 | query, indices, dists, knn, flann::SearchParams(0), 1.0, gt_indices); 89 | } 90 | 91 | 92 | 93 | 94 | class Linear_SIFT100K_byte : public DatasetTestFixture { 95 | protected: 96 | Linear_SIFT100K_byte() : DatasetTestFixture("../datasets/sift100K_byte.h5") {} 97 | }; 98 | 99 | 100 | 101 | TEST_F(Linear_SIFT100K_byte, TestSearch) 102 | { 103 | TestSearch >(data, flann::LinearIndexParams(), 104 | query, indices, dists, knn, flann::SearchParams(0), 1.0, gt_indices); 105 | } 106 | 107 | 108 | 109 | int main(int argc, char** argv) 110 | { 111 | testing::InitGoogleTest(&argc, argv); 112 | return RUN_ALL_TESTS(); 113 | } 114 | -------------------------------------------------------------------------------- /test/flann_lsh_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "flann_tests.h" 8 | 9 | using namespace flann; 10 | 11 | 12 | class LshIndex_Brief100K : public FLANNTestFixture 13 | { 14 | protected: 15 | typedef flann::Hamming Distance; 16 | typedef Distance::ElementType ElementType; 17 | typedef Distance::ResultType DistanceType; 18 | flann::Matrix data; 19 | flann::Matrix query; 20 | flann::Matrix gt_indices; 21 | flann::Matrix dists; 22 | flann::Matrix gt_dists; 23 | flann::Matrix indices; 24 | unsigned int k_nn_; 25 | 26 | void SetUp() 27 | { 28 | k_nn_ = 3; 29 | printf("Reading test data..."); 30 | fflush(stdout); 31 | flann::load_from_file(data, "../datasets/brief100K.h5", "dataset"); 32 | flann::load_from_file(query, "../datasets/brief100K.h5", "query"); 33 | 34 | dists = flann::Matrix(new DistanceType[query.rows * k_nn_], query.rows, k_nn_); 35 | indices = flann::Matrix(new size_t[query.rows * k_nn_], query.rows, k_nn_); 36 | 37 | printf("done\n"); 38 | 39 | // The matches are bogus so we compute them the hard way 40 | // flann::load_from_file(match,"../datasets/brief100K.h5","indices"); 41 | 42 | flann::Index index(data, flann::LinearIndexParams()); 43 | index.buildIndex(); 44 | 45 | start_timer("Searching KNN for ground truth..."); 46 | gt_indices = flann::Matrix(new size_t[query.rows * k_nn_], query.rows, k_nn_); 47 | gt_dists = flann::Matrix(new DistanceType[query.rows * k_nn_], query.rows, k_nn_); 48 | index.knnSearch(query, gt_indices, gt_dists, k_nn_, flann::SearchParams(-1)); 49 | printf("done (%g seconds)\n", stop_timer()); 50 | } 51 | 52 | void TearDown() 53 | { 54 | delete[] data.ptr(); 55 | delete[] query.ptr(); 56 | delete[] gt_indices.ptr(); 57 | delete[] gt_dists.ptr(); 58 | delete[] dists.ptr(); 59 | delete[] indices.ptr(); 60 | } 61 | }; 62 | 63 | 64 | TEST_F(LshIndex_Brief100K, TestSearch) 65 | { 66 | TestSearch(data, flann::LshIndexParams(12, 20, 2), 67 | query, indices, dists, k_nn_, flann::SearchParams(-1), 0.9, gt_indices, gt_dists); 68 | } 69 | 70 | TEST_F(LshIndex_Brief100K, TestSearch2) 71 | { 72 | TestSearch2(data, flann::LshIndexParams(12, 20, 2), 73 | query, indices, dists, k_nn_, flann::SearchParams(-1), 0.9, gt_indices, gt_dists); 74 | } 75 | 76 | TEST_F(LshIndex_Brief100K, TestAddIncremental) 77 | { 78 | TestAddIncremental(data, flann::LshIndexParams(12, 20, 2), 79 | query, indices, dists, k_nn_, flann::SearchParams(-1), 0.9, gt_indices, gt_dists); 80 | } 81 | 82 | TEST_F(LshIndex_Brief100K, TestIncremental2) 83 | { 84 | TestAddIncremental2(data, flann::LshIndexParams(12, 20, 2), 85 | query, indices, dists, k_nn_, flann::SearchParams(-1), 0.9, gt_indices, gt_dists); 86 | } 87 | 88 | 89 | TEST_F(LshIndex_Brief100K, TestRemove) 90 | { 91 | TestRemove(data, flann::LshIndexParams(12, 20, 2), 92 | query, indices, dists, k_nn_, flann::SearchParams(-1)); 93 | } 94 | 95 | 96 | TEST_F(LshIndex_Brief100K, TestSave) 97 | { 98 | TestSave(data, flann::LshIndexParams(12, 20, 2), 99 | query, indices, dists, k_nn_, flann::SearchParams(-1), 0.9, gt_indices, gt_dists); 100 | } 101 | 102 | 103 | TEST_F(LshIndex_Brief100K, TestCopy) 104 | { 105 | TestCopy(data, flann::LshIndexParams(12, 20, 2), 106 | query, indices, dists, k_nn_, flann::SearchParams(-1), 0.9, gt_indices, gt_dists); 107 | } 108 | 109 | 110 | TEST_F(LshIndex_Brief100K, TestCopy2) 111 | { 112 | TestCopy2 >(data, flann::LshIndexParams(12, 20, 2), 113 | query, indices, dists, k_nn_, flann::SearchParams(-1), 0.9, gt_indices, gt_dists); 114 | } 115 | 116 | int main(int argc, char** argv) 117 | { 118 | testing::InitGoogleTest(&argc, argv); 119 | return RUN_ALL_TESTS(); 120 | } 121 | -------------------------------------------------------------------------------- /test/memusage_clustering.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | from os.path import * 4 | from pyflann import * 5 | from guppy import hpy 6 | from numpy.random import rand 7 | 8 | import os, gc 9 | 10 | _proc_status = '/proc/%d/status' % os.getpid() 11 | 12 | _scale = {'kB': 1024.0, 'mB': 1024.0*1024.0, 13 | 'KB': 1024.0, 'MB': 1024.0*1024.0} 14 | 15 | def _VmB(VmKey): 16 | '''Private. 17 | ''' 18 | global _proc_status, _scale 19 | # get pseudo file /proc//status 20 | try: 21 | t = open(_proc_status) 22 | v = t.read() 23 | t.close() 24 | except: 25 | return 0.0 # non-Linux? 26 | # get VmKey line e.g. 'VmRSS: 9999 kB\n ...' 27 | i = v.index(VmKey) 28 | v = v[i:].split(None, 3) # whitespace 29 | if len(v) < 3: 30 | return 0.0 # invalid format? 31 | # convert Vm value to bytes 32 | return float(v[1]) * _scale[v[2]] 33 | 34 | 35 | def memory(since=0.0): 36 | '''Return memory usage in bytes. 37 | ''' 38 | return _VmB('VmSize:') - since 39 | 40 | 41 | def resident(since=0.0): 42 | '''Return resident memory usage in bytes. 43 | ''' 44 | return _VmB('VmRSS:') - since 45 | 46 | 47 | def stacksize(since=0.0): 48 | '''Return stack size in bytes. 49 | ''' 50 | return _VmB('VmStk:') - since 51 | 52 | 53 | 54 | if __name__ == '__main__': 55 | 56 | print 'Profiling Memory usage for pyflann; CTRL-C to stop.' 57 | print 'Increasing total process memory, relative to the python memory, ' 58 | print 'implies a memory leak in the external libs.' 59 | print 'Increasing python memory implies a memory leak in the python code.' 60 | 61 | h = hpy() 62 | 63 | while True: 64 | s = str(h.heap()) 65 | 66 | print 'Python: %s; Process Total: %s' % (s[:s.find('\n')], memory()) 67 | 68 | X = rand(30000, 2) 69 | pf = FLANN() 70 | cl = pf.kmeans(X, 20) 71 | del X 72 | del cl 73 | del pf 74 | gc.collect() 75 | 76 | -------------------------------------------------------------------------------- /test/memusage_nn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | from os.path import * 4 | from pyflann import * 5 | from guppy import hpy 6 | from numpy.random import rand 7 | 8 | import os, gc 9 | 10 | _proc_status = '/proc/%d/status' % os.getpid() 11 | 12 | _scale = {'kB': 1024.0, 'mB': 1024.0*1024.0, 13 | 'KB': 1024.0, 'MB': 1024.0*1024.0} 14 | 15 | def _VmB(VmKey): 16 | '''Private. 17 | ''' 18 | global _proc_status, _scale 19 | # get pseudo file /proc//status 20 | try: 21 | t = open(_proc_status) 22 | v = t.read() 23 | t.close() 24 | except: 25 | return 0.0 # non-Linux? 26 | # get VmKey line e.g. 'VmRSS: 9999 kB\n ...' 27 | i = v.index(VmKey) 28 | v = v[i:].split(None, 3) # whitespace 29 | if len(v) < 3: 30 | return 0.0 # invalid format? 31 | # convert Vm value to bytes 32 | return float(v[1]) * _scale[v[2]] 33 | 34 | 35 | def memory(since=0.0): 36 | '''Return memory usage in bytes. 37 | ''' 38 | return _VmB('VmSize:') - since 39 | 40 | 41 | def resident(since=0.0): 42 | '''Return resident memory usage in bytes. 43 | ''' 44 | return _VmB('VmRSS:') - since 45 | 46 | 47 | def stacksize(since=0.0): 48 | '''Return stack size in bytes. 49 | ''' 50 | return _VmB('VmStk:') - since 51 | 52 | 53 | 54 | if __name__ == '__main__': 55 | 56 | print 'Profiling Memory usage for pyflann; CTRL-C to stop.' 57 | print 'Increasing total process memory, relative to the python memory, ' 58 | print 'implies a memory leak in the external libs.' 59 | print 'Increasing python memory implies a memory leak in the python code.' 60 | 61 | h = hpy() 62 | 63 | while True: 64 | s = str(h.heap()) 65 | 66 | print 'Python: %s; Process Total: %s' % (s[:s.find('\n')], memory()) 67 | 68 | X1 = rand(50000, 2) 69 | X2 = rand(50000, 2) 70 | pf = FLANN() 71 | nnlist = pf.nn(X1, X2) 72 | del X1 73 | del X2 74 | del nnlist 75 | del pf 76 | gc.collect() 77 | 78 | -------------------------------------------------------------------------------- /test/test_clustering.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | from os.path import * 4 | from pyflann import * 5 | import os 6 | from copy import copy 7 | from numpy import * 8 | from numpy.random import * 9 | import unittest, time 10 | 11 | class Test_PyFLANN_clustering(unittest.TestCase): 12 | 13 | def setUp(self): 14 | self.nn = FLANN(iterations=11) 15 | 16 | ################################################################################ 17 | 18 | def test_Rand(self): 19 | x = rand(100, 10000) 20 | nK = 10 21 | centroids = self.nn.kmeans(x, nK) 22 | self.assertTrue(len(centroids) == nK) 23 | 24 | 25 | def test2d_small(self): 26 | self.__nd_random_clustering_test(2,2) 27 | 28 | def test3d_small(self): 29 | self.__nd_random_clustering_test(3,3) 30 | 31 | def test4d_small(self): 32 | self.__nd_random_clustering_test(4,4) 33 | 34 | def test3d_large(self): 35 | self.__nd_random_clustering_test(3,3, 1000) 36 | 37 | def test10d_large(self): 38 | self.__nd_random_clustering_test(10,2,10) 39 | 40 | def test500d(self): 41 | self.__nd_random_clustering_test(500,2, 10) 42 | 43 | def __nd_random_clustering_test(self, dim, N, dup=1): 44 | """ 45 | Make a set of random points, then pass the same ones to the 46 | query points. Each point should be closest to itself. 47 | """ 48 | seed(0) 49 | x = rand(N, dim) 50 | xc = concatenate(tuple([x for i in range(dup)])) 51 | 52 | if dup > 1: xc += randn(xc.shape[0], xc.shape[1])*0.000001/dim 53 | 54 | rnseed = int(time.time()) 55 | centroids = self.nn.kmeans(xc[permutation(len(xc))], N, centers_init = "random", random_seed=2) 56 | mindists = array([[ sum((d1-d2)**2) for d1 in x] for d2 in centroids]).min(0) 57 | #print mindists 58 | for m in mindists: self.assertAlmostEqual(m, 0.0, 1) 59 | 60 | rnseed = int(time.time()) 61 | centroids = self.nn.kmeans(xc[permutation(len(xc))], N, centers_init = "gonzales", random_seed=2) 62 | mindists = array([[ sum((d1-d2)**2) for d1 in x] for d2 in centroids]).min(0) 63 | #print mindists 64 | for m in mindists: self.assertAlmostEqual(m, 0.0, 1) 65 | 66 | centroids = self.nn.kmeans(xc[permutation(len(xc))], N, centers_init = "kmeanspp", random_seed=2) 67 | mindists = array([[ sum((d1-d2)**2) for d1 in x] for d2 in centroids]).min(0) 68 | #print mindists 69 | for m in mindists: self.assertAlmostEqual(m, 0.0, 1) 70 | 71 | def testrandomnumber_same(self): 72 | 73 | data = rand(1000,2) # Random, so we can get a lot of local minima 74 | 75 | rnseed = int(time.time()) 76 | cl1 = self.nn.kmeans(data, 50, random_seed = rnseed) 77 | cl2 = self.nn.kmeans(data, 50, random_seed = rnseed) 78 | 79 | self.assertTrue(all(cl1 == cl2)) 80 | 81 | 82 | def testrandnumber_different(self): 83 | 84 | data = rand(1000,100) # Random, so we can get a lot of local minima 85 | 86 | rnseed = int(time.time()) 87 | cl1 = self.nn.kmeans(data, 50, random_seed = rnseed) 88 | cl2 = self.nn.kmeans(data, 50) 89 | 90 | self.assertTrue(any(cl1 != cl2)) 91 | 92 | 93 | 94 | if __name__ == '__main__': 95 | unittest.main() 96 | -------------------------------------------------------------------------------- /test/test_index_save.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from pyflann import * 4 | from copy import copy 5 | from numpy import * 6 | from numpy.random import * 7 | import unittest 8 | 9 | 10 | class Test_PyFLANN_nn(unittest.TestCase): 11 | 12 | def setUp(self): 13 | self.nn = FLANN() 14 | 15 | 16 | class Test_PyFLANN_nn_index(unittest.TestCase): 17 | 18 | def testnn_index_save_kdtree_1(self): 19 | self.run_nn_index_save_perturbed(64,1000, algorithm="kdtree", trees=1) 20 | 21 | def testnn_index_save_kdtree_4(self): 22 | self.run_nn_index_save_perturbed(64,1000, algorithm="kdtree", trees=4) 23 | 24 | def testnn_index_save_kdtree_10(self): 25 | self.run_nn_index_save_perturbed(64,1000, algorithm="kdtree", trees=10) 26 | 27 | 28 | def testnn_index_save_kmeans_2(self): 29 | self.run_nn_index_save_perturbed(64,1000, algorithm="kmeans", branching=2, iterations=11) 30 | 31 | def testnn_index_save_kmeans_16(self): 32 | self.run_nn_index_save_perturbed(64,1000, algorithm="kmeans", branching=16, iterations=11) 33 | 34 | def testnn_index_save_kmeans_32(self): 35 | self.run_nn_index_save_perturbed(64,1000, algorithm="kmeans", branching=32, iterations=11) 36 | 37 | def testnn_index_save_kmeans_64(self): 38 | self.run_nn_index_save_perturbed(64,1000, algorithm="kmeans", branching=64, iterations=11) 39 | 40 | 41 | def testnn__save_kdtree_1(self): 42 | self.run_nn_index_save_rand(64,10000,1000, algorithm="kdtree", trees=1, checks=128) 43 | 44 | def testnn__save_kdtree_4(self): 45 | self.run_nn_index_save_rand(64,10000,1000, algorithm="kdtree", trees=4, checks=128) 46 | 47 | def testnn__save_kdtree_10(self): 48 | self.run_nn_index_save_rand(64,10000,1000, algorithm="kdtree", trees=10, checks=128) 49 | 50 | def testnn__save_kmeans_2(self): 51 | self.run_nn_index_save_rand(64,1000,1000, algorithm="kmeans", branching=2, iterations=11, checks=64) 52 | 53 | def testnn__save_kmeans_8(self): 54 | self.run_nn_index_save_rand(64,10000,1000, algorithm="kmeans", branching=8, iterations=11, checks=32) 55 | 56 | def testnn__save_kmeans_16(self): 57 | self.run_nn_index_save_rand(64,10000,1000, algorithm="kmeans", branching=16, iterations=11, checks=40) 58 | 59 | def testnn__save_kmeans_32(self): 60 | self.run_nn_index_save_rand(64,10000,1000, algorithm="kmeans", branching=32, iterations=11, checks=56) 61 | 62 | 63 | 64 | 65 | def run_nn_index_save_perturbed(self, dim, N, **kwargs): 66 | 67 | x = rand(N, dim) 68 | 69 | nn = FLANN() 70 | nn.build_index(x, **kwargs) 71 | nn.save_index("index.dat") 72 | nn.delete_index(); 73 | 74 | nn = FLANN() 75 | nn.load_index("index.dat",x) 76 | x_query = x + randn(x.shape[0], x.shape[1])*0.0001/dim 77 | nnidx, nndist = nn.nn_index(x_query) 78 | correct = all(nnidx == arange(N, dtype = index_type)) 79 | 80 | nn.delete_index() 81 | self.assertTrue(correct) 82 | 83 | def run_nn_index_save_rand(self, dim, N, Nq, **kwargs): 84 | 85 | x = rand(N, dim) 86 | x_query = rand(Nq,dim) 87 | 88 | # build index, search and delete it 89 | nn = FLANN() 90 | nn.build_index(x, **kwargs) 91 | nnidx, nndist = nn.nn_index(x_query, checks=kwargs["checks"]) 92 | nn.save_index("index.dat") 93 | del nn 94 | 95 | 96 | # now reload index and search again 97 | nn = FLANN() 98 | nn.load_index("index.dat",x) 99 | nnidx2, nndist2 = nn.nn_index(x_query, checks=kwargs["checks"]) 100 | del nn 101 | 102 | correct = all(nnidx == nnidx2) 103 | self.assertTrue(correct) 104 | 105 | if __name__ == '__main__': 106 | unittest.main() 107 | -------------------------------------------------------------------------------- /test/test_nn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | from os.path import * 4 | import os 5 | from pyflann import * 6 | from copy import copy 7 | from numpy import * 8 | from numpy.random import * 9 | import unittest 10 | 11 | class Test_PyFLANN_nn(unittest.TestCase): 12 | 13 | def setUp(self): 14 | self.nn = FLANN() 15 | 16 | ################################################################################ 17 | # The typical 18 | 19 | def test_nn_2d_10pt_kmeans(self): 20 | self.__nd_random_test(2, 2, algorithm='kdtree') 21 | 22 | def test_nn_2d_1000pt_kmeans(self): 23 | self.__nd_random_test(2, 1000, algorithm='kmeans') 24 | 25 | def test_nn_100d_1000pt_kmeans(self): 26 | self.__nd_random_test(100, 1000, algorithm='kmeans') 27 | 28 | def test_nn_500d_100pt_kmeans(self): 29 | self.__nd_random_test(500, 100, algorithm='kmeans') 30 | 31 | def test_nn_2d_1000pt_kdtree(self): 32 | self.__nd_random_test(2, 1000, algorithm='kdtree') 33 | 34 | def test_nn_100d_1000pt_kdtree(self): 35 | self.__nd_random_test(100, 1000, algorithm='kdtree') 36 | 37 | def test_nn_500d_100pt_kdtree(self): 38 | self.__nd_random_test(500, 100, algorithm='kdtree') 39 | 40 | def test_nn_2d_1000pt_linear(self): 41 | self.__nd_random_test(2, 1000, algorithm='linear') 42 | 43 | def test_nn_100d_50pt_linear(self): 44 | self.__nd_random_test(100, 50, algorithm='linear') 45 | 46 | 47 | def test_nn_2d_1000pt_composite(self): 48 | self.__nd_random_test(2, 1000, algorithm='composite') 49 | 50 | def test_nn_100d_1000pt_composite(self): 51 | self.__nd_random_test(100, 1000, algorithm='composite') 52 | 53 | def test_nn_500d_100pt_composite(self): 54 | self.__nd_random_test(500, 100, algorithm='composite') 55 | 56 | 57 | def test_nn_multtrees_2d_1000pt_kmeans(self): 58 | self.__nd_random_test(2, 1000, algorithm='kmeans', trees=8) 59 | 60 | def test_nn_multtrees_100d_1000pt_kmeans(self): 61 | self.__nd_random_test(100, 1000, algorithm='kmeans', trees=8) 62 | 63 | def test_nn_multtrees_500d_100pt_kmeans(self): 64 | self.__nd_random_test(500, 100, algorithm='kmeans', trees=8) 65 | 66 | 67 | 68 | ########################################################################################## 69 | # Stress it should handle 70 | 71 | def test_nn_stress_1d_1pt_kmeans(self): 72 | self.__nd_random_test(1, 1, algorithm='kmeans') 73 | 74 | def test_nn_stress_1d_1pt_linear(self): 75 | self.__nd_random_test(1, 1, algorithm='linear') 76 | 77 | def test_nn_stress_1d_1pt_kdtree(self): 78 | self.__nd_random_test(1, 1, algorithm='kdtree') 79 | 80 | def test_nn_stress_1d_1pt_composite(self): 81 | self.__nd_random_test(1, 1, algorithm='composite') 82 | 83 | def __nd_random_test(self, dim, N, type=float32, num_neighbors = 10, **kwargs): 84 | """ 85 | Make a set of random points, then pass the same ones to the 86 | query points. Each point should be closest to itself. 87 | """ 88 | seed(0) 89 | x = array(rand(N, dim), dtype=type) 90 | perm = permutation(N) 91 | 92 | idx,dists = self.nn.nn(x, x[perm], **kwargs) 93 | self.assertTrue(all(idx == perm)) 94 | 95 | # Make sure it's okay if we do make all the points equal 96 | x_mult_nn = concatenate([x for i in range(num_neighbors)]) 97 | nidx,ndists = self.nn.nn(x_mult_nn, x, num_neighbors = num_neighbors, **kwargs) 98 | 99 | correctness = 0.0 100 | 101 | for i in range(N): 102 | correctness += float(len(set(nidx[i]).intersection([i + n*N for n in range(num_neighbors)])))/num_neighbors 103 | 104 | self.assertTrue(correctness / N >= 0.99, 105 | 'failed #1: N=%d,correctness=%f' % (N, correctness/N)) 106 | 107 | # now what happens if they are slightly off 108 | x_mult_nn += randn(x_mult_nn.shape[0], x_mult_nn.shape[1])*0.0001/dim 109 | n2idx,n2dists = self.nn.nn(x_mult_nn, x, num_neighbors = num_neighbors, **kwargs) 110 | 111 | for i in range(N): 112 | correctness += float(len(set(n2idx[i]).intersection([i + n*N for n in range(num_neighbors)])))/num_neighbors 113 | 114 | self.assertTrue(correctness / N >= 0.99, 115 | 'failed #2: N=%d,correctness=%f' % (N, correctness/N)) 116 | 117 | if __name__ == '__main__': 118 | unittest.main() 119 | -------------------------------------------------------------------------------- /test/test_nn_autotune.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | from os.path import * 4 | import os 5 | from pyflann import * 6 | from copy import copy 7 | from numpy import * 8 | from numpy.random import * 9 | import unittest 10 | 11 | class Test_PyFLANN_nn(unittest.TestCase): 12 | 13 | def setUp(self): 14 | self.nn = FLANN(log_level="warning") 15 | 16 | ################################################################################ 17 | # The typical 18 | 19 | def test_nn_2d_10pt(self): 20 | self.__nd_random_test_autotune(2, 2) 21 | 22 | def test_nn_autotune_2d_1000pt(self): 23 | self.__nd_random_test_autotune(2, 1000) 24 | 25 | def test_nn_autotune_100d_1000pt(self): 26 | self.__nd_random_test_autotune(100, 1000) 27 | 28 | def test_nn_autotune_500d_100pt(self): 29 | self.__nd_random_test_autotune(500, 100) 30 | 31 | # 32 | # ########################################################################################## 33 | # # Stress it should handle 34 | # 35 | def test_nn_stress_1d_1pt_kmeans_autotune(self): 36 | self.__nd_random_test_autotune(1, 1) 37 | 38 | def __ensure_list(self,arg): 39 | if type(arg)!=list: 40 | return [arg] 41 | else: 42 | return arg 43 | 44 | 45 | def __nd_random_test_autotune(self, dim, N, num_neighbors = 1, **kwargs): 46 | """ 47 | Make a set of random points, then pass the same ones to the 48 | query points. Each point should be closest to itself. 49 | """ 50 | seed(0) 51 | x = rand(N, dim) 52 | xq = rand(N, dim) 53 | perm = permutation(N) 54 | 55 | # compute ground truth nearest neighbors 56 | gt_idx, gt_dist = self.nn.nn(x,xq, 57 | algorithm='linear', 58 | num_neighbors=num_neighbors) 59 | 60 | for tp in [0.70, 0.80, 0.90]: 61 | nidx,ndist = self.nn.nn(x, xq, 62 | algorithm='autotuned', 63 | sample_fraction=1.0, 64 | num_neighbors = num_neighbors, 65 | target_precision = tp, checks=-2, **kwargs) 66 | 67 | correctness = 0.0 68 | for i in range(N): 69 | l1 = self.__ensure_list(nidx[i]) 70 | l2 = self.__ensure_list(gt_idx[i]) 71 | correctness += float(len(set(l1).intersection(l2)))/num_neighbors 72 | correctness /= N 73 | self.assertTrue(correctness >= tp*0.9, 74 | 'failed #1: targ_prec=%f, N=%d,correctness=%f' % (tp, N, correctness)) 75 | 76 | if __name__ == '__main__': 77 | unittest.main() 78 | -------------------------------------------------------------------------------- /test/test_nn_index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from pyflann import * 4 | from copy import copy 5 | from numpy import * 6 | from numpy.random import * 7 | import unittest 8 | 9 | 10 | class Test_PyFLANN_nn(unittest.TestCase): 11 | 12 | def setUp(self): 13 | self.nn = FLANN() 14 | 15 | 16 | class Test_PyFLANN_nn_index(unittest.TestCase): 17 | 18 | def testnn_index(self): 19 | 20 | dim = 10 21 | N = 100 22 | 23 | x = rand(N, dim) 24 | nn = FLANN() 25 | nn.build_index(x) 26 | 27 | nnidx, nndist = nn.nn_index(x) 28 | correct = all(nnidx == arange(N, dtype = index_type)) 29 | 30 | nn.delete_index() 31 | self.assertTrue(correct) 32 | 33 | 34 | def testnn_index_random_permute(self): 35 | 36 | numtests = 500 37 | dim = 10 38 | N = 100 39 | 40 | nns = [None]*numtests 41 | x = [rand(N, dim) for i in range(numtests)] 42 | correct = ones(numtests, dtype=bool_) 43 | 44 | for i in permutation(numtests): 45 | nns[i] = FLANN() 46 | nns[i].build_index(x[i]) 47 | 48 | # For kicks 49 | if rand() < 0.5: 50 | nns[i].kmeans(x[i], 5) 51 | if rand() < 0.5: 52 | nns[i].nn(x[i], x[i]) 53 | 54 | 55 | for i in permutation(numtests): 56 | nnidx,nndist = nns[i].nn_index(x[i]) 57 | correct[i] = all(nnidx == arange(N, dtype = index_type)) 58 | 59 | for i in reversed(range(numtests)): 60 | if rand() < 0.5: 61 | nns[i].delete_index() 62 | else: 63 | del nns[i] 64 | 65 | self.assertTrue(all(correct)) 66 | 67 | def testnn_index_bad_index_call_noindex(self): 68 | nn = FLANN() 69 | self.assertRaises(FLANNException, lambda: nn.nn_index(rand(5,5))) 70 | 71 | 72 | def testnn_index_bad_index_call_delindex(self): 73 | nn = FLANN() 74 | nn.build_index(rand(5,5)) 75 | nn.delete_index() 76 | 77 | self.assertRaises(FLANNException, lambda: nn.nn_index(rand(5,5))) 78 | 79 | 80 | if __name__ == '__main__': 81 | unittest.main() 82 | --------------------------------------------------------------------------------