most_discriminating_data_points.cpp
Go to the documentation of this file.
00001 
00064 #include "cob_3d_features/most_discriminating_data_points.h"
00065 #include <float.h>
00066 #include <math.h>
00067 #include <iostream>
00068 #include <algorithm>
00069 
00070 // TODO: change data type to Eigen::VectorXF or something
00071 
00072 int
00073 cob_3d_features::MostDiscriminatingDataPoints::eStep()
00074 {
00075   int n_chg = 0; // number of changed data points
00076   int k_min;
00077   float d_min,d;
00078   for (size_t k=0;k<k_;k++) count_[k] = 0;
00079   //std::cout << "cleared count_" << std::endl;
00080 
00081   for (size_t n=0;n<n_;n++) // iterate data points
00082   {
00083     d_min = FLT_MAX;
00084     for (size_t k=0;k<k_;k++) // iterate mean clusters
00085     {
00086       // calc distance to each mean cluster and save k with min distance
00087       d = 0.0;
00088       //std::cout << "compute distance: " << k<<"/"<<k_<< std::endl;
00089       for (size_t m=0;m<m_;m++) d += pow( (pdata_->at(n)).at(m) - (pmeans_->at(k)).at(m), 2 );
00090       //for (size_t m=0;m<m_;m++) d += std::min( (pdata_->at(n)).at(m),(pmeans_->at(k)).at(m) );
00091       //std::cout << "distance: " << d << std::endl;
00092       if (d < d_min) {d_min = d; k_min = k;}
00093     }
00094     //std::cout << "n: " << n << " dmin: " << d_min << " kmin: " << k_min << std::endl;
00095     //std::cout << assigned_classes_.size() << std::endl;
00096     if (k_min != assigned_classes_[n]) n_chg++;
00097     assigned_classes_[n] = k_min;
00098     count_[k_min]++;
00099   }
00100   return n_chg;
00101 }
00102 
00103 void
00104 cob_3d_features::MostDiscriminatingDataPoints::mStep()
00105 {
00106   for (size_t k=0;k<k_;k++)
00107     for (size_t m=0;m<m_;m++)
00108       (pmeans_->at(k)).at(m) = 0.0;
00109   for (size_t n=0;n<n_;n++)
00110     for (size_t m=0;m<m_;m++)
00111       (pmeans_->at(assigned_classes_[n])).at(m) += (pdata_->at(n)).at(m);
00112   for (size_t k=0;k<k_;k++)
00113   {
00114     if (count_[k] > 0)
00115       for (size_t m=0;m<m_;m++) (pmeans_->at(k)).at(m) /= count_[k];
00116   }
00117 }
00118 
00119 void
00120 cob_3d_features::MostDiscriminatingDataPoints::computeKmeans()
00121 {
00122   // fill initial means:
00123   for (size_t k=0;k<k_;k++)
00124   {
00125     pmeans_->at(k) = pdata_->at(init_indices_->at(k));
00126   }
00127   //std::cout << "Start computing k-means..." << std::endl;
00128   int steps = 0;
00129   int changed_points = -1;
00130   while (changed_points != 0)
00131   {
00132     changed_points = eStep();
00133     //std::cout << "Re-assigned Points: " << changed_points << std::endl;
00134     mStep();
00135     steps++;
00136   }
00137   //std::cout<<std::endl<< "K-Means needed " << steps << " steps to find cluster centers!" << std::endl;
00138 }
00139 
00140 void
00141 cob_3d_features::MostDiscriminatingDataPoints::computeInitialMeans(std::vector<int> * const output_init_indices)
00142 {
00143   if (!pdata_)
00144   {
00145     std::cout << "[computeInitialMeans]: No input data points defined" << std::endl;
00146     return;
00147   }
00148   std::vector<float> mean(m_,0.0);
00149   for (size_t n=0;n<n_;n++)
00150     for (size_t m=0;m<m_;m++)
00151       mean.at(m) += (pdata_->at(n)).at(m);
00152 
00153   //std::cout << "Created mean data: | ";
00154   for (size_t m=0;m<m_;m++)
00155   {
00156     mean.at(m) /= n_;
00157   }
00158 
00159   std::vector<SortableDataPoint> sorted_by_dist;
00160   cob_3d_features::SortableDataPoint p;
00161   for (size_t n=0;n<n_;n++)
00162   {
00163     p.idx = n;
00164     p.dist = 0.0;
00165     // histogram intersection kernel:
00166     for (size_t m=0;m<m_;m++) p.dist += std::min((pdata_->at(n)).at(m), mean.at(m));
00167     // manhatten distance:
00168     //for (size_t m=0;m<m_;m++) p.dist += pow((pdata_->at(n)).at(m) - mean.at(m), 2);
00169     sorted_by_dist.push_back(p);
00170   }
00171   sort(sorted_by_dist.begin(), sorted_by_dist.end());
00172   //std::cout << "Sorted input data by distance to mean data..." << std::endl;
00173   output_init_indices->clear();
00174   output_init_indices->resize(k_);
00175 
00176 
00177   size_t bin_size = floor((float)n_ / (float)k_);
00178   size_t n_idx = round(0.5f*(float)bin_size);
00179   //std::cout << "Select initial indices... " << std::endl;
00180   for (size_t k=0;k<k_;k++)
00181   {
00182     output_init_indices->at( k ) = (sorted_by_dist.at(n_idx)).idx;
00183     n_idx += bin_size;
00184   }
00185   //std::cout << std::endl;
00186   return;
00187 }
00188 
00189 void
00190 cob_3d_features::MostDiscriminatingDataPoints::computeDataPoints(std::vector<std::vector<float> > * const k_means)
00191 {
00192   if (!pdata_)
00193   {
00194     std::cout << "[computeDataPoints]: No input data points defined" << std::endl;
00195     return;
00196   }
00197 
00198   pmeans_ = k_means;
00199   pmeans_->clear();
00200   pmeans_->resize(k_);
00201   assigned_classes_.clear();
00202   assigned_classes_.resize(n_);
00203   count_.resize(k_);
00204 
00205   if (predefined_initial_centers_)
00206   {
00207     computeKmeans();
00208   }
00209   else
00210   {
00211     init_indices_ = new std::vector<int>(k_);
00212     computeInitialMeans(init_indices_);
00213     computeKmeans();
00214   }
00215 }


cob_3d_features
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:02:26