source: util/src/average.cpp@ e34098

Last change on this file since e34098 was 5a84ee, checked in by Frederik Heber <heber@…>, 15 years ago

Rewrite of average.cpp and added first UnitTest.

  • average.cpp is now called averager.cpp and uses a function AverageColumns().
  • new function AverageColumns(): takes an input streamd and a set of column indices for which averages shall be computed
  • Introduced unit tests to Utils part of ESPACK:
    • new unit test AverageColumnsUnitTest testing the above.
    • Makefile generation introduced into configure.ac
    • subdir forked in Makefile.am
  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * average.cpp
3 *
4 * Created on: Apr 15, 2010
5 * Author: heber
6 */
7
8using namespace std;
9
10#include <iostream>
11#include <iomanip>
12#include <string>
13#include <sstream>
14
15#include "average.hpp"
16
17/** Takes the average over all entries in a list of columns per column.
18 * Note that point in ifstream \a data is returned to its position on beginning.
19 * \param data input stream with entries, columns are white-space separated, rows by new-line.
20 * \param Columns set of indices (zero-based) for which columns to compute the average,
21 * note that Columns is copied to allow for removal of faulty column indices.
22 * \return pointer to map with column index as key and tuple (mean,std deviation) as value
23 */
24MeanErrorMap *AverageColumns(istream &data, IndexSet Columns)
25{
26 MeanErrorMap *Values = new MeanErrorMap;
27 map<int, int> CountMap;
28 double tmp = 0.;
29 int cols = 0;
30 int lines = 0;
31 string zeile;
32 stringstream line;
33
34 // store position of ifstream
35 size_t position = data.tellg();
36
37 // set initial values in maps to zero
38 for (IndexSet::iterator ColRunner = Columns.begin(); ColRunner != Columns.end(); ++ColRunner) {
39 Values->insert( pair<int, pair<double, double> > (*ColRunner, pair<double, double> (0., 0.) ) );
40 CountMap.insert( pair<int, int> (0, 0) );
41 }
42
43 /// The average is taken by going through each line, scanning the desired column, adding up
44 /// and keeping count of the number of summands.
45 lines = 0;
46 while (getline(data, zeile, '\n')) {
47 // get next line
48 line.clear();
49 line.str(zeile);
50 lines++;
51 // go through the columns
52 cols = -1;
53 IndexSet::const_iterator Eraser = Columns.end();
54 for (IndexSet::const_iterator ColRunner = Columns.begin(); ColRunner != Columns.end(); ++ColRunner) {
55 // delete earlier column if necessary
56 if (Eraser != Columns.end()) {
57 Columns.erase(Eraser);
58 Eraser = Columns.end();
59 }
60 // skip to next desired column
61 for(;cols!=*ColRunner;++cols)
62 if (!line.eof()) // check for end of line
63 line >> ws >> tmp;
64 else
65 break;
66 if (cols == *ColRunner) { // if end of line has not been reached
67 (*Values)[*ColRunner].first += tmp;
68 ++CountMap[*ColRunner];
69 } else {
70 cerr << "Not enough columns in line " << lines << "." << endl;
71 Eraser = ColRunner;
72 break;
73 }
74 }
75 if (Eraser != Columns.end()) {
76 Columns.erase(Eraser);
77 Eraser = Columns.end();
78 }
79 }
80
81 // go through each value in Results and take average
82 {
83 MeanErrorMap::iterator Eraser = Values->end();
84 for (MeanErrorMap::iterator Runner = Values->begin(); Runner != Values->end(); ++Runner) {
85 if(Eraser != Values->end()) {
86 Values->erase(Eraser);
87 Eraser = Values->end();
88 }
89 if (CountMap[Runner->first] != 0)
90 Runner->second.first /= CountMap[Runner->first];
91 else {
92 cerr << "For column " << CountMap[Runner->first] << " no entries have been found." << endl;
93 Eraser = Runner;
94 }
95 }
96 if(Eraser != Values->end()) {
97 Values->erase(Eraser);
98 Eraser = Values->end();
99 }
100 }
101
102 // goto to beginning again for second sweep
103 data.clear();
104 data.seekg(position);
105
106 /// The average is taken by going through each line, scanning the desired column, adding up
107 /// and keeping count of the number of summands.
108 lines = 0;
109 while (getline(data, zeile, '\n')) {
110 // get next line
111 line.clear();
112 line.str(zeile);
113 lines++;
114 // go through the columns
115 cols = 0;
116 for (IndexSet::const_iterator ColRunner = Columns.begin(); ColRunner != Columns.end(); ++ColRunner) {
117 // skip to next desired column
118 for(;cols!=*ColRunner;++cols)
119 if (!line.eof()) // check for end of line
120 line >> ws >> tmp;
121 else
122 break;
123 if (cols == *ColRunner) { // if end of line has not been reached
124 (*Values)[*ColRunner].second += (tmp - (*Values)[*ColRunner].first)*(tmp - (*Values)[*ColRunner].first);
125 } else {
126 cerr << "Not enough columns in line " << lines << "." << endl;
127 break;
128 }
129 }
130 }
131
132 // go through each value in Results and take std deviation
133 for (MeanErrorMap::iterator Runner = Values->begin(); Runner != Values->end(); ++Runner)
134 if (CountMap[Runner->first] != 0)
135 Runner->second.second /= CountMap[Runner->first];
136 else
137 cerr << "For column " << CountMap[Runner->first] << " no entries have been found." << endl;
138
139 // go back to initial pointer of data
140 data.clear();
141 data.seekg(position);
142
143 return Values;
144};
Note: See TracBrowser for help on using the repository browser.