www.pudn.com > mputil.rar > cluster.h
#ifndef __CLUSTER_H__ #define __CLUSTER_H__ #include "common.h" #include "faceboxlist.h" #include#include #include #include
class ActData{ public: int mode; double val; ActData() { mode = -1; val = 0.0; }; ~ActData(){}; }; using namespace std; class ModeData{ private: int mode; double mean; double varience; double meanSquare; std::vector< double > List; std::vector< double > squareList; double m_max; double m_min; public: ModeData() { mode = -1; mean = 0; varience = 0; meanSquare = 0; m_max = -5000.0; m_min = 5000.0; }; ModeData(std::vector< ActData > data, int _mode) { mode = _mode; m_max = -5000.0; m_min = 5000.0; int dataSize = data.size(); for (int i = 0; i < dataSize; i++) { if (data[i].mode == mode) { double val = data[i].val; mean += val; meanSquare += val*val; squareList.push_back(val*val); List.push_back(val); m_max = max((double)m_max, val); m_min = min((double)m_min, val); } } mean /= List.size(); meanSquare /= squareList.size(); setVarience(); }; //Copy Constructor ModeData(const ModeData &_data) { mode = _data.mode; mean = _data.mean; m_max = _data.m_max; m_min = _data.m_min; meanSquare = _data.meanSquare; varience = _data.varience; List = _data.List; squareList = _data.squareList; }; ~ModeData(){squareList.clear(); List.clear();}; inline double getMean() {return mean;}; inline double getMin() {return m_min;}; inline double getMax() {return m_max;}; inline double getVarience() { return varience; }; inline void setVarience() { varience = meanSquare - (mean*mean); }; inline int getSize() { return List.size(); }; // ================================================================ inline int addData(ActData data) { if (mode == data.mode) { double SquareListVal = meanSquare*squareList.size(); double ListVal = mean*List.size(); squareList.push_back(data.val*data.val); List.push_back(data.val); meanSquare = (SquareListVal + (data.val*data.val))/squareList.size(); mean = (ListVal + data.val)/List.size(); setVarience(); m_max = max((double)m_max, data.val); m_min = min((double)m_min, data.val); return 1; } return 0; }; // ================================================================ inline int subData(ActData data) { if(data.mode == mode) { double val = data.val; double squareVal = data.val*data.val; double squareListVal = meanSquare * squareList.size(); double ListVal = mean*List.size(); std::vector ::iterator it = List.begin(); for (; it != List.end(); ++it) { if(*it == val) { List.erase(it); break; } } it = squareList.begin(); for (; it != List.end(); ++it) { if(*it == squareVal) { squareList.erase(it); break; } } meanSquare = (squareListVal - squareVal)/squareList.size(); mean = (ListVal - val)/List.size(); setVarience(); m_max = max((double)m_max, data.val); m_min = min((double)m_min, data.val); return 1; } return 0; }; // ================================================================ inline void printData(ofstream &os) { os << "mode = " << mode << endl; for(unsigned int i = 0; i < List.size(); i++) { os << List[i] << "\t"; } os << endl << endl; } }; //ModeData // ================================================================ // class Cluster // ================================================================ class Cluster { public: Cluster(int _modes = 2) { m_modeSize = _modes; m_modesSet = 0; m_contData = 0; m_suggModeMean.reserve(m_modeSize); m_modes.reserve(m_modeSize); } // Constructor ~Cluster() { m_dataList.clear(); m_modes.clear(); } // Destructor // ================================================================ inline double UpdateCluster(double curAct) { float lamda = 0.1f; ActData data; m_contData = curAct*lamda + (1-lamda)*m_contData; data.val = m_contData; static int curI = 0; int curSize = m_dataList.size(); if (curSize > 2000) { subVal(); m_dataList.erase(m_dataList.begin()); curSize--; } else m_dataList.push_back(data); if (curSize > 150 && !m_modesSet){ setModes(); for(int m = 0; m < m_modeSize; m++) { ModeData curMode(m_dataList, m); m_modes[m] = curMode; } m_modesSet = 1; } else if (curI > 500) { curI = 0; setModes(); m_modes.clear(); m_modesSet = 0; for(int m = 0; m < m_modeSize; m++) { ModeData curMode(m_dataList, m); m_modes[m] = curMode; } printData(); m_modesSet = 2; } else { int closestMode = 0; double dist = 100000.0; for (int m = 0; m < m_modeSize; m++) { double curDist = data.val - m_suggModeMean[m]; if (fabs(curDist) < dist) { dist = fabs(curDist); closestMode = m; } } data.mode = closestMode; m_modes[data.mode].addData(data); } curI++; //only works with 2 modes, change later if (m_modes.size() > 1) m_currThresh = min(m_modes[0].getMax(), m_modes[1].getMax()) - max(m_modes[0].getMin(), m_modes[1].getMin()); else m_currThresh = 0.0; return m_currThresh; //return (find optimal position); } // ================================================================ private: std::vector < ActData > m_dataList; std::vector < ModeData > m_modes; std::vector < double > m_suggModeMean; double m_min, m_max, m_mean, m_contData; double m_currThresh; int m_modesSet, m_modeSize; // ================================================================ inline int subVal() { int mode = m_dataList[0].mode; int rtn = m_modes[mode].subData(m_dataList[0]); m_dataList.erase(m_dataList.begin()); return rtn; } // ================================================================ inline void setModes(int maxTrials = 100) { int dataSize = m_dataList.size(); int i, m, trial = 0; int notStable = 1; std::vector < double > curModeMean; curModeMean.reserve(m_modeSize); std::vector < int > curModeSize; curModeSize.reserve(m_modeSize); while (notStable && trial < maxTrials) { for (i = 0; i < dataSize; i++) { int closestMode = 0; double dist = 100000.0; for (m = 0; m < m_modeSize; m++) { double curDist = m_dataList[i].val - m_suggModeMean[m]; if (fabs(curDist) < dist) { dist = fabs(curDist); closestMode = m; curModeMean[m] += m_dataList[i].val; curModeSize[m]++; } } m_dataList[i].mode = closestMode; } notStable = 0; for (m = 0; m < m_modeSize; m++) { double curMean = m_suggModeMean[m]; m_suggModeMean[m] = curModeMean[m]/curModeSize[m]; if (m_suggModeMean[m] != curMean) notStable++; } trial++; } } // ================================================================ inline void printData() { ofstream os; os.open("c:\\timedata.out", ios::trunc); os << "data size = " << m_dataList.size() << "; Threshold = " << m_currThresh << endl; for(unsigned int i = 0; i < m_dataList.size(); i++) os << m_dataList[i].val << "\t"; for(int m = 0; m < m_modeSize; m++) { os << "mode = " << m << endl; os << "mean = " << m_modes[m].getMean() << "; varience = " << m_modes[m].getVarience() << "; size = " << m_modes[m].getSize() << endl; m_modes[m].printData(os); } os << endl << endl; os.close(); } /////////////////////////////////////////////////////////// }; // Cluster #endif //__CLUSTER_H__