Go to the documentation of this file.00001 #ifndef VOCABULARY_TREE_TREE_BUILDER_H
00002 #define VOCABULARY_TREE_TREE_BUILDER_H
00003 
00004 #include "vocabulary_tree/mutable_tree.h"
00005 #include "vocabulary_tree/simple_kmeans.h"
00006 #include <deque>
00007 
00008 
00009 namespace vt {
00010 
00015 template<class Feature, class Distance = distance::L2<Feature>,
00016          class FeatureAllocator = typename DefaultAllocator<Feature>::type>
00017 class TreeBuilder
00018 {
00019 public:
00020   typedef MutableVocabularyTree<Feature, Distance, FeatureAllocator> Tree;
00021   typedef SimpleKmeans<Feature, Distance, FeatureAllocator> Kmeans;
00022   typedef std::vector<Feature, FeatureAllocator> FeatureVector;
00023 
00030   TreeBuilder(const Feature& zero = Feature(), Distance d = Distance());
00031 
00041   void build(const FeatureVector& training_features, uint32_t k, uint32_t levels);
00042 
00044   const Tree& tree() const { return tree_; }
00045 
00047   Kmeans& kmeans() { return kmeans_; }
00049   const Kmeans& kmeans() const { return kmeans_; }
00050 
00051 protected:
00052   Tree tree_;
00053   Kmeans kmeans_;
00054   Feature zero_;
00055 };
00056 
00057 
00058 template<class Feature, class Distance, class FeatureAllocator>
00059 TreeBuilder<Feature, Distance, FeatureAllocator>::TreeBuilder(const Feature& zero, Distance d)
00060   : tree_(d),
00061     kmeans_(zero, d),
00062     zero_(zero)
00063 {
00064 }
00065 
00066 template<class Feature, class Distance, class FeatureAllocator>
00067 void TreeBuilder<Feature, Distance, FeatureAllocator>::build(const FeatureVector& training_features,
00068                                                              uint32_t k, uint32_t levels)
00069 {
00070   
00071   tree_.clear();
00072   tree_.setSize(levels, k);
00073   tree_.centers().reserve(tree_.nodes());
00074   tree_.validCenters().reserve(tree_.nodes());
00075 
00076   
00077   
00078   std::deque< std::vector<Feature*> > subset_queue(1);
00079 
00080   
00081   std::vector<Feature*> &feature_ptrs = subset_queue.front();
00082   feature_ptrs.reserve(training_features.size());
00083   BOOST_FOREACH(const Feature& f, training_features)
00084     feature_ptrs.push_back(const_cast<Feature*>(&f));
00085 
00086   FeatureVector centers; 
00087   for (uint32_t level = 0; level < levels; ++level) {
00088     
00089     std::vector<unsigned int> membership;
00090 
00091     for (size_t i = 0, ie = subset_queue.size(); i < ie; ++i) {
00092       std::vector<Feature*> &subset = subset_queue.front();
00093       
00094 
00095       
00096       if (subset.size() <= k) {
00097         for (size_t j = 0; j < subset.size(); ++j) {
00098           tree_.centers().push_back(*subset[j]);
00099           tree_.validCenters().push_back(1);
00100         }
00101         
00102         tree_.centers().insert(tree_.centers().end(), k - subset.size(), zero_);
00103         tree_.validCenters().insert(tree_.validCenters().end(), k - subset.size(), 0);
00104 
00105         
00106         subset_queue.pop_front();
00107         subset_queue.insert(subset_queue.end(), k, std::vector<Feature*>());
00108       }
00109       else {
00110         
00111         kmeans_.clusterPointers(subset, k, centers, membership);
00112 
00113         
00114         tree_.centers().insert(tree_.centers().end(), centers.begin(), centers.end());
00115         tree_.validCenters().insert(tree_.validCenters().end(), k, 1);
00116 
00117         
00118         std::vector< std::vector<Feature*> > new_subsets(k);
00119         for (size_t j = 0; j < subset.size(); ++j) {
00120           new_subsets[ membership[j] ].push_back(subset[j]);
00121         }
00122 
00123         
00124         subset_queue.pop_front();
00125         subset_queue.insert(subset_queue.end(), new_subsets.begin(), new_subsets.end());
00126       }
00127     }
00128     
00129   }
00130 }
00131 
00132 } 
00133 
00134 #endif