openCV library for Renesas RZ/A

Dependents:   RZ_A2M_Mbed_samples

Committer:
RyoheiHagimoto
Date:
Fri Jan 29 04:53:38 2021 +0000
Revision:
0:0e0631af0305
copied from https://github.com/d-kato/opencv-lib.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RyoheiHagimoto 0:0e0631af0305 1 /***********************************************************************
RyoheiHagimoto 0:0e0631af0305 2 * Software License Agreement (BSD License)
RyoheiHagimoto 0:0e0631af0305 3 *
RyoheiHagimoto 0:0e0631af0305 4 * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
RyoheiHagimoto 0:0e0631af0305 5 * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
RyoheiHagimoto 0:0e0631af0305 6 *
RyoheiHagimoto 0:0e0631af0305 7 * THE BSD LICENSE
RyoheiHagimoto 0:0e0631af0305 8 *
RyoheiHagimoto 0:0e0631af0305 9 * Redistribution and use in source and binary forms, with or without
RyoheiHagimoto 0:0e0631af0305 10 * modification, are permitted provided that the following conditions
RyoheiHagimoto 0:0e0631af0305 11 * are met:
RyoheiHagimoto 0:0e0631af0305 12 *
RyoheiHagimoto 0:0e0631af0305 13 * 1. Redistributions of source code must retain the above copyright
RyoheiHagimoto 0:0e0631af0305 14 * notice, this list of conditions and the following disclaimer.
RyoheiHagimoto 0:0e0631af0305 15 * 2. Redistributions in binary form must reproduce the above copyright
RyoheiHagimoto 0:0e0631af0305 16 * notice, this list of conditions and the following disclaimer in the
RyoheiHagimoto 0:0e0631af0305 17 * documentation and/or other materials provided with the distribution.
RyoheiHagimoto 0:0e0631af0305 18 *
RyoheiHagimoto 0:0e0631af0305 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
RyoheiHagimoto 0:0e0631af0305 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
RyoheiHagimoto 0:0e0631af0305 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
RyoheiHagimoto 0:0e0631af0305 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
RyoheiHagimoto 0:0e0631af0305 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
RyoheiHagimoto 0:0e0631af0305 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
RyoheiHagimoto 0:0e0631af0305 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
RyoheiHagimoto 0:0e0631af0305 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
RyoheiHagimoto 0:0e0631af0305 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
RyoheiHagimoto 0:0e0631af0305 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RyoheiHagimoto 0:0e0631af0305 29 *************************************************************************/
RyoheiHagimoto 0:0e0631af0305 30 #ifndef OPENCV_FLANN_AUTOTUNED_INDEX_H_
RyoheiHagimoto 0:0e0631af0305 31 #define OPENCV_FLANN_AUTOTUNED_INDEX_H_
RyoheiHagimoto 0:0e0631af0305 32
RyoheiHagimoto 0:0e0631af0305 33 #include "general.h"
RyoheiHagimoto 0:0e0631af0305 34 #include "nn_index.h"
RyoheiHagimoto 0:0e0631af0305 35 #include "ground_truth.h"
RyoheiHagimoto 0:0e0631af0305 36 #include "index_testing.h"
RyoheiHagimoto 0:0e0631af0305 37 #include "sampling.h"
RyoheiHagimoto 0:0e0631af0305 38 #include "kdtree_index.h"
RyoheiHagimoto 0:0e0631af0305 39 #include "kdtree_single_index.h"
RyoheiHagimoto 0:0e0631af0305 40 #include "kmeans_index.h"
RyoheiHagimoto 0:0e0631af0305 41 #include "composite_index.h"
RyoheiHagimoto 0:0e0631af0305 42 #include "linear_index.h"
RyoheiHagimoto 0:0e0631af0305 43 #include "logger.h"
RyoheiHagimoto 0:0e0631af0305 44
RyoheiHagimoto 0:0e0631af0305 45 namespace cvflann
RyoheiHagimoto 0:0e0631af0305 46 {
RyoheiHagimoto 0:0e0631af0305 47
RyoheiHagimoto 0:0e0631af0305 48 template<typename Distance>
RyoheiHagimoto 0:0e0631af0305 49 NNIndex<Distance>* create_index_by_type(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance);
RyoheiHagimoto 0:0e0631af0305 50
RyoheiHagimoto 0:0e0631af0305 51
RyoheiHagimoto 0:0e0631af0305 52 struct AutotunedIndexParams : public IndexParams
RyoheiHagimoto 0:0e0631af0305 53 {
RyoheiHagimoto 0:0e0631af0305 54 AutotunedIndexParams(float target_precision = 0.8, float build_weight = 0.01, float memory_weight = 0, float sample_fraction = 0.1)
RyoheiHagimoto 0:0e0631af0305 55 {
RyoheiHagimoto 0:0e0631af0305 56 (*this)["algorithm"] = FLANN_INDEX_AUTOTUNED;
RyoheiHagimoto 0:0e0631af0305 57 // precision desired (used for autotuning, -1 otherwise)
RyoheiHagimoto 0:0e0631af0305 58 (*this)["target_precision"] = target_precision;
RyoheiHagimoto 0:0e0631af0305 59 // build tree time weighting factor
RyoheiHagimoto 0:0e0631af0305 60 (*this)["build_weight"] = build_weight;
RyoheiHagimoto 0:0e0631af0305 61 // index memory weighting factor
RyoheiHagimoto 0:0e0631af0305 62 (*this)["memory_weight"] = memory_weight;
RyoheiHagimoto 0:0e0631af0305 63 // what fraction of the dataset to use for autotuning
RyoheiHagimoto 0:0e0631af0305 64 (*this)["sample_fraction"] = sample_fraction;
RyoheiHagimoto 0:0e0631af0305 65 }
RyoheiHagimoto 0:0e0631af0305 66 };
RyoheiHagimoto 0:0e0631af0305 67
RyoheiHagimoto 0:0e0631af0305 68
RyoheiHagimoto 0:0e0631af0305 69 template <typename Distance>
RyoheiHagimoto 0:0e0631af0305 70 class AutotunedIndex : public NNIndex<Distance>
RyoheiHagimoto 0:0e0631af0305 71 {
RyoheiHagimoto 0:0e0631af0305 72 public:
RyoheiHagimoto 0:0e0631af0305 73 typedef typename Distance::ElementType ElementType;
RyoheiHagimoto 0:0e0631af0305 74 typedef typename Distance::ResultType DistanceType;
RyoheiHagimoto 0:0e0631af0305 75
RyoheiHagimoto 0:0e0631af0305 76 AutotunedIndex(const Matrix<ElementType>& inputData, const IndexParams& params = AutotunedIndexParams(), Distance d = Distance()) :
RyoheiHagimoto 0:0e0631af0305 77 dataset_(inputData), distance_(d)
RyoheiHagimoto 0:0e0631af0305 78 {
RyoheiHagimoto 0:0e0631af0305 79 target_precision_ = get_param(params, "target_precision",0.8f);
RyoheiHagimoto 0:0e0631af0305 80 build_weight_ = get_param(params,"build_weight", 0.01f);
RyoheiHagimoto 0:0e0631af0305 81 memory_weight_ = get_param(params, "memory_weight", 0.0f);
RyoheiHagimoto 0:0e0631af0305 82 sample_fraction_ = get_param(params,"sample_fraction", 0.1f);
RyoheiHagimoto 0:0e0631af0305 83 bestIndex_ = NULL;
RyoheiHagimoto 0:0e0631af0305 84 }
RyoheiHagimoto 0:0e0631af0305 85
RyoheiHagimoto 0:0e0631af0305 86 AutotunedIndex(const AutotunedIndex&);
RyoheiHagimoto 0:0e0631af0305 87 AutotunedIndex& operator=(const AutotunedIndex&);
RyoheiHagimoto 0:0e0631af0305 88
RyoheiHagimoto 0:0e0631af0305 89 virtual ~AutotunedIndex()
RyoheiHagimoto 0:0e0631af0305 90 {
RyoheiHagimoto 0:0e0631af0305 91 if (bestIndex_ != NULL) {
RyoheiHagimoto 0:0e0631af0305 92 delete bestIndex_;
RyoheiHagimoto 0:0e0631af0305 93 bestIndex_ = NULL;
RyoheiHagimoto 0:0e0631af0305 94 }
RyoheiHagimoto 0:0e0631af0305 95 }
RyoheiHagimoto 0:0e0631af0305 96
RyoheiHagimoto 0:0e0631af0305 97 /**
RyoheiHagimoto 0:0e0631af0305 98 * Method responsible with building the index.
RyoheiHagimoto 0:0e0631af0305 99 */
RyoheiHagimoto 0:0e0631af0305 100 virtual void buildIndex()
RyoheiHagimoto 0:0e0631af0305 101 {
RyoheiHagimoto 0:0e0631af0305 102 std::ostringstream stream;
RyoheiHagimoto 0:0e0631af0305 103 bestParams_ = estimateBuildParams();
RyoheiHagimoto 0:0e0631af0305 104 print_params(bestParams_, stream);
RyoheiHagimoto 0:0e0631af0305 105 Logger::info("----------------------------------------------------\n");
RyoheiHagimoto 0:0e0631af0305 106 Logger::info("Autotuned parameters:\n");
RyoheiHagimoto 0:0e0631af0305 107 Logger::info("%s", stream.str().c_str());
RyoheiHagimoto 0:0e0631af0305 108 Logger::info("----------------------------------------------------\n");
RyoheiHagimoto 0:0e0631af0305 109
RyoheiHagimoto 0:0e0631af0305 110 bestIndex_ = create_index_by_type(dataset_, bestParams_, distance_);
RyoheiHagimoto 0:0e0631af0305 111 bestIndex_->buildIndex();
RyoheiHagimoto 0:0e0631af0305 112 speedup_ = estimateSearchParams(bestSearchParams_);
RyoheiHagimoto 0:0e0631af0305 113 stream.str(std::string());
RyoheiHagimoto 0:0e0631af0305 114 print_params(bestSearchParams_, stream);
RyoheiHagimoto 0:0e0631af0305 115 Logger::info("----------------------------------------------------\n");
RyoheiHagimoto 0:0e0631af0305 116 Logger::info("Search parameters:\n");
RyoheiHagimoto 0:0e0631af0305 117 Logger::info("%s", stream.str().c_str());
RyoheiHagimoto 0:0e0631af0305 118 Logger::info("----------------------------------------------------\n");
RyoheiHagimoto 0:0e0631af0305 119 }
RyoheiHagimoto 0:0e0631af0305 120
RyoheiHagimoto 0:0e0631af0305 121 /**
RyoheiHagimoto 0:0e0631af0305 122 * Saves the index to a stream
RyoheiHagimoto 0:0e0631af0305 123 */
RyoheiHagimoto 0:0e0631af0305 124 virtual void saveIndex(FILE* stream)
RyoheiHagimoto 0:0e0631af0305 125 {
RyoheiHagimoto 0:0e0631af0305 126 save_value(stream, (int)bestIndex_->getType());
RyoheiHagimoto 0:0e0631af0305 127 bestIndex_->saveIndex(stream);
RyoheiHagimoto 0:0e0631af0305 128 save_value(stream, get_param<int>(bestSearchParams_, "checks"));
RyoheiHagimoto 0:0e0631af0305 129 }
RyoheiHagimoto 0:0e0631af0305 130
RyoheiHagimoto 0:0e0631af0305 131 /**
RyoheiHagimoto 0:0e0631af0305 132 * Loads the index from a stream
RyoheiHagimoto 0:0e0631af0305 133 */
RyoheiHagimoto 0:0e0631af0305 134 virtual void loadIndex(FILE* stream)
RyoheiHagimoto 0:0e0631af0305 135 {
RyoheiHagimoto 0:0e0631af0305 136 int index_type;
RyoheiHagimoto 0:0e0631af0305 137
RyoheiHagimoto 0:0e0631af0305 138 load_value(stream, index_type);
RyoheiHagimoto 0:0e0631af0305 139 IndexParams params;
RyoheiHagimoto 0:0e0631af0305 140 params["algorithm"] = (flann_algorithm_t)index_type;
RyoheiHagimoto 0:0e0631af0305 141 bestIndex_ = create_index_by_type<Distance>(dataset_, params, distance_);
RyoheiHagimoto 0:0e0631af0305 142 bestIndex_->loadIndex(stream);
RyoheiHagimoto 0:0e0631af0305 143 int checks;
RyoheiHagimoto 0:0e0631af0305 144 load_value(stream, checks);
RyoheiHagimoto 0:0e0631af0305 145 bestSearchParams_["checks"] = checks;
RyoheiHagimoto 0:0e0631af0305 146 }
RyoheiHagimoto 0:0e0631af0305 147
RyoheiHagimoto 0:0e0631af0305 148 /**
RyoheiHagimoto 0:0e0631af0305 149 * Method that searches for nearest-neighbors
RyoheiHagimoto 0:0e0631af0305 150 */
RyoheiHagimoto 0:0e0631af0305 151 virtual void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
RyoheiHagimoto 0:0e0631af0305 152 {
RyoheiHagimoto 0:0e0631af0305 153 int checks = get_param<int>(searchParams,"checks",FLANN_CHECKS_AUTOTUNED);
RyoheiHagimoto 0:0e0631af0305 154 if (checks == FLANN_CHECKS_AUTOTUNED) {
RyoheiHagimoto 0:0e0631af0305 155 bestIndex_->findNeighbors(result, vec, bestSearchParams_);
RyoheiHagimoto 0:0e0631af0305 156 }
RyoheiHagimoto 0:0e0631af0305 157 else {
RyoheiHagimoto 0:0e0631af0305 158 bestIndex_->findNeighbors(result, vec, searchParams);
RyoheiHagimoto 0:0e0631af0305 159 }
RyoheiHagimoto 0:0e0631af0305 160 }
RyoheiHagimoto 0:0e0631af0305 161
RyoheiHagimoto 0:0e0631af0305 162
RyoheiHagimoto 0:0e0631af0305 163 IndexParams getParameters() const
RyoheiHagimoto 0:0e0631af0305 164 {
RyoheiHagimoto 0:0e0631af0305 165 return bestIndex_->getParameters();
RyoheiHagimoto 0:0e0631af0305 166 }
RyoheiHagimoto 0:0e0631af0305 167
RyoheiHagimoto 0:0e0631af0305 168 SearchParams getSearchParameters() const
RyoheiHagimoto 0:0e0631af0305 169 {
RyoheiHagimoto 0:0e0631af0305 170 return bestSearchParams_;
RyoheiHagimoto 0:0e0631af0305 171 }
RyoheiHagimoto 0:0e0631af0305 172
RyoheiHagimoto 0:0e0631af0305 173 float getSpeedup() const
RyoheiHagimoto 0:0e0631af0305 174 {
RyoheiHagimoto 0:0e0631af0305 175 return speedup_;
RyoheiHagimoto 0:0e0631af0305 176 }
RyoheiHagimoto 0:0e0631af0305 177
RyoheiHagimoto 0:0e0631af0305 178
RyoheiHagimoto 0:0e0631af0305 179 /**
RyoheiHagimoto 0:0e0631af0305 180 * Number of features in this index.
RyoheiHagimoto 0:0e0631af0305 181 */
RyoheiHagimoto 0:0e0631af0305 182 virtual size_t size() const
RyoheiHagimoto 0:0e0631af0305 183 {
RyoheiHagimoto 0:0e0631af0305 184 return bestIndex_->size();
RyoheiHagimoto 0:0e0631af0305 185 }
RyoheiHagimoto 0:0e0631af0305 186
RyoheiHagimoto 0:0e0631af0305 187 /**
RyoheiHagimoto 0:0e0631af0305 188 * The length of each vector in this index.
RyoheiHagimoto 0:0e0631af0305 189 */
RyoheiHagimoto 0:0e0631af0305 190 virtual size_t veclen() const
RyoheiHagimoto 0:0e0631af0305 191 {
RyoheiHagimoto 0:0e0631af0305 192 return bestIndex_->veclen();
RyoheiHagimoto 0:0e0631af0305 193 }
RyoheiHagimoto 0:0e0631af0305 194
RyoheiHagimoto 0:0e0631af0305 195 /**
RyoheiHagimoto 0:0e0631af0305 196 * The amount of memory (in bytes) this index uses.
RyoheiHagimoto 0:0e0631af0305 197 */
RyoheiHagimoto 0:0e0631af0305 198 virtual int usedMemory() const
RyoheiHagimoto 0:0e0631af0305 199 {
RyoheiHagimoto 0:0e0631af0305 200 return bestIndex_->usedMemory();
RyoheiHagimoto 0:0e0631af0305 201 }
RyoheiHagimoto 0:0e0631af0305 202
RyoheiHagimoto 0:0e0631af0305 203 /**
RyoheiHagimoto 0:0e0631af0305 204 * Algorithm name
RyoheiHagimoto 0:0e0631af0305 205 */
RyoheiHagimoto 0:0e0631af0305 206 virtual flann_algorithm_t getType() const
RyoheiHagimoto 0:0e0631af0305 207 {
RyoheiHagimoto 0:0e0631af0305 208 return FLANN_INDEX_AUTOTUNED;
RyoheiHagimoto 0:0e0631af0305 209 }
RyoheiHagimoto 0:0e0631af0305 210
RyoheiHagimoto 0:0e0631af0305 211 private:
RyoheiHagimoto 0:0e0631af0305 212
RyoheiHagimoto 0:0e0631af0305 213 struct CostData
RyoheiHagimoto 0:0e0631af0305 214 {
RyoheiHagimoto 0:0e0631af0305 215 float searchTimeCost;
RyoheiHagimoto 0:0e0631af0305 216 float buildTimeCost;
RyoheiHagimoto 0:0e0631af0305 217 float memoryCost;
RyoheiHagimoto 0:0e0631af0305 218 float totalCost;
RyoheiHagimoto 0:0e0631af0305 219 IndexParams params;
RyoheiHagimoto 0:0e0631af0305 220 };
RyoheiHagimoto 0:0e0631af0305 221
RyoheiHagimoto 0:0e0631af0305 222 void evaluate_kmeans(CostData& cost)
RyoheiHagimoto 0:0e0631af0305 223 {
RyoheiHagimoto 0:0e0631af0305 224 StartStopTimer t;
RyoheiHagimoto 0:0e0631af0305 225 int checks;
RyoheiHagimoto 0:0e0631af0305 226 const int nn = 1;
RyoheiHagimoto 0:0e0631af0305 227
RyoheiHagimoto 0:0e0631af0305 228 Logger::info("KMeansTree using params: max_iterations=%d, branching=%d\n",
RyoheiHagimoto 0:0e0631af0305 229 get_param<int>(cost.params,"iterations"),
RyoheiHagimoto 0:0e0631af0305 230 get_param<int>(cost.params,"branching"));
RyoheiHagimoto 0:0e0631af0305 231 KMeansIndex<Distance> kmeans(sampledDataset_, cost.params, distance_);
RyoheiHagimoto 0:0e0631af0305 232 // measure index build time
RyoheiHagimoto 0:0e0631af0305 233 t.start();
RyoheiHagimoto 0:0e0631af0305 234 kmeans.buildIndex();
RyoheiHagimoto 0:0e0631af0305 235 t.stop();
RyoheiHagimoto 0:0e0631af0305 236 float buildTime = (float)t.value;
RyoheiHagimoto 0:0e0631af0305 237
RyoheiHagimoto 0:0e0631af0305 238 // measure search time
RyoheiHagimoto 0:0e0631af0305 239 float searchTime = test_index_precision(kmeans, sampledDataset_, testDataset_, gt_matches_, target_precision_, checks, distance_, nn);
RyoheiHagimoto 0:0e0631af0305 240
RyoheiHagimoto 0:0e0631af0305 241 float datasetMemory = float(sampledDataset_.rows * sampledDataset_.cols * sizeof(float));
RyoheiHagimoto 0:0e0631af0305 242 cost.memoryCost = (kmeans.usedMemory() + datasetMemory) / datasetMemory;
RyoheiHagimoto 0:0e0631af0305 243 cost.searchTimeCost = searchTime;
RyoheiHagimoto 0:0e0631af0305 244 cost.buildTimeCost = buildTime;
RyoheiHagimoto 0:0e0631af0305 245 Logger::info("KMeansTree buildTime=%g, searchTime=%g, build_weight=%g\n", buildTime, searchTime, build_weight_);
RyoheiHagimoto 0:0e0631af0305 246 }
RyoheiHagimoto 0:0e0631af0305 247
RyoheiHagimoto 0:0e0631af0305 248
RyoheiHagimoto 0:0e0631af0305 249 void evaluate_kdtree(CostData& cost)
RyoheiHagimoto 0:0e0631af0305 250 {
RyoheiHagimoto 0:0e0631af0305 251 StartStopTimer t;
RyoheiHagimoto 0:0e0631af0305 252 int checks;
RyoheiHagimoto 0:0e0631af0305 253 const int nn = 1;
RyoheiHagimoto 0:0e0631af0305 254
RyoheiHagimoto 0:0e0631af0305 255 Logger::info("KDTree using params: trees=%d\n", get_param<int>(cost.params,"trees"));
RyoheiHagimoto 0:0e0631af0305 256 KDTreeIndex<Distance> kdtree(sampledDataset_, cost.params, distance_);
RyoheiHagimoto 0:0e0631af0305 257
RyoheiHagimoto 0:0e0631af0305 258 t.start();
RyoheiHagimoto 0:0e0631af0305 259 kdtree.buildIndex();
RyoheiHagimoto 0:0e0631af0305 260 t.stop();
RyoheiHagimoto 0:0e0631af0305 261 float buildTime = (float)t.value;
RyoheiHagimoto 0:0e0631af0305 262
RyoheiHagimoto 0:0e0631af0305 263 //measure search time
RyoheiHagimoto 0:0e0631af0305 264 float searchTime = test_index_precision(kdtree, sampledDataset_, testDataset_, gt_matches_, target_precision_, checks, distance_, nn);
RyoheiHagimoto 0:0e0631af0305 265
RyoheiHagimoto 0:0e0631af0305 266 float datasetMemory = float(sampledDataset_.rows * sampledDataset_.cols * sizeof(float));
RyoheiHagimoto 0:0e0631af0305 267 cost.memoryCost = (kdtree.usedMemory() + datasetMemory) / datasetMemory;
RyoheiHagimoto 0:0e0631af0305 268 cost.searchTimeCost = searchTime;
RyoheiHagimoto 0:0e0631af0305 269 cost.buildTimeCost = buildTime;
RyoheiHagimoto 0:0e0631af0305 270 Logger::info("KDTree buildTime=%g, searchTime=%g\n", buildTime, searchTime);
RyoheiHagimoto 0:0e0631af0305 271 }
RyoheiHagimoto 0:0e0631af0305 272
RyoheiHagimoto 0:0e0631af0305 273
RyoheiHagimoto 0:0e0631af0305 274 // struct KMeansSimpleDownhillFunctor {
RyoheiHagimoto 0:0e0631af0305 275 //
RyoheiHagimoto 0:0e0631af0305 276 // Autotune& autotuner;
RyoheiHagimoto 0:0e0631af0305 277 // KMeansSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {}
RyoheiHagimoto 0:0e0631af0305 278 //
RyoheiHagimoto 0:0e0631af0305 279 // float operator()(int* params) {
RyoheiHagimoto 0:0e0631af0305 280 //
RyoheiHagimoto 0:0e0631af0305 281 // float maxFloat = numeric_limits<float>::max();
RyoheiHagimoto 0:0e0631af0305 282 //
RyoheiHagimoto 0:0e0631af0305 283 // if (params[0]<2) return maxFloat;
RyoheiHagimoto 0:0e0631af0305 284 // if (params[1]<0) return maxFloat;
RyoheiHagimoto 0:0e0631af0305 285 //
RyoheiHagimoto 0:0e0631af0305 286 // CostData c;
RyoheiHagimoto 0:0e0631af0305 287 // c.params["algorithm"] = KMEANS;
RyoheiHagimoto 0:0e0631af0305 288 // c.params["centers-init"] = CENTERS_RANDOM;
RyoheiHagimoto 0:0e0631af0305 289 // c.params["branching"] = params[0];
RyoheiHagimoto 0:0e0631af0305 290 // c.params["max-iterations"] = params[1];
RyoheiHagimoto 0:0e0631af0305 291 //
RyoheiHagimoto 0:0e0631af0305 292 // autotuner.evaluate_kmeans(c);
RyoheiHagimoto 0:0e0631af0305 293 //
RyoheiHagimoto 0:0e0631af0305 294 // return c.timeCost;
RyoheiHagimoto 0:0e0631af0305 295 //
RyoheiHagimoto 0:0e0631af0305 296 // }
RyoheiHagimoto 0:0e0631af0305 297 // };
RyoheiHagimoto 0:0e0631af0305 298 //
RyoheiHagimoto 0:0e0631af0305 299 // struct KDTreeSimpleDownhillFunctor {
RyoheiHagimoto 0:0e0631af0305 300 //
RyoheiHagimoto 0:0e0631af0305 301 // Autotune& autotuner;
RyoheiHagimoto 0:0e0631af0305 302 // KDTreeSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {}
RyoheiHagimoto 0:0e0631af0305 303 //
RyoheiHagimoto 0:0e0631af0305 304 // float operator()(int* params) {
RyoheiHagimoto 0:0e0631af0305 305 // float maxFloat = numeric_limits<float>::max();
RyoheiHagimoto 0:0e0631af0305 306 //
RyoheiHagimoto 0:0e0631af0305 307 // if (params[0]<1) return maxFloat;
RyoheiHagimoto 0:0e0631af0305 308 //
RyoheiHagimoto 0:0e0631af0305 309 // CostData c;
RyoheiHagimoto 0:0e0631af0305 310 // c.params["algorithm"] = KDTREE;
RyoheiHagimoto 0:0e0631af0305 311 // c.params["trees"] = params[0];
RyoheiHagimoto 0:0e0631af0305 312 //
RyoheiHagimoto 0:0e0631af0305 313 // autotuner.evaluate_kdtree(c);
RyoheiHagimoto 0:0e0631af0305 314 //
RyoheiHagimoto 0:0e0631af0305 315 // return c.timeCost;
RyoheiHagimoto 0:0e0631af0305 316 //
RyoheiHagimoto 0:0e0631af0305 317 // }
RyoheiHagimoto 0:0e0631af0305 318 // };
RyoheiHagimoto 0:0e0631af0305 319
RyoheiHagimoto 0:0e0631af0305 320
RyoheiHagimoto 0:0e0631af0305 321
RyoheiHagimoto 0:0e0631af0305 322 void optimizeKMeans(std::vector<CostData>& costs)
RyoheiHagimoto 0:0e0631af0305 323 {
RyoheiHagimoto 0:0e0631af0305 324 Logger::info("KMEANS, Step 1: Exploring parameter space\n");
RyoheiHagimoto 0:0e0631af0305 325
RyoheiHagimoto 0:0e0631af0305 326 // explore kmeans parameters space using combinations of the parameters below
RyoheiHagimoto 0:0e0631af0305 327 int maxIterations[] = { 1, 5, 10, 15 };
RyoheiHagimoto 0:0e0631af0305 328 int branchingFactors[] = { 16, 32, 64, 128, 256 };
RyoheiHagimoto 0:0e0631af0305 329
RyoheiHagimoto 0:0e0631af0305 330 int kmeansParamSpaceSize = FLANN_ARRAY_LEN(maxIterations) * FLANN_ARRAY_LEN(branchingFactors);
RyoheiHagimoto 0:0e0631af0305 331 costs.reserve(costs.size() + kmeansParamSpaceSize);
RyoheiHagimoto 0:0e0631af0305 332
RyoheiHagimoto 0:0e0631af0305 333 // evaluate kmeans for all parameter combinations
RyoheiHagimoto 0:0e0631af0305 334 for (size_t i = 0; i < FLANN_ARRAY_LEN(maxIterations); ++i) {
RyoheiHagimoto 0:0e0631af0305 335 for (size_t j = 0; j < FLANN_ARRAY_LEN(branchingFactors); ++j) {
RyoheiHagimoto 0:0e0631af0305 336 CostData cost;
RyoheiHagimoto 0:0e0631af0305 337 cost.params["algorithm"] = FLANN_INDEX_KMEANS;
RyoheiHagimoto 0:0e0631af0305 338 cost.params["centers_init"] = FLANN_CENTERS_RANDOM;
RyoheiHagimoto 0:0e0631af0305 339 cost.params["iterations"] = maxIterations[i];
RyoheiHagimoto 0:0e0631af0305 340 cost.params["branching"] = branchingFactors[j];
RyoheiHagimoto 0:0e0631af0305 341
RyoheiHagimoto 0:0e0631af0305 342 evaluate_kmeans(cost);
RyoheiHagimoto 0:0e0631af0305 343 costs.push_back(cost);
RyoheiHagimoto 0:0e0631af0305 344 }
RyoheiHagimoto 0:0e0631af0305 345 }
RyoheiHagimoto 0:0e0631af0305 346
RyoheiHagimoto 0:0e0631af0305 347 // Logger::info("KMEANS, Step 2: simplex-downhill optimization\n");
RyoheiHagimoto 0:0e0631af0305 348 //
RyoheiHagimoto 0:0e0631af0305 349 // const int n = 2;
RyoheiHagimoto 0:0e0631af0305 350 // // choose initial simplex points as the best parameters so far
RyoheiHagimoto 0:0e0631af0305 351 // int kmeansNMPoints[n*(n+1)];
RyoheiHagimoto 0:0e0631af0305 352 // float kmeansVals[n+1];
RyoheiHagimoto 0:0e0631af0305 353 // for (int i=0;i<n+1;++i) {
RyoheiHagimoto 0:0e0631af0305 354 // kmeansNMPoints[i*n] = (int)kmeansCosts[i].params["branching"];
RyoheiHagimoto 0:0e0631af0305 355 // kmeansNMPoints[i*n+1] = (int)kmeansCosts[i].params["max-iterations"];
RyoheiHagimoto 0:0e0631af0305 356 // kmeansVals[i] = kmeansCosts[i].timeCost;
RyoheiHagimoto 0:0e0631af0305 357 // }
RyoheiHagimoto 0:0e0631af0305 358 // KMeansSimpleDownhillFunctor kmeans_cost_func(*this);
RyoheiHagimoto 0:0e0631af0305 359 // // run optimization
RyoheiHagimoto 0:0e0631af0305 360 // optimizeSimplexDownhill(kmeansNMPoints,n,kmeans_cost_func,kmeansVals);
RyoheiHagimoto 0:0e0631af0305 361 // // store results
RyoheiHagimoto 0:0e0631af0305 362 // for (int i=0;i<n+1;++i) {
RyoheiHagimoto 0:0e0631af0305 363 // kmeansCosts[i].params["branching"] = kmeansNMPoints[i*2];
RyoheiHagimoto 0:0e0631af0305 364 // kmeansCosts[i].params["max-iterations"] = kmeansNMPoints[i*2+1];
RyoheiHagimoto 0:0e0631af0305 365 // kmeansCosts[i].timeCost = kmeansVals[i];
RyoheiHagimoto 0:0e0631af0305 366 // }
RyoheiHagimoto 0:0e0631af0305 367 }
RyoheiHagimoto 0:0e0631af0305 368
RyoheiHagimoto 0:0e0631af0305 369
RyoheiHagimoto 0:0e0631af0305 370 void optimizeKDTree(std::vector<CostData>& costs)
RyoheiHagimoto 0:0e0631af0305 371 {
RyoheiHagimoto 0:0e0631af0305 372 Logger::info("KD-TREE, Step 1: Exploring parameter space\n");
RyoheiHagimoto 0:0e0631af0305 373
RyoheiHagimoto 0:0e0631af0305 374 // explore kd-tree parameters space using the parameters below
RyoheiHagimoto 0:0e0631af0305 375 int testTrees[] = { 1, 4, 8, 16, 32 };
RyoheiHagimoto 0:0e0631af0305 376
RyoheiHagimoto 0:0e0631af0305 377 // evaluate kdtree for all parameter combinations
RyoheiHagimoto 0:0e0631af0305 378 for (size_t i = 0; i < FLANN_ARRAY_LEN(testTrees); ++i) {
RyoheiHagimoto 0:0e0631af0305 379 CostData cost;
RyoheiHagimoto 0:0e0631af0305 380 cost.params["algorithm"] = FLANN_INDEX_KDTREE;
RyoheiHagimoto 0:0e0631af0305 381 cost.params["trees"] = testTrees[i];
RyoheiHagimoto 0:0e0631af0305 382
RyoheiHagimoto 0:0e0631af0305 383 evaluate_kdtree(cost);
RyoheiHagimoto 0:0e0631af0305 384 costs.push_back(cost);
RyoheiHagimoto 0:0e0631af0305 385 }
RyoheiHagimoto 0:0e0631af0305 386
RyoheiHagimoto 0:0e0631af0305 387 // Logger::info("KD-TREE, Step 2: simplex-downhill optimization\n");
RyoheiHagimoto 0:0e0631af0305 388 //
RyoheiHagimoto 0:0e0631af0305 389 // const int n = 1;
RyoheiHagimoto 0:0e0631af0305 390 // // choose initial simplex points as the best parameters so far
RyoheiHagimoto 0:0e0631af0305 391 // int kdtreeNMPoints[n*(n+1)];
RyoheiHagimoto 0:0e0631af0305 392 // float kdtreeVals[n+1];
RyoheiHagimoto 0:0e0631af0305 393 // for (int i=0;i<n+1;++i) {
RyoheiHagimoto 0:0e0631af0305 394 // kdtreeNMPoints[i] = (int)kdtreeCosts[i].params["trees"];
RyoheiHagimoto 0:0e0631af0305 395 // kdtreeVals[i] = kdtreeCosts[i].timeCost;
RyoheiHagimoto 0:0e0631af0305 396 // }
RyoheiHagimoto 0:0e0631af0305 397 // KDTreeSimpleDownhillFunctor kdtree_cost_func(*this);
RyoheiHagimoto 0:0e0631af0305 398 // // run optimization
RyoheiHagimoto 0:0e0631af0305 399 // optimizeSimplexDownhill(kdtreeNMPoints,n,kdtree_cost_func,kdtreeVals);
RyoheiHagimoto 0:0e0631af0305 400 // // store results
RyoheiHagimoto 0:0e0631af0305 401 // for (int i=0;i<n+1;++i) {
RyoheiHagimoto 0:0e0631af0305 402 // kdtreeCosts[i].params["trees"] = kdtreeNMPoints[i];
RyoheiHagimoto 0:0e0631af0305 403 // kdtreeCosts[i].timeCost = kdtreeVals[i];
RyoheiHagimoto 0:0e0631af0305 404 // }
RyoheiHagimoto 0:0e0631af0305 405 }
RyoheiHagimoto 0:0e0631af0305 406
RyoheiHagimoto 0:0e0631af0305 407 /**
RyoheiHagimoto 0:0e0631af0305 408 * Chooses the best nearest-neighbor algorithm and estimates the optimal
RyoheiHagimoto 0:0e0631af0305 409 * parameters to use when building the index (for a given precision).
RyoheiHagimoto 0:0e0631af0305 410 * Returns a dictionary with the optimal parameters.
RyoheiHagimoto 0:0e0631af0305 411 */
RyoheiHagimoto 0:0e0631af0305 412 IndexParams estimateBuildParams()
RyoheiHagimoto 0:0e0631af0305 413 {
RyoheiHagimoto 0:0e0631af0305 414 std::vector<CostData> costs;
RyoheiHagimoto 0:0e0631af0305 415
RyoheiHagimoto 0:0e0631af0305 416 int sampleSize = int(sample_fraction_ * dataset_.rows);
RyoheiHagimoto 0:0e0631af0305 417 int testSampleSize = std::min(sampleSize / 10, 1000);
RyoheiHagimoto 0:0e0631af0305 418
RyoheiHagimoto 0:0e0631af0305 419 Logger::info("Entering autotuning, dataset size: %d, sampleSize: %d, testSampleSize: %d, target precision: %g\n", dataset_.rows, sampleSize, testSampleSize, target_precision_);
RyoheiHagimoto 0:0e0631af0305 420
RyoheiHagimoto 0:0e0631af0305 421 // For a very small dataset, it makes no sense to build any fancy index, just
RyoheiHagimoto 0:0e0631af0305 422 // use linear search
RyoheiHagimoto 0:0e0631af0305 423 if (testSampleSize < 10) {
RyoheiHagimoto 0:0e0631af0305 424 Logger::info("Choosing linear, dataset too small\n");
RyoheiHagimoto 0:0e0631af0305 425 return LinearIndexParams();
RyoheiHagimoto 0:0e0631af0305 426 }
RyoheiHagimoto 0:0e0631af0305 427
RyoheiHagimoto 0:0e0631af0305 428 // We use a fraction of the original dataset to speedup the autotune algorithm
RyoheiHagimoto 0:0e0631af0305 429 sampledDataset_ = random_sample(dataset_, sampleSize);
RyoheiHagimoto 0:0e0631af0305 430 // We use a cross-validation approach, first we sample a testset from the dataset
RyoheiHagimoto 0:0e0631af0305 431 testDataset_ = random_sample(sampledDataset_, testSampleSize, true);
RyoheiHagimoto 0:0e0631af0305 432
RyoheiHagimoto 0:0e0631af0305 433 // We compute the ground truth using linear search
RyoheiHagimoto 0:0e0631af0305 434 Logger::info("Computing ground truth... \n");
RyoheiHagimoto 0:0e0631af0305 435 gt_matches_ = Matrix<int>(new int[testDataset_.rows], testDataset_.rows, 1);
RyoheiHagimoto 0:0e0631af0305 436 StartStopTimer t;
RyoheiHagimoto 0:0e0631af0305 437 t.start();
RyoheiHagimoto 0:0e0631af0305 438 compute_ground_truth<Distance>(sampledDataset_, testDataset_, gt_matches_, 0, distance_);
RyoheiHagimoto 0:0e0631af0305 439 t.stop();
RyoheiHagimoto 0:0e0631af0305 440
RyoheiHagimoto 0:0e0631af0305 441 CostData linear_cost;
RyoheiHagimoto 0:0e0631af0305 442 linear_cost.searchTimeCost = (float)t.value;
RyoheiHagimoto 0:0e0631af0305 443 linear_cost.buildTimeCost = 0;
RyoheiHagimoto 0:0e0631af0305 444 linear_cost.memoryCost = 0;
RyoheiHagimoto 0:0e0631af0305 445 linear_cost.params["algorithm"] = FLANN_INDEX_LINEAR;
RyoheiHagimoto 0:0e0631af0305 446
RyoheiHagimoto 0:0e0631af0305 447 costs.push_back(linear_cost);
RyoheiHagimoto 0:0e0631af0305 448
RyoheiHagimoto 0:0e0631af0305 449 // Start parameter autotune process
RyoheiHagimoto 0:0e0631af0305 450 Logger::info("Autotuning parameters...\n");
RyoheiHagimoto 0:0e0631af0305 451
RyoheiHagimoto 0:0e0631af0305 452 optimizeKMeans(costs);
RyoheiHagimoto 0:0e0631af0305 453 optimizeKDTree(costs);
RyoheiHagimoto 0:0e0631af0305 454
RyoheiHagimoto 0:0e0631af0305 455 float bestTimeCost = costs[0].searchTimeCost;
RyoheiHagimoto 0:0e0631af0305 456 for (size_t i = 0; i < costs.size(); ++i) {
RyoheiHagimoto 0:0e0631af0305 457 float timeCost = costs[i].buildTimeCost * build_weight_ + costs[i].searchTimeCost;
RyoheiHagimoto 0:0e0631af0305 458 if (timeCost < bestTimeCost) {
RyoheiHagimoto 0:0e0631af0305 459 bestTimeCost = timeCost;
RyoheiHagimoto 0:0e0631af0305 460 }
RyoheiHagimoto 0:0e0631af0305 461 }
RyoheiHagimoto 0:0e0631af0305 462
RyoheiHagimoto 0:0e0631af0305 463 float bestCost = costs[0].searchTimeCost / bestTimeCost;
RyoheiHagimoto 0:0e0631af0305 464 IndexParams bestParams = costs[0].params;
RyoheiHagimoto 0:0e0631af0305 465 if (bestTimeCost > 0) {
RyoheiHagimoto 0:0e0631af0305 466 for (size_t i = 0; i < costs.size(); ++i) {
RyoheiHagimoto 0:0e0631af0305 467 float crtCost = (costs[i].buildTimeCost * build_weight_ + costs[i].searchTimeCost) / bestTimeCost +
RyoheiHagimoto 0:0e0631af0305 468 memory_weight_ * costs[i].memoryCost;
RyoheiHagimoto 0:0e0631af0305 469 if (crtCost < bestCost) {
RyoheiHagimoto 0:0e0631af0305 470 bestCost = crtCost;
RyoheiHagimoto 0:0e0631af0305 471 bestParams = costs[i].params;
RyoheiHagimoto 0:0e0631af0305 472 }
RyoheiHagimoto 0:0e0631af0305 473 }
RyoheiHagimoto 0:0e0631af0305 474 }
RyoheiHagimoto 0:0e0631af0305 475
RyoheiHagimoto 0:0e0631af0305 476 delete[] gt_matches_.data;
RyoheiHagimoto 0:0e0631af0305 477 delete[] testDataset_.data;
RyoheiHagimoto 0:0e0631af0305 478 delete[] sampledDataset_.data;
RyoheiHagimoto 0:0e0631af0305 479
RyoheiHagimoto 0:0e0631af0305 480 return bestParams;
RyoheiHagimoto 0:0e0631af0305 481 }
RyoheiHagimoto 0:0e0631af0305 482
RyoheiHagimoto 0:0e0631af0305 483
RyoheiHagimoto 0:0e0631af0305 484
RyoheiHagimoto 0:0e0631af0305 485 /**
RyoheiHagimoto 0:0e0631af0305 486 * Estimates the search time parameters needed to get the desired precision.
RyoheiHagimoto 0:0e0631af0305 487 * Precondition: the index is built
RyoheiHagimoto 0:0e0631af0305 488 * Postcondition: the searchParams will have the optimum params set, also the speedup obtained over linear search.
RyoheiHagimoto 0:0e0631af0305 489 */
RyoheiHagimoto 0:0e0631af0305 490 float estimateSearchParams(SearchParams& searchParams)
RyoheiHagimoto 0:0e0631af0305 491 {
RyoheiHagimoto 0:0e0631af0305 492 const int nn = 1;
RyoheiHagimoto 0:0e0631af0305 493 const size_t SAMPLE_COUNT = 1000;
RyoheiHagimoto 0:0e0631af0305 494
RyoheiHagimoto 0:0e0631af0305 495 assert(bestIndex_ != NULL); // must have a valid index
RyoheiHagimoto 0:0e0631af0305 496
RyoheiHagimoto 0:0e0631af0305 497 float speedup = 0;
RyoheiHagimoto 0:0e0631af0305 498
RyoheiHagimoto 0:0e0631af0305 499 int samples = (int)std::min(dataset_.rows / 10, SAMPLE_COUNT);
RyoheiHagimoto 0:0e0631af0305 500 if (samples > 0) {
RyoheiHagimoto 0:0e0631af0305 501 Matrix<ElementType> testDataset = random_sample(dataset_, samples);
RyoheiHagimoto 0:0e0631af0305 502
RyoheiHagimoto 0:0e0631af0305 503 Logger::info("Computing ground truth\n");
RyoheiHagimoto 0:0e0631af0305 504
RyoheiHagimoto 0:0e0631af0305 505 // we need to compute the ground truth first
RyoheiHagimoto 0:0e0631af0305 506 Matrix<int> gt_matches(new int[testDataset.rows], testDataset.rows, 1);
RyoheiHagimoto 0:0e0631af0305 507 StartStopTimer t;
RyoheiHagimoto 0:0e0631af0305 508 t.start();
RyoheiHagimoto 0:0e0631af0305 509 compute_ground_truth<Distance>(dataset_, testDataset, gt_matches, 1, distance_);
RyoheiHagimoto 0:0e0631af0305 510 t.stop();
RyoheiHagimoto 0:0e0631af0305 511 float linear = (float)t.value;
RyoheiHagimoto 0:0e0631af0305 512
RyoheiHagimoto 0:0e0631af0305 513 int checks;
RyoheiHagimoto 0:0e0631af0305 514 Logger::info("Estimating number of checks\n");
RyoheiHagimoto 0:0e0631af0305 515
RyoheiHagimoto 0:0e0631af0305 516 float searchTime;
RyoheiHagimoto 0:0e0631af0305 517 float cb_index;
RyoheiHagimoto 0:0e0631af0305 518 if (bestIndex_->getType() == FLANN_INDEX_KMEANS) {
RyoheiHagimoto 0:0e0631af0305 519 Logger::info("KMeans algorithm, estimating cluster border factor\n");
RyoheiHagimoto 0:0e0631af0305 520 KMeansIndex<Distance>* kmeans = (KMeansIndex<Distance>*)bestIndex_;
RyoheiHagimoto 0:0e0631af0305 521 float bestSearchTime = -1;
RyoheiHagimoto 0:0e0631af0305 522 float best_cb_index = -1;
RyoheiHagimoto 0:0e0631af0305 523 int best_checks = -1;
RyoheiHagimoto 0:0e0631af0305 524 for (cb_index = 0; cb_index < 1.1f; cb_index += 0.2f) {
RyoheiHagimoto 0:0e0631af0305 525 kmeans->set_cb_index(cb_index);
RyoheiHagimoto 0:0e0631af0305 526 searchTime = test_index_precision(*kmeans, dataset_, testDataset, gt_matches, target_precision_, checks, distance_, nn, 1);
RyoheiHagimoto 0:0e0631af0305 527 if ((searchTime < bestSearchTime) || (bestSearchTime == -1)) {
RyoheiHagimoto 0:0e0631af0305 528 bestSearchTime = searchTime;
RyoheiHagimoto 0:0e0631af0305 529 best_cb_index = cb_index;
RyoheiHagimoto 0:0e0631af0305 530 best_checks = checks;
RyoheiHagimoto 0:0e0631af0305 531 }
RyoheiHagimoto 0:0e0631af0305 532 }
RyoheiHagimoto 0:0e0631af0305 533 searchTime = bestSearchTime;
RyoheiHagimoto 0:0e0631af0305 534 cb_index = best_cb_index;
RyoheiHagimoto 0:0e0631af0305 535 checks = best_checks;
RyoheiHagimoto 0:0e0631af0305 536
RyoheiHagimoto 0:0e0631af0305 537 kmeans->set_cb_index(best_cb_index);
RyoheiHagimoto 0:0e0631af0305 538 Logger::info("Optimum cb_index: %g\n", cb_index);
RyoheiHagimoto 0:0e0631af0305 539 bestParams_["cb_index"] = cb_index;
RyoheiHagimoto 0:0e0631af0305 540 }
RyoheiHagimoto 0:0e0631af0305 541 else {
RyoheiHagimoto 0:0e0631af0305 542 searchTime = test_index_precision(*bestIndex_, dataset_, testDataset, gt_matches, target_precision_, checks, distance_, nn, 1);
RyoheiHagimoto 0:0e0631af0305 543 }
RyoheiHagimoto 0:0e0631af0305 544
RyoheiHagimoto 0:0e0631af0305 545 Logger::info("Required number of checks: %d \n", checks);
RyoheiHagimoto 0:0e0631af0305 546 searchParams["checks"] = checks;
RyoheiHagimoto 0:0e0631af0305 547
RyoheiHagimoto 0:0e0631af0305 548 speedup = linear / searchTime;
RyoheiHagimoto 0:0e0631af0305 549
RyoheiHagimoto 0:0e0631af0305 550 delete[] gt_matches.data;
RyoheiHagimoto 0:0e0631af0305 551 delete[] testDataset.data;
RyoheiHagimoto 0:0e0631af0305 552 }
RyoheiHagimoto 0:0e0631af0305 553
RyoheiHagimoto 0:0e0631af0305 554 return speedup;
RyoheiHagimoto 0:0e0631af0305 555 }
RyoheiHagimoto 0:0e0631af0305 556
RyoheiHagimoto 0:0e0631af0305 557 private:
RyoheiHagimoto 0:0e0631af0305 558 NNIndex<Distance>* bestIndex_;
RyoheiHagimoto 0:0e0631af0305 559
RyoheiHagimoto 0:0e0631af0305 560 IndexParams bestParams_;
RyoheiHagimoto 0:0e0631af0305 561 SearchParams bestSearchParams_;
RyoheiHagimoto 0:0e0631af0305 562
RyoheiHagimoto 0:0e0631af0305 563 Matrix<ElementType> sampledDataset_;
RyoheiHagimoto 0:0e0631af0305 564 Matrix<ElementType> testDataset_;
RyoheiHagimoto 0:0e0631af0305 565 Matrix<int> gt_matches_;
RyoheiHagimoto 0:0e0631af0305 566
RyoheiHagimoto 0:0e0631af0305 567 float speedup_;
RyoheiHagimoto 0:0e0631af0305 568
RyoheiHagimoto 0:0e0631af0305 569 /**
RyoheiHagimoto 0:0e0631af0305 570 * The dataset used by this index
RyoheiHagimoto 0:0e0631af0305 571 */
RyoheiHagimoto 0:0e0631af0305 572 const Matrix<ElementType> dataset_;
RyoheiHagimoto 0:0e0631af0305 573
RyoheiHagimoto 0:0e0631af0305 574 /**
RyoheiHagimoto 0:0e0631af0305 575 * Index parameters
RyoheiHagimoto 0:0e0631af0305 576 */
RyoheiHagimoto 0:0e0631af0305 577 float target_precision_;
RyoheiHagimoto 0:0e0631af0305 578 float build_weight_;
RyoheiHagimoto 0:0e0631af0305 579 float memory_weight_;
RyoheiHagimoto 0:0e0631af0305 580 float sample_fraction_;
RyoheiHagimoto 0:0e0631af0305 581
RyoheiHagimoto 0:0e0631af0305 582 Distance distance_;
RyoheiHagimoto 0:0e0631af0305 583
RyoheiHagimoto 0:0e0631af0305 584
RyoheiHagimoto 0:0e0631af0305 585 };
RyoheiHagimoto 0:0e0631af0305 586 }
RyoheiHagimoto 0:0e0631af0305 587
RyoheiHagimoto 0:0e0631af0305 588 #endif /* OPENCV_FLANN_AUTOTUNED_INDEX_H_ */