33 #ifndef GRT_MEAN_SHIFT_HEADER
34 #define GRT_MEAN_SHIFT_HEADER
36 #include "../../CoreModules/MLBase.h"
43 classType =
"MeanShift";
44 infoLog.setProceedingText(
"[MeanShift]");
45 debugLog.setProceedingText(
"[DEBUG MeanShift]");
46 errorLog.setProceedingText(
"[ERROR MeanShift]");
47 trainingLog.setProceedingText(
"[TRAINING MeanShift]");
48 warningLog.setProceedingText(
"[WARNING MeanShift]");
55 bool search(
const VectorDouble &meanStart,
const vector< VectorDouble > &points,
const double searchRadius,
const double sigma = 20.0 ){
60 const unsigned int numDimensions = (
unsigned int)meanStart.size();
61 const unsigned int numPoints = (
unsigned int)points.size();
62 const double gamma = 1.0 / (2 * SQR(sigma) );
63 unsigned int iteration = 0;
64 VectorDouble numer(2,0);
65 VectorDouble denom(2,0);
66 VectorDouble kernelDist(2,0);
67 double pointsWithinSearchRadius = 0;
70 VectorDouble lastMean = mean;
76 pointsWithinSearchRadius = 0;
77 std::fill(numer.begin(),numer.end(),0);
78 std::fill(denom.begin(),denom.end(),0);
79 std::fill(kernelDist.begin(),kernelDist.end(),0);
82 for(
unsigned int i=0; i<numPoints; i++){
85 double distToMean = euclideanDist( mean, points[i] );
88 if( distToMean < searchRadius ){
90 for(
unsigned int j=0; j<numDimensions; j++){
91 kernelDist[j] = gaussKernel( points[i][j], mean[j], gamma );
92 numer[j] += kernelDist[j] * points[i][j];
93 denom[j] += kernelDist[j];
96 pointsWithinSearchRadius++;
102 for(
unsigned int j=0; j<numDimensions; j++){
104 mean[j] = numer[j] / denom[j];
106 change += SQR( mean[j] - lastMean[j] );
108 lastMean[j] = mean[j];
110 change = sqrt( change );
112 trainingLog <<
"iteration: " << iteration;
113 trainingLog <<
" mean: ";
114 for(
unsigned int j=0; j<numDimensions; j++){
115 trainingLog << mean[j] <<
" ";
117 trainingLog <<
" change: " << change << endl;
119 if( change < minChange ){
120 trainingLog <<
"min changed limit reached - stopping search" << endl;
124 if( ++iteration >= maxNumEpochs ){
125 trainingLog <<
"max number of iterations reached - stopping search." << endl;
130 numTrainingIterationsToConverge = iteration;
136 VectorDouble getMean()
const {
140 double gaussKernel(
const double &x,
const double &mu,
const double gamma ){
141 return exp( gamma * SQR(x-mu) );
144 double gaussKernel(
const VectorDouble &x,
const VectorDouble &mu,
const double gamma ){
147 const size_t N = x.size();
148 for(
size_t i=0; i<N; i++){
149 y += SQR(x[i]-mu[i]);
151 return exp( gamma * y );
154 double euclideanDist(
const VectorDouble &x,
const VectorDouble &y ){
157 const size_t N = x.size();
158 for(
size_t i=0; i<N; i++){
173 #endif //GRT_MEAN_SHIFT_HEADER