CEDRIC  Revision_backup-2009-02
FeatureCovar.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 2008 Boris Iven, Max Hermann
4  *
5  * This file is part of the "CEDRIC Event Display" application.
6  *
7  *****************************************************************************/
8 
9 #ifndef FEATURECOVAR_H
10 #define FEATURECOVAR_H
11 
12 #include <iostream>
13 #include <vector>
14 #include <math.h>
15 
21 template<class F,int DIM_FEAT>
23 {
24 public:
25  FeatureCovar( const std::vector<F>& values_ );
26 
27  void compute();
28  void print();
29 
30  unsigned int size() const { return DIM_FEAT; };
31 
32  double getUnitVarCovMat (int r, int c) const;
33  double getInvUnitVarCovMat(int r, int c) const;
34  double getRawCovMat (int r, int c) const;
35  double getInvRawCovMat (int r, int c) const;
36  double getVarScaledCovMat (int r, int c) const;
37  double getMean(int d) const;
38 
39 private:
40  double rawCovMat[DIM_FEAT][DIM_FEAT];
41  double invRawCovMat[DIM_FEAT][DIM_FEAT];
42  double unitVarCovMat[DIM_FEAT][DIM_FEAT];
43  double varScaledCovMat[DIM_FEAT][DIM_FEAT];
44  double invUnitVarCovMat[DIM_FEAT][DIM_FEAT];
45  double means[DIM_FEAT];
46 
47  const std::vector<F>& values;
48  std::vector<F> zeroMeanValues;
49  std::vector<F> varScaledValues;
50  std::vector<F> unitVarianceValues;
51 
52  int invert (double a[][2*DIM_FEAT], double ainv[][2*DIM_FEAT], int n);
53 };
54 
55 
56 
57 //=====================================================================================================================
58 
59 // TEMPLATE IMPLEMENTATION
60 
61 //=====================================================================================================================
62 
63 
64 template<class F,int DIM_FEAT>
65 FeatureCovar<F,DIM_FEAT>::FeatureCovar( const std::vector<F>& values_ )
66 : values(values_)
67 {
68  for(int r = 0; r < DIM_FEAT; r++)
69  for(int c = 0; c < DIM_FEAT; c++)
70  {
71  means[r] = 0;
72  rawCovMat[r][c] = 0;
73  unitVarCovMat[r][c] = 0;
74  invUnitVarCovMat[r][c] = 0;
75  varScaledCovMat[r][c] = 0;
76  }
77 }
78 
79 template<class F,int DIM_FEAT>
81 {
82  using namespace std;
83 
84  //for matrix inversion
85  double tmp[2*DIM_FEAT][2*DIM_FEAT];
86  double res[2*DIM_FEAT][2*DIM_FEAT];
87 
88  cout << "Computing covariance matrix... " << endl;
89 
90  //vector<double> means(6,0);
91 
92  int num = values.size();
93 
94  //compute means
95 
96  for (int v = 0; v < num; v++)
97  {
98  for(int d = 0; d < DIM_FEAT; d++)
99  {
100  means[d] += values[v][d] / num;
101  }
102  }
103 
104  cout << "Means: " << endl;
105 
106  for (int d = 0; d < DIM_FEAT; d++)
107  cout << d << ": " << means[d] << endl;
108  cout << endl;
109 
110  //compute "raw" covariance matrix
111 
112  for (int r = 0; r < DIM_FEAT; r++)
113  {
114  for (int c = 0; c < DIM_FEAT; c++)
115  {
116  for (int v = 0; v < num; v++)
117  rawCovMat[r][c] += (values[v][r] - means[r]) * (values[v][c] - means[c]) / num;
118  }
119  }
120 
121  //compute inverse raw covariance matrix
122 
123  for (int r = 0; r < DIM_FEAT; r++)
124  for (int c = 0; c < DIM_FEAT; c++)
125  tmp[r][c] = rawCovMat[r][c];
126 
127  invert(tmp, res, DIM_FEAT);
128 
129 
130 
131  for (int r = 0; r < DIM_FEAT; r++)
132  for (int c = 0; c < DIM_FEAT; c++)
133  invRawCovMat[r][c] = res[r][c];
134 
135  //compute zero mean values
136  zeroMeanValues = values;
137 
138  for (int i = 0; i < num; i++)
139  {
140  for (int d = 0; d < DIM_FEAT; d++)
141  zeroMeanValues[i][d] -= means[d];
142  }
143 
144  //compute variance scaled values
145 
146  varScaledValues = zeroMeanValues;
147 
148  for (int i = 0; i < num; i++)
149  {
150  for (int d = 0; d < DIM_FEAT; d++)
151  varScaledValues[i][d] /= rawCovMat[d][d];
152  }
153 
154 
155  //compute unit variance values
156 
157  unitVarianceValues = zeroMeanValues;
158 
159  for (int i = 0; i < num; i++)
160  {
161  for (int d = 0; d < DIM_FEAT; d++)
162  unitVarianceValues[i][d] /= sqrt(rawCovMat[d][d]);
163  }
164 
165  //compute unit variance covariance matrix
166 
167  for (int r = 0; r < DIM_FEAT; r++)
168  {
169  for (int c = 0; c < DIM_FEAT; c++)
170  {
171  for (int v = 0; v < num; v++)
172  unitVarCovMat[r][c] += ((unitVarianceValues[v][r]) * (unitVarianceValues[v][c]) / num);
173 
174  }
175  }
176 
177  //compute mysterious variance scaled covariance matrix
178 
179  for (int r = 0; r < DIM_FEAT; r++)
180  {
181  for (int c = 0; c < DIM_FEAT; c++)
182  {
183  for (int v = 0; v < num; v++)
184  varScaledCovMat[r][c] += ((varScaledValues[v][r]) * (varScaledValues[v][c]) / num);
185 
186  }
187  }
188 
189 
190  //compute inverse covariance matrix
191 
192 
193  for (int r = 0; r < DIM_FEAT; r++)
194  for (int c = 0; c < DIM_FEAT; c++)
195  tmp[r][c] = unitVarCovMat[r][c];
196 
197  invert(tmp, res, DIM_FEAT);
198 
199 
200 
201  for (int r = 0; r < DIM_FEAT; r++)
202  for (int c = 0; c < DIM_FEAT; c++)
203  invUnitVarCovMat[r][c] = res[r][c];
204 }
205 
206 template<class F,int DIM_FEAT>
208 {
209  using namespace std;
210 
211  cout << "ORIGINAL (RAW) COVARIANCE MATRIX:" << endl << endl;;
212  for(int r = 0; r < DIM_FEAT; r++)
213  {
214  for(int c = 0; c < DIM_FEAT; c++)
215  {
216  cout << rawCovMat[r][c] << "\t";
217  }
218  cout << endl;
219  }
220  cout << endl;
221 
222  cout << "INVERSE (RAW) COVARIANCE MATRIX:" << endl << endl;;
223  for(int r = 0; r < DIM_FEAT; r++)
224  {
225  for(int c = 0; c < DIM_FEAT; c++)
226  {
227  cout << invRawCovMat[r][c] << "\t";
228  }
229  cout << endl;
230  }
231  cout << endl;
232 
233 
234  cout << "VAR^-1-SCALED COVARIANCE MATRIX(EXPERIMENTAL):" << endl << endl;;
235  for(int r = 0; r < DIM_FEAT; r++)
236  {
237  for(int c = 0; c < DIM_FEAT; c++)
238  {
239  cout << varScaledCovMat[r][c] << "\t";
240  }
241  cout << endl;
242  }
243  cout << endl;
244 
245 
246  cout << "UNIT VARIANCE COVARIANCE MATRIX:" << endl << endl;;
247  for(int r = 0; r < DIM_FEAT; r++)
248  {
249  for(int c = 0; c < DIM_FEAT; c++)
250  {
251  cout << unitVarCovMat[r][c] << "\t";
252  }
253  cout << endl;
254  }
255  cout << endl;
256 
257  cout << "INVERSE UNIT VARIANCE COVARIANCE MATRIX:" << endl << endl;;
258  for(int r = 0; r < DIM_FEAT; r++)
259  {
260  for(int c = 0; c < DIM_FEAT; c++)
261  {
262  cout << invUnitVarCovMat[r][c] << "\t";
263  }
264  cout << endl;
265  }
266  cout << endl;
267 
268 }
269 
270 template<class F,int DIM_FEAT>
272 {
273  return unitVarCovMat[r][c];
274 }
275 
276 template<class F,int DIM_FEAT>
278 {
279  return invUnitVarCovMat[r][c];
280 }
281 
282 template<class F,int DIM_FEAT>
283 double FeatureCovar<F,DIM_FEAT>::getRawCovMat(int r, int c) const
284 {
285  return rawCovMat[r][c];
286 }
287 
288 template<class F,int DIM_FEAT>
290 {
291  return invRawCovMat[r][c];
292 }
293 
294 template<class F,int DIM_FEAT>
296 {
297  return varScaledCovMat[r][c];
298 }
299 
300 template<class F,int DIM_FEAT>
302 {
303  return means[d];
304 }
305 
306 template<class F,int DIM_FEAT>
307 int FeatureCovar<F,DIM_FEAT>::invert (double a[][2*DIM_FEAT], double ainv[][2*DIM_FEAT], int n)
308 {
309  using namespace std;
310 
311  int i, j; // Zeile, Spalte
312  int s; // Elimininationsschritt
313  int pzeile; // Pivotzeile
314  int fehler = 0; // Fehlerflag
315  double f; // Multiplikationsfaktor
316  const double Epsilon = 0.01; // Genauigkeit
317  double Maximum; // Zeilenpivotisierung
318  //extern FILE *fout;
319  int pivot = 1;
320 
321  // ergänze die Matrix a um eine Einheitsmatrix (rechts anhängen)
322  for (i = 0; i < n; i++) {
323  for (j = 0; j < n; j++)
324  {
325  a[i][n+j] = 0.0;
326  if (i == j)
327  a[i][n+j] = 1.0;
328  }
329  }
330 
331  // die einzelnen Eliminationsschritte
332  s = 0;
333  do {
334  // Pivotisierung vermeidet unnötigen Abbruch bei einer Null in der Diagnonalen und
335  // erhöht die Rechengenauigkeit
336  Maximum = fabs(a[s][s]);
337  if (pivot)
338  {
339  pzeile = s ;
340  for (i = s+1; i < n; i++)
341  if (fabs(a[i][s]) > Maximum) {
342  Maximum = fabs(a[i][s]) ;
343  pzeile = i;
344  }
345  }
346  fehler = (Maximum < Epsilon);
347 
348  if (fehler) break; // nicht lösbar
349 
350  if (pivot)
351  {
352  if (pzeile != s) // falls erforderlich, Zeilen tauschen
353  { double h;
354  for (j = s ; j < 2*n; j++) {
355  h = a[s][j];
356  a[s][j] = a[pzeile][j];
357  a[pzeile][j]= h;
358  }
359  }
360  }
361 
362  // Eliminationszeile durch Pivot-Koeffizienten f = a[s][s] dividieren
363  f = a[s][s];
364  for (j = s; j < 2*n; j++)
365  a[s][j] = a[s][j] / f;
366 
367  // Elimination --> Nullen in Spalte s oberhalb und unterhalb der Diagonalen
368  // durch Addition der mit f multiplizierten Zeile s zur jeweiligen Zeile i
369  for (i = 0; i < n; i++ ) {
370  if (i != s)
371  {
372  f = -a[i][s]; // Multiplikationsfaktor
373  for (j = s; j < 2*n ; j++) // die einzelnen Spalten
374  a[i][j] += f*a[s][j]; // Addition der Zeilen i, s
375  }
376  }
377  s++;
378  } while ( s < n ) ;
379 
380  if (fehler)
381  {
382  cout <<"Inverse: Matrix ist singulär\n" << endl;
383  return 0;
384  }
385  // Die angehängte Einheitsmatrix Matrix hat sich jetzt in die inverse Matrix umgewandelt
386  // Umkopieren auf die Zielmatrix
387  for (i = 0; i < n; i++) {
388  for (j = 0; j < n; j++) {
389  ainv[i][j] = a[i][n+j];
390  }
391  }
392  return 1;
393 }
394 
395 #endif // FEATURECOVAR_H
unsigned int size() const
Definition: FeatureCovar.h:30
double getInvRawCovMat(int r, int c) const
Definition: FeatureCovar.h:289
double getRawCovMat(int r, int c) const
Definition: FeatureCovar.h:283
double getMean(int d) const
Definition: FeatureCovar.h:301
double getVarScaledCovMat(int r, int c) const
Definition: FeatureCovar.h:295
double getUnitVarCovMat(int r, int c) const
Definition: FeatureCovar.h:271
void compute()
Definition: FeatureCovar.h:80
double getInvUnitVarCovMat(int r, int c) const
Definition: FeatureCovar.h:277
Definition: FeatureCovar.h:22
void print()
Definition: FeatureCovar.h:207
FeatureCovar(const std::vector< F > &values_)
Definition: FeatureCovar.h:65