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
00071
00072 int
00073 cob_3d_features::MostDiscriminatingDataPoints::eStep()
00074 {
00075 int n_chg = 0;
00076 int k_min;
00077 float d_min,d;
00078 for (size_t k=0;k<k_;k++) count_[k] = 0;
00079
00080
00081 for (size_t n=0;n<n_;n++)
00082 {
00083 d_min = FLT_MAX;
00084 for (size_t k=0;k<k_;k++)
00085 {
00086
00087 d = 0.0;
00088
00089 for (size_t m=0;m<m_;m++) d += pow( (pdata_->at(n)).at(m) - (pmeans_->at(k)).at(m), 2 );
00090
00091
00092 if (d < d_min) {d_min = d; k_min = k;}
00093 }
00094
00095
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
00123 for (size_t k=0;k<k_;k++)
00124 {
00125 pmeans_->at(k) = pdata_->at(init_indices_->at(k));
00126 }
00127
00128 int steps = 0;
00129 int changed_points = -1;
00130 while (changed_points != 0)
00131 {
00132 changed_points = eStep();
00133
00134 mStep();
00135 steps++;
00136 }
00137
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
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
00166 for (size_t m=0;m<m_;m++) p.dist += std::min((pdata_->at(n)).at(m), mean.at(m));
00167
00168
00169 sorted_by_dist.push_back(p);
00170 }
00171 sort(sorted_by_dist.begin(), sorted_by_dist.end());
00172
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
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
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 }