Structural deformable models
Clusterer.h
Go to the documentation of this file.
1 #ifndef _CLUSTERER_H_
2 #define _CLUSTERER_H_
3 #include <iostream>
4 #include <math.h>
5 #include <string>
6 #include "common.h"
7 
8 template<int D>
9 class CElement {
10 public:
11  CElement() : id(0), multiv(0) {}
12  CElement(float v) : id(0), multiv(0) {
13  operator=(v);
14  }
15  CElement(const vector<float> &rhs) : id(0), multiv(0) {
16  operator=(rhs);
17  }
18  CElement<D>& operator=(const vector<float> &rhs) {
19  for(int i=0; i<D; i++) val[i]=rhs[i];
20  return *this;
21  }
23  for(int i=0; i<D; i++) val[i]=rhs.val[i];
24  id = rhs.id;
25  multiv = rhs.multiv;
26  return *this;
27  }
28  CElement<D>& operator=(float v) {
29  for(int i=0; i<D; i++) val[i]=v;
30  return *this;
31  }
33  for(int i=0; i<D; i++) val[i]+=rhs.val[i];
34  return *this;
35  }
37  for(int i=0; i<D; i++) val[i]*=rhs.val[i];
38  return *this;
39  }
40  CElement<D>& operator*=(float v) {
41  for(int i=0; i<D; i++) val[i]*=v;
42  return *this;
43  }
44  CElement<D>& operator/=(float v) {
45  for(int i=0; i<D; i++) val[i]/=v;
46  return *this;
47  }
48  CElement<D>& randomize(float min=0, float max=1) {
49  for(int i=0; i<D; i++) val[i]=frand(max-min)+min;
50  return *this;
51  }
52  float dist2(const CElement<D> &rhs) const {
53  float d=0;
54  for(int i=0; i<D; i++) {
55  register float cd = val[i]-rhs.val[i];
56  d += cd*cd;
57  }
58  return d;
59  }
60  float dist(const CElement<D> &rhs) const {
61  return sqrt(dist2(rhs));
62  }
63 
64  dword getNMembers() const { return multiv; }
65  dword& getNMembers() { return multiv; }
66  dword getClassID() const { return multiv; }
67  void setClassID(dword cid) { multiv = cid; }
68  friend ostream& operator<<(ostream& os, const CElement<D> &rhs) {
69  for(int i=0; i<D; i++) {
70  if(i) os << " ";
71  os << rhs.val[i];
72  }
73  return os;
74  }
75 
76 public:
77  float val[D];
79  dword multiv; // class ID or number of members
80 };
81 
82 template<int D>
83 class Clusterer {
84 public:
85  typedef typename vector< CElement<D> >::iterator eiterator;
86  typedef typename vector< CElement<D> >::const_iterator const_eiterator;
87 
88  Clusterer(dword nclasses=1, float min=0, float max=1 ) {
89  initialize(nclasses, min, max);
90  };
91 
93  dword cid=0;
94  for(eiterator cv = m_ElemAcc.begin();
95  cv != m_ElemAcc.end(); cv++, cid++)
96  {
97  *cv = 0;
98  cv->id = cid;
99  cv->getNMembers() = 0;
100  }
101  }
102 
103  void initialize( dword nclasses, float min=0, float max=1 ) {
104  m_Classes.resize(nclasses);
105  m_ElemAcc.resize(nclasses);
106  dword cid=0;
107  for(eiterator cv = m_Classes.begin();
108  cv != m_Classes.end(); cv++, cid++)
109  {
110  cv->id = cid;
111  cv->getNMembers() = 0;
112  cv->randomize(min,max);
113  //cout << *cv << endl;
114  }
115  clearAccumulation();
116  }
117 
119  float mind=numeric_limits<float>::max();
120  dword minid=0;
121  dword cid=0;
122  for(eiterator cv = m_Classes.begin();
123  cv != m_Classes.end(); cv++, cid++)
124  {
125  float d = elem.dist2(*cv);
126  if(d<mind) {
127  mind = d;
128  minid = cid;
129  }
130  }
131  CElement<D> &ae = m_ElemAcc[minid];
132  ae += elem;
133  ae.getNMembers()++;
134  elem.setClassID(minid);
135  return minid;
136  }
137 
139  dword reclass = 0;
140  clearAccumulation();
141  for(eiterator e=m_Elements.begin();
142  e != m_Elements.end(); e++)
143  {
144  dword oldclass = e->getClassID();
145  if(oldclass != classify(*e))
146  reclass++;
147  }
148  for(eiterator ci=m_Classes.begin(), ca=m_ElemAcc.begin();
149  ci!=m_Classes.end(); ci++, ca++)
150  {
151  if(ca->getNMembers()) {
152  *ca *= 1.0f/ca->getNMembers();
153  *ci = *ca;
154  } else ci->getNMembers() = 0;
155  //cout << *ci << " members: " << ci->getNMembers() << endl;
156  }
157  cout << reclass << " re-classifications" << endl; //DEBUG
158  return reclass;
159  }
160 
161  void iterateClassification( dword maxit=10) {
162  int counter=0; //DEBUG
163  while(maxit>0) {
164  cout << "iteration " << (++counter) << endl; //DEBUG
165  if(classifyAll() == 0) break;
166  maxit--;
167  }
168  int cu=0;
169  for(eiterator ci=m_Classes.begin(); ci!=m_Classes.end(); ci++)
170  if(ci->getNMembers()) cu++;
171  cout << "number of classes used: " << cu << endl;
172  }
173 
174 public:
175  vector< CElement<D> > m_Elements;
176  vector< CElement<D> > m_Classes;
177  vector< CElement<D> > m_ElemAcc;
178 };
179 
180 #endif
dword getNMembers() const
Definition: Clusterer.h:64
float dist2(const CElement< D > &rhs) const
Definition: Clusterer.h:52
CElement()
Definition: Clusterer.h:11
vector< CElement< D > > m_ElemAcc
Definition: Clusterer.h:177
void iterateClassification(dword maxit=10)
Definition: Clusterer.h:161
CElement< D > & operator=(const vector< float > &rhs)
Definition: Clusterer.h:18
#define frand(max)
Definition: mathutil.h:48
vector< CElement< D > > m_Classes
Definition: Clusterer.h:176
CElement(const vector< float > &rhs)
Definition: Clusterer.h:15
dword id
Definition: Clusterer.h:78
CElement< D > & operator=(float v)
Definition: Clusterer.h:28
dword multiv
Definition: Clusterer.h:79
vector< CElement< D > >::iterator eiterator
Definition: Clusterer.h:85
void initialize(dword nclasses, float min=0, float max=1)
Definition: Clusterer.h:103
Clusterer(dword nclasses=1, float min=0, float max=1)
Definition: Clusterer.h:88
dword classify(CElement< D > &elem)
Definition: Clusterer.h:118
CElement(float v)
Definition: Clusterer.h:12
void clearAccumulation()
Definition: Clusterer.h:92
dword getClassID() const
Definition: Clusterer.h:66
CElement< D > & operator=(const CElement &rhs)
Definition: Clusterer.h:22
void setClassID(dword cid)
Definition: Clusterer.h:67
CElement< D > & operator+=(const CElement< D > &rhs)
Definition: Clusterer.h:32
unsigned long dword
Definition: simpletypes.h:6
vector< CElement< D > >::const_iterator const_eiterator
Definition: Clusterer.h:86
CElement< D > & randomize(float min=0, float max=1)
Definition: Clusterer.h:48
dword classifyAll()
Definition: Clusterer.h:138
float val[D]
Definition: Clusterer.h:77
vector< CElement< D > > m_Elements
Definition: Clusterer.h:175
dword & getNMembers()
Definition: Clusterer.h:65
CElement< D > & operator*=(float v)
Definition: Clusterer.h:40
CElement< D > & operator/=(float v)
Definition: Clusterer.h:44
float dist(const CElement< D > &rhs) const
Definition: Clusterer.h:60
CElement< D > & operator*=(const CElement< D > &rhs)
Definition: Clusterer.h:36
DMatrix< T > & sqrt(DMatrix< T > &mat)
Definition: DMatrixUtil.h:81